From 90ae413a94da014dbf7a6a8ab584f7c668483a5a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 27 Feb 2014 00:01:50 +0000 Subject: pgf 3.0.0 git-svn-id: svn://tug.org/texlive/trunk@33057 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/context/third/pgf/basiclayer/t-pgf.tex | 9 +- .../tex/context/third/pgf/basiclayer/t-pgfbim.tex | 9 +- .../tex/context/third/pgf/basiclayer/t-pgfcor.tex | 7 + .../tex/context/third/pgf/frontendlayer/t-tikz.tex | 9 +- .../tex/context/third/pgf/math/t-pgfmat.tex | 9 +- .../tex/context/third/pgf/systemlayer/t-pgfsys.tex | 9 +- .../tex/context/third/pgf/utilities/t-pgfcal.tex | 7 + .../tex/context/third/pgf/utilities/t-pgffor.tex | 9 +- .../tex/context/third/pgf/utilities/t-pgfkey.tex | 9 +- .../tex/context/third/pgf/utilities/t-pgfmod.tex | 9 +- .../tex/context/third/pgf/utilities/t-pgfrcs.tex | 9 +- .../generic/pgf/basiclayer/pgfcorearrows.code.tex | 1318 ++++-- .../pgf/basiclayer/pgfcoreexternal.code.tex | 50 +- .../pgf/basiclayer/pgfcoregraphicstate.code.tex | 34 +- .../generic/pgf/basiclayer/pgfcoreimage.code.tex | 21 +- .../generic/pgf/basiclayer/pgfcorelayers.code.tex | 83 +- .../pgf/basiclayer/pgfcorepathconstruct.code.tex | 221 +- .../pgf/basiclayer/pgfcorepathprocessing.code.tex | 100 +- .../pgf/basiclayer/pgfcorepathusage.code.tex | 606 ++- .../pgf/basiclayer/pgfcorepatterns.code.tex | 169 +- .../generic/pgf/basiclayer/pgfcorepoints.code.tex | 123 +- .../generic/pgf/basiclayer/pgfcorescopes.code.tex | 76 +- .../generic/pgf/basiclayer/pgfcoreshade.code.tex | 39 +- .../pgf/basiclayer/pgfcoretransformations.code.tex | 131 +- .../pgf/basiclayer/pgfcoretransparency.code.tex | 91 +- .../tex/generic/pgf/frontendlayer/svg/svgpgf.cfg | 2 - .../tex/generic/pgf/frontendlayer/svg/svgpgf.xmt | 48 - .../tex/generic/pgf/frontendlayer/svg/svgtest.cfg | 3 - .../tex/generic/pgf/frontendlayer/svg/svgtest.tex | 15 - .../tex/generic/pgf/frontendlayer/svg/svgtest.xml | 30 - .../circuits/tikzlibrarycircuits.code.tex | 16 +- .../circuits/tikzlibrarycircuits.ee.code.tex | 30 +- .../tikzlibrarydatavisualization.code.tex | 1220 +++-- .../tikzlibrarydatavisualization.polar.code.tex | 543 ++- .../graphs/tikzlibrarygraphs.basic.code.tex | 29 - .../libraries/graphs/tikzlibrarygraphs.code.tex | 2213 ++++++++- .../graphs/tikzlibrarygraphs.standard.code.tex | 112 + .../tikz/libraries/tikzexternalshared.code.tex | 319 +- .../tikz/libraries/tikzlibrary3d.code.tex | 6 +- .../tikz/libraries/tikzlibraryangles.code.tex | 72 + .../tikz/libraries/tikzlibrarybabel.code.tex | 17 + .../tikz/libraries/tikzlibrarybackgrounds.code.tex | 12 +- .../tikz/libraries/tikzlibrarybending.code.tex | 15 + .../tikz/libraries/tikzlibrarycalc.code.tex | 101 +- .../tikz/libraries/tikzlibrarycalendar.code.tex | 18 +- .../tikz/libraries/tikzlibrarychains.code.tex | 8 +- .../tikz/libraries/tikzlibrarydecorations.code.tex | 14 +- .../libraries/tikzlibrarydecorations.text.code.tex | 693 ++- .../tikz/libraries/tikzlibraryfit.code.tex | 92 +- .../tikz/libraries/tikzlibraryfolding.code.tex | 2028 +++++++- .../libraries/tikzlibraryintersections.code.tex | 53 +- .../tikz/libraries/tikzlibrarymath.code.tex | 725 +++ .../tikz/libraries/tikzlibrarymatrix.code.tex | 21 +- .../tikz/libraries/tikzlibrarymindmap.code.tex | 26 +- .../tikz/libraries/tikzlibrarypetri.code.tex | 4 +- .../tikz/libraries/tikzlibraryquotes.code.tex | 88 + .../tikz/libraries/tikzlibrarysnakes.code.tex | 4 +- .../tikz/libraries/tikzlibraryspy.code.tex | 10 +- .../tikz/libraries/tikzlibrarysvg.path.code.tex | 8 +- .../generic/pgf/frontendlayer/tikz/tikz.code.tex | 1697 +++++-- .../generic/pgf/graphdrawing/lua/LUA_CODING_STYLE | 27 + .../tex/generic/pgf/graphdrawing/lua/pgf.lua | 72 + .../tex/generic/pgf/graphdrawing/lua/pgf/gd.lua | 72 + .../pgf/graphdrawing/lua/pgf/gd/bindings.lua | 26 + .../graphdrawing/lua/pgf/gd/bindings/Binding.lua | 264 ++ .../lua/pgf/gd/bindings/BindingToPGF.lua | 280 ++ .../pgf/graphdrawing/lua/pgf/gd/circular.lua | 22 + .../lua/pgf/gd/circular/Tantau2012.lua | 144 + .../graphdrawing/lua/pgf/gd/circular/library.lua | 30 + .../pgf/graphdrawing/lua/pgf/gd/control.lua | 26 + .../graphdrawing/lua/pgf/gd/control/Anchoring.lua | 104 + .../lua/pgf/gd/control/ComponentAlign.lua | 521 +++ .../lua/pgf/gd/control/ComponentDirection.lua | 61 + .../lua/pgf/gd/control/ComponentDistance.lua | 102 + .../lua/pgf/gd/control/ComponentOrder.lua | 107 + .../graphdrawing/lua/pgf/gd/control/Components.lua | 129 + .../graphdrawing/lua/pgf/gd/control/Distances.lua | 461 ++ .../graphdrawing/lua/pgf/gd/control/FineTune.lua | 164 + .../lua/pgf/gd/control/LayoutPipeline.lua | 1282 ++++++ .../lua/pgf/gd/control/NodeAnchors.lua | 174 + .../lua/pgf/gd/control/Orientation.lua | 314 ++ .../graphdrawing/lua/pgf/gd/control/Sublayouts.lua | 536 +++ .../graphdrawing/lua/pgf/gd/control/library.lua | 199 + .../graphdrawing/lua/pgf/gd/deprecated/Cluster.lua | 65 + .../graphdrawing/lua/pgf/gd/deprecated/Edge.lua | 358 ++ .../graphdrawing/lua/pgf/gd/deprecated/Graph.lua | 396 ++ .../lua/pgf/gd/deprecated/Iterators.lua | 91 + .../graphdrawing/lua/pgf/gd/deprecated/Node.lua | 280 ++ .../graphdrawing/lua/pgf/gd/deprecated/Vector.lua | 256 ++ .../generic/pgf/graphdrawing/lua/pgf/gd/doc.lua | 122 + .../lua/pgf/gd/doc/circular/Tantau2012.lua | 136 + .../lua/pgf/gd/doc/control/Anchoring.lua | 224 + .../lua/pgf/gd/doc/ogdf/energybased.lua | 19 + .../lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua | 129 + .../doc/ogdf/energybased/FastMultipoleEmbedder.lua | 51 + .../lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua | 103 + .../gd/doc/ogdf/energybased/MultilevelLayout.lua | 33 + .../gd/doc/ogdf/energybased/SpringEmbedderFR.lua | 54 + .../doc/ogdf/energybased/SpringEmbedderFRExact.lua | 57 + .../gd/doc/ogdf/energybased/SpringEmbedderKK.lua | 64 + .../multilevelmixer/BarycenterPlacer.lua | 33 + .../energybased/multilevelmixer/CirclePlacer.lua | 45 + .../multilevelmixer/EdgeCoverMerger.lua | 33 + .../multilevelmixer/IndependentSetMerger.lua | 33 + .../multilevelmixer/LocalBiconnectedMerger.lua | 33 + .../energybased/multilevelmixer/MatchingMerger.lua | 33 + .../energybased/multilevelmixer/MedianPlacer.lua | 27 + .../energybased/multilevelmixer/RandomMerger.lua | 33 + .../energybased/multilevelmixer/RandomPlacer.lua | 33 + .../energybased/multilevelmixer/SolarMerger.lua | 39 + .../energybased/multilevelmixer/SolarPlacer.lua | 27 + .../energybased/multilevelmixer/ZeroPlacer.lua | 33 + .../graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua | 19 + .../gd/doc/ogdf/layered/BarycenterHeuristic.lua | 23 + .../gd/doc/ogdf/layered/CoffmanGrahamRanking.lua | 35 + .../pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua | 27 + .../gd/doc/ogdf/layered/FastHierarchyLayout.lua | 99 + .../doc/ogdf/layered/FastSimpleHierarchyLayout.lua | 97 + .../pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua | 27 + .../gd/doc/ogdf/layered/GreedyInsertHeuristic.lua | 23 + .../pgf/gd/doc/ogdf/layered/LongestPathRanking.lua | 57 + .../pgf/gd/doc/ogdf/layered/MedianHeuristic.lua | 24 + .../lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua | 35 + .../pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua | 34 + .../lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua | 24 + .../lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua | 116 + .../lua/pgf/gd/doc/ogdf/misclayout.lua | 19 + .../pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua | 48 + .../pgf/gd/doc/ogdf/misclayout/CircularLayout.lua | 95 + .../gd/doc/ogdf/module/AcyclicSubgraphModule.lua | 18 + .../gd/doc/ogdf/module/HierarchyLayoutModule.lua | 17 + .../lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua | 17 + .../pgf/gd/doc/ogdf/module/MultilevelBuilder.lua | 17 + .../lua/pgf/gd/doc/ogdf/module/RankingModule.lua | 17 + .../pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua | 17 + .../graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua | 19 + .../gd/doc/ogdf/planarity/PlanarizationLayout.lua | 66 + .../lua/pgf/gd/doc/trees/ReingoldTilford1981.lua | 309 ++ .../pgf/graphdrawing/lua/pgf/gd/examples.lua | 26 + .../lua/pgf/gd/examples/ASCIIDisplayer.lua | 32 + .../lua/pgf/gd/examples/BindingToASCII.lua | 87 + .../lua/pgf/gd/examples/SimpleDemo.lua | 82 + .../lua/pgf/gd/examples/SimpleEdgeDemo.lua | 142 + .../lua/pgf/gd/examples/SimpleHuffman.lua | 277 ++ .../examples/example_graph_for_ascii_displayer.txt | 20 + .../graphdrawing/lua/pgf/gd/examples/library.lua | 30 + .../generic/pgf/graphdrawing/lua/pgf/gd/force.lua | 26 + .../graphdrawing/lua/pgf/gd/force/CoarseGraph.lua | 435 ++ .../pgf/graphdrawing/lua/pgf/gd/force/Control.lua | 28 + .../lua/pgf/gd/force/ControlCoarsening.lua | 148 + .../lua/pgf/gd/force/ControlElectric.lua | 100 + .../lua/pgf/gd/force/ControlIteration.lua | 144 + .../lua/pgf/gd/force/ControlSprings.lua | 58 + .../graphdrawing/lua/pgf/gd/force/ControlStart.lua | 40 + .../pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua | 280 ++ .../lua/pgf/gd/force/SpringElectricalHu2006.lua | 521 +++ .../lua/pgf/gd/force/SpringElectricalLayouts.lua | 54 + .../pgf/gd/force/SpringElectricalWalshaw2000.lua | 516 +++ .../graphdrawing/lua/pgf/gd/force/SpringHu2006.lua | 387 ++ .../lua/pgf/gd/force/SpringLayouts.lua | 36 + .../pgf/graphdrawing/lua/pgf/gd/force/library.lua | 126 + .../pgf/graphdrawing/lua/pgf/gd/interface.lua | 26 + .../lua/pgf/gd/interface/InterfaceCore.lua | 174 + .../lua/pgf/gd/interface/InterfaceToAlgorithms.lua | 938 ++++ .../lua/pgf/gd/interface/InterfaceToC.lua | 77 + .../lua/pgf/gd/interface/InterfaceToDisplay.lua | 990 ++++ .../graphdrawing/lua/pgf/gd/interface/Scope.lua | 92 + .../pgf/graphdrawing/lua/pgf/gd/layered.lua | 159 + .../layered/CrossingMinimizationGansnerKNV1993.lua | 342 ++ .../pgf/gd/layered/CycleRemovalBergerS1990a.lua | 75 + .../pgf/gd/layered/CycleRemovalBergerS1990b.lua | 76 + .../lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua | 124 + .../pgf/gd/layered/CycleRemovalGansnerKNV1993.lua | 52 + .../pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua | 22 + .../lua/pgf/gd/layered/NetworkSimplex.lua | 898 ++++ .../gd/layered/NodePositioningGansnerKNV1993.lua | 154 + .../pgf/gd/layered/NodeRankingGansnerKNV1993.lua | 159 + .../pgf/gd/layered/NodeRankingMinimumHeight.lua | 47 + .../graphdrawing/lua/pgf/gd/layered/Ranking.lua | 291 ++ .../graphdrawing/lua/pgf/gd/layered/Sugiyama.lua | 478 ++ .../lua/pgf/gd/layered/crossing_minimization.lua | 81 + .../lua/pgf/gd/layered/cycle_removal.lua | 139 + .../lua/pgf/gd/layered/edge_routing.lua | 50 + .../graphdrawing/lua/pgf/gd/layered/library.lua | 91 + .../lua/pgf/gd/layered/node_positioning.lua | 57 + .../lua/pgf/gd/layered/node_ranking.lua | 74 + .../generic/pgf/graphdrawing/lua/pgf/gd/lib.lua | 356 ++ .../pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua | 160 + .../lua/pgf/gd/lib/DepthFirstSearch.lua | 125 + .../pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua | 95 + .../pgf/graphdrawing/lua/pgf/gd/lib/Event.lua | 98 + .../graphdrawing/lua/pgf/gd/lib/LookupTable.lua | 111 + .../graphdrawing/lua/pgf/gd/lib/PathLengths.lua | 209 + .../graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua | 342 ++ .../graphdrawing/lua/pgf/gd/lib/Simplifiers.lua | 279 ++ .../pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua | 61 + .../pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua | 110 + .../pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua | 104 + .../generic/pgf/graphdrawing/lua/pgf/gd/model.lua | 26 + .../pgf/graphdrawing/lua/pgf/gd/model/Arc.lua | 592 +++ .../graphdrawing/lua/pgf/gd/model/Collection.lua | 208 + .../graphdrawing/lua/pgf/gd/model/Coordinate.lua | 301 ++ .../pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua | 843 ++++ .../pgf/graphdrawing/lua/pgf/gd/model/Edge.lua | 205 + .../graphdrawing/lua/pgf/gd/model/Hyperedge.lua | 56 + .../pgf/graphdrawing/lua/pgf/gd/model/Path.lua | 1220 +++++ .../pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua | 277 ++ .../pgf/graphdrawing/lua/pgf/gd/model/library.lua | 15 + .../generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua | 26 + .../pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua | 33 + .../pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua | 21 + .../gd/phylogenetics/AuthorDefinedPhylogeny.lua | 77 + .../gd/phylogenetics/BalancedMinimumEvolution.lua | 593 +++ .../BalancedNearestNeighbourInterchange.lua | 372 ++ .../lua/pgf/gd/phylogenetics/DistanceMatrix.lua | 440 ++ .../lua/pgf/gd/phylogenetics/Maeusle2012.lua | 778 ++++ .../lua/pgf/gd/phylogenetics/PhylogeneticTree.lua | 91 + .../lua/pgf/gd/phylogenetics/SokalMichener1958.lua | 261 ++ .../lua/pgf/gd/phylogenetics/library.lua | 35 + .../graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua | 183 + .../generic/pgf/graphdrawing/lua/pgf/gd/trees.lua | 21 + .../graphdrawing/lua/pgf/gd/trees/ChildSpec.lua | 227 + .../lua/pgf/gd/trees/ReingoldTilford1981.lua | 211 + .../lua/pgf/gd/trees/SpanningTreeComputation.lua | 637 +++ .../pgf/graphdrawing/lua/pgf/gd/trees/library.lua | 35 + .../tex/pgflibrarygraphdrawing.circular.code.tex | 16 + .../tex/pgflibrarygraphdrawing.code.tex | 1126 +++++ .../tex/pgflibrarygraphdrawing.examples.code.tex | 17 + .../tex/pgflibrarygraphdrawing.force.code.tex | 136 + .../tex/pgflibrarygraphdrawing.layered.code.tex | 17 + .../tex/pgflibrarygraphdrawing.trees.code.tex | 19 + .../tex/tikzlibrarygraphdrawing.code.tex | 240 + ...arydatavisualization.formats.functions.code.tex | 20 +- .../pgflibrarydatavisualization.polar.code.tex | 56 +- .../pgflibrarydecorations.markings.code.tex | 13 +- .../pgflibrarydecorations.shapes.code.tex | 4 +- .../libraries/luamath/pgflibraryluamath.code.tex | 499 ++ .../pgf/libraries/luamath/pgfluamath.functions.lua | 313 ++ .../pgf/libraries/luamath/pgfluamath.parser.lua | 647 +++ .../pgf/libraries/pgflibraryarrows.code.tex | 17 +- .../pgf/libraries/pgflibraryarrows.meta.code.tex | 1612 +++++++ .../pgf/libraries/pgflibraryarrows.spaced.code.tex | 92 + .../pgf/libraries/pgflibrarycurvilinear.code.tex | 378 ++ .../pgflibraryfixedpointarithmetic.code.tex | 4 +- .../generic/pgf/libraries/pgflibraryfpu.code.tex | 127 +- .../pgf/libraries/pgflibraryintersections.code.tex | 78 +- .../pgflibrarylindenmayersystems.code.tex | 2 +- .../pgf/libraries/pgflibraryplothandlers.code.tex | 380 +- .../pgf/libraries/pgflibraryplotmarks.code.tex | 4 +- .../pgf/libraries/pgflibraryprofiler.code.tex | 35 +- .../pgf/libraries/pgflibrarysnakes.code.tex | 5 +- .../pgf/libraries/pgflibrarysvg.path.code.tex | 6 +- .../circuits/pgflibraryshapes.gates.ee.code.tex | 9 +- .../pgflibraryshapes.gates.logic.IEC.code.tex | 1274 +++--- .../pgflibraryshapes.gates.logic.US.code.tex | 20 +- .../shapes/pgflibraryshapes.callouts.code.tex | 16 +- .../shapes/pgflibraryshapes.misc.code.tex | 8 +- .../shapes/pgflibraryshapes.symbols.code.tex | 4820 ++++++++++---------- .../texmf-dist/tex/generic/pgf/lua/pgf/manual.lua | 18 + .../generic/pgf/lua/pgf/manual/DocumentParser.lua | 596 +++ .../tex/generic/pgf/math/pgfmath.code.tex | 6 + .../tex/generic/pgf/math/pgfmathcalc.code.tex | 598 ++- .../tex/generic/pgf/math/pgfmathfloat.code.tex | 245 +- .../pgf/math/pgfmathfunctions.base.code.tex | 28 + .../pgf/math/pgfmathfunctions.basic.code.tex | 172 +- .../tex/generic/pgf/math/pgfmathfunctions.code.tex | 7 + .../pgfmathfunctions.integerarithmetics.code.tex | 124 + .../pgf/math/pgfmathfunctions.misc.code.tex | 27 +- .../math/pgfmathfunctions.trigonometric.code.tex | 2761 +++++------ .../tex/generic/pgf/math/pgfmathode.code.tex | 178 + .../tex/generic/pgf/math/pgfmathparser.code.tex | 1073 +++-- .../tex/generic/pgf/math/pgfmathutil.code.tex | 4 +- .../generic/pgf/modules/pgfmodulebending.code.tex | 355 ++ .../modules/pgfmoduledatavisualization.code.tex | 485 +- .../pgf/modules/pgfmoduledecorations.code.tex | 2175 +++++---- .../generic/pgf/modules/pgfmodulematrix.code.tex | 72 +- .../pgfmodulenonlineartransformations.code.tex | 342 ++ .../tex/generic/pgf/modules/pgfmoduleoo.code.tex | 472 +- .../generic/pgf/modules/pgfmoduleparser.code.tex | 6 +- .../tex/generic/pgf/modules/pgfmoduleplot.code.tex | 260 +- .../generic/pgf/modules/pgfmoduleshapes.code.tex | 269 +- .../generic/pgf/modules/pgfmodulesnakes.code.tex | 7 +- .../generic/pgf/rendering/pgfrenderpoints.code.tex | 138 - .../pgf/rendering/pgfrendertransform.code.tex | 117 - .../pgf/systemlayer/pgfsys-common-pdf-via-dvi.def | 4 +- .../generic/pgf/systemlayer/pgfsys-common-pdf.def | 34 +- .../generic/pgf/systemlayer/pgfsys-common-svg.def | 91 +- .../tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def | 9 +- .../generic/pgf/systemlayer/pgfsys-dvipdfmx.def | 143 +- .../tex/generic/pgf/systemlayer/pgfsys-dvips.def | 14 +- .../tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def | 78 + .../tex/generic/pgf/systemlayer/pgfsys-pdftex.def | 66 +- .../tex/generic/pgf/systemlayer/pgfsys-tex4ht.def | 352 +- .../generic/pgf/systemlayer/pgfsys-textures.def | 10 +- .../tex/generic/pgf/systemlayer/pgfsys-vtex.def | 11 +- .../tex/generic/pgf/systemlayer/pgfsys-xetex.def | 82 +- .../tex/generic/pgf/systemlayer/pgfsys.code.tex | 131 +- .../pgf/systemlayer/pgfsyssoftpath.code.tex | 41 +- .../tex/generic/pgf/utilities/pgffor.code.tex | 102 +- .../tex/generic/pgf/utilities/pgfkeys.code.tex | 441 +- .../generic/pgf/utilities/pgfkeysfiltered.code.tex | 6 +- .../tex/generic/pgf/utilities/pgfrcs.code.tex | 12 +- .../generic/pgf/utilities/pgfutil-common-lists.tex | 159 + .../tex/generic/pgf/utilities/pgfutil-common.tex | 136 +- .../tex/generic/pgf/utilities/pgfutil-context.def | 68 +- .../tex/generic/pgf/utilities/pgfutil-latex.def | 77 +- .../tex/generic/pgf/utilities/pgfutil-plain.def | 88 +- Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty | 2 +- .../tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex | 22 +- .../latex/pgf/doc/pgfmanual.prettyprinter.code.tex | 10 +- .../libraries/tikzlibraryexternal.code.tex | 33 + Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty | 1 + .../tex/latex/pgf/systemlayer/pgfsys.sty | 4 + .../texmf-dist/tex/latex/pgf/utilities/pgffor.sty | 1 + .../tex/latex/pgf/utilities/pgfpages.sty | 57 +- 315 files changed, 56529 insertions(+), 10101 deletions(-) delete mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg delete mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt delete mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg delete mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex delete mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml delete mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleDemo.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleEdgeDemo.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua create mode 100644 Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex delete mode 100644 Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex delete mode 100644 Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex create mode 100644 Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def create mode 100644 Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex (limited to 'Master/texmf-dist/tex') diff --git a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex index eab81dec5b4..333d7c3d14a 100644 --- a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex +++ b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgf.tex @@ -10,6 +10,10 @@ % ConTeXt module pgf. +\writestatus{loading}{ConTeXt User Module / pgf} + +\unprotect + \ifx\pgfdefined\undefined \let\pgfdefined=\relax @@ -24,4 +28,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex index 7e1cad0623f..943a34cf833 100644 --- a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex +++ b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfbim.tex @@ -9,7 +9,14 @@ % ConTeXt module pgfbaseimage. +\writestatus{loading}{ConTeXt User Module / pgfbim} + +\unprotect + \PackageWarning{pgf}{This module is obsolete and no longer needed} -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex index 172019d86da..975bfc252ca 100644 --- a/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex +++ b/Master/texmf-dist/tex/context/third/pgf/basiclayer/t-pgfcor.tex @@ -9,6 +9,10 @@ % ConTeXt module pgfcore. +\writestatus{loading}{ConTeXt User Module / pgfcor} + +\unprotect + \ifx\pgfcoredefined\undefined @@ -50,4 +54,7 @@ \fi +\stopmodule + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex b/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex index d3fc269d385..85c6fcf2f0b 100644 --- a/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex +++ b/Master/texmf-dist/tex/context/third/pgf/frontendlayer/t-tikz.tex @@ -9,6 +9,10 @@ % ConTeXt module tikz. +\writestatus{loading}{ConTeXt User Module / tikz} + +\unprotect + % \input xkeyval.tex % no longer used/needed @@ -31,4 +35,7 @@ \let\starttikzpicture=\tikzpicture \let\stoptikzpicture=\endtikzpicture -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex b/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex index 45fc7606906..bdc8e6569de 100644 --- a/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex +++ b/Master/texmf-dist/tex/context/third/pgf/math/t-pgfmat.tex @@ -9,6 +9,10 @@ % ConTeXt module pgfmath. +\writestatus{loading}{ConTeXt User Module / pgfmath} + +\unprotect + \ifx\pgfmathdefined\undefined \let\pgfmathdefined=\relax @@ -28,4 +32,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex b/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex index 8b2453b094f..5d78653282e 100644 --- a/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex +++ b/Master/texmf-dist/tex/context/third/pgf/systemlayer/t-pgfsys.tex @@ -9,6 +9,10 @@ % ConTeXt module pgfsys. +\writestatus{loading}{ConTeXt User Module / pgfsys} + +\unprotect + \ifx\pgfsysdefined\undefined \let\pgfsysdefined=\relax @@ -32,4 +36,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex index 8d74ee6db5a..4651a99cf96 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfcal.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgfcalendar. +\writestatus{loading}{ConTeXt User Module / pgfcalendar} + +\unprotect + \ifx\pgfcalendardefined\undefined \let\pgfcalendardefined=\relax @@ -26,4 +30,7 @@ \fi +\stopmodule + +\protect \endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex index 8fea962d972..390e9dccde2 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgffor.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgffor. +\writestatus{loading}{ConTeXt User Module / pgffor} + +\unprotect + \ifx\pgffordefined\undefined \let\pgffordefined=\relax @@ -27,4 +31,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex index dbc393a8276..291384bc58f 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfkey.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgfkeys. +\writestatus{loading}{ConTeXt User Module / pgfkey} + +\unprotect + \ifx\pgfkeysdefined\undefined \let\pgfkeysdefined=\relax @@ -24,4 +28,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex index ab7b456f5c7..d8c0fa39c8d 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfmod.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\writestatus{loading}{ConTeXt User Module / pgfmodules} + +\unprotect + % ConTeXt module pgfmodules. @@ -41,4 +45,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex index a0a12dd47be..b4bb290b164 100644 --- a/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex +++ b/Master/texmf-dist/tex/context/third/pgf/utilities/t-pgfrcs.tex @@ -8,6 +8,10 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. % ConTeXt module pgfrcs. +\writestatus{loading}{ConTeXt User Module / pgfrcs} + +\unprotect + \ifx\pgfrcsdefined\undefined \let\pgfrcsdefined=\relax @@ -32,4 +36,7 @@ \fi -\endinput \ No newline at end of file +\stopmodule + +\protect +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex index 19e73e0b44e..d0fdab957aa 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorearrows.code.tex @@ -1,4 +1,4 @@ -% Copyright 2006 by Till Tantau +% Copyright 2006, 2013 by Till Tantau % % This file may be distributed and/or modified % @@ -7,406 +7,1061 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorearrows.code.tex,v 1.11 2008/04/23 14:59:01 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorearrows.code.tex,v 1.40 2013/11/07 15:45:46 tantau Exp $ -% Sets the end arrow + +% Define a new (meta) arrow or a shorthand % -% #1 = An arrow name +% #1 = key--value pairs % -% Example: +% Description: % -% \pgfsetarrowsend{stealth} - -\def\pgfsetarrowsend#1{\pgf@arrowset{end}{#1}} -\def\pgf@arrowset#1#2{% - \pgfutil@ifundefined{pgf@arrow@code@#2} - {\PackageError{pgf}{Arrow #1 type ``#2'' unknown}{}} - {% - \edef\pgf@arrow@temp{#2}% - \ifx\pgf@arrow@temp\pgfutil@empty% ah. clear! - \expandafter\let\csname pgf@#1arrow\endcsname=\pgfutil@empty% - \expandafter\let\csname pgf@shorten@#1\endcsname=\pgfutil@empty% +% This command is used to define a new arrow tip kind. For more +% details on the description of the keys, please see the pgfmanual. +% +% name = Name of the arrow. If the name contains a dash +% (hyphen), the text before the hyphen is the start name +% and the text behind it the end name. +% +% means = If set, none of the below options may be +% given. The effect is that whenever the arrow is +% used, it gets replaced by this "text", which is +% parsed by the parser. +% +% setup code = Code that does "precomputations". These will be +% executed only once for each combination of the +% dependencies. At the end of this code, you can use +% \savethe and \save to "save" computed values, which +% will then be available inside the "code". Values needed +% only for the "... end" keys and the convex hull do not +% need to be saved since these are also executed only +% once. +% drawing code = Code for drawing the arrow. When the cache key is set to +% true, which is the default, the code will be protocolled +% and the resulting code is inserted using \pgflowlevelobj. +% cache = Boolean that decides whether the arrow can be cached. The +% default is true, so you have to say cache=false to switch +% caching off. In this case, each time the arrow is drawn, +% its code is simply executed. This allows you to put things +% like text or shadings in arrow tips. +% bending mode = Can be set to "orthogonal", "polar", or +% "none". Defaults to "orthogonal". +% defaults = A list of "default" options for the arrow tip. These +% are executed as if they were given to the arrow tip in +% brackets. This is useful for setting up default values. +% parameters = A list of comma-separated macro names on whose values +% the appearance of the arrow tip depends. When an arrow +% tip is used, these macros are expanded. If an +% arrow tip was already installed with the same macro +% names (and caching is true), the cached code is +% used. Note that when you use dimensions here, add \the. +% +% Inside the setup code, the following macros are available: +% +% \pgfarrowsettipend +% The code should draw an arrow pointing "right along the x +% axis". The "tip" key specifies how far the arrow goes +% along the x axis, that is, it should be the x coordinate +% of the very tip of the arrow. In previous versions this +% was called the "right extend". The value passed to this +% key should be some code that sets the dimension +% "\pgfarrowresult", which is \let to be equal to +% \pgf@x. A \relax will be added after the code provided +% here, so you can write things like "\pgfarrowresult=1pt". +% \pgfarrowsetbackend +% The leftmost x-coordinate that is still part of the +% arrow tip (the "back end" of the arrow"). This coordinate +% will be used when multiple arrow tips are +% composed. Defaults to 0pt. +% \pgfarrowsetlineend +% The x-coordinate where a line should stop inside the arrow +% tip so that it gets "obscured" by the arrow. Defaults to 0pt. +% \pgfarrowsetvisualtipend +% When the arrow tip is drawn in flex mode, it is rotated +% such that the x-coordinates of "visual tip end" and "visual +% back end" lie on the path. Defaults to \pgfarrowsettipend. +% \pgfarrowsetvisualbackend +% See above. Defaults to \pgfarrowsetbackend + +\def\pgfdeclarearrow#1{% + \let\pgf@decl@arrow@defaults\pgfutil@empty% + \let\pgf@decl@arrow@means\relax% + \let\pgf@decl@arrow@code\relax% + \pgfkeys{/pgf/@arrows decl/.cd, + name=, + setup code=, + cache=true, + bending mode=orthogonal, + parameters=,% + #1% + }% + \ifx\pgf@decl@arrow@name@end\pgfutil@empty% + \pgferror{Declaring unnamed arrow}% + \else% + \pgf@arrow@letter{name@end}% + \pgf@arrow@letter{name@start}% + \expandafter\let\csname pgf@ar@start@\pgf@decl@arrow@name@start\endcsname\pgf@decl@arrow@name@end% + \expandafter\let\expandafter\pgf@old@code\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname% + \expandafter\let\expandafter\pgf@old@means\csname pgf@ar@means@\pgf@decl@arrow@name@end\endcsname% + \ifx\pgf@decl@arrow@code\relax% + \ifx\pgf@decl@arrow@means\relax% + \pgferror{You must set either the 'means' or the drawing code' keys for arrow tip '\pgf@decl@arrow@name@end'}% + \else% + \ifx\pgf@old@code\relax% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \let\pgf@arrow@translate\relax% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@\pgf@decl@arrow@means\endcsname% + \ifx\pgf@arrows@direct\relax% + \let\pgf@arrows@options\pgfutil@empty% + \expandafter\pgfarrows@initial@parser\pgf@decl@arrow@means[]\pgf@stop% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \pgf@arrow@letter@\pgf@arrow@tip@sequence{means}% + \expandafter\let\csname pgf@ar@code@\pgf@decl@arrow@name@end\endcsname\relax% + \else% + \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already + defined with key 'drawing code' previously and you cannot change this}% + \fi% + \fi% \else% - %\pgf@arrow@prepare{#2}% - \expandafter\def\csname pgf@#1arrow\endcsname{\pgf@arrow@call{#2}}% - \expandafter\edef\csname pgf@shorten@#1\endcsname{\expandafter\noexpand\csname pgf@arrow@right@#2\endcsname}% + \ifx\pgf@decl@arrow@means\relax% + \ifx\pgf@old@means\relax% + \pgf@arrow@letter{code}% + \pgf@arrow@letter{defaults}% + \pgf@arrow@letter{setup}% + \pgf@arrow@letter{bending@mode}% + \pgf@arrow@letter{par}% + \expandafter\let\csname pgf@ar@do@cache@\pgf@decl@arrow@name@end\endcsname\pgf@decl@arrow@cache% + \else% + \pgferror{Arrow tip '\pgf@decl@arrow@name@end' was already + defined with key 'means' previously and you cannot change this}% + \fi% + \else% + \pgferror{You cannot set both the 'means' and also the 'drawing code' + keys for arrow tip '\pgf@decl@arrow@name@end'}% + \fi% \fi% + \fi% +} + +\def\pgf@arrow@letter#1{% + \expandafter\pgf@arrow@letter@\expandafter{\csname pgf@decl@arrow@#1\endcsname}{#1}% +} +\def\pgf@arrow@letter@#1#2{% + \expandafter\let\csname pgf@ar@#2@\pgf@decl@arrow@name@end\endcsname#1% +} + +\pgfkeys{ + /pgf/@arrows decl/.cd, + name/.code={% + \pgfutil@in@-{#1}% + \ifpgfutil@in@% + \pgf@arrows@name@decomp#1\pgf@stop% + \else% + \def\pgf@decl@arrow@name@end{#1}\let\pgf@decl@arrow@name@start\pgf@decl@arrow@name@end% + \fi}, + means/.store in=\pgf@decl@arrow@means, + setup code/.store in=\pgf@decl@arrow@setup, + drawing code/.store in=\pgf@decl@arrow@code, + cache/.store in=\pgf@decl@arrow@cache, + bending mode/.is choice, + bending mode/none/.code=\let\pgf@decl@arrow@bending@mode\pgfutil@empty, + bending mode/orthogonal/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierorthogonal}, + bending mode/polar/.code=\def\pgf@decl@arrow@bending@mode{\pgfpointcurvilinearbezierpolar}, + parameters/.store in=\pgf@decl@arrow@par, + defaults/.code={% + \let\pgf@arrows@options\pgfutil@empty% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@decl@arrow@defaults\pgf@arrows@options% + } +} + +\def\pgf@arrows@name@decomp#1-#2\pgf@stop{% + \def\pgf@decl@arrow@name@start{#1}% + \def\pgf@decl@arrow@name@end{#2}% +} + + +% Handler for defining arrow tips: +% +% Description: +% +% When you write "my name/.tip = arrow spec", this has the same +% effect as writeing \pgfdeclarearrow{name = my name, means = arrow spec}. + +\pgfkeys{/handlers/.tip/.code=% + \expandafter\expandafter\expandafter\pgf@arrows@unravel\pgfkeyscurrentpath/\pgf@stop% + \expandafter\pgf@arrows@key@call\expandafter{\pgf@arrows@unravelled}{#1}} +\def\pgf@arrows@unravel#1/{\pgfutil@ifnextchar\pgf@stop{\def\pgf@arrows@unravelled{#1}\pgfutil@gobble}{\pgf@arrows@unravel}} +\def\pgf@arrows@key@call#1#2{\pgfdeclarearrow{name={#1},means={#2}}} + + + + +% Draw an arrow +% +% #1 = arrow specification +% +% Description: +% +% Draws the arrow in the given specification (and "end" +% specification). The arrow will be drawn such that it touches the +% origin "from the left", that is, the arrow will lie completely in +% the half plane with negative $x$ values and the tip will end exactly +% at the origin. + +\def\pgfarrowdraw#1{% + {% + \pgfsetarrowsend{#1}% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@xb% }% } -% Sets the start arrow -% -% #1 = An arrow name -% -% Example: -% -% \pgfsetarrowsstart{stealth} -\def\pgfsetarrowsstart#1{\pgf@arrowset{start}{\csname pgf@arrows@invert#1\endcsname}} +% Compute the length of an arrow +% +% #1 = arrow specification +% +% Description: +% +% In \pgf@x, this will return the total length of the arrow given as +% #1, in \pgf@xa it will return the distance from the tip to the line +% end. + +\def\pgfarrowtotallength#1{% + {% + \pgfsetarrowsend{#1}% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \expandafter\expandafter\expandafter% + }% + \expandafter\expandafter\expandafter\pgf@x\expandafter\the\expandafter\pgf@xb\expandafter\pgf@xa\the\pgf@xa% +} -\def\pgf@arrows@invname#1#2{\expandafter\def\csname pgf@arrows@invert#1\endcsname{#2}} -\pgf@arrows@invname{}{} -% Sets arrows +% Sets the end arrow tip % -% #1 = An arrow specification of the form ``left''-``right''. The last -% and right should be arrow types that have been defined using -% the \pgfarrowsdef command +% #1 = An arrow specification % -% Example: +% Description: +% +% An "arrow specification" is a sequence of names of meta arrow tips +% together with options in brackets. In detail: +% +% In #1, consider the text from the start up to the first bracket. If +% this text is the name of a (meta) arrow tip, we use this arrow tip +% with the provided options. If it is the name of a arrow tip +% shorthand, this shorthand is expanded and the options are applied to +% each arrow tip inside the shorthand. If the text is neither or the +% above, the first letter of text is treated as a shorthand without +% options. +% +% The special arrow tip "." is used to indicate the end of the line. % -% \pgfsetarrows{-to} +% \pgfsetarrowsend{stealth[reversed]} +% \pgfsetarrowsend{stealth[length=1pt] . stealth[length=2pt]} +% \pgfsetarrowsend{>>>} +% \pgfsetarrowsend{>.>} + +\def\pgfsetarrowsend#1{% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \pgf@arrows@translatefalse% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@end@#1\endcsname% + \ifx\pgf@arrows@direct\relax% + \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}% + \pgf@marshal% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \let\pgf@end@tip@sequence\pgf@arrow@tip@sequence% +} -\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop} -\def\pgf@arrows#1-#2\pgf@stop{% - \pgfsetarrowsstart{#1} - \pgfsetarrowsend{#2} +\newif\ifpgf@arrows@translate + +\def\pgfarrows@initial@parser{% + \pgfutil@ifnextchar[\pgfarrows@initial@parser@{\pgfarrows@initial@parser@[]}}%} + +\def\pgfarrows@initial@parser@[#1]{% + \let\pgf@arrows@options\pgfutil@empty% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@arrows@options@initial\pgf@arrows@options% + \pgfarrows@parser% } -\def\pgf@arrows@checked#1#2#3{% - \pgfutil@ifundefined{pgf@arrow@code@#2}% - {% - \PackageError{pgf}{Arrow end type ``#2'' unknown}{}}% - {% - \pgfutil@ifundefined{pgf@arrow@code@\csname pgf@arrows@invert#1\endcsname} - {\PackageError{pgf}{Arrow start type ``#1'' unknown}{}}% - {#3}% - }% +\def\pgfarrows@parser#1[{% + \pgfkeys@spdef\pgf@temp{#1}% + \ifx\pgf@temp\pgfutil@empty% + \let\pgf@next\pgf@arrows@empty% + \else% + \ifx\pgf@temp\pgf@dot@text% + \let\pgf@next\pgf@arrows@dot@parsed% + \else% + \let\pgf@untranslated\pgf@temp% + \ifpgf@arrows@translate% + \pgf@arrow@swapper% + \fi% + % Now, let's see what we do with this... + \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax + \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax + % #1 should start with a single-char shorthands + \let\pgf@next\pgf@arrows@single@char@parser% + \let\pgf@temp\pgf@untranslated% + \else% + % #1 is a shorthand! + \let\pgf@next\pgf@arrows@shorthand@parsed% + \fi% + \else% + % #1 is a meta arrow! + \let\pgf@next\pgf@arrows@meta@parsed% + \fi% + \fi% + \fi% + \expandafter\pgf@next\pgf@temp[% +} + +\def\pgf@arrows@empty[#1]{% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} + +\def\pgf@arrows@single@char@parser#1{% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@dot@text% + \let\pgf@next\pgf@arrows@dot@parsed% + \else% + \let\pgf@untranslated\pgf@temp% + \ifpgf@arrows@translate% + \pgf@arrow@swapper% + \fi% + \expandafter\ifx\csname pgf@ar@code@\pgf@temp\endcsname\relax + \expandafter\ifx\csname pgf@ar@means@\pgf@temp\endcsname\relax + \let\pgf@temp\pgf@untranslated% + \let\pgf@next\pgf@arrows@unknown% + \else% + \let\pgf@next\pgf@arrows@shorthand@parsed% + \fi% + \else% + \let\pgf@next\pgf@arrows@meta@parsed% + \fi + \fi + \expandafter\pgf@next\pgf@temp[]% +} +\def\pgf@arrows@unknown#1[]#2[#3]{% + \pgferror{Unknown arrow tip kind '#1#2'}% } -\def\pgf@arrows@check@already#1#2#3{% - \pgfutil@ifundefined{pgf@arrow@code@#2} - {#3}% - {\PackageError{pgf}{Arrow end type ``#2'' already defined}{}}% +\def\pgf@arrows@meta@parsed#1[#2]{% + % Ok, run the keys #2. This will add commands to \pgf@arrows@options: + % + \let\pgf@arrows@options\pgf@arrows@options@initial% + \pgfkeys{/pgf/arrow keys/.cd,#2}% + % Append the arrow and its options to the arrow tip sequence: + \expandafter\pgf@arrows@meta@set\expandafter{\pgf@arrows@options}{#1}{\pgf@arrow@handle}% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% } +\def\pgf@arrows@parser@done#1{% +} -% Called when an arrow needs to be rendered +\def\pgf@arrows@dot@parsed#1[#2]{% + \pgf@arrows@append@to@tips{\pgf@arrow@handle@dot}% + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} -\def\pgf@arrow@call#1{% - \expandafter\ifx\csname\pgf@arrow@full@name{#1}\endcsname\relax% - \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp% - {% - \pgfinterruptpath% - \let\pgfusepath=\pgf@nousepath@here% - \pgf@relevantforpicturesizefalse% - \pgftransformreset% - \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% - \pgfsysprotocol@bufferedtrue% - \pgfsys@beginscope% - \csname pgf@arrow@code@#1\endcsname% - \pgfsys@endscope% - \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp% - \global\let\pgf@@arrow@temp=\pgf@@arrow@temp% - \endpgfinterruptpath% - \expandafter\def\expandafter\pgf@temp\expandafter{\expandafter\pgfsys@invoke\expandafter{\pgf@@arrow@temp}}% - \expandafter\global\expandafter\let\csname\pgf@arrow@full@name{#1}\endcsname=\pgf@temp% - }% - \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp% +\def\pgf@arrows@meta@set#1#2#3{% + \pgf@arrows@append@to@tips{#3{#2}{#1}}% +} +\def\pgf@arrows@append@to@tips#1{% + \let\pgf@tempa\pgf@arrow@tip@sequence% + \def\pgf@tempb{#1}% + \ifpgf@arrows@translate% + \let\pgf@tempa\pgf@tempb% + \let\pgf@tempb\pgf@arrow@tip@sequence% + \fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrow@tip@sequence% + \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\pgf@tempb}% +} + +\def\pgf@arrows@shorthand@parsed#1[#2]{% + \let\pgf@arrows@options\pgf@arrows@options@initial% + \pgfkeys{/pgf/arrow keys/.cd,#2}% + \ifx\pgf@arrows@options\pgfutil@empty% + \expandafter\pgf@arrows@append@to@tips\expandafter{% + \expandafter\pgf@arrow@handle@shorthand@empty\expandafter{\csname pgf@ar@means@#1\endcsname}}% + \else% + \expandafter\expandafter\expandafter\pgf@arrows@meta@set\expandafter\expandafter\expandafter{% + \expandafter\pgf@arrows@options\expandafter}\expandafter{\csname pgf@ar@means@#1\endcsname}{\pgf@arrow@handle@shorthand}% \fi% - \csname\pgf@arrow@full@name{#1}\endcsname% -} + \pgfutil@ifnextchar\pgf@stop\pgf@arrows@parser@done\pgfarrows@parser% +} + -\def\pgf@arrow@full@name#1{pgf@arrow@prot@#1@\the\pgflinewidth @\pgfinnerlinewidth @\pgfgetarrowoptions{#1}} +% General handler: -\def\pgf@arrow@code@{} % dummy +\def\pgf@arrow@handle@shorthand@empty#1{#1} -\def\pgf@nousepath@here#1{% - \PackageError{pgf}{The definition of an arrow may not use \string\pgfusepath}{} +\def\pgf@arrow@handle@shorthand#1#2{% + \def\pgf@temp@opt{#2}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@nested@options@temp% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp@opt\pgf@arrows@nested@options}% + \expandafter\let\expandafter\pgf@arrows@nested@options\expandafter\pgf@arrows@nested@options@temp% + \expandafter#1% all these expandafters to avoid creating groups, but having the options nest + \expandafter\def\expandafter\pgf@arrows@nested@options\expandafter{\pgf@arrows@nested@options}% } +\let\pgf@arrows@nested@options\pgfutil@empty + + -% Get options for an arrow + +% Sets the start arrow tip % -% #1 = arrow tip name +% #1 = An arrow specification % % Description: +% +% This works like \pgfsetarrowsend, only the order of the tips in the +% arrow specification is reversed and the "reversed names" are used. % -% For every arrow tip certain options can be set, which may influence -% the appearance of the arrow tip. How the options are used is up the -% arrow tip code. This command will expand to the current value of -% the options for this tip. The default is 0. +% \pgfsetarrowsend{<<} +% \pgfsetarrowsend{>.>} + +\def\pgfsetarrowsstart#1{% + \let\pgf@arrow@tip@sequence\pgfutil@empty% + \pgf@arrows@translatetrue% + \expandafter\let\expandafter\pgf@arrows@direct\csname pgf@arrows@direct@name@start@#1\endcsname% + \ifx\pgf@arrows@direct\relax% + \edef\pgf@marshal{\noexpand\pgfarrows@initial@parser#1[]\noexpand\pgf@stop}% + \pgf@marshal% + \else% + \let\pgf@arrow@tip@sequence\pgf@arrows@direct% + \fi% + \let\pgf@start@tip@sequence\pgf@arrow@tip@sequence% +} -\def\pgfgetarrowoptions#1{% - \expandafter\ifx\csname pgf@arrow@opt@#1\endcsname\relax0\else\csname pgf@arrow@opt@#1\endcsname\fi% +\def\pgf@arrow@swapper{% + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@start@\pgf@temp\endcsname% + \ifx\pgf@temp\relax% + \def\pgf@temp{undefined}% + \fi% } +\let\pgf@start@tip@sequence\pgfutil@empty +\let\pgf@end@tip@sequence\pgfutil@empty + + +\expandafter\def\csname pgf@arrows@direct@name@start@\endcsname{} +\expandafter\def\csname pgf@arrows@direct@name@end@\endcsname{} + + +% Predefined lengths and ifs + +\newdimen\pgfarrowsep + +\newif\ifpgfarrowswap +\newif\ifpgfarrowreversed +\newif\ifpgfarrowharpoon +\newif\ifpgfarrowopen + +\let\pgf@arrows@stroke@color\pgfutil@empty +\let\pgf@arrows@fill@color\pgfutil@empty + +\def\pgfarrows@length@scale{1} +\def\pgfarrows@width@scale{1} +\def\pgfarrows@slant{0} + +\let\pgfarrows@scale@list\pgfutil@empty +\def\pgfarrowsaddtolengthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@length@scale#1}} +\def\pgfarrowsaddtowidthscalelist#1{\expandafter\def\expandafter\pgfarrows@scale@list\expandafter{\pgfarrows@scale@list#1\pgfarrows@width@scale#1}} + +\pgfkeys{ + /pgf/arrow keys/.cd, + scale/.code={% + \pgfmathparse{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}% + }, + scale length/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@length@scale\expandafter{\pgfmathresult}}}, + scale width/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@width@scale\expandafter{\pgfmathresult}}}, + slant/.code={\pgfmathparse{#1}\expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrows@slant\expandafter{\pgfmathresult}}}, + sep/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowsep\pgf@x}% + }, + sep/.default=0.88pt .3 1, + % + swap/.code=\pgfarrowsaddtooptions{\ifpgfarrowswap\pgfarrowswapfalse\else\pgfarrowswaptrue\fi}, + reversed/.code=\pgfarrowsaddtooptions{\ifpgfarrowreversed\pgfarrowreversedfalse\else\pgfarrowreversedtrue\fi}, + harpoon/.is choice, + harpoon/.default=true, + harpoon/true/.code=\pgfarrowsaddtooptions{\pgfarrowharpoontrue}, + harpoon/false/.code=\pgfarrowsaddtooptions{\pgfarrowharpoonfalse}, + left/.style={harpoon}, + right/.style={harpoon,swap}, + % + color/.code=\pgfarrowsaddtooptions{\def\pgf@arrows@stroke@color{#1}}, + fill/.code={% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@nonetext% + \pgfarrowsaddtooptions{\pgfarrowopentrue} + \else + \pgfarrowsaddtooptions{\pgfarrowopenfalse\def\pgf@arrows@fill@color{#1}} + \fi + }, + fill/.value required, + open/.style={fill=none}, + .unknown/.code={ + \expandafter\pgfutil@in@\expandafter!\expandafter{\pgfkeyscurrentname}% + \ifpgfutil@in@% + % this is a color! + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}% + \else% + \pgfutil@doifcolorelse{\pgfkeyscurrentname} + {% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgf@arrows@stroke@color\expandafter{\pgfkeyscurrentname}}% + } + {% + \edef\pgf@temp{\pgfkeyscurrentname}% + \pgfkeys{/errors/unknown key/.expand once=\expandafter{\pgf@temp}{#1}}% + } + \fi + } +} +\def\pgf@nonetext{none} -% Set options for an arrow -% -% #1 = arrow tip name -% #2 = options -% -% Description: -% -% Sets the arrow tip options for an arrow. The options should be a -% normal string and will be used to detect whether an arrow should be -% recached. For instance, when you set the arrow tip options of -% "myarrow" to "1", the arrow will be rendered in a certain way. Then, -% when you set the options to "2", the arrow will be rerendered. +\def\pgfarrowsaddtooptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options#1}} +\def\pgfarrowsaddtolateoptions#1{\expandafter\def\expandafter\pgf@arrows@options\expandafter{\pgf@arrows@options\pgf@arrows@add@to@late@options{#1}}} +\def\pgf@arrows@add@to@late@options#1{\expandafter\def\expandafter\pgf@arrows@late@options\expandafter{\pgf@arrows@late@options#1}} -\def\pgfsetarrowoptions#1#2{% - \expandafter\def\csname pgf@arrow@opt@#1\endcsname{#2}% + + +\def\pgfarrowsthreeparameters#1{% + \pgfarrowsthreeparameters@#1 +0 +0 +0 \pgf@stop% +} +\def\pgfarrowsthreeparameters@#1 #2 #3 #4\pgf@stop{% + \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetmacro\pgf@temp@a{#2}% + \pgfmathsetmacro\pgf@temp@b{#3}% + \edef\pgfarrowstheparameters{{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}% } +\def\pgfarrowsfourparameters#1{% + \pgfarrowsfourparameters@#1 +0 +0 +0 \pgf@stop% +} +\def\pgfarrowsfourparameters@#1:#2 #3 #4 #5\pgf@stop{% + \pgfmathsetmacro\pgf@temp@z{#1}% + \pgfmathsetlength\pgf@x{#2}% + \pgfmathsetmacro\pgf@temp@a{#3}% + \pgfmathsetmacro\pgf@temp@b{#4}% + \edef\pgfarrowstheparameters{{\pgf@temp@z}{\the\pgf@x}{\pgf@temp@a}{\pgf@temp@b}}% +} +\def\pgfarrows@angle@setup#1#2#3#4{% + \pgfarrowslinewidthdependent{#2}{#3}{#4} + \pgf@xc\pgf@x + \pgf@yc#1 pt% + \pgf@yc.5\pgf@yc% + \pgfpointpolar{\pgf@yc}{\pgf@xc} + \pgfarrowlength\pgf@x% + \pgf@y2\pgf@y% + \expandafter\pgf@arrows@add@to@late@options\expandafter{\expandafter\pgfarrowwidth\the\pgf@y}% +} +\def\pgfarrows@angle@setup@prime#1{% + \pgf@yc#1 pt% + \pgfmathtan@{.5\pgf@yc}% + \pgfarrowwidth\pgfmathresult\pgfarrowlength% + \pgfarrowwidth2\pgfarrowwidth% +} -% Define an arrow type. -% -% #1 = name or mnemonic for arrow when used at the start (examples: ``to'' or ``<'') -% #2 = name or mnemonic for arrow when used at the end (examples: ``to'' or ``>'') -% #3 = code to setup the left and right extend of the arrow. To set -% the left extend, call \pgfarrowsleftextend, for the right \pgfarrowsrightextend. -% #4 = protocolable code -% -% Description: -% -% When you define an arrow using this command, you must give two -% names. The first is used for the arrow when it is ``at the start'', -% the other when it is at the end. For example, a simple arrow might -% have the names ``<'' and ``>'', though these particular names are -% not used by pgf and left for the user. -% -% The code should be ``protocolable'' code. This means that it uses -% only pretty simple commands. -% -% The arrow code will be protocolled once for each line width at which -% the arrow is used. Thus, the code can (and often should) depend on -% the line width. -% -% The arrow should ``point right'' in the coordinate system. The end -% of the line at which the arrow should be drawn will be at the origin -% of the coordinate system. The coordinate system will be scaled and -% rotated appropriately before the arrow is drawn. -% -% The right extend of the arrow should be set to how much the arrow -% ``protrudes over the right''. Prior to drawing the arrow, the line -% will be shortened by this amount so that the arrow tip will exactly -% touch the original right end of the unshortened line. -% -% The left extend specifies the leftmost point of the arrow. This is -% important only if you use the swapping command, when this end is -% used to compute the shortening. -% -% The definition of an arrow should normally take care of the fact -% that the line cap of the main line may be a butt cap, a round cap or -% a rect cap. In all cases, the arrow should ``cover'' the cap -% completely or not at all. -% -% Example: -% -% \pgfarrowsdeclare{stealth}{stealth} -% { -% \pgfarrowsleftextend{-6\pgflinewidth} -% \pgfarrowsrightextend{2\pgflinewidth} -% { -% \pgfpathmoveto{\pgfpoint{2\pgflinewidth}{0pt}} -% \pgfpathlineto{\pgfpoint{-6\pgflinewidth}{4\pgflinewidth}} -% \pgfpathlineto{\pgfpoint{-3\pgflinewidth}{0pt}} -% \pgfpathlineto{\pgfpoint{-6\pgflinewidth}{-4\pgflinewidth}} -% \pgfusepathqfill -% } +\def\pgfarrowslinewidthdependent#1#2#3{% + \pgf@x#1% + \ifdim\pgfinnerlinewidth>0pt% + \pgf@arrows@inner@line@width@dep{#2}{#3}% + \else% + \advance\pgf@x by#2\pgflinewidth% + \fi% +} +\def\pgf@arrows@inner@line@width@dep#1#2{% + % #1*((1-#2/2)*full line width - (#2/2) * inner line width) + % Compute "real" line width + \pgf@xa\pgflinewidth% + \pgf@xb-.5\pgflinewidth% + \pgf@xb#2\pgf@xb% + \advance\pgf@xa by\pgf@xb% + \pgf@xb\pgfinnerlinewidth% + \pgf@xb-.5\pgf@xb + \advance\pgf@xa by#2\pgf@xb% + \advance\pgf@x by#1\pgf@xa% +} -\def\pgfarrowsdeclare#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2} - {% - \expandafter\def\csname pgf@arrow@code@#2\endcsname{#4}% - \expandafter\def\csname pgf@arrow@left@#2\endcsname{#3\advance\pgf@x by-\pgf@xa}% - \expandafter\def\csname pgf@arrow@right@#2\endcsname{#3\advance\pgf@x by\pgf@xb}% - \pgf@arrows@invname{#1}{#2}% - }% + +\def\pgfarrowslengthdependent#1#2#3#4{% + #4#1% + \advance#4by#2\pgfarrowlength% + \advance#4by#3\pgflinewidth% } -\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}} -\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}} -\def\pgf@arrows@repeat#1#2{% - \edef\pgf@arrows@marshal{\noexpand\let\expandafter\noexpand\csname#2\endcsname=\expandafter\noexpand\csname#1\endcsname}% - \pgf@arrows@marshal} +% Build the full name: +\def\pgf@arrow@fullname#1{pgf@@ar@#1@\the\pgflinewidth @\pgfinnerlinewidth @\ifpgfarrowreversed r\fi @\pgf@arrows@stroke@color @\pgf@arrows@fill@color @\csname pgf@ar@par@#1\endcsname} +\def\pgf@arrow@id@count{0}% -% Declare a new arrow type to be the same as another one. -% -% #1 = name of new start -% #2 = name or new end -% #3 = name or old start -% #4 = name or old end -% -% Example: -% -% \pgfarrowsdeclarealias{<}{>}{to}{to} +% Compute the arrow id of an arrow +% +% #1 = arrow name +% #2 = options +% +% Description: +% +% Returns the an id in \pgf@arrow@id that identifies the instantiation +% of the given arrow. If the arrow was not instantiated, this happens now. + +\def\pgfarrows@getid#1#2{% + % Execute options: + \let\pgf@arrows@late@options\pgfutil@empty% + % 1. Defaults: + \csname pgf@ar@defaults@#1\endcsname% + % 2. Scope: + \pgf@arrows@options@scope + % 3. Local: + #2\relax% + % 4. Nested: + \pgf@arrows@nested@options% + % 5. Last options: + \pgf@arrows@late@options% + % 6. Scaling: + \pgfarrows@scale@list% + % Now, test: + \expandafter\global\expandafter\let\expandafter\pgf@arrow@id\csname\pgf@arrow@fullname{#1}\endcsname\relax% + \ifx\pgf@arrow@id\relax% + \pgf@arrows@instantiate{#1} + \fi% +} -\def\pgfarrowsdeclarealias#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2} +\def\pgf@arrows@instantiate#1{% + % Not defined. Rats! + % Allocate new id: + \pgfutil@tempcnta\pgf@arrow@id@count\relax% + \advance\pgfutil@tempcnta by1\relax% + \xdef\pgf@arrow@id@count{\the\pgfutil@tempcnta}% + \expandafter\global\expandafter\let\csname\pgf@arrow@fullname{#1}\endcsname\pgf@arrow@id@count% + \global\let\pgf@arrow@id\pgf@arrow@id@count% {% - \pgf@arrows@checked{#3}{#4}% - {% - \pgf@arrows@repeat{pgf@arrow@code@#4}{pgf@arrow@code@#2}% - \pgf@arrows@repeat{pgf@arrow@left@#4}{pgf@arrow@left@#2}% - \pgf@arrows@repeat{pgf@arrow@right@#4}{pgf@arrow@right@#2}% - \pgf@arrows@invname{#1}{#2}% + \csname pgf@ar@setup@#1\endcsname% + % Handle reversal + \ifpgfarrowreversed% + % Compute transformation: + \pgf@arrows@handle@reverse% + \fi% + % Save computed values + \expandafter\global\expandafter\let\csname pgf@ar@saves@\pgf@arrow@id\endcsname\pgf@arrows@saves% + \expandafter\global\expandafter\let\csname pgf@ar@hull@\pgf@arrow@id\endcsname\pgf@arrows@convexhull% + \expandafter\xdef\csname pgf@ar@ends@\pgf@arrow@id\endcsname{{\pgf@arrows@the@tipend}{\pgf@arrows@the@backend}{\pgf@arrows@the@lineend}}% + \expandafter\xdef\csname pgf@ar@visual@\pgf@arrow@id\endcsname{{\pgf@arrows@the@visualtipend}{\pgf@arrows@the@visualbackend}{}}% + % Save code (needed for bending) + \edef\pgf@arrow@code{% + \ifpgfarrowreversed\noexpand\pgftransformxscale{-1}\fi% + \expandafter\noexpand\csname pgf@ar@code@#1\endcsname% }% + \expandafter\global\expandafter\let\csname pgf@ar@inst@code@\pgf@arrow@id\endcsname\pgf@arrow@code% + % Should we cache? + \expandafter\ifx\csname pgf@ar@do@cache@#1\endcsname\pgf@truetext% + \pgfsysprotocol@getcurrentprotocol\pgf@arrow@temp% + {% + \pgfinterruptpath% + \let\pgfusepath=\pgf@nousepath@here% + \pgf@relevantforpicturesizefalse% + \pgftransformreset% + \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% + \pgfsysprotocol@bufferedtrue% + \pgfscope% + \pgf@arrow@code% + \endpgfscope% + \pgfsysprotocol@getcurrentprotocol\pgf@@arrow@temp% + \expandafter\gdef\expandafter\pgf@arrow@code\expandafter{\expandafter\pgfsysprotocol@literal\expandafter{\pgf@@arrow@temp}}% + \endpgfinterruptpath% + }% + \pgfsysprotocol@setcurrentprotocol\pgf@arrow@temp% + \fi% + \expandafter\global\expandafter\let\csname pgf@ar@cache@\pgf@arrow@id\endcsname\pgf@arrow@code% }% } +\def\pgf@truetext{true} + +% Ok, now run setup: +\def\pgf@arrows@copy@tipend{\pgf@arrows@the@tipend} +\def\pgf@arrows@copy@backend{\pgf@arrows@the@backend} +\def\pgf@arrows@copy@lineend{\pgf@arrows@the@lineend} +\def\pgf@arrows@zeropt{0pt}% + +\let\pgf@arrows@saves\pgfutil@empty% +\let\pgf@arrows@convexhull\pgfutil@empty% +\let\pgf@arrows@the@tipend\pgf@arrows@zeropt% +\let\pgf@arrows@the@backend\pgf@arrows@zeropt% +\let\pgf@arrows@the@lineend\pgf@arrows@zeropt% +\let\pgf@arrows@the@visualtipend\pgf@arrows@copy@tipend% +\let\pgf@arrows@the@visualbackend\pgf@arrows@copy@backend% + + +\def\pgf@arrows@handle@reverse{% + \pgf@x\pgf@arrows@the@visualtipend\pgf@x-\pgf@x% + \pgf@y\pgf@arrows@the@visualbackend\pgf@y-\pgf@y + \edef\pgf@arrows@the@visualtipend{\the\pgf@y}% + \edef\pgf@arrows@the@visualbackend{\the\pgf@x}% + \pgf@x\pgf@arrows@the@tipend\pgf@x-\pgf@x% + \pgf@y\pgf@arrows@the@backend\pgf@y-\pgf@y + \edef\pgf@arrows@the@tipend{\the\pgf@y}% + \edef\pgf@arrows@the@backend{\the\pgf@x}% + \pgf@x\pgf@arrows@the@lineend\pgf@x-\pgf@x\edef\pgf@arrows@the@lineend{\the\pgf@x}% + \let\pgf@temp\pgf@arrows@convexhull% + \let\pgf@arrows@convexhull\pgfutil@empty% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@reverse% + \pgf@temp% +} +\def\pgf@arrow@hull@point@reverse#1#2{% + \pgf@x#1% + \pgfarrowshullpoint{-\pgf@x}{#2}% +} + +\def\pgf@nousepath@here#1{\pgferror{The definition of an arrow may not use \string\pgfusepath}} + +\def\pgfarrowssavethe#1{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@saves% + \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter#1\the#1\relax} +} +\def\pgfarrowssave#1{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrows@saves% + \expandafter\expandafter\expandafter{\expandafter\pgf@arrows@saves\expandafter\def\expandafter#1\expandafter{#1}} +} +\def\pgfarrowshullpoint#1#2{% + \pgf@x#1\relax% + \pgf@y#2\relax% + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}% +} +\def\pgfarrowsupperhullpoint#1#2{% + \pgf@x#1\relax% + \pgf@y#2\relax% + \ifdim\pgf@y>0pt + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}\ifpgfarrowharpoon\else\noexpand\pgf@arrow@hull@point{\the\pgf@x}{-\the\pgf@y}\fi}% + \else + \edef\pgf@arrows@temp{\noexpand\pgf@arrows@convexhull\noexpand\pgf@arrow@hull@point{\the\pgf@x}{\the\pgf@y}}% + \fi + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgf@arrows@convexhull\expandafter\expandafter\expandafter{\pgf@arrows@temp}% +} -% Creates a new arrows by ``swapping'' an existing arrow. -% -% #1 = name of new start -% #2 = name of new end -% #3 = name of old start -% #4 = name of old end -% -% Example: -% -% \pgfarrowsdeclarealias{]}{[}{[}{]} +\def\pgfarrowssettipend#1{\pgf@x#1\edef\pgf@arrows@the@tipend{\the\pgf@x}} +\def\pgfarrowssetbackend#1{\pgf@x#1\edef\pgf@arrows@the@backend{\the\pgf@x}} +\def\pgfarrowssetlineend#1{\pgf@x#1\edef\pgf@arrows@the@lineend{\the\pgf@x}} +\def\pgfarrowssetvisualtipend#1{\pgf@x#1\edef\pgf@arrows@the@visualtipend{\the\pgf@x}} +\def\pgfarrowssetvisualbackend#1{\pgf@x#1\edef\pgf@arrows@the@visualbackend{\the\pgf@x}} -\def\pgfarrowsdeclarereversed#1#2#3#4{% - \pgf@arrows@check@already{#1}{#2}% - {% - \pgf@arrows@checked{#3}{#4}% - {% - \expandafter\def\csname pgf@arrow@code@#2\endcsname{% - \pgflowlevel{\pgftransformxscale{-1}}% - \csname pgf@arrow@code@#4\endcsname}% - \pgf@arrows@repeat{pgf@arrow@right@#4}{pgf@arrow@left@#2}% - \pgf@arrows@repeat{pgf@arrow@left@#4}{pgf@arrow@right@#2}% - \pgf@arrows@invname{#1}{#2}% - }% - }% + +% Internal computatin of the line end (shortening) for an arrow +% +% #1 = arrow tip list +% +% Description: +% +% \pgf@xa will contain the necessary path shortening for the given +% arrow tip list, \pgf@xb will contain the total length of the arrow +% tip list (sum of the differences between tip end and back end plus +% the seps). + +\def\pgf@arrow@compute@shortening#1{% + \let\pgf@arrow@handle\pgf@arrow@compute@shortening@ + \let\pgf@arrow@handle@dot\pgf@arrow@after@line@endtrue% + \pgf@arrow@after@line@endfalse% + \pgf@xa0pt% + \pgf@xb0pt% + #1% +} +\newif\ifpgf@arrow@after@line@end + +\def\pgf@arrow@compute@shortening@#1#2{% + {\pgfarrows@getid{#1}{#2}\ifnum\pgf@arrow@flex@mode>0\relax\global\pgf@precise@shorteningtrue\fi\expandafter}\expandafter\pgf@x\the\pgfarrowsep% + \expandafter\expandafter\expandafter\pgf@arrow@cont@short\csname pgf@ar@ends@\pgf@arrow@id\endcsname% +} +\def\pgf@dot@text{.} + +\def\pgf@arrow@cont@short#1#2#3{% tip end, back end, line end, sep + \advance\pgf@xb by#1% + \pgf@xc#2% + \advance\pgf@xb by-\pgf@xc% + \advance\pgf@xb by\pgf@x% + \ifpgf@arrow@after@line@end% + \advance\pgf@xa by#1% + \advance\pgf@xa by\pgf@x% + \pgf@xc#2% + \advance\pgf@xa by-\pgf@xc% + \else% + \pgf@xa#1% + \advance\pgf@xa by\pgf@x% + \pgf@xc#3% + \advance\pgf@xa by-\pgf@xc% + \fi% } -% Creates new arrows by combining two existing arrows. -% -% #1 = optional additional space -% #2 = name of new start -% #3 = name of new end -% #4 = name of second (innermost) start -% #5 = name of second end -% #6 = name of first (outermost) start -% #7 = name of first end -% -% In the star form, the line will end at the innermost arrows, -% otherwise the line will end at the outermost arrows. -% -% Example: -% -% \pgfarrowsdeclarecombine*{|<}{>|}{|}{|}{<}{>} -% \pgfarrowsdeclarecombine{<<}{>>}{<}{>}{<}{>} -\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}} +% Draw an arrow +% +% #1 = arrow tip list +% #2 = total length of the arrow (the value of \pgf@xb computed by +% \pgf@arrow@compute@shortening) +% +% Description: +% +% Draws an arrow tip list. The coordinate system must have been +% transformed so that the to-be-drawn arrow points right and should +% "end" at the origin. -\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}} -\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{% - \pgf@arrows@check@already{#2}{#3}% +\def\pgf@arrow@draw@arrow#1#2{% {% - \pgf@arrows@checked{#4}{#5}% - {% - \pgf@arrows@checked{#6}{#7}% - {% - \expandafter\edef\csname pgf@arrow@code@#3\endcsname{% - \noexpand\pgfscope% - {\expandafter\noexpand\csname pgf@arrow@code@#7\endcsname}% - \noexpand\endpgfscope% - {% - \noexpand\pgfmathsetlength\pgf@x{#1}% - \noexpand\pgf@process{\expandafter\noexpand\csname pgf@arrow@left@#7\endcsname}% - \noexpand\pgf@process{\expandafter\noexpand\csname pgf@arrow@right@#5\endcsname}% - \pgf@x=-\pgf@x% - \noexpand\pgflowlevel{\noexpand\pgftransformxshift{\pgf@x}}% - \expandafter\noexpand\csname pgf@arrow@code@#5\endcsname}% - }% - \pgf@arrows@repeat{pgf@arrow@right@#7}{pgf@arrow@right@#3}% - \expandafter\def\csname pgf@arrow@left@#3\endcsname{% - \pgf@process{% - \pgfmathsetlength\pgf@y{#1}% - \advance\pgf@x by\pgf@y% - \pgf@process{\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\csname pgf@arrow@right@#5\endcsname}% - \pgf@process{\csname pgf@arrow@left@#5\endcsname}% - }% - }% - \pgf@arrows@invname{#2}{#3}% - }% - }% + \pgf@xb=#2% + \pgftransformxshift{-\pgf@xb}% + \let\pgf@arrow@handle\pgf@arrow@drawer + \let\pgf@arrow@handle@dot\relax% + #1% }% } -\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}} -\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{% - \pgf@arrows@check@already{#2}{#3}% + +\def\pgf@arrow@drawer#1#2{% + % Prepare: {% - \pgf@arrows@checked{#4}{#5}% + \pgfarrows@getid{#1}{#2}% + % Do shift: + \expandafter\expandafter\expandafter\pgf@arrow@drawer@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + % do swap: + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% {% - \pgf@arrows@checked{#6}{#7}% - {% - \expandafter\edef\csname pgf@arrow@code@#3\endcsname{% - \noexpand\pgfscope% - {% - \noexpand\pgfmathsetlength\pgf@x{#1}% - \pgf@process{\expandafter\noexpand\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\expandafter\noexpand\csname pgf@arrow@right@#5\endcsname}% - \noexpand\pgflowlevel{\noexpand\pgftransformxshift{\pgf@x}}% - }% - {\expandafter\noexpand\csname pgf@arrow@code@#7\endcsname}% - \noexpand\endpgfscope% - \expandafter\noexpand\csname pgf@arrow@code@#5\endcsname% - }% - \pgf@arrows@repeat{pgf@arrow@left@#7}{pgf@arrow@left@#3}% - \expandafter\def\csname pgf@arrow@right@#3\endcsname{% - \pgf@process{% - \pgfmathsetlength\pgf@y{#1}% - \advance\pgf@x by\pgf@y% - \pgf@process{\csname pgf@arrow@left@#7\endcsname}% - \pgf@process{\csname pgf@arrow@right@#5\endcsname}% - \pgf@process{\csname pgf@arrow@right@#7\endcsname}% - }% - }% - \pgf@arrows@invname{#2}{#3}% - }% - }% - }% + \csname pgf@ar@saves@\pgf@arrow@id\endcsname% + \pgfscope% + \pgf@arrows@color@setup% + \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname% + \endpgfscope% + \pgf@arrows@rigid@hull% + }% + \expandafter}% + % Transform to next tip: + \expandafter\pgftransformxshift\expandafter{\the\pgf@xc}% +} + +\def\pgf@arrows@color@setup{% + \ifx\pgf@arrows@stroke@color\pgfutil@empty\else\pgfsetstrokecolor{\pgf@arrows@stroke@color}\fi% + \ifx\pgf@arrows@fill@color\pgfutil@empty% + \expandafter\expandafter\expandafter\ifx% + \expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \else + \pgfsetfillcolor{pgfstrokecolor}% + \fi% + \else% + \pgfsetfillcolor{\pgf@arrows@fill@color}% + \fi% +} + +\def\pgf@arrow@drawer@shift#1#2#3{% tip end, back end, line end, sep + \pgf@xb#2\pgftransformxshift{-\pgf@xb}% + \pgf@xc#1% + \advance\pgf@xc by\pgfarrowsep% + \advance\pgf@xc by-\pgf@xb% +} + +\def\pgf@arrows@rigid@hull{% + \ifpgf@relevantforpicturesize% + % Do bb update: + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname% + \ifx\pgf@temp\pgfutil@empty\else% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@first% + \pgf@temp% + \pgf@arrow@update@bb% + \fi% + \fi +} + + +% Convex hull stuff: + +\def\pgf@arrow@hull@point@first#1#2{% +% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}% + \pgf@x#1\pgf@y#2% + \pgf@xa\pgf@pt@aa\pgf@x% + \advance\pgf@xa by\pgf@pt@ba\pgf@y% + \pgf@ya\pgf@pt@ab\pgf@x% + \advance\pgf@ya by\pgf@pt@bb\pgf@y% + \pgf@xb\pgf@xa\pgf@yb\pgf@ya% + \let\pgf@arrow@hull@point\pgf@arrow@hull@point@other% +} +\def\pgf@arrow@hull@point@other#1#2{% +% {\pgfsys@beginscope\pgfpathcircle{\pgfqpoint{#1}{#2}}{0.5pt}\pgfusepathqfill\pgfsys@endscope}% + \pgfutil@tempdima#1\pgfutil@tempdimb#2% + \pgf@x\pgf@pt@aa\pgfutil@tempdima% + \advance\pgf@x by\pgf@pt@ba\pgfutil@tempdimb% + \pgf@y\pgf@pt@ab\pgfutil@tempdima% + \advance\pgf@y by\pgf@pt@bb\pgfutil@tempdimb% + \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi% } +\def\pgf@arrow@update@bb{% + \advance\pgf@xa by\pgf@pt@x% + \advance\pgf@ya by\pgf@pt@y% + \advance\pgf@xb by\pgf@pt@x% + \advance\pgf@yb by\pgf@pt@y% + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picminx\pgf@xa% + \global\pgf@picmaxx\pgf@xb% + \global\pgf@picminy\pgf@ya% + \global\pgf@picmaxy\pgf@yb% + \else% + \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi% + \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi% + \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi% + \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi% + \fi% +} -% Creates new arrows by doubling/tripling existing arrows. +% Sets arrows % -% #1 = optional additional space in multiples of line width -% #2 = name of new start -% #3 = name of new end -% #4 = name of old start -% #5 = name of old end +% #1 = An arrow specification of the form +% -. This will call \pgfsetstartarrow{start +% spec} and \pgfsetendarrow{end spec}. +% +% Alternatively, it may be of the form [options]. In this case, +% the arrow options are set for the local scope and all arrows in +% the current scope will have these options set. % % Example: % -% \pgfarrowsdeclaredouble{<<}{>>}{<}{>} +% \pgfsetarrows{-to} -\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}} -\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}} -\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}} -\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{% - \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}% - \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}% +\def\pgfsetarrows#1{\pgf@arrows#1\pgf@stop} +\def\pgf@arrows{\pgfutil@ifnextchar[\pgf@arrows@test@opt\pgf@arrows@}%} +\def\pgf@arrows@#1-#2\pgf@stop{% + \pgfsetarrowsstart{#1}% + \pgfsetarrowsend{#2}% +} +\def\pgf@arrows@test@opt[{% + \pgfutil@ifnextchar-{\pgf@arrows@[}%} go back to normal reading for compat. reasons. + \pgf@arrows@test@opt@% +} +\def\pgf@arrows@test@opt@#1]{% + \pgfutil@ifnextchar\pgf@stop{% + \let\pgf@arrows@options\pgf@arrows@options@scope% + \pgfkeys{/pgf/arrow keys/.cd,#1}% + \let\pgf@arrows@options@scope\pgf@arrows@options% + % Ok, setup the options + \pgfutil@gobble% + }{% + \pgf@arrows@[#1]% Oops: go back to normal mode + }% } +\let\pgf@arrows@options@scope\pgfutil@empty + + + + -% A stealth-fighter-like pointed arrow -% -% Example: % -% \pgfsetarrows{-stealth} +% Predefined arrows: +% + + +% A dot is used to indicate the end of the line: + +\pgfdeclarearrow{ + name = ., + drawing code = +} + + +% An underscore adds a space as in >_> or >_ >. However, it will be +% faster to say ">[sep] >" or ">[sep=2pt] >". + +\pgfdeclarearrow{ + name = _, + defaults = {sep}, + drawing code = +} + + + +% Default shorthands: + +\pgfdeclarearrow{ name = To, means = } % forward declaration +\pgfdeclarearrow{ name = Bar, means = } % forward declaration +\pgfkeys{ + <-> /.tip = {To}, + >-< /.tip = {>[reversed]}, + | /.tip = {Bar} +} + + + +% Compatibility with old arrow system: + +\pgfkeys {} + +\def\pgf@arrows@direct@def#1#2{\expandafter\pgf@arrows@direct@def@\expandafter{\csname pgf@ar@means@#2\endcsname}{#1}} +\def\pgf@arrows@direct@def@#1#2{\expandafter\def\csname pgf@arrows@direct@name@#2\endcsname{\pgf@arrow@handle@shorthand@empty{#1}}} +\pgf@arrows@direct@def{start@[}{]} +\pgf@arrows@direct@def{start@]}{[} +\pgf@arrows@direct@def{start@spaced [}{spaced ]} +\pgf@arrows@direct@def{start@spaced ]}{spaced [} +\pgf@arrows@direct@def{end@[}{[} +\pgf@arrows@direct@def{end@]}{]} +\pgf@arrows@direct@def{end@spaced [}{spaced [} +\pgf@arrows@direct@def{end@spaced ]}{spaced ]} + +\def\pgfsetarrowoptions#1#2{\expandafter\def\csname pgf@arrow@compat@opt@#1\endcsname{#2}} +\def\pgfgetarrowoptions#1{\csname pgf@arrow@compat@opt@#1\endcsname} +\def\pgfarrowsdeclare#1#2#3#4{% + \pgfdeclarearrow{ name ={#1}-{#2}, setup code ={#3}, drawing code={#4}, parameters/.expand once={\csname pgf@arrow@compat@opt@#2\endcsname}} + \expandafter\def\csname pgf@arrow@compat@opt@#2\endcsname{0}} +\def\pgfarrowsleftextend#1{\pgfmathsetlength\pgf@xa{#1}\pgfarrowssetbackend{\pgf@xa}} +\def\pgfarrowsrightextend#1{\pgfmathsetlength\pgf@xb{#1}\pgfarrowssettipend{\pgf@xb}} +\def\pgfarrowsdeclarealias#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means ={#4} } } +\def\pgfarrowsdeclarereversed#1#2#3#4{\pgfdeclarearrow{ name ={#1}-{#2}, means={{#4}[reversed]}}} +\def\pgfarrowsdeclarecombine{\pgfutil@ifnextchar*{\pgfarrowsdeclarecombine@star}{\pgf@@arrowsdeclarecombine}} +\def\pgf@@arrowsdeclarecombine{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine}{\pgf@arrowsdeclarecombine[0pt]}} +\def\pgf@arrowsdeclarecombine[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi% + \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp]#6}}} +\def\pgf@linewidth@text{\pgflinewidth} +\def\pgfarrowsdeclarecombine@star*{\pgfutil@ifnextchar[{\pgf@arrowsdeclarecombine@star}{\pgf@arrowsdeclarecombine@star[0pt]}} +\def\pgf@arrowsdeclarecombine@star[#1]#2#3#4#5#6#7{\def\pgf@@temp{#1}\ifx\pgf@@temp\pgf@linewidthtext\def\pgf@@temp{+0pt 1}\fi% + \pgfdeclarearrow{name ={#2}-{#3}, means={#5[sep/.expand once=\pgf@@temp].#6}}} +\def\pgfarrowsdeclaredouble{\pgfutil@ifnextchar[{\pgf@arrowsdeclaredouble}{\pgf@arrowsdeclaredouble[0pt]}} +\def\pgf@arrowsdeclaredouble[#1]#2#3#4#5{\pgfarrowsdeclarecombine[#1]{#2}{#3}{#4}{#5}{#4}{#5}} +\def\pgfarrowsdeclaretriple{\pgfutil@ifnextchar[{\pgf@arrowsdeclaretriple}{\pgf@arrowsdeclaretriple[0pt]}} +\def\pgf@arrowsdeclaretriple[#1]#2#3#4#5{ \pgfarrowsdeclarecombine[#1]{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}{#4}{#5}% + \pgfarrowsdeclarecombine[#1]{#2}{#3}{pgf@trip@#2}{pgf@trip@#3}{#4}{#5}} +\def\pgf@linewidthtext{\pgflinewidth} \pgfarrowsdeclare{stealth}{stealth} { @@ -432,16 +1087,7 @@ \pgfpathlineto{\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqfill } - \pgfarrowsdeclarereversed{stealth reversed}{stealth reversed}{stealth}{stealth} - - -% An arrow similar to the $\to$ arrow -% -% Example: -% -% \pgfsetarrow{-to} - \pgfarrowsdeclare{to}{to} { \pgfutil@tempdima=-0.84pt% @@ -469,7 +1115,7 @@ {\pgfqpoint{-3\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqstroke } - +\pgfkeys{To /.tip = to} \pgfarrowsdeclare{to reversed}{to reversed} { \pgfutil@tempdima=-0.21pt% @@ -497,15 +1143,6 @@ {\pgfqpoint{3.5\pgfutil@tempdima}{-4\pgfutil@tempdima}} \pgfusepathqstroke } - - - -% LaTeX's orginal arrow type -% -% Example: -% -% \pgfsetarrows{-latex} - \pgfarrowsdeclare{latex}{latex} { \pgfutil@tempdima=0.28pt% @@ -537,16 +1174,7 @@ \pgfusepathqfill } \pgfarrowsdeclarereversed{latex reversed}{latex reversed}{latex}{latex} - - - -% A bar shaped arrow -% -% Example: -% -% \pgfsetarrows{-|} - -\pgfarrowsdeclare{|}{|} +\pgfarrowsdeclare{@bar}{@bar} { \pgfarrowsleftextend{+-0.25\pgflinewidth} \pgfarrowsrightextend{+.75\pgflinewidth} @@ -560,17 +1188,7 @@ \pgfpathlineto{\pgfqpoint{0.25\pgflinewidth}{\pgfutil@tempdima}} \pgfusepathqstroke } - - -% A space arrow -% -% This arrow can be combined with other arrows to add "space" around -% them. -% -% Example: -% -% \pgfarrowsdeclarecombine{my<}{my>}{<}{>}{space}{space} - +\pgfkeys{Bar /.tip = @bar} \pgfarrowsdeclare{space}{space} { \pgfutil@tempdima=0.88pt% @@ -583,3 +1201,5 @@ \endinput + + diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex index d8eaca5aee7..75789f2d16c 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreexternal.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreexternal.code.tex,v 1.17 2010/09/01 08:56:40 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreexternal.code.tex,v 1.20 2013/07/15 12:05:31 tantau Exp $ @@ -107,10 +107,32 @@ \ifpgfexternal@aux@in@dpth \csname newwrite\endcsname\w@pgfexternal@auxout \fi + \pgfexternal@geometry@compatibility \fi% \gdef\pgfrealjobname##1{}% avoid multiple calls. } +\def\pgfexternal@geometry@compatibility{% + % check if \usepackage{geometry} is loaded: + \pgfutil@ifundefined{geometry}{% + }{% + % The geometry package hooks into \begin{document}, evaluates + % its driver -- and generates \special instructions to set the + % paper size. + % + % Unfortunately, this confuses dvips utterly - and perhaps + % other drivers as well. + % + % Thus, if we currently about to generate some external + % graphics, we WANT to disable geometry (it has no purpose in + % this context anyway). + % + % This here works well: + \immediate\write16{Package TikZ externalization: calling \string\geometry{driver=none} during externalization.^^J}% + \geometry{driver=none}% + }% +}% + \def\pgfexternal@nofiles{% % replace \relax. The \nofiles macros does % \let\makeglossary=\relax @@ -158,7 +180,7 @@ % This will be overwritten by the tikz external lib if it is loaded. \def\pgfexternal@error@no@shipout{% - \PackageError{pgf}{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname'. Perhaps there was a typo somewhere? Please check that your document contains '\string\beginpgfgraphicnamed{\pgfactualjobname} ... \string\endpgfgraphicnamed'}% + \pgferror{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname'. Perhaps there was a typo somewhere? Please check that your document contains '\string\beginpgfgraphicnamed{\pgfactualjobname} ... \string\endpgfgraphicnamed'}% }% @@ -238,13 +260,23 @@ \endgroup } -% Defines \pgfexternaldepth to be the depth of the external picture -% '#1' and \pgfexternaltrimleft / \pgfexternaltrimright to be the 'hbaseline' shift. -% +% Reads the .dpth file which contains meta data of the external +% picture. +% +% This command handles the following stuff: +% - it defines \pgfexternaldepth . The macro contains the contents of +% a line which does not start with a control sequence (for example a +% line containing '50pt') +% - it defines \pgfexternaltrimleft and \pgfexternaltrimright +% - it checks if the .dpth file contains content stored by means of +% \pgfexternalstorecommand. If so, the argument of +% \pgfexternalstorecommand will be restored. +% - anything else will be appended to the main .aux file, assuming that +% it contains \label or \ref information (only if the LaTeX switch +% \if@filesw is \iftrue). % -% Furthermore, it handles any auxiliary information stored in the -% .dpth file (it appends it to the main aux file). % +% #1: the image file name (such that #1.dpth exists) \def\pgfexternalreaddpth#1{% % no \begingroup. Handle that manually: \edef\pgfexternalreaddpth@restore{% @@ -291,6 +323,10 @@ % the .aux file. % \expandafter\ifx\pgf@first\pgfexternal@restore + % if the first line in the .dpth file starts with the + % magic string \pgfexternal@restore, the complete line + % will be executed as-is. Example: + % \pgfexternal@restore{\def\somevalue{1}} #1% \else % do NOT execute #1! many LaTeX commands don't support it (\label for example) diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex index eeb6c3e8635..81b39f34659 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex,v 1.9 2008/04/22 17:03:26 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoregraphicstate.code.tex,v 1.11 2013/09/19 22:34:34 tantau Exp $ % Globals @@ -123,13 +123,15 @@ % \pgfsetstrokecolor{red} \def\pgfsetstrokecolor#1{% - \pgfutil@colorlet{pgf@tempcolor}{#1}% - \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% - \expandafter\expandafter\expandafter\pgf@setstrokecolor\csname\string\color@pgf@tempcolor\endcsname% + \pgfutil@colorlet{pgfstrokecolor}{#1}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfstrokecolor}}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\expandafter\expandafter\pgf@setstrokecolor\csname\string\color@pgfstrokecolor\endcsname% } \def\pgf@setstrokecolor#1#2#3#4#5{% \expandafter\ifx\csname pgfsys@color@#4@stroke\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4@stroke\endcsname}% \pgf@uncomma#5,,% @@ -155,13 +157,15 @@ % \pgfsetfillcolor{gray} \def\pgfsetfillcolor#1{% - \pgfutil@colorlet{pgf@tempcolor}{#1}% - \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% - \expandafter\expandafter\expandafter\pgf@setfillcolor\csname\string\color@pgf@tempcolor\endcsname% + \pgfutil@colorlet{pgffillcolor}{#1}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgffillcolor}}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgffillcolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \expandafter\expandafter\expandafter\pgf@setfillcolor\csname\string\color@pgffillcolor\endcsname% } \def\pgf@setfillcolor#1#2#3#4#5{% \expandafter\ifx\csname pgfsys@color@#4@fill\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4@fill\endcsname}% \pgf@uncomma#5,,% @@ -177,13 +181,17 @@ % \pgfsetcolor{blue} \def\pgfsetcolor#1{% - \pgfutil@colorlet{pgf@tempcolor}{#1}% - \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% - \expandafter\expandafter\expandafter\pgf@setcolor\csname\string\color@pgf@tempcolor\endcsname% + \pgfutil@colorlet{pgfstrokecolor}{#1}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgfstrokecolor}}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgffillcolor\expandafter\endcsname\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\expandafter\expandafter\pgf@setcolor\csname\string\color@pgfstrokecolor\endcsname% } \def\pgf@setcolor#1#2#3#4#5{% \expandafter\ifx\csname pgfsys@color@#4\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4\endcsname}% \pgf@uncomma#5,,% diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex index 59a3699f70d..1f2d6ea5d17 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreimage.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreimage.code.tex,v 1.16 2010/03/25 20:57:13 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreimage.code.tex,v 1.18 2013/07/15 15:41:24 tantau Exp $ @@ -44,8 +44,8 @@ \pgfkeys{/pgf/images/page=}% make page empty \fi% \ifx\pgf@filename\pgfutil@empty% - \PackageWarning{pgf}% - {File "#3" not found when defining image "#2".\MessageBreak + \pgfwarning% + {File "#3" not found when defining image "#2". Tried all extensions in "\pgfsys@imagesuffixlist"}% \pgf@declaredraftimage{#2}{#3}% \else% @@ -66,13 +66,14 @@ \pgfkeys{/pgf/images/height/.estore in=\pgf@imageheight} \pgfkeys{/pgf/images/page/.estore in=\pgf@imagepage} \pgfkeys{/pgf/images/interpolate/.cd,.code=\edef\pgf@imageinterpolate{#1},.default=true} +\let\pgf@imageinterpolate\pgfutil@empty \pgfkeys{/pgf/images/mask/.code=% {% \edef\pgf@imagemask{#1}% \ifx\pgf@imagemask\pgfutil@empty% \else% \pgfutil@ifundefined{pgf@mask@#1}% - {\PackageError{pgf}{Undefined mask "#1".}{}% + {\pgferror{Undefined mask "#1".}% \edef\pgf@imagemask{}}% {\edef\pgf@imagemask{\csname pgf@mask@#1\endcsname}% }% @@ -92,11 +93,11 @@ % #2: file name \def\pgf@declaredraftimage#1#2{% \ifx\pgf@imagewidth\pgfutil@empty% - \PackageWarning{pgf}{Missing width for image "#1" ("#2") in draft mode.\MessageBreak Using 1cm instead}% + \pgfwarning{Missing width for image "#1" ("#2") in draft mode. Using 1cm instead}% \edef\pgf@imagewidth{1cm}% \fi% \ifx\pgf@imageheight\pgfutil@empty% - \PackageWarning{pgf}{Missing height for image "#1" ("#2") in draft mode.\MessageBreak Using 1cm instead}% + \pgfwarning{Missing height for image "#1" ("#2") in draft mode. Using 1cm instead}% \edef\pgf@imageheight{1cm}% \fi% \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepagetext{ page \pgf@imagepage}\fi% @@ -105,7 +106,7 @@ \vrule\kern-0.4pt% \vbox to \pgf@imageheight{% \hrule\vfil% - \hbox to \pgf@imagewidth{\hskip-10cm\hfil\noexpand\tiny#2\pgf@imagepage\hfil\hskip-10cm}% + \hbox to \pgf@imagewidth{\hskip-10cm\hfil\noexpand\pgfutil@font@tiny#2\pgf@imagepage\hfil\hskip-10cm}% \vfil\hrule}% \kern-0.4pt\vrule}% }% @@ -141,8 +142,8 @@ \gdef\pgf@filename{}% \expandafter\pgf@findfile\pgfsys@imagesuffixlist:+{#3}% \ifx\pgf@filename\pgfutil@empty% - \PackageWarning{pgf}% - {File "#3" not found when defining mask "#2".\MessageBreak + \pgfwarning% + {File "#3" not found when defining mask "#2". Tried all extensions in "\pgfsys@imagesuffixlist"}% \else% \pgfsys@definemask{#2}% @@ -183,7 +184,7 @@ \def\pgf@imagename{pgf@image@#1}% \pgf@tryextensions{\pgf@imagename}{\pgfalternateextension}% \expandafter\pgfutil@ifundefined\expandafter{\pgf@imagename}% - {\PackageError{pgf}{Undefined image "#1"}{}}% + {\pgferror{Undefined image "#1"}}% {{\leavevmode\csname\pgf@imagename\endcsname}}} \def\pgf@tryextensions#1#2{% diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex index e18aea0cde9..880b41c4a30 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorelayers.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorelayers.code.tex,v 1.2 2010/08/27 12:51:47 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorelayers.code.tex,v 1.7 2013/07/18 17:07:38 tantau Exp $ % Creates a new pgf layer @@ -21,8 +21,10 @@ % \pgfdeclarelayer{background} \def\pgfdeclarelayer#1{% - \expandafter\pgf@newbox\csname pgf@layerbox@#1\endcsname% - \expandafter\pgf@newbox\csname pgf@layerboxsaved@#1\endcsname% + \pgfutil@ifundefined{pgf@layerbox@#1}{% + \expandafter\expandafter\csname pgf@newbox\endcsname\csname pgf@layerbox@#1\endcsname% + \expandafter\expandafter\csname pgf@newbox\endcsname\csname pgf@layerboxsaved@#1\endcsname% + }{}% } \let\pgf@newbox=\newbox % avoid plain TeX outer problem @@ -35,6 +37,9 @@ % Sets the list of layers that make up the picture. The layers will be % put on top of each other in the order given. % +% This command can also be given inside of a picture in which case it +% applies only to that very picture. +% % Example: % % \pgfsetlayers{background,main} @@ -42,8 +47,6 @@ \def\pgfsetlayers#1{\edef\pgf@layerlist{#1}} \pgfsetlayers{main} - - % Adds code to a layer % % #1 = layer name @@ -58,30 +61,80 @@ % \fill[red] (0,0) -- (1,1); % \end{pgfonlayer} +\def\pgfonlayer@name{main} + \def\pgfonlayer#1{% \pgfutil@ifundefined{pgf@layerbox@#1}{% - \PackageError{pgf}{Sorry, the requested layer '#1' could not be found. Maybe you misspelled it?}{}% - \bgroup - \begingroup + \pgferror{Sorry, the requested layer '#1' could not be found. Maybe you misspelled it?}% + \bgroup + \begingroup }{% - \expandafter\global\expandafter% - \setbox\csname pgf@layerbox@#1\endcsname=\hbox to 0pt% - \bgroup% - \expandafter\box\csname pgf@layerbox@#1\endcsname% - \begingroup% + \begingroup + \edef\pgf@temp{#1}% + \ifx\pgf@temp\pgfonlayer@name + % we are already on this layer. + \def\pgf@temp{% + \bgroup + \begingroup + }% + \else + \let\pgfonlayer@name=\pgf@temp + \pgfonlayer@assert@is@active + \def\pgf@temp{% + \expandafter\global\expandafter% + \setbox\csname pgf@layerbox@#1\endcsname=\hbox to 0pt% + \bgroup% + \expandafter\box\csname pgf@layerbox@#1\endcsname% + \begingroup% + }% + \fi + \pgfsetlinewidth{0.4pt}% always reset the line width + \pgf@temp }% } \def\endpgfonlayer{% \endgroup% \hss \egroup% + \endgroup } \let\startpgfonlayer=\pgfonlayer \let\stoppgfonlayer=\endpgfonlayer - - +\def\pgfdiscardlayername{discard} + +\def\pgfonlayer@assert@is@active{% + \ifx\pgfonlayer@name\pgfdiscardlayername + % this special layer name can be used as /dev/null without + % warning. + \else + \begingroup + \def\pgfonlayer@isactive{0}% + \expandafter\pgf@assert@layer@is@active@loop\pgf@layerlist,,\relax% + \if0\pgfonlayer@isactive + \pgfonlayer@assert@fail + \fi + \endgroup + \fi +}% +\def\pgfonlayer@assert@fail{% + \pgferror{Sorry, the requested layer '\pgfonlayer@name' is not + part of the layer list. Please verify that you provided + \string\pgfsetlayers\space and that '\pgfonlayer@name' is part of this list}% +}% +\def\pgf@assert@layer@is@active@loop#1,#2,\relax{% + \edef\pgf@test{#1}% + \ifx\pgf@test\pgfonlayer@name + \def\pgfonlayer@isactive{1}% + \else + \def\pgf@test{#2}% + \ifx\pgf@test\pgfutil@empty% + \else% + \pgf@assert@layer@is@active@loop#2,\relax% + \fi% + \fi +} % Hooks into the scoping: diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex index db62f73b6bf..60cede3f006 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex,v 1.24 2010/08/03 12:27:36 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathconstruct.code.tex,v 1.29 2013/10/07 15:51:46 tantau Exp $ \newdimen\pgf@path@lastx @@ -16,6 +16,8 @@ \let\pgfgetpath=\pgfsyssoftpath@getcurrentpath \let\pgfsetpath=\pgfsyssoftpath@setcurrentpath + + % Replace corners by arcs. % % #1 = in-size of arc @@ -75,6 +77,36 @@ } + +% The following protocol the passed sizes and all the corresponding +% softpath commands. The nonlinear transformation (nlt) module +% overwrites these commands. + +\def\pgf@lt@moveto#1#2{% + \pgf@protocolsizes{#1}{#2}% + \pgfsyssoftpath@moveto{\the#1}{\the#2}% +} +\def\pgf@lt@lineto#1#2{% + \pgf@protocolsizes{#1}{#2}% + \pgfsyssoftpath@lineto{\the#1}{\the#2}% +} +\def\pgf@lt@curveto#1#2#3#4#5#6{% + \pgf@protocolsizes{#1}{#2}% + \pgf@protocolsizes{#3}{#4}% + \pgf@protocolsizes{#5}{#6}% + \pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}% +} + +\let\pgf@lt@closepath\pgfsyssoftpath@closepath + +\let\pgf@nlt@moveto\pgf@lt@moveto +\let\pgf@nlt@lineto\pgf@lt@lineto +\let\pgf@nlt@curveto\pgf@lt@curveto +\let\pgf@nlt@closepath\pgf@lt@closepath + +\let\pgf@nlt@list\pgfutil@empty % If non-empty, the nlt module is active + + % Move current point to #1. % % #1 = new current point @@ -87,8 +119,7 @@ \def\pgfpathmoveto#1{% \pgfpointtransformed{#1}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% + \pgf@nlt@moveto{\pgf@x}{\pgf@y}% \global\pgf@path@lastx=\pgf@x% \global\pgf@path@lasty=\pgf@y% } @@ -147,9 +178,8 @@ \def\pgfpathlineto#1{% \pgfpointtransformed{#1}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@roundcornerifneeded% - \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% + \pgf@nlt@lineto{\pgf@x}{\pgf@y}% \global\pgf@path@lastx=\pgf@x% \global\pgf@path@lasty=\pgf@y% } @@ -173,7 +203,7 @@ \def\pgfpathclose{% \pgf@roundcornerifneeded% - \pgfsyssoftpath@closepath% + \pgf@nlt@closepath% } @@ -192,17 +222,14 @@ \def\pgfpathcurveto#1#2#3{% \pgfpointtransformed{#3}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgfpointtransformed{#2}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgfpointtransformed{#1}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@roundcornerifneeded% - \pgfsyssoftpath@curveto{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% + \pgf@nlt@curveto{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% } @@ -223,7 +250,6 @@ \def\pgfpathquadraticcurveto#1#2{% \pgfpointtransformed{#2}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgfpointtransformed{#1}% @@ -234,13 +260,11 @@ \pgf@ya=.33333333\pgf@yb% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% % compute first control point \advance\pgf@xc by.3333333\pgf@path@lastx% \advance\pgf@yc by.3333333\pgf@path@lasty% - \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% \pgf@roundcornerifneeded% - \pgfsyssoftpath@curveto{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@xa}{\pgf@ya}{\pgf@xb}{\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% } @@ -374,12 +398,9 @@ \pgf@yc=\pgf@yb\relax% \advance \pgf@xc by \pgf@x\relax% \advance \pgf@yc by \pgf@y\relax% - \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xc}{\the\pgf@yc}{\the\pgf@xb}{\the\pgf@yb}% + \pgf@nlt@curveto{\pgf@xa}{\pgf@ya}{\pgf@xc}{\pgf@yc}{\pgf@xb}{\pgf@yb}% \global\pgf@path@lastx=\pgf@xb% \global\pgf@path@lasty=\pgf@yb% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% - \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% - \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% }% } @@ -819,7 +840,7 @@ \pgfpatharcofellipse@{% \pgfpoint {\pgfpath@center@x + #5*cos(\pgfpath@angle@i)} - {\pgfpath@center@y + #6*sin(\pgfpath@angle@i)} + {\pgfpath@center@y + #6*sin(\pgfpath@angle@i)}% }% % \advance\c@pgf@countd by1 @@ -900,8 +921,7 @@ {% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% - \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% }% \pgf@x=0.55228475\pgf@xb% first arc \pgf@y=0.55228475\pgf@yb% @@ -909,8 +929,7 @@ \advance\pgf@y by\pgf@ya% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xa% \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% @@ -919,10 +938,9 @@ \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xb by\pgf@xc% - \advance\pgf@yb by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xb}{\the\pgf@yb}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \advance\pgf@yb by\pgf@yc% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}% }% \pgf@xa=-\pgf@xa% flip first axis \pgf@ya=-\pgf@ya% @@ -932,8 +950,7 @@ \advance\pgf@y by\pgf@yb% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xb% \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% @@ -942,10 +959,9 @@ \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% \advance\pgf@xa by\pgf@xc% - \advance\pgf@ya by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \advance\pgf@ya by\pgf@yc% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}% }% \pgf@xb=-\pgf@xb% flip second axis \pgf@yb=-\pgf@yb% @@ -955,8 +971,7 @@ \advance\pgf@y by\pgf@ya% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xa% \pgf@y=0.55228475\pgf@ya% \advance\pgf@x by\pgf@xb% @@ -966,9 +981,8 @@ \advance\pgf@y by\pgf@yc% \advance\pgf@xb by\pgf@xc% \advance\pgf@yb by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xb}{\the\pgf@yb}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xb}{\pgf@yb}% }% \pgf@xa=-\pgf@xa% flip first axis once more \pgf@ya=-\pgf@ya% @@ -978,8 +992,7 @@ \advance\pgf@y by\pgf@yb% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \edef\pgf@temp{{\the\pgf@x}{\the\pgf@y}}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \edef\pgf@temp{\pgf@xc\the\pgf@x\pgf@yc\the\pgf@y}% \pgf@x=0.55228475\pgf@xb% \pgf@y=0.55228475\pgf@yb% \advance\pgf@x by\pgf@xa% @@ -989,12 +1002,11 @@ \advance\pgf@y by\pgf@yc% \advance\pgf@xa by\pgf@xc% \advance\pgf@ya by\pgf@yc% - \expandafter\pgfsyssoftpath@curveto\pgf@temp{\the\pgf@x}{\the\pgf@y}{\the\pgf@xa}{\the\pgf@ya}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@temp% + \pgf@nlt@curveto{\pgf@xc}{\pgf@yc}{\pgf@x}{\pgf@y}{\pgf@xa}{\pgf@ya}% }% - \pgfsyssoftpath@closepath% - \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% + \pgf@nlt@closepath% + \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% } @@ -1029,7 +1041,9 @@ \ifpgf@pt@identity% \ifpgf@arccorners% \else% - \let\pgfrect@next=\pgf@normalrect% + \ifx\pgf@nlt@list\pgfutil@empty% + \let\pgfrect@next=\pgf@normalrect% + \fi% \fi% \fi% \pgfrect@next% @@ -1087,8 +1101,8 @@ % Append a grid to the current path. % -% #1 = lower left point of grid -% #2 = upper right point of grid +% #1 = first corner point of grid +% #2 = second corner point of grid % % Options: % @@ -1119,97 +1133,86 @@ \pgf@xb=\pgf@x% \pgf@yb=\pgf@y% \pgf@process{#2}% - \pgf@xa=\pgf@x\relax% - \pgf@ya=\pgf@y\relax% - {% - % compute bounding box - % first corner - \pgf@x=\pgf@xb% - \pgf@y=\pgf@yb% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - % second corner + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + % Swap coordinates if one of them is smaller than the other: + \ifdim\pgf@xa>\pgf@xb% \pgf@x=\pgf@xb% - \pgf@y=\pgf@ya% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - % third corner - \pgf@x=\pgf@xa% + \pgf@xb=\pgf@xa% + \pgf@xa=\pgf@x% + \fi% + \ifdim\pgf@ya>\pgf@yb% \pgf@y=\pgf@yb% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - % fourth corner - \pgf@x=\pgf@xa% - \pgf@y=\pgf@ya% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgf@protocolsizes{\pgf@x}{\pgf@y}% - }% - \c@pgf@counta=\pgf@y\relax% + \pgf@yb=\pgf@ya% + \pgf@ya=\pgf@y% + \fi% + \c@pgf@counta=\pgf@ya\relax% \c@pgf@countb=\pgf@yc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% - \pgf@y=\c@pgf@counta\pgf@yc\relax% - \ifdim\pgf@y<\pgf@ya% - \advance\pgf@y by\pgf@yc% + \pgfutil@tempdima=\c@pgf@counta\pgf@yc\relax% + \ifdim\pgfutil@tempdima<\pgf@ya% + \advance\pgfutil@tempdima by\pgf@yc% \fi% - \loop% horizontal lines + \pgfutil@tempdimb\pgf@x + \pgfutil@loop% horizontal lines {% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa=\pgfutil@tempdimb% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% \pgf@xa=\pgf@xb% - \pgf@ya=\pgf@y% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}% }% - \advance\pgf@y by\pgf@yc% - \ifdim\pgf@y<\pgf@yb% - \repeat% - \advance\pgf@y by-0.01pt\relax% - \ifdim\pgf@y<\pgf@yb% + \advance\pgfutil@tempdima by\pgf@yc% + \ifdim\pgfutil@tempdima<\pgf@yb% + \pgfutil@repeat% + \advance\pgfutil@tempdima by-0.01pt\relax% + \ifdim\pgfutil@tempdima<\pgf@yb% {% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa=\pgfutil@tempdimb% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@moveto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@moveto{\pgf@xa}{\pgf@ya}% \pgf@xa=\pgf@xb% - \pgf@ya=\pgf@y% + \pgf@ya=\pgfutil@tempdima% \pgf@pos@transform{\pgf@xa}{\pgf@ya} - \pgfsyssoftpath@lineto{\the\pgf@xa}{\the\pgf@ya}% + \pgf@nlt@lineto{\pgf@xa}{\pgf@ya}% }% \fi% - \c@pgf@counta=\pgf@x\relax% + \c@pgf@counta=\pgfutil@tempdimb\relax% \c@pgf@countb=\pgf@xc\relax% \divide\c@pgf@counta by\c@pgf@countb\relax% - \pgf@x=\c@pgf@counta\pgf@xc\relax% - \ifdim\pgf@x<\pgf@xa% - \advance\pgf@x by\pgf@xc% + \pgfutil@tempdimb=\c@pgf@counta\pgf@xc\relax% + \ifdim\pgfutil@tempdimb<\pgf@xa% + \advance\pgfutil@tempdimb by\pgf@xc% \fi% - \loop% vertical lines + \pgfutil@loop% vertical lines {% - \pgf@xc=\pgf@x% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% - \pgf@xc=\pgf@x% + \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}% + \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}% }% - \advance\pgf@x by\pgf@xc% - \ifdim\pgf@x<\pgf@xb% - \repeat% - \advance\pgf@x by-0.01pt\relax% - \ifdim\pgf@x<\pgf@xb% + \advance\pgfutil@tempdimb by\pgf@xc% + \ifdim\pgfutil@tempdimb<\pgf@xb% + \pgfutil@repeat% + \advance\pgfutil@tempdimb by-0.01pt\relax% + \ifdim\pgfutil@tempdimb<\pgf@xb% {% - \pgf@xc=\pgf@x% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@ya% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@moveto{\the\pgf@xc}{\the\pgf@yc}% - \pgf@xc=\pgf@x% + \pgf@nlt@moveto{\pgf@xc}{\pgf@yc}% + \pgf@xc=\pgfutil@tempdimb% \pgf@yc=\pgf@yb% \pgf@pos@transform{\pgf@xc}{\pgf@yc} - \pgfsyssoftpath@lineto{\the\pgf@xc}{\the\pgf@yc}% + \pgf@nlt@lineto{\pgf@xc}{\pgf@yc}% }% \fi% } diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex index 9bcfc739f56..b9c47231afa 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex @@ -7,9 +7,107 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex,v 1.8 2008/10/09 16:46:56 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathprocessing.code.tex,v 1.9 2013/09/09 10:05:41 tantau Exp $ +% Split a path at the last subpath of a path +% +% #1 = a macro that stores a path +% +% Description: +% +% This command will split the path into two parts: +% +% \pgfprocessresultpathprefix +% The part of the path before the last subpath. +% +% \pgfprocessresultpathsuffix +% The last subpath on the path. +% +% #1 will always be equal to the contents of the two above macros +% concatenated. Normally, your objective will be to modify the +% \pgfprocessresultpathsuffix and then concatenate the result. + +\def\pgfprocesssplitpath#1{% + \let\pgfprocessresultpathprefix\pgfutil@empty% + \let\pgfprocessresultpathsuffix\pgfutil@empty% + \let\pgf@next\pgf@process@split% + \expandafter\pgf@process@split#1\pgfsyssoftpath@movetotoken{}{}\pgf@stop% +} + +\def\pgf@process@split#1\pgfsyssoftpath@movetotoken#2#3#4{% + \ifx#4\pgf@stop% ok, end reached! + \expandafter\def\expandafter\pgfprocessresultpathsuffix\expandafter{\pgfprocessresultpathsuffix#1}% + \let\pgf@next\pgfutil@gobble% + \else% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathprefix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix#1}% + \def\pgfprocessresultpathsuffix{\pgfsyssoftpath@movetotoken{#2}{#3}}% + \fi% + \pgf@next#4% +} + + + +% Split a subpath at the end +% +% #1 = a macro that stores an open subpath that contains at least two +% path commands (so, not just a moveto); +% +% Description: +% +% Splits the supath into two parts: +% +% \pgfprocessresultsubpathsuffix +% This macro contains the last two "relevant" path commands: The end +% of the path command that led to the last path command and this +% last path command. In essence, this macro contains everything you +% "need to modify" if you wish to modify the end of the path. +% +% \pgfprocessresultsubpathprefix +% Everything before the previous macro on the subpath. + +\def\pgfprocesssplitsubpath#1{% + % First, we need to find the end: + \let\pgf@tempa\pgfutil@emtpy% + \let\pgf@tempb\pgfutil@emtpy% + \let\pgf@tempc\pgfutil@emtpy% + \let\pgf@tempd\pgfutil@emtpy% + \let\pgfprocessresultsubpathprefix\pgfutil@empty% + \let\pgfprocessresultsubpathsuffix\pgfutil@empty% + \let\pgf@next\pgf@split@subpath% + \expandafter\pgf@split@subpath#1\pgf@stop% +} + +\newif\ifpgf@split@move + +\def\pgf@split@subpath#1#2#3#4{% + \ifx#4\pgf@stop% + \expandafter\def\expandafter\pgfprocessresultsubpathsuffix\expandafter{\pgfprocessresultsubpathsuffix#1{#2}{#3}}% + \let\pgf@next\pgfutil@gobble% + \else% + \pgf@split@movetrue% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \pgf@split@movefalse% + \else + \ifx#1\pgfsyssoftpath@curvetosupportbtoken% + \pgf@split@movefalse% + \fi% + \fi% + \ifpgf@split@move% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultsubpathprefix% + \expandafter\expandafter\expandafter{% + \expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% + \def\pgfprocessresultsubpathsuffix{#1{#2}{#3}}% + \else% + \expandafter\def\expandafter\pgfprocessresultsubpathsuffix\expandafter{\pgfprocessresultsubpathsuffix#1{#2}{#3}}% + \fi% + \fi% + \pgf@next#4% +} + diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex index b803cce9caf..e60f66cce2f 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepathusage.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathusage.code.tex,v 1.12 2008/04/22 17:03:26 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepathusage.code.tex,v 1.23 2013/12/13 15:11:58 tantau Exp $ % Stroke/fill/clip/etc. the current path. Depending on the options, @@ -16,9 +16,9 @@ % of them are performed (in a sensible order). % % #1 = action(s) to be applied to the current path. Valid actions are: -% stroke - strokes the path. If no options are given, this is the -% default. -% draw - same as stroke. +% stroke - strokes the path. +% draw - strokes the path and adds arrow tips. +% tips - adds arrow tips. % fill - fills the path. % clip - clip the path. % discard - Discards the path. Same effect as having an empty @@ -33,27 +33,73 @@ % \pgfusepath{stroke} \pgfkeys{ - /pgf/stroke/.code=\def\pgf@up@stroke{stroke}, - /pgf/draw/.code=\def\pgf@up@stroke{stroke}, - /pgf/fill/.code=\def\pgf@up@fill{fill}, - /pgf/clip/.code=\def\pgf@up@clip{clip}, + /pgf/stroke/.code=\let\pgf@up@stroke\pgf@up@stroke@text\pgf@up@path@neededtrue, + /pgf/draw/.code=\let\pgf@up@stroke\pgf@up@stroke@text\pgf@up@path@neededtrue, + /pgf/fill/.code=\let\pgf@up@fill\pgf@up@fill@text\pgf@up@path@neededtrue, + /pgf/clip/.code=\let\pgf@up@clip\pgf@up@clip@text\pgf@up@path@neededtrue, /pgf/discard/.code=, - /pgf/use as bounding box/.code=\def\pgf@up@bb{\pgf@relevantforpicturesizefalse} + /pgf/use as bounding box/.code=\let\pgf@up@bb\pgf@do@up@bb, + /pgf/arrow keys/flex/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows}, + /pgf/arrow keys/flex'/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows}, + /pgf/arrow keys/bend/.code=\pgferror{You need to say \string\usetikzlibrary{bending} for flexing and bending arrows}, + /pgf/arrow keys/quick/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@quick}, } +\pgfkeys{ + /pgf/.cd, + tips/.is choice, + tips/.default=true, + tips/proper/.code=\let\pgf@tips@mode\pgf@tips@mode@onproper, + tips/on proper draw/.code=\let\pgf@tips@mode\pgf@tips@mode@onproperdraw, + tips/true/.code=\let\pgf@tips@mode\pgf@tips@mode@true, + tips/on draw/.code=\let\pgf@tips@mode\pgf@tips@mode@ondraw, + tips/never/.code=\let\pgf@tips@mode\pgf@tips@mode@false, + tips/false/.code=\let\pgf@tips@mode\pgf@tips@mode@false, +} +\def\pgf@tips@mode@onproper{4} +\def\pgf@tips@mode@onproperdraw{3} +\def\pgf@tips@mode@true{2} +\def\pgf@tips@mode@ondraw{1} +\def\pgf@tips@mode@false{0} +\let\pgf@tips@mode\pgf@tips@mode@ondraw + + +% The following can only be set to "true" using the options in the +% module "bending" +\newif\ifpgf@precise@shortening +\def\pgf@arrow@mode@is@quick{0} +\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@quick + +\newif\ifpgf@up@path@needed +\newif\ifpgf@up@draw@arrows +\def\pgf@up@stroke@text{stroke} +\def\pgf@up@fill@text{fill} +\def\pgf@up@clip@text{clip} +\def\pgf@do@up@bb{\pgf@relevantforpicturesizefalse} + \def\pgfusepath#1{% + \pgf@up@path@neededfalse% + \pgf@up@draw@arrowsfalse% \let\pgf@up@stroke\pgfutil@empty% \let\pgf@up@fill\pgfutil@empty% \let\pgf@up@clip\pgfutil@empty% - \let\pgf@up@discard\pgfutil@empty% \let\pgf@up@bb\pgfutil@empty% \pgfset{#1}% \expandafter\def\expandafter\pgf@up@action\expandafter{\csname pgfsys@\pgf@up@fill\pgf@up@stroke\endcsname}% + \ifnum\pgf@tips@mode=2\relax% + \pgf@up@path@neededtrue% + \fi% + \ifnum\pgf@tips@mode=4\relax% + \pgf@up@path@neededtrue% + \fi% + \ifpgf@up@path@needed% + \else% + \pgfsyssoftpath@setcurrentpath\pgfutil@empty% + \fi% \ifx\pgf@up@stroke\pgfutil@empty% \ifx\pgf@up@fill\pgfutil@empty% + \let\pgf@up@action=\pgfutil@empty% \ifx\pgf@up@clip\pgfutil@empty% - \let\pgf@up@action=\pgfutil@empty% - \pgfsyssoftpath@setcurrentpath\pgfutil@empty% \else% % only clipping \let\pgf@up@action=\pgfsys@discardpath% @@ -86,29 +132,38 @@ % \ifx\pgf@up@clip\pgfutil@empty% \ifx\pgf@up@stroke\pgfutil@empty% - \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% - \pgf@up@action% - \else% - \pgf@check@for@arrows% - \ifpgf@drawarrows% - \pgf@shorten@path@as@needed% - \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% - \pgf@up@action% - \pgf@stroke@inner@line@if@needed% - \pgfsyssoftpath@setcurrentpath\pgfutil@empty% - \pgf@add@arrows@as@needed% - \else% + \ifx\pgf@up@action\pgfutil@empty% + \ifnum\pgf@tips@mode=2\relax% + \pgf@up@draw@arrows@only% + \fi% + \ifnum\pgf@tips@mode=4\relax% + \pgf@up@draw@arrows@only% + \fi% + \else% \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% \pgf@up@action% - \pgf@stroke@inner@line@if@needed% + \fi% + \else% + \pgfgetpath\pgf@arrowpath% + \pgf@path@setup@tempswa% + \pgfprocesscheckclosed{\pgf@arrowpath}{\pgfutil@tempswafalse}% + \pgf@path@check@proper% + \ifpgfutil@tempswa% + \pgf@prepare@end@of@path% + \begingroup% + \pgf@prepare@start@of@path% + \fi% + \pgfsyssoftpath@invokecurrentpath% + \pgf@up@action% + \pgf@stroke@inner@line@if@needed% + \ifpgfutil@tempswa% + \pgf@add@arrow@at@start% + \endgroup% + \pgf@add@arrow@at@end% \fi% \fi% \else% \pgfsyssoftpath@invokecurrentpath% - \pgfsyssoftpath@getcurrentpath\pgf@last@used@path% \pgfsys@clipnext% \pgf@up@action% \pgf@relevantforpicturesizefalse% @@ -118,9 +173,70 @@ \pgf@resetpathsizes% \ignorespaces% } +\def\pgf@path@setup@tempswa{% + \ifnum\pgf@tips@mode>0\relax + \pgfutil@tempswatrue% + \else + \pgfutil@tempswafalse% + \fi% +} +\def\pgf@up@draw@arrows@only{% + \pgfgetpath\pgf@arrowpath% + \pgfutil@tempswatrue% + \pgfprocesscheckclosed{\pgf@arrowpath}{\pgfutil@tempswafalse}% + \pgf@path@check@proper% + \ifpgfutil@tempswa% + \pgf@prepare@end@of@path% + \begingroup% + \pgf@prepare@start@of@path% + \pgf@add@arrow@at@start% + \endgroup% + \pgf@add@arrow@at@end% + \fi% +} + +\def\pgf@path@check@proper{% + \ifpgfutil@tempswa% + \ifnum\pgf@tips@mode>2\relax% + \pgf@path@check@proper@% + \fi% + \fi% +} + + +\def\pgf@path@check@proper@{% + {% + \pgf@x0pt\pgf@y\pgf@x% + \pgfutil@tempswatrue% + \let\pgfsyssoftpath@movetotoken\pgf@path@proper@init% + \let\pgfsyssoftpath@linetotoken\pgf@path@proper@test%% + \let\pgfsyssoftpath@curvetosupportatoken\pgf@path@proper@test% + \let\pgfsyssoftpath@curvetosupportbtoken=\pgf@path@proper@test% + \let\pgfsyssoftpath@curvetotoken\pgf@path@proper@test% + \let\pgfsyssoftpath@rectcornertoken\pgf@path@proper@test% + \let\pgfsyssoftpath@rectsizetoken\pgf@path@proper@zero@test% + \let\pgfsyssoftpath@closepathtoken\pgf@path@proper@test% + % Execute the path: + \pgf@arrowpath% + \expandafter + }% + \ifpgfutil@tempswa\pgfutil@tempswafalse\else\pgfutil@tempswatrue\fi% +} + +\def\pgf@path@proper@init#1#2{\pgfutil@tempswatrue\pgf@x#1\pgf@y#2}% +\def\pgf@path@proper@test#1#2{% + \ifdim\pgf@x=#1\relax\else\pgfutil@tempswafalse\fi% + \ifdim\pgf@y=#2\relax\else\pgfutil@tempswafalse\fi} +\def\pgf@path@proper@zero@test#1#2{% + \ifdim\pgf@x=0pt\relax\else\pgfutil@tempswafalse\fi% + \ifdim\pgf@y=0pt\relax\else\pgfutil@tempswafalse\fi} + + + \def\pgf@stroke@inner@line@if@needed{% \ifdim\pgfinnerlinewidth>0pt\relax% + \expandafter\let\expandafter\pgf@temp@save\csname\string\color@pgfstrokecolor\endcsname% \pgfsys@beginscope% {% \pgfsys@setlinewidth{\pgfinnerlinewidth}% @@ -129,9 +245,17 @@ \pgfsys@stroke% }% \pgfsys@endscope% + \expandafter\global\expandafter\let\csname\string\color@pgfstrokecolor\endcsname\pgf@temp@save% \fi% } +\let\pgf@prepare@start@of@path\relax% +\let\pgf@add@arrow@at@end\relax% +\let\pgf@add@arrow@at@start\relax% + + + + % Shorten start/end of paths by a certain amount. % % #1 = amount by which paths should be shortened. @@ -149,94 +273,374 @@ \def\pgfsetshortenstart#1{\pgfmathsetlength\pgf@shorten@start@additional{#1}} \def\pgfsetshortenend#1{\pgfmathsetlength\pgf@shorten@end@additional{#1}} -\newif\ifpgf@drawarrows - -\def\pgf@check@for@arrows{% - \pgf@drawarrowsfalse% - \ifx\pgf@startarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi% - \ifx\pgf@endarrow\pgfutil@empty\else\pgf@drawarrowstrue\fi% - \ifdim\pgf@shorten@end@additional=0pt\relax\else\pgf@drawarrowstrue\fi% - \ifdim\pgf@shorten@start@additional=0pt\relax\else\pgf@drawarrowstrue\fi% - \ifpgf@drawarrows% - \pgfsyssoftpath@getcurrentpath\pgf@arrowpath% - \ifx\pgf@arrowpath\pgfutil@empty% - \pgf@drawarrowsfalse% - \else% - \pgfprocesscheckclosed{\pgf@arrowpath}{\pgf@drawarrowsfalse}% +\newdimen\pgf@shorten@end@additional +\newdimen\pgf@shorten@start@additional + + + +% +% +% Handling the end of a path +% +% +% The "handling" consists of first testing whether we need to do +% anything at all, namely because either an arrow tip should be drawn +% at the end or because the path should be shortened at the end. If +% so, we shorten the path if needed and, later on, add the arrow tip. +% + +\newif\ifpgf@worry + + +% Prepare the end of the path: Test whether anything must be done +% (step 0) and, if so, split the path (step 1), extract the interesting points from +% the path (step 2), prepare further computations (step 3), shorten +% the path (step 4) if necessary, and add the arrow tip (step 4 in +% macro \pgf@add@arrow@at@end, which is called later). + +\def\pgf@prepare@end@of@path{% + \let\pgfprocessresultpathsuffix\relax% flag that nothing has happened... + \let\pgfprocessresultsubpathsuffix\relax% + \pgfsyssoftpath@getcurrentpath\pgf@arrowpath% + % + % Step 0 start: + % + % Do we need to worry about the end? + % + \ifx\pgf@arrowpath\pgfutil@empty\else% + \pgf@worryfalse% + \ifx\pgf@end@tip@sequence\pgfutil@empty\else\pgf@worrytrue\fi% Yes, worry if we have to draw an arrow + \pgf@precise@shorteningfalse% + \pgf@arrow@compute@shortening\pgf@end@tip@sequence% + \advance\pgf@xa by\pgf@shorten@end@additional% + \advance\pgf@xb by\pgf@shorten@end@additional% + \ifdim\pgf@xa=0pt\relax\else\pgf@worrytrue\fi% Also, worry if shortening is requested + \edef\pgf@path@shortening@distance{\the\pgf@xa}% + \edef\pgf@arrow@tip@total@length{\the\pgf@xb}% + % + % Step 0 done. + % + \ifpgf@worry% + % Ok, need to "worry" about the end, either because we need to + % shorten it or to draw an arrow head. + % + % Step 1: Split + % + \pgfprocesssplitpath{\pgf@arrowpath}% + \pgfprocesssplitsubpath{\pgfprocessresultpathsuffix}% + % + % Step 2: extract + % + \expandafter\pgf@parse@end\pgfprocessresultsubpathsuffix\pgf@stop\pgf@stop\pgf@stop% + % + % Step 3: prep + % + \pgf@prep@end% + % + % Step 4: shorten + % + \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@end\fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrowpath% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}% + \pgfsyssoftpath@setcurrentpath\pgf@arrowpath% \fi% \fi% } -\newdimen\pgf@shorten@end@additional -\newdimen\pgf@shorten@start@additional +\def\pgf@parse@end#1#2#3#4#5#6{% + \ifx#4\pgf@stop% Only a moveto! -> do nothing! + \def\pgfpointlastonpath{\pgfqpoint{#2}{#3}}% + \let\pgf@next\relax% + \let\pgf@do@shorten@end\relax% + \let\pgf@do@draw@end\pgf@do@draw@straightend% + \let\pgf@prep@end\pgf@prep@movetoend% + \else\ifx#4\pgfsyssoftpath@curvetosupportatoken% A curve -> this will get complicated... + \def\pgfsubpathfourthlasttoken{#1}% + \def\pgfpointfourthlastonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointthirdlastonpath{\pgfqpoint{#5}{#6}}% + \ifpgf@precise@shortening% + \let\pgf@do@shorten@end\pgf@do@shorten@curvedend% + \let\pgf@do@draw@end\pgf@do@draw@curvedend% + \let\pgf@prep@end\pgf@prep@curveend% + \else% + \def\pgfsubpathstart{\noexpand#1{#2}{#3}\noexpand#4{#5}{#6}}% + \let\pgf@do@shorten@end\pgf@do@shorten@straightend% + \let\pgf@do@draw@end\pgf@do@draw@straightend% + \let\pgf@prep@end\pgf@prep@straightend% + \fi% + \let\pgf@next\pgf@parse@end@curve@cont% + \else% A straight line -> great! + \def\pgfsubpathstart{\noexpand#1{#2}{#3}\noexpand#4}% + \def\pgfpointsecondlastonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointlastonpath{\pgfqpoint{#5}{#6}}% + \let\pgfpointfourthlastonpath\relax% + \let\pgfpointthirdlastonpath\relax% + \let\pgf@next\pgf@parse@end@gobble@three% + \let\pgf@do@shorten@end\pgf@do@shorten@straightend% + \let\pgf@do@draw@end\pgf@do@draw@straightend% + \let\pgf@prep@end\pgf@prep@straightend% + \fi\fi% + \pgf@next% Needed for reading rest of path... +} -\let\pgf@shorten@end=\pgfutil@empty -\let\pgf@shorten@start=\pgfutil@empty +\def\pgf@parse@end@gobble@three#1#2#3{}% +\def\pgf@parse@end@curve@cont#1#2#3#4#5#6#7#8#9{% + \def\pgfpointsecondlastonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointlastonpath{\pgfqpoint{#5}{#6}}% + \ifpgf@precise@shortening% + \else% + \expandafter\def\expandafter\pgfsubpathstart\expandafter{\pgfsubpathstart\noexpand#1{#2}{#3}\noexpand#4}% + \fi% +} -\def\pgf@shorten@path@as@needed{% - \pgfprocesspathextractpoints{\pgf@arrowpath}% - \let\pgf@arrow@next=\pgf@shorten@now% - \ifx\pgf@shorten@start\pgfutil@empty% - \ifx\pgf@shorten@end\pgfutil@empty% - \ifdim\pgf@shorten@end@additional=0pt\relax% - \ifdim\pgf@shorten@start@additional=0pt\relax% - \let\pgf@arrow@next=\relax% - \fi% +% +% Preps +% +\def\pgf@prep@movetoend{% + \pgf@process{\pgfpointlastonpath}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgf@xc\pgf@x + \pgf@yc\pgf@y +} +\def\pgf@prep@straightend{% + \let\pgf@ref\pgfpointsecondlastonpath + \ifx\pgfpointlastonpath\pgfpointsecondlastonpath% degenerate! + \ifx\pgfpointthirdlastonpath\relax% cannot help it: really a zero-length path + \else% + \ifx\pgfpointlastonpath\pgfpointthirdlastonpath% double degenerate! + \let\pgf@ref\pgfpointfourthlastonpath% Use third point for reference. + \else + \let\pgf@ref\pgfpointthirdlastonpath% Use third point for reference. \fi% \fi% \fi% - \pgf@arrow@next% + \pgfpointlineatdistance{\pgf@path@shortening@distance}{\pgfpointlastonpath}{\pgf@ref}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% } -\def\pgf@shorten@now{% - {% - \pgf@x=0pt% - \pgf@shorten@start% - \advance\pgf@x by\pgf@shorten@start@additional% - \pgf@xc=\pgf@x% - \pgfpointlineatdistance{\pgf@xc}{\pgfpointfirstonpath}{\pgfpointsecondonpath}% - \global\pgf@xb=\pgf@x% - \global\pgf@yb=\pgf@y% - \pgf@process{\pgfpointsecondonpath}% - \global\advance\pgf@x by\pgf@xa% - \global\advance\pgf@y by\pgf@ya% - }% - \edef\pgfpointfirstonpath{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% - \edef\pgfpointsecondonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + +% +% Line shortening for straight lines: +% +\def\pgf@do@shorten@straightend{% + \edef\pgfprocessresultsubpathsuffix{\pgfsubpathstart{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% +} + + +% +% Draw an end arrow by calling an appropriate subfunction, if necessary +% + +\def\pgf@add@arrow@at@end{% + \ifx\pgf@arrowpath\pgfutil@empty\else% + \ifx\pgf@end@tip@sequence\pgfutil@empty\else% + \pgf@do@draw@end% + \fi% + \fi% +} + +% +% Draw an end arrow at the end of a straight line +% +\def\pgf@do@draw@straightend{% {% - \pgf@x=0pt% - \pgf@shorten@end% - \advance\pgf@x by\pgf@shorten@end@additional% - \pgf@xc=\pgf@x% - \pgfpointlineatdistance{\pgf@xc}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}% - \global\pgf@xb=\pgf@x% - \global\pgf@yb=\pgf@y% - \pgf@process{\pgfpointsecondlastonpath}% - \global\advance\pgf@x by\pgf@xa% - \global\advance\pgf@y by\pgf@ya% + \pgftransformreset% + \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgf@arrow@draw@arrow\pgf@end@tip@sequence\pgf@arrow@tip@total@length% }% - \edef\pgfpointlastonpath{\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}% - \edef\pgfpointsecondlastonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - \pgfprocesspathreplacestartandend{\pgf@arrowpath}{\pgfpointfirstonpath}{\pgfpointlastonpath}% - \pgfsyssoftpath@setcurrentpath\pgf@arrowpath% } -\def\pgf@add@arrows@as@needed{% - \ifx\pgf@startarrow\pgfutil@empty% - \else% - \pgflowlevelobj% - {\pgftransformarrow{\pgfpointsecondonpath}{\pgfpointfirstonpath}} - {\pgf@startarrow}% + + +% +% +% Handling the start of a path +% +% +% The "handling" is similar to the case for the start of the path. We +% may be able to skip the splitting if that was done already for the +% end. Otherwise, things are basically the same. +% + +% Prepare the start of the path: Test whether anything must be done +% (step 0) and, if so, split the path (step 1) if necesssary, extract +% the interesting points from the path (step 2), prepare computations +% (step 3) needed for both shortening and tip adding, shorten the path +% (step 4), and add the arrow tip (step 5 in macro +% \pgf@add@arrow@at@start, which is called later). + +\def\pgf@prepare@start@of@path{% + % + % Step 0 start: + % + % Do we need to worry about the start? + % + \ifx\pgf@arrowpath\pgfutil@empty\else% + \pgf@worryfalse% + \ifx\pgf@start@tip@sequence\pgfutil@empty\else\pgf@worrytrue\fi% Yes, worry if we have to draw an arrow + \pgf@precise@shorteningfalse% + \pgf@arrow@compute@shortening\pgf@start@tip@sequence% + \advance\pgf@xa by\pgf@shorten@start@additional% + \advance\pgf@xb by\pgf@shorten@start@additional% + \ifdim\pgf@xa=0pt\relax\else\pgf@worrytrue\fi% Also, worry if shortening is requested + \edef\pgf@path@shortening@distance{\the\pgf@xa}% + \edef\pgf@arrow@tip@total@length{\the\pgf@xb}% + % + % Step 0 done. + % + \ifpgf@worry% + % Ok, need to "worry" about the start, either because we need to + % shorten it or to draw an arrow head. + % + % Step 1: Split + % + \ifx\pgfprocessresultpathsuffix\relax% + % Ok, still need to compute the split: + \pgfprocesssplitpath{\pgf@arrowpath}% + \fi% + % + % Step 2: extract + % + \expandafter\pgf@parse@start\pgfprocessresultpathsuffix\pgf@stop\pgf@stop\pgf@stop% + % + % Step 3: prep + % + \pgf@prep@start% + % + % Step 4: shorten + % + \ifdim\pgf@path@shortening@distance=0pt\else\pgf@do@shorten@start\fi% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@arrowpath% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathprefix\pgfprocessresultpathsuffix}% + \pgfsyssoftpath@setcurrentpath\pgf@arrowpath% + \fi% \fi% - \ifx\pgf@endarrow\pgfutil@empty% - \else% - \pgflowlevelobj% - {\pgftransformarrow{\pgfpointsecondlastonpath}{\pgfpointlastonpath}} - {\pgf@endarrow}% - \fi% } -\let\pgf@startarrow=\pgfutil@empty -\let\pgf@endarrow=\pgfutil@empty +\def\pgf@parse@start#1#2#3#4#5#6{% + \def\pgfpointfirstonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointsecondonpath{\pgfqpoint{#5}{#6}}% + \let\pgfpointthirdonpath\relax% + \let\pgfpointfourthonpath\relax% + \def\pgfsubpathfirsttoken{\noexpand#1}% + \def\pgfsubpathsecondtoken{\noexpand#4}% + \ifx#4\pgf@stop% Only a moveto! -> do nothing! + \let\pgf@next\relax% + \let\pgf@do@shorten@start\relax% + \let\pgf@prep@start\pgf@prep@movetostart% + \let\pgf@do@draw@start\pgf@do@draw@straightstart% + \else\ifx#4\pgfsyssoftpath@curvetosupportatoken% A curve -> this will get complicated... + \ifpgf@precise@shortening% + \let\pgf@next\pgf@parse@start@curve@cont% + \let\pgf@do@shorten@start\pgf@do@shorten@curvedstart% + \let\pgf@do@draw@start\pgf@do@draw@curvedstart% + \let\pgf@prep@start\pgf@prep@curvedstart% + \else% can treat the end like a straight line... + \let\pgf@next\pgf@parse@start@curve@cont@straight% + \let\pgf@do@shorten@start\pgf@do@shorten@straightstart% + \let\pgf@do@draw@start\pgf@do@draw@straightstart% + \let\pgf@prep@start\pgf@prep@straightstart% + \fi% + \else% A straight line -> great! + \let\pgf@next\pgf@parse@start@till@stop% + \let\pgf@do@shorten@start\pgf@do@shorten@straightstart% + \let\pgf@do@draw@start\pgf@do@draw@straightstart% + \let\pgf@prep@start\pgf@prep@straightstart% + \fi\fi% + \pgf@next% Needed for reading rest of path... +} + +\def\pgf@parse@start@till@stop#1\pgf@stop\pgf@stop\pgf@stop{\def\pgfsubpathend{#1}}% + +\def\pgf@parse@start@curve@cont#1#2#3#4#5#6#7\pgf@stop\pgf@stop\pgf@stop{% + \def\pgfpointthirdonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointfourthonpath{\pgfqpoint{#5}{#6}}% + \def\pgfsubpathend{#7}% +} + +\def\pgf@parse@start@curve@cont@straight#1#2#3#4#5#6#7\pgf@stop\pgf@stop\pgf@stop{% + \def\pgfpointthirdonpath{\pgfqpoint{#2}{#3}}% + \def\pgfpointfourthonpath{\pgfqpoint{#5}{#6}}% + \def\pgfsubpathend{#1{#2}{#3}#4{#5}{#6}#7}% +} + +% +% Preps +% +\def\pgf@prep@movetostart{% + \pgf@process{\pgfpointfirstonpath}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgf@xc\pgf@x + \pgf@yc\pgf@y +} +\def\pgf@prep@straightstart{% + \let\pgf@ref\pgfpointsecondonpath + \ifx\pgfpointfirstonpath\pgfpointsecondonpath% degenerate! + \ifx\pgfpointthirdonpath\relax% cannot help it: really a zero-length path + \else% + \ifx\pgfpointfirstonpath\pgfpointthirdonpath% double degenerate! + \let\pgf@ref\pgfpointfourthonpath% Use third point for reference. + \else + \let\pgf@ref\pgfpointthirdonpath% Use third point for reference. + \fi% + \fi% + \fi% + \pgfpointlineatdistance{\pgf@path@shortening@distance}{\pgfpointfirstonpath}{\pgf@ref}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% +} + +% +% Line shortening for straight lines: +% +\def\pgf@do@shorten@straightstart{% + \edef\pgfprocessresultpathsuffix{\pgfsubpathfirsttoken{\the\pgf@xa}{\the\pgf@ya}\pgfsubpathsecondtoken{\the\pgf@xc}{\the\pgf@yc}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}% +} + + +% +% Draw a start arrow by calling an appropriate subfunction, if necessary +% + +\def\pgf@add@arrow@at@start{% + \ifx\pgf@arrowpath\pgfutil@empty\else% + \ifx\pgf@start@tip@sequence\pgfutil@empty\else% + \pgf@do@draw@start% + \fi% + \fi% +} + +% +% Draw an start arrow at the start of a straight line +% +\def\pgf@do@draw@straightstart{% + {% + \pgftransformreset% + \pgftransformarrow{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgf@arrow@draw@arrow\pgf@start@tip@sequence\pgf@arrow@tip@total@length% + }% +} + + + +\let\pgf@shorten@end=\pgfutil@empty +\let\pgf@shorten@start=\pgfutil@empty + + +\endinput% + + + + -\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex index b308c5aef8f..54b5afcf6ae 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepatterns.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepatterns.code.tex,v 1.3 2009/07/02 11:43:15 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepatterns.code.tex,v 1.5 2013/11/07 15:45:46 tantau Exp $ % Creates a new uncolored pattern % @@ -53,8 +53,8 @@ % } % \def\pgfdeclarepatternformonly{% - \def\pgf@pattern@type{formonly}% - \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% + \def\pgf@pattern@type{formonly}% + \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% } @@ -92,8 +92,8 @@ % } % \def\pgfdeclarepatterninherentlycolored{% - \def\pgf@pattern@type{inherentlycolored}% - \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% + \def\pgf@pattern@type{inherentlycolored}% + \pgfutil@ifnextchar[{\pgf@declarepattern@checkarg}{\pgf@declarepattern@checkarg[]}% } @@ -101,26 +101,26 @@ \def\pgf@declarepattern@checkarg[#1]{% - \def\pgf@pattern@tempvars{#1}% - \ifx\pgf@pattern@tempvars\pgfutil@empty% - \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type\endcsname% - \else% - \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type @mutable\endcsname% - \fi% - \pgf@next} + \def\pgf@pattern@tempvars{#1}% + \ifx\pgf@pattern@tempvars\pgfutil@empty% + \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type\endcsname% + \else% + \expandafter\let\expandafter\pgf@next\csname pgf@declarepattern\pgf@pattern@type @mutable\endcsname% + \fi% + \pgf@next} \long\def\pgf@declarepatternformonly#1#2#3#4#5{\pgf@declarepattern{#1}{#2}{#3}{#4}{#5}{0}} - + \long\def\pgf@declarepatterninherentlycolored#1#2#3#4#5{\pgf@declarepattern{#1}{#2}{#3}{#4}{#5}{1}} - + \long\def\pgf@declarepatternformonly@mutable#1#2#3#4#5{% - \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% - \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{2}% + \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% + \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{2}% } \long\def\pgf@declarepatterninherentlycolored@mutable#1#2#3#4#5#6{% - \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% - \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{3}% + \def\pgf@marshal{\pgf@declarepatternmutable{#1}}% + \expandafter\pgf@marshal\expandafter{\pgf@pattern@tempvars}{#2}{#3}{#4}{#5}{3}% } \def\pgf@declarepattern#1#2#3#4#5#6{% @@ -134,6 +134,7 @@ \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% \pgfsysprotocol@bufferedtrue% \pgfsys@beginscope% + \pgfsetarrows{-}% #5% \pgfsys@endscope% \pgfsysprotocol@getcurrentprotocol\pgf@pattern@code% @@ -162,22 +163,22 @@ \expandafter\global\expandafter\let\csname pgf@pattern@instantiate@#1\endcsname=\pgf@marshal% } {% - \PackageError{pgfcorepatterns}{Pattern `#1' already defined}{}% + \pgferror{Pattern `#1' already defined}% }% } \def\pgf@pattern@number{0}% \def\pgf@declarepatternmutable#1#2#3#4#5#6#7{% - \pgfutil@ifundefined{pgf@pattern@name@#1}{% - \expandafter\gdef\csname pgf@pattern@name@#1\endcsname{#1}% - \expandafter\gdef\csname pgf@pattern@variables@#1\endcsname{#2}% - \expandafter\gdef\csname pgf@pattern@lowerleft@#1\endcsname{#3}% - \expandafter\gdef\csname pgf@pattern@upperright@#1\endcsname{#4}% - \expandafter\gdef\csname pgf@pattern@tilesize@#1\endcsname{#5}% - \expandafter\long\expandafter\gdef\csname pgf@pattern@code@#1\endcsname{#6}% - \expandafter\gdef\csname pgf@pattern@type@#1\endcsname{7}% - }{\PackageError{pgfcorepatterns}{The pattern `#1' is already defined}{}}% + \pgfutil@ifundefined{pgf@pattern@name@#1}{% + \expandafter\gdef\csname pgf@pattern@name@#1\endcsname{#1}% + \expandafter\gdef\csname pgf@pattern@variables@#1\endcsname{#2}% + \expandafter\gdef\csname pgf@pattern@lowerleft@#1\endcsname{#3}% + \expandafter\gdef\csname pgf@pattern@upperright@#1\endcsname{#4}% + \expandafter\gdef\csname pgf@pattern@tilesize@#1\endcsname{#5}% + \expandafter\long\expandafter\gdef\csname pgf@pattern@code@#1\endcsname{#6}% + \expandafter\gdef\csname pgf@pattern@type@#1\endcsname{7}% + }{\pgferror{The pattern `#1' is already defined}}% } \def\pgf@ifpatternisinherentlycolored#1#2#3{% @@ -210,49 +211,49 @@ % \pgfsetfillpattern{stars}{red} % \def\pgfsetfillpattern#1#2{% - \pgfutil@ifundefined{pgf@pattern@name@#1}% - {% - \PackageError{pgfcorepatterns}{Undefined pattern `#1'}{}% - }% - {% - \pgf@ifpatternismutable{#1}% - {% - % So, a mutable pattern. Check to see if the pattern - % has been used with the current variable values... - \let\pgf@pattern@tempvars\pgfutil@empty% - \expandafter\expandafter\expandafter\pgf@pattern@check@vars% - \csname pgf@pattern@variables@#1\endcsname,\pgf@stop,% - \edef\pgf@pattern@nametemp{pgf@pattern@#1@\pgf@pattern@tempvars}% - \expandafter\pgfutil@ifundefined\expandafter{\pgf@pattern@nametemp}% - {% - % ...Nope. So declare a new instance of the mutable pattern. - \pgf@ifpatternisinherentlycolored{#1}% - {\let\pgf@set@fillpattern@declare\pgfdeclarepatterninherentlycolored}% - {\let\pgf@set@fillpattern@declare\pgfdeclarepatternformonly}% - \pgf@set@fillpattern@declare% - {\pgf@pattern@nametemp}% - {\csname pgf@pattern@lowerleft@#1\endcsname}% - {\csname pgf@pattern@upperright@#1\endcsname}% - {\csname pgf@pattern@tilesize@#1\endcsname}% - {\csname pgf@pattern@code@#1\endcsname}% - }% - {% - % ...Yep. So do nothing. - }% - \expandafter\pgf@set@fillpattern\expandafter{\pgf@pattern@nametemp}{#2}% - \expandafter\gdef\csname\pgf@pattern@nametemp\endcsname{#1}% - }% - {% - % A non-mutable pattern. - \pgf@set@fillpattern{#1}{#2}% - }% - }% + \pgfutil@ifundefined{pgf@pattern@name@#1}% + {% + \pgferror{Undefined pattern `#1'}% + }% + {% + \pgf@ifpatternismutable{#1}% + {% + % So, a mutable pattern. Check to see if the pattern + % has been used with the current variable values... + \let\pgf@pattern@tempvars\pgfutil@empty% + \expandafter\expandafter\expandafter\pgf@pattern@check@vars% + \csname pgf@pattern@variables@#1\endcsname,\pgf@stop,% + \edef\pgf@pattern@nametemp{pgf@pattern@#1@\pgf@pattern@tempvars}% + \expandafter\pgfutil@ifundefined\expandafter{\pgf@pattern@nametemp}% + {% + % ...Nope. So declare a new instance of the mutable pattern. + \pgf@ifpatternisinherentlycolored{#1}% + {\let\pgf@set@fillpattern@declare\pgfdeclarepatterninherentlycolored}% + {\let\pgf@set@fillpattern@declare\pgfdeclarepatternformonly}% + \pgf@set@fillpattern@declare% + {\pgf@pattern@nametemp}% + {\csname pgf@pattern@lowerleft@#1\endcsname}% + {\csname pgf@pattern@upperright@#1\endcsname}% + {\csname pgf@pattern@tilesize@#1\endcsname}% + {\csname pgf@pattern@code@#1\endcsname}% + }% + {% + % ...Yep. So do nothing. + }% + \expandafter\pgf@set@fillpattern\expandafter{\pgf@pattern@nametemp}{#2}% + \expandafter\gdef\csname\pgf@pattern@nametemp\endcsname{#1}% + }% + {% + % A non-mutable pattern. + \pgf@set@fillpattern{#1}{#2}% + }% + }% } \def\pgf@set@fillpattern#1#2{% \pgfutil@ifundefined{pgf@pattern@name@#1}{% - \PackageError{pgfcorepatterns}{Undefined pattern `#1'}{}} + \pgferror{Undefined pattern `#1'}} {% \csname pgf@pattern@instantiate@#1\endcsname% \expandafter\global\expandafter\let\csname pgf@pattern@instantiate@#1\endcsname=\relax% @@ -273,24 +274,24 @@ } \def\pgf@pattern@check@vars#1,{% - \ifx#1\pgf@stop% - \let\pgf@next\relax% - \else% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\let\expandafter\pgf@pattern@char#1#1\pgfmath@% - \ifx\pgf@pattern@char/% - \edef\pgf@pattern@tempvar{(\pgfkeysvalueof{#1})}% - \else% - \expandafter\ifcat\pgf@pattern@char\relax% - \edef\pgf@pattern@tempvar{(\the#1)}% - \else% - \edef\pgf@pattern@tempvar{(#1)}% - \fi% - \fi% - \edef\pgf@pattern@tempvars{\pgf@pattern@tempvars\pgf@pattern@tempvar}% - \let\pgf@next\pgf@pattern@check@vars% - \fi% - \pgf@next% + \ifx#1\pgf@stop% + \let\pgf@next\relax% + \else% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\let\expandafter\pgf@pattern@char#1#1\pgfmath@% + \ifx\pgf@pattern@char/% + \edef\pgf@pattern@tempvar{(\pgfkeysvalueof{#1})}% + \else% + \expandafter\ifcat\pgf@pattern@char\relax% + \edef\pgf@pattern@tempvar{(\the#1)}% + \else% + \edef\pgf@pattern@tempvar{(#1)}% + \fi% + \fi% + \edef\pgf@pattern@tempvars{\pgf@pattern@tempvars\pgf@pattern@tempvar}% + \let\pgf@next\pgf@pattern@check@vars% + \fi% + \pgf@next% } \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex index 79cb3a06f77..b546d5df40f 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorepoints.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepoints.code.tex,v 1.20 2010/04/09 08:53:45 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorepoints.code.tex,v 1.27 2013/10/07 15:51:46 tantau Exp $ \newdimen\pgf@picminx \newdimen\pgf@picmaxx @@ -99,10 +99,6 @@ % point yourself. In the below example, this command is used for a low level % coordinate system shift. % -% In addition to applying the transformation matrix to the given -% point, this function also applies the pre- and post-morphing -% macros. -% % Example: % % \begin{pgflowleveltransformshiftscope}{\pgfpointtransformed{\pgfpointorigin}} @@ -112,9 +108,7 @@ \def\pgfpointtransformed#1{% \pgf@process{% #1% - \pgfmorph@prelist% \pgf@pos@transform{\pgf@x}{\pgf@y}% - \pgfmorph@postlist% }% } @@ -201,7 +195,7 @@ % \pgfpointintersectionoflines{\pgfpointxy{0}{1}}{\pgfpointxy{1}{0}}{\pgfpointxy{2}{2}}{\pgfpointxy{3}{4}} \def\pgfpointintersectionoflines#1#2#3#4{% - { + {% % % Compute orthogonal vector to #1--#2 % @@ -439,6 +433,9 @@ % % x = x-component of #1*start + (1-#1)*end % y = y-component of #1*start + (1-#1)*end +% xa/ya = #1*start + (1-#1)*end +% xb/yb = start point +% xc/yc = end point % % Example: % @@ -447,14 +444,19 @@ \def\pgfpointlineattime#1#2#3{% \pgf@process{#3}% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xc\pgf@x% + \pgf@yc\pgf@y% \pgf@process{#2}% - \advance\pgf@xa by-\pgf@x\relax% - \advance\pgf@ya by-\pgf@y\relax% - \advance\pgf@x by #1\pgf@xa\relax% - \advance\pgf@y by #1\pgf@ya\relax% - \ignorespaces} + \pgf@xb\pgf@x% + \pgf@yb\pgf@y% + \pgfmathsetmacro\pgf@temp{#1}% + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \advance\pgf@x by\pgf@temp\pgf@xa% + \advance\pgf@y by\pgf@temp\pgf@ya% +} % Move point #2 #1 many units in the direction of #3. @@ -462,27 +464,35 @@ % #1 = a distance % #2 = start point % #3 = end point +% +% Description: +% +% Computes % -% x = x-component of start + #1*(normalise(end-start)) -% y = y-component of start + #1*(normalise(end-start)) -% xa = #1*(normalise(end-start)) -% ya = #1*(normalise(end-start)) +% x/y = start + #1*(normalise(end-start)) % -% Example: +% and additionally % +% xa/ya = #1*(normalise(end-start)) +% xb/yb = start +% xc/yc = end +% +% Example: % % \pgfpathmoveto{\pgfpointlineatdistance{2pt}{\pgfpointxy{0}{1}}{\pgfpointxy{2}{3}}} % \pgfpathlineto{\pgfpointlineatdistance{3pt}{\pgfpointxy{2}{3}}{\pgfpointxy{0}{1}}} \def\pgfpointlineatdistance#1#2#3{% + \pgfmathsetlength\pgf@xa{#1}% \pgf@process{#2}% - \pgf@xb=\pgf@x\relax% xb/yb = start point - \pgf@yb=\pgf@y\relax% + \pgf@xb\pgf@x% xb/yb = start point + \pgf@yb\pgf@y% \pgf@process{#3}% + \pgf@xc\pgf@x% + \pgf@yc\pgf@y% \advance\pgf@x by-\pgf@xb\relax% \advance\pgf@y by-\pgf@yb\relax% \pgf@process{\pgfpointnormalised{}}% x/y = normalised vector - \pgfmathsetlength\pgf@xa{#1}% \pgf@ya=\pgf@xa\relax% \pgf@xa=\pgf@sys@tonumber{\pgf@x}\pgf@xa% \pgf@ya=\pgf@sys@tonumber{\pgf@y}\pgf@ya% @@ -490,7 +500,7 @@ \pgf@y=\pgf@yb\relax% \advance\pgf@x by\pgf@xa\relax% \advance\pgf@y by\pgf@ya\relax% - \ignorespaces} +} % Returns point on a curve from #2 to #5 with controls #3 and #4 at time #1. @@ -506,7 +516,9 @@ % % Additionally, (\pgf@xa,\pgf@ya) and (\pgf@xb,\pgf@yb) will be on a % tangent to the point on the curve (this can be useful for computing -% a label rotation). +% a label rotation). (\pgf@xc,\pgf@yc) will be equal to the end +% point. \pgf@time@s will equal the value of #1 and \pgf@time@t will +% equal 1-#1. % % Example: % @@ -552,6 +564,58 @@ +% Returns point on an arc at a certain "time" +% +% #1 = a time +% #2 = center of a ellipse +% #3 = 0-degree exis of the ellipse +% #4 = 90-degree exis of the ellipse +% #5 = start angle of an arc on the ellipse +% #6 = end angle of an arc on the ellipse +% +% Result: +% +% \pgf@x = x-component of place on the arc at time t +% \pgf@y = y-component of place on the arc at time t +% +% Additionally, (\pgf@xa,\pgf@ya) will be a tangent to the +% point on the arc (this can be useful for computing a label rotation). +% +% Example: +% +% \pgfpointarcaxesattime{0.25}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1cm}}{1cm}{30}{40} + +\def\pgfpointarcaxesattime#1#2#3#4#5#6{% + \pgfmathsetmacro\pgf@angle@start{#5}% + \pgfmathsetmacro\pgf@angle@end{#6}% + \pgfmathparse{#1}% + \pgf@x=\pgfmathresult pt% + \pgf@x=-\pgf@x% + \advance\pgf@x by 1pt% + \pgfmathsetmacro\pgf@angle@mid{\pgf@angle@end*\pgfmathresult+\pgf@angle@start*\pgf@sys@tonumber{\pgf@x}}% + \pgfmathcos@{\pgf@angle@mid}% + \let\pgf@angle@cos\pgfmathresult% + \pgfmathsin@{\pgf@angle@mid}% + \let\pgf@angle@sin\pgfmathresult% + \pgf@process{#3}% + \edef\pgf@angle@zero@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + \pgf@process{#4}% + \edef\pgf@angle@ninety@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + % Compute tangent + \pgf@process{\pgfpointadd{\pgfpointscale{\pgf@angle@sin}{\pgf@angle@zero@axis}}% + {\pgfpointscale{-\pgf@angle@cos}{\pgf@angle@ninety@axis}}}% + \ifdim\pgf@angle@start pt>\pgf@angle@end pt% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \else% + \pgf@xa=-\pgf@x% + \pgf@ya=-\pgf@y% + \fi% + % Compute position + \pgf@process{\pgfpointadd{#2}{% + \pgfpointadd{\pgfpointscale{\pgf@angle@cos}{\pgf@angle@zero@axis}}% + {\pgfpointscale{\pgf@angle@sin}{\pgf@angle@ninety@axis}}}}% +} @@ -1202,4 +1266,13 @@ \pgf@def{cosfrac}{97}{0.717792} \pgf@def{cosfrac}{98}{0.714213} \pgf@def{cosfrac}{99}{0.710651} \pgf@def{cosfrac}{100}{0.707107} + + + +% Forward declarations for nonlinear stuff (have no effect till module +% nonlineartransformations is loaded) + +\let\pgfpointtransformednonlinear\pgfpointtransformed + + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex index 558f715788c..406d52e3a22 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcorescopes.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorescopes.code.tex,v 1.34 2010/09/08 15:07:18 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcorescopes.code.tex,v 1.44 2013/10/09 18:30:27 tantau Exp $ % Globals @@ -50,10 +50,14 @@ \pgfsys@beginscope% \pgf@resetpathsizes% \edef\pgfscope@linewidth{\the\pgflinewidth}% + \expandafter\let\expandafter\pgfscope@stroke@color\csname\string\color@pgfstrokecolor\endcsname% + \expandafter\let\expandafter\pgfscope@fill@color\csname\string\color@pgffillcolor\endcsname% \begingroup} \def\endpgfscope{% \endgroup% \global\pgflinewidth=\pgfscope@linewidth% + \expandafter\global\expandafter\let\csname\string\color@pgfstrokecolor\endcsname\pgfscope@stroke@color% + \expandafter\global\expandafter\let\csname\string\color@pgffillcolor\endcsname\pgfscope@fill@color% \pgfsys@endscope} @@ -116,6 +120,8 @@ \expandafter\pgf@text@setkeys\expandafter{\pgf@text@options}% \csname pgf@halign\pgf@text@hshift\endcsname% \csname pgf@valign\pgf@text@vshift\endcsname% + % + \pgfapproximatenonlineartransformation% % Protocol sizes: \pgf@process{\pgfpointtransformed{\pgfqpoint{0pt}{\dp\pgf@hbox}}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% @@ -190,8 +196,6 @@ % \pgfusepath{stroke} % \end{pgfpicture} -\newif\ifpgfpicture - \def\pgfresetboundingbox{% \global\pgf@picmaxx=-16000pt\relax% \global\pgf@picminx=16000pt\relax% @@ -257,23 +261,26 @@ \pgf@relevantforpicturesizefalse% \pgf@process{\pgf@baseline}% \xdef\pgf@shift@baseline{\the\pgf@y}% - % + % \pgf@process{\pgf@trimleft}% \global\advance\pgf@x by-\pgf@picminx - % prepare \hskip\pgf@trimleft@final. + % prepare \hskip\pgf@trimleft@final. % note that \pgf@trimleft@final is also queried % by the pgf image externalization. \xdef\pgf@trimleft@final{-\the\pgf@x}% - % + % \pgf@process{\pgf@trimright}% \global\advance\pgf@x by-\pgf@picmaxx - % prepare \hskip\pgf@trimright@final. + % prepare \hskip\pgf@trimright@final. % note that \pgf@trimright@final is also queried % by the pgf image externalization. \xdef\pgf@trimright@final{\the\pgf@x}% + % + \pgf@remember@layerlist@globally \endgroup% \hss% \egroup% + \pgf@restore@layerlist@from@global \pgf@insertlayers% \endgroup% \pgfsys@discardpath% @@ -287,6 +294,12 @@ \endgroup% } +\def\pgf@remember@layerlist@globally{% + \global\let\pgf@layerlist@=\pgf@layerlist +}% +\def\pgf@restore@layerlist@from@global{% + \let\pgf@layerlist=\pgf@layerlist@ +}% \def\pgf@insertlayers{% \box\pgf@layerbox@main% } @@ -356,20 +369,20 @@ % \pgfsetbaseline{default}% resets to default value \def\pgfsetbaseline#1{% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgf@default@text - \pgfsetbaseline{\pgf@picminy}% - \else - \pgfsetbaselinepointlater{\pgfpoint{0pt}{#1}}% - \fi + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@default@text + \pgfsetbaseline{\pgf@picminy}% + \else + \pgfsetbaselinepointlater{\pgfpoint{0pt}{#1}}% + \fi } \pgfsetbaseline{\pgf@picminy} % controls how the image externalization implements trim: \newif\ifpgf@trim@lowlevel \pgfkeys{ - /pgf/trim lowlevel/.is if=pgf@trim@lowlevel, - /pgf/trim lowlevel/.default=true, + /pgf/trim lowlevel/.is if=pgf@trim@lowlevel, + /pgf/trim lowlevel/.default=true, } % Same as the y-baseline for horizontal alignment. @@ -385,12 +398,12 @@ % or % \pgfsettrimleft{default} \def\pgfsettrimleft#1{% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgf@default@text - \pgfsettrimleft{\pgf@picminx} - \else - \pgfsettrimleftpointlater{\pgfpoint{#1}{0pt}}% - \fi + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@default@text + \pgfsettrimleft{\pgf@picminx} + \else + \pgfsettrimleftpointlater{\pgfpoint{#1}{0pt}}% + \fi } \pgfsettrimleft{\pgf@picminx} @@ -404,12 +417,12 @@ % or % \pgfsettrimright{default} \def\pgfsettrimright#1{% - \def\pgf@temp{#1}% - \ifx\pgf@temp\pgf@default@text - \pgfsettrimright{\pgf@picmaxx}% - \else - \pgfsettrimrightpointlater{\pgfpoint{#1}{0pt}}% - \fi + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@default@text + \pgfsettrimright{\pgf@picmaxx}% + \else + \pgfsettrimrightpointlater{\pgfpoint{#1}{0pt}}% + \fi } \pgfsettrimright{\pgf@picmaxx} @@ -445,6 +458,7 @@ \pgfsyssoftpath@setcurrentpath\pgfutil@empty% \edef\pgfscope@linewidth{\the\pgflinewidth}% \let\pgf@interrupt@lastmoveto=\pgfsyssoftpath@lastmoveto% + \let\pgf@interrupt@nlt@infos=\pgf@nlt@infos% \begingroup% } \def\endpgfinterruptpath @@ -453,9 +467,10 @@ \global\pgflinewidth=\pgfscope@linewidth% \pgfsyssoftpath@setcurrentpath\pgf@interrupt@path% \pgf@setpathsizes\pgf@interrupt@pathsizes% - \global\pgf@path@lastx=\pgf@interrupt@savex% - \global\pgf@path@lasty=\pgf@interrupt@savey% - \global\let\pgfsyssoftpath@lastmoveto=\pgf@interrupt@lastmoveto% + \global\pgf@path@lastx\pgf@interrupt@savex% + \global\pgf@path@lasty\pgf@interrupt@savey% + \global\let\pgfsyssoftpath@lastmoveto\pgf@interrupt@lastmoveto% + \global\let\pgf@nlt@infos=\pgf@interrupt@nlt@infos% \endgroup% } @@ -570,5 +585,4 @@ \let\pgf@savelayers=\relax \let\pgf@restorelayers=\relax - \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex index d4b0e8bee74..86bd57c32fe 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoreshade.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreshade.code.tex,v 1.13 2008/11/23 16:07:47 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoreshade.code.tex,v 1.15 2013/07/15 14:24:02 tantau Exp $ % % Parsing functions @@ -133,8 +133,8 @@ \pgfutil@ifnextchar g{\pgf@grabgray}% {% \pgfutil@ifnextchar c{\pgf@grabcolor}% - {\PackageError{pgfshade}{Illformed shading - specification}{}\pgf@converttorgb}% + {\pgferror{Illformed shading + specification}\pgf@converttorgb}% }% }% }% @@ -424,7 +424,7 @@ \edef\pgf@shadingname{@pgfshading#1}% \pgf@tryextensions{\pgf@shadingname}{\pgfalternateextension}% \expandafter\pgfutil@ifundefined\expandafter{\pgf@shadingname}% - {\PackageError{pgfshade}{Undefined shading "#1"}{}}% + {\pgferror{Undefined shading "#1"}}% {% {% \pgfutil@globalcolorsfalse% @@ -531,22 +531,25 @@ \def\pgfshadepath#1#2{% \ifdim\pgf@pathminx=16000pt% - \PackageWarning{pgfshade}{No path specified that can be filled}% + \pgfwarning{No path specified that can be filled}% \else% \begingroup% + % Calculate center: + \pgf@xb=.5\pgf@pathmaxx% + \advance\pgf@xb by.5\pgf@pathminx% + \pgf@yb=.5\pgf@pathmaxy% + \advance\pgf@yb by.5\pgf@pathminy% + % Calculate scaling: + \pgf@xc=\pgf@pathmaxx% + \advance\pgf@xc by-\pgf@pathminx% + \pgf@yc=\pgf@pathmaxy% + \advance\pgf@yc by-\pgf@pathminy% + \pgf@xc=.01992528\pgf@xc% + \pgf@yc=.01992528\pgf@yc% + \ifdim\pgf@xc<0.0001pt\relax\ifdim\pgf@xc>-0.0001pt\relax\pgf@no@shadetrue\fi\fi% + \ifdim\pgf@yc<0.0001pt\relax\ifdim\pgf@yc>-0.0001pt\relax\pgf@no@shadetrue\fi\fi% + \ifpgf@no@shade\else% \pgfsys@beginscope% - % Calculate center: - \pgf@xb=.5\pgf@pathmaxx% - \advance\pgf@xb by.5\pgf@pathminx% - \pgf@yb=.5\pgf@pathmaxy% - \advance\pgf@yb by.5\pgf@pathminy% - % Calculate scaling: - \pgf@xc=\pgf@pathmaxx% - \advance\pgf@xc by-\pgf@pathminx% - \pgf@yc=\pgf@pathmaxy% - \advance\pgf@yc by-\pgf@pathminy% - \pgf@xc=.01992528\pgf@xc% - \pgf@yc=.01992528\pgf@yc% \pgfsyssoftpath@invokecurrentpath% \pgfsys@clipnext% \pgfsys@discardpath% @@ -570,10 +573,12 @@ \fi% \pgfuseshading{#1}% \pgfsys@endscope% + \fi% \endgroup% \fi% } +\newif\ifpgf@no@shade % Additionally transform shade paths % diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex index 442531ffa6f..83f89b1fa2d 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransformations.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransformations.code.tex,v 1.11 2009/06/10 09:22:57 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransformations.code.tex,v 1.17 2013/10/10 08:53:09 tantau Exp $ % Position transformations @@ -57,15 +57,15 @@ % % \pgfsettransformentries\aa\ab\ba\bb\shiftx\shifty \def\pgfgettransformentries#1#2#3#4#5#6{% - \edef#1{\pgf@pt@aa}% - \edef#2{\pgf@pt@ab}% - \edef#3{\pgf@pt@ba}% - \edef#4{\pgf@pt@bb}% - \edef#5{\the\pgf@pt@x}% - \edef#6{\the\pgf@pt@y}% + \edef#1{\pgf@pt@aa}% + \edef#2{\pgf@pt@ab}% + \edef#3{\pgf@pt@ba}% + \edef#4{\pgf@pt@bb}% + \edef#5{\the\pgf@pt@x}% + \edef#6{\the\pgf@pt@y}% }% \def\pgfsettransformentries#1#2#3#4#5#6{% - \pgfsettransform{{#1}{#2}{#3}{#4}{#5}{#6}}% + \pgfsettransform{{#1}{#2}{#3}{#4}{#5}{#6}}% }% % Restore the current transformation matrix from a macro. @@ -273,41 +273,6 @@ } -% Add a pre-morph -% -% #1 = morphing code -% -% Description: -% -% This function adds code to the pre-morphing list. When a -% coordinate is transformed, the current pre-morphing code is -% called first. Then the transformation matrix is applied. Finally, all -% post-morphing code is called. The morphing list is local to the -% current TeX group. -% -% The job of the #1 macro is to modify the values of \pgf@x and -% \pgf@y. It should not have any other sideeffects. -% -% Example: -% -% \pgfmorphaddmorph{\advance\pgf@x by 1cm\relax} - -\def\pgfmorphaddpre#1{\expandafter\def\expandafter\pgfmorph@prelist\expandafter{\pgfmorph@prelist#1}} -\let\pgfmorph@prelist=\pgfutil@empty - - -% Add a post-morph -% -% #1 = morphing macro -% -% Description: -% -% The only difference to the pre-morphs is that post morphs are -% executed after the transformation matrix has been applied. - -\def\pgfmorphaddpost#1{\expandafter\def\expandafter\pgfmorph@postlist\expandafter{\pgfmorph@postlist#1}} -\let\pgfmorph@postlist=\pgfutil@empty - % Transformation into a given triangle. The three corners of the % triangle are called "origin", "x" and "y" are given. After this @@ -385,9 +350,9 @@ % % \pgftansformshift{\pgfpoint{1cm}{1cm}} -\def\pgftransformshift#1{\pgftransformcm{1.0}{0}{0}{1.0}{#1}} -\def\pgftransformxshift#1{\pgftransformcm{1.0}{0}{0}{1.0}{\pgfpoint{#1}{0pt}}} -\def\pgftransformyshift#1{\pgftransformcm{1.0}{0}{0}{1.0}{\pgfpoint{0pt}{#1}}} +\def\pgftransformshift#1{\pgftransformcm{1}{0}{0}{1}{#1}} +\def\pgftransformxshift#1{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{#1}{+0pt}}} +\def\pgftransformyshift#1{\pgftransformcm{1}{0}{0}{1}{\pgfpoint{+0pt}{#1}}} @@ -487,25 +452,71 @@ % } % \def\pgftransformlineattime#1#2#3{% - \pgftransformshift{\pgfpointlineattime{#1}{#2}{#3}}% + \pgf@process{#2}% + \pgf@xb=\pgf@x% xb/yb = start point + \pgf@yb=\pgf@y% + \pgf@process{#3}% + \pgf@xc=\pgf@x% xc/yc = end point + \pgf@yc=\pgf@y% + \pgftransformshift{\pgfpointlineattime{#1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% + \ifpgfresetnontranslationattime% + \pgftransformresetnontranslations% + \fi% + \ifpgfslopedattime% + \advance\pgf@xc by-\pgf@xb% + \advance\pgf@yc by-\pgf@yb% + \ifpgfallowupsidedownattime% + \else% + \ifdim\pgf@xc<0pt% + \pgf@xc=-\pgf@xc% + \pgf@yc=-\pgf@yc% + \fi% + \fi% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \pgfpointnormalised{}% x/y = normalised vector + \pgf@ya=-\pgf@y% + \pgftransformcm% + {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}% + {\pgf@sys@tonumber{\pgf@ya}}{\pgf@sys@tonumber{\pgf@x}}{\pgfpointorigin}% + \fi% +} + + +% Transform to the coordinate system of a point on an arc +% +% #1 = a time fraction of line where to put the label, where 0 means start, +% 1 means end, and for example 0.5 means the middle. +% #2 = center of an ellipse +% #3 = 0-degree axis of the ellipse +% #4 = 90-degree axis of the ellipse +% #4 = start angle of the arc on this ellipse +% #5 = end angle of the arc on this ellipse +% +% Example: +% +% { +% \pgftransformlineattime{.5}{\pgfpoint{1cm}{1cm}}{\pgfpoint{1cm}{0cm}}{\pgfpoint{0cm}{1cm}}{30}{40} +% \pgftext{Hi!} +% } + +\def\pgftransformarcaxesattime#1#2#3#4#5#6{% + \pgfpointarcaxesattime{#1}{#2}{#3}{#4}{#5}{#6}% + \pgftransformshift{\pgfqpoint{\pgf@x}{\pgf@y}}% \ifpgfresetnontranslationattime% \pgftransformresetnontranslations% \fi% \ifpgfslopedattime% - \pgf@process{#2}% - \pgf@xa=\pgf@x% xb/yb = start point - \pgf@ya=\pgf@y% - \pgf@process{#3}% - \advance\pgf@x by-\pgf@xa% - \advance\pgf@y by-\pgf@ya% + \pgf@x=\pgf@xa% + \pgf@y=\pgf@ya% + \pgf@process{\pgfpointnormalised{}}% \ifpgfallowupsidedownattime% \else% - \ifdim\pgf@x<0pt% + \ifdim\pgf@x<0pt% \pgf@x=-\pgf@x% \pgf@y=-\pgf@y% \fi% \fi% - \pgfpointnormalised{}% x/y = normalised vector \pgf@ya=-\pgf@y% \pgftransformcm% {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}% @@ -579,8 +590,8 @@ % \pgftransformarrow{\pgfpointorigin}{\pgfpoint{1cm}{0cm}} \def\pgftransformarrow#1#2{% - \pgftransformshift{#2}% \pgf@process{#2}% + \pgftransformshift{}% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgf@process{#1}% @@ -658,5 +669,13 @@ +% Forward declarations for nonlinear stuff (have no effect till module +% nonlineartransformations is loaded) + +\let\pgfapproximatenonlineartranslation\relax +\let\pgfapproximatenonlineartransformation\relax +\def\pgftransformnonlinear#1{\pgferror{You need to say + \string\usepgfmodule{nonlineartransformation} to use nonlinear transformations}} + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex index 3048e6077fe..47484997af7 100644 --- a/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/basiclayer/pgfcoretransparency.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransparency.code.tex,v 1.2 2008/01/17 20:09:16 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/basiclayer/pgfcoretransparency.code.tex,v 1.5 2013/09/30 18:30:15 tantau Exp $ % Sets the opacity of stroking operations. @@ -39,6 +39,37 @@ +% Sets the current blend mode. See Section 7.2.4 of the PDF +% Specification 1.7 for an introduction to blend modes in general. +% +% #1 = One of the following modes, see also section 7.2.4 of the +% PDF Specification 1.7. (The PGF names, which are all lowercase with +% spaces as usual, must be mapped to the PDF or SVG by the drivers.) +% +% normal +% multiply +% screen +% overlay +% darken +% lighten +% color dodge +% color burn +% hard light +% soft light +% difference +% exclusion +% saturation +% color +% hue +% luminosity +% +% Example: +% +% \pgfsetblendmode{multiply} + +\def\pgfsetblendmode#1{\pgfsys@blend@mode{#1}} + + % Declares a new fading based on the contents of a box. % % #1 = name of the fading @@ -156,8 +187,10 @@ % Calculate scaling: \pgf@xc=\pgf@pathmaxx% \advance\pgf@xc by-\pgf@pathminx% + \ifdim\pgf@xc<0.1pt\pgf@xc=0.1pt\fi% \pgf@yc=\pgf@pathmaxy% \advance\pgf@yc by-\pgf@pathminy% + \ifdim\pgf@yc<0.1pt\pgf@yc=0.1pt\fi% \pgf@xc=.02\pgf@xc% \pgf@yc=.02\pgf@yc% % Compute new transformation matrix: @@ -171,6 +204,49 @@ +% Use a previously declared fading scaled for the current path. +% +% #1 - an fading +% #2 - extra transformations +% +% Description: +% +% This command works like \pgfsetfadingforcurrentpath, only it takes +% the current line width into account: Before the path is considered, +% it is enlarged by half the line width in all directions. + +\def\pgfsetfadingforcurrentpathstroked#1#2{% + \ifdim\pgf@pathminx=16000pt% + % Path was empty -> use natural size + \pgfsetfading{#1}{#2}% + \else% + \pgfsetfading{#1}{% + % Calculate center: + \pgf@xb=.5\pgf@pathmaxx% + \advance\pgf@xb by.5\pgf@pathminx% + \pgf@yb=.5\pgf@pathmaxy% + \advance\pgf@yb by.5\pgf@pathminy% + % Calculate scaling: + \pgf@xc=\pgf@pathmaxx% + \advance\pgf@xc by-\pgf@pathminx% + \advance\pgf@xc by\pgflinewidth% + \ifdim\pgf@xc<0.1pt\pgf@xc=0.1pt\fi% + \pgf@yc=\pgf@pathmaxy% + \advance\pgf@yc by-\pgf@pathminy% + \advance\pgf@yc by\pgflinewidth% + \ifdim\pgf@yc<0.1pt\pgf@yc=0.1pt\fi% + \pgf@xc=.02\pgf@xc% + \pgf@yc=.02\pgf@yc% + % Compute new transformation matrix: + \pgftransformcm{1}{0}{0}{1}{\pgfqpoint{\pgf@xb}{\pgf@yb}}% + \pgftransformcm{\pgf@sys@tonumber{\pgf@xc}}{0}{0}{\pgf@sys@tonumber{\pgf@yc}}{\pgfpointorigin}% + #2% + }% + \fi% +} + + + % Group things in a a transparency group % % Description: @@ -186,9 +262,22 @@ % \def\pgftransparencygroup{% + \pgfutil@ifnextchar[{\pgftransparencygroup@}{\pgftransparencygroup@[]}% +} +\def\pgftransparencygroup@[#1]{% \begingroup% + \pgfkeys{/pgf/transparency group options/.cd,% + isolated=false, + knockout=false, + #1}% \setbox\pgfutil@tempboxa=\hbox\bgroup% } +\pgfkeys{ + /pgf/transparency group options/.cd, + isolated/.is if=pgfsys@transparency@group@isolated, + knockout/.is if=pgfsys@transparency@group@knockout +} + \def\endpgftransparencygroup{% \egroup% % Now compute the correct position. This is a bit tricky... diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg deleted file mode 100644 index f1e0f36ce16..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.cfg +++ /dev/null @@ -1,2 +0,0 @@ -\SYSTEM {http://www.tcs.uni-luebeck.de/dtds/svgpgf.dtd} {svgpgf.xmt} -\NAME{svgpgf} {svgpgf.xmt} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt deleted file mode 100644 index 7a3e688e6ee..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgpgf.xmt +++ /dev/null @@ -1,48 +0,0 @@ -\DeclareNamespace{svg}{http://www.w3.org/2000/svg} - -\XMLelement{svg:svg}{ -} -{\begin{pgfpicture} - \pgfsetyvec{\pgfpoint{0cm}{-1cm}}} -{\end{pgfpicture}} - -\XMLelement{svg:rect}{ - \XMLattribute{width}{\svgwidth}{0} - \XMLattribute{height}{\svgheight}{0} - \XMLattribute{x}{\svgx}{0} - \XMLattribute{y}{\svgy}{0} - \XMLattribute{fill}{\svgfill}{x000} -} -{ - \expandafter\svgparsefill\svgfill - \pgfsetfillcolor{mycol} - \pgfpathrectangle{\pgfpointxy{\svgx}{\svgy}}{\pgfpointxy{\svgwidth}{\svgheight}} - \pgfusepath{fill}} -{} - -\gdef\svgparsefill#1#2#3#4{% - \pgfmathparse{\csname tonum#2\endcsname/16} - \let\myred=\pgfmathresult - \pgfmathparse{\csname tonum#3\endcsname/16} - \let\mygreen=\pgfmathresult - \pgfmathparse{\csname tonum#4\endcsname/16} - \let\myblue=\pgfmathresult - \definecolor{mycol}{rgb}{\myred,\mygreen,\myblue} -} - -\expandafter\gdef\csname tonum0\endcsname{0} -\expandafter\gdef\csname tonum1\endcsname{1} -\expandafter\gdef\csname tonum2\endcsname{2} -\expandafter\gdef\csname tonum3\endcsname{3} -\expandafter\gdef\csname tonum4\endcsname{4} -\expandafter\gdef\csname tonum5\endcsname{5} -\expandafter\gdef\csname tonum6\endcsname{6} -\expandafter\gdef\csname tonum7\endcsname{7} -\expandafter\gdef\csname tonum8\endcsname{8} -\expandafter\gdef\csname tonum9\endcsname{9} -\expandafter\gdef\csname tonuma\endcsname{10} -\expandafter\gdef\csname tonumb\endcsname{11} -\expandafter\gdef\csname tonumc\endcsname{12} -\expandafter\gdef\csname tonumd\endcsname{13} -\expandafter\gdef\csname tonume\endcsname{14} -\expandafter\gdef\csname tonumf\endcsname{15} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg deleted file mode 100644 index f658cf84240..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.cfg +++ /dev/null @@ -1,3 +0,0 @@ -%\PUBLIC {-//W3C//DTD SVG 1.1//EN} {svgpgf.xmt} -%\NAME{svg} {svgpgf.xmt} - diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex deleted file mode 100644 index 4e919ca1371..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.tex +++ /dev/null @@ -1,15 +0,0 @@ -\documentclass{article} - -\usepackage{pgfsvg} - -\begin{document} - -Huhu... - -\xmlinclude{svgtest.xml} -foo... -\xmlinclude{rect01.xml} - -%\xmlinclude{svgtest.xml} - -\end{document} \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml b/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml deleted file mode 100644 index 109ee812629..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/svg/svgtest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex index 693da7c5907..e8aeabd2468 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.code.tex @@ -77,8 +77,8 @@ } } \newcount\tikz@lib@circ@count -\def\tikz@zero@text{0} -\def\tikz@one@text{1} +\def\tikz@zero@text{0.0} +\def\tikz@one@text{1.0} \def\tikz@lib@circ@compute@direction#1{% \tikz@scan@one@point\tikz@lib@circ@save@start(\tikztostart)% @@ -176,6 +176,7 @@ [annotation arrow,->] [label distance=#2,##1] #3 + \tikz@after@path% \egroup% } }, @@ -189,6 +190,7 @@ [annotation arrow,->] [label distance=#2,##1] #3 + \tikz@after@path% \egroup% } } @@ -251,13 +253,15 @@ \def\tikz@lib@circ@lab[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,#1]$\mathrm{#2#3}$}}} \def\tikz@lib@circ@lab@sloped[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,transform shape,#1]$\mathrm{#2#3}$}}} -\def\tikz@lib@circ@labp[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,#1]below:$\mathrm{#2#3}$}}} -\def\tikz@lib@circ@lab@slopedp[#1]#2\pgf@stop#3#4{\tikzset{label={[every info/.try,every #4/.try,transform shape,#1]below:$\mathrm{#2#3}$}}} +\def\tikz@lib@circ@labp[#1]#2\pgf@stop#3#4{\tikzset{label={[label position=below,every info/.try,every #4/.try,#1]$\mathrm{#2#3}$}}} +\def\tikz@lib@circ@lab@slopedp[#1]#2\pgf@stop#3#4{\tikzset{label={[label +position=below,every info/.try,every #4/.try,transform shape,#1]$\mathrm{#2#3}$}}} \def\tikz@lib@circ@lab@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,#1]#2}}} \def\tikz@lib@circ@lab@sloped@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,transform shape,#1]#2}}} -\def\tikz@lib@circ@labp@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,#1]below:#2}}} -\def\tikz@lib@circ@lab@slopedp@plain[#1]#2\pgf@stop{\tikzset{label={[every info/.try,transform shape,#1]below:#2}}} +\def\tikz@lib@circ@labp@plain[#1]#2\pgf@stop{\tikzset{label={[label position=below,every info/.try,#1]#2}}} +\def\tikz@lib@circ@lab@slopedp@plain[#1]#2\pgf@stop{\tikzset{label={[label +position=below,every info/.try,transform shape,#1]#2}}} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex index 91641309ab5..d8337acefcd 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/circuits/tikzlibrarycircuits.ee.code.tex @@ -127,29 +127,15 @@ (.2\tikzcircuitssizeunit,.65\tikzcircuitssizeunit) edge[line to] ++(-45:1.25\tikzcircuitssizeunit) (-.2\tikzcircuitssizeunit,.25\tikzcircuitssizeunit) edge[line to] ++(-45:1.25\tikzcircuitssizeunit) }, - adjustable/.style={ - append after command={% - \bgroup - [current point is local=true] - [every adjustable/.try] - [annotation arrow,->] - let \p1=(\tikzlastnode.north), \p2=(\tikzlastnode.south) in - [label distance=1.5\tikzcircuitssizeunit-.5*abs(\y2-\y1),#1] - (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) - \egroup% - } + circuit declare annotation={adjustable}{1.5\tikzcircuitssizeunit} + { + [shift=(\tikzlastnode.center)] + (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) }, - adjustable'/.style={ - append after command={% - \bgroup - [current point is local=true,yscale=-1] - [every adjustable/.try] - [annotation arrow,->] - let \p1=(\tikzlastnode.north), \p2=(\tikzlastnode.south) in - [label distance=1.5\tikzcircuitssizeunit-.5*abs(\y2-\y1),#1] - (-1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) - \egroup% - } + circuit declare annotation={adjustable'}{1.5\tikzcircuitssizeunit} + { + [shift=(\tikzlastnode.center)] + (-1.5\tikzcircuitssizeunit,1.5\tikzcircuitssizeunit) edge[line to] (1.5\tikzcircuitssizeunit,-1.5\tikzcircuitssizeunit) } } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex index c717e95cf7b..e181c3b97ab 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex,v 1.31 2010/09/15 22:27:36 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.code.tex,v 1.44 2013/07/19 13:16:48 tantau Exp $ \usepgfmodule{datavisualization} \usetikzlibrary{backgrounds} @@ -60,14 +60,29 @@ % /tikz/every data is executed for each data, which can be useful to % generally set, say, a certain data format. % -% "info" blocks. % -% Syntax: info [options] {code} +% "data set" blocks. +% +% Syntax: data set [options] {name} = { ... } +% Syntax: data set [options] {name} += { ... } +% Syntax: data set [options] {name} +% +% The first syntax allows you to define a data set. The data block +% inside {...} will be stored inside the data set +% "name". Subsequently, the data set can be referenced by using the +% third syntax. The second syntax allows you to extend the +% definition of an already defined data set. +% +% +% "info" and "info'" blocks. +% +% Syntax: info [options] {code} +% Syntax: info' [options] {code} +% +% A block starting with "info" or "info'" may contain any code. It +% will be executed after the visualization (info) or before the +% visualization (info'). % -% A block starting with "info" may contain any code. It -% will be executed after the visualization. In order to execute code -% at some other time (like, say, before the visualization), use -% options like "before visualization". % % Options blocks. % @@ -103,7 +118,7 @@ % var x: interval [0:3]; % func y = \value x*\value x; % } -% [before visualization={ +% [at begin visualization={ % \fill [black!10] (visualization cs:x=0,y=0) -- (visualization cs:x=3,y=9); % }] % info[red] @@ -121,6 +136,7 @@ \def\tikz@lib@datavisualization{ \begingroup% + \let\tikz@path@do@at@end=\relax% % Ok, first, start a new data visualization \pgfoonew \tikz@main@dv=new data visualization()% % Next, create a scope for the dv @@ -141,6 +157,7 @@ \tikz@main@dv.before visualization(% )% \tikz@main@dv.after visualization(% + \tikz@lib@dv@alias@dv@bb \pgfkeysvalueof{/tikz/data visualization/grid actions} \pgfkeysvalueof{/tikz/data visualization/subminor grid actions} \pgfkeysvalueof{/tikz/data visualization/minor grid actions} @@ -167,7 +184,7 @@ \pgfutil@ifnextchar i\tikz@lib@dv@handle@info{% \pgfutil@ifnextchar [\tikz@lib@dv@handle@options{% \pgfutil@ifnextchar \egroup\tikz@lib@dv@handle@endscope{% - \PackageError{tikz}{Semicolon expected}{}% + \tikzerror{Semicolon expected}% \endgroup% }% }% @@ -177,11 +194,12 @@ }% }% } -\def\tikz@lib@dv@parse@end{% +\def\tikz@lib@dv@parse@end;{% % Go! \tikz@main@dv.survey()% \tikz@main@dv.visualize()% \endgroup% + \tikz@path@do@at@end% } \def\tikz@lib@dv@handle@par\par{\tikz@lib@dv@parse@loop} @@ -196,27 +214,74 @@ } \def\tikz@lib@dv@beg@opt[#1]{% \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})}% \pgfutil@ifnextchar\bgroup{ \afterassignment\tikz@lib@dv@parse@loop% \let\tikz@dummy=%get rid of \bgroup }{% - \PackageError{pgf}{Opening brace expected}{}% + \tikzerror{Opening brace expected}% + \tikz@lib@dv@parse@loop% }% } \def\tikz@lib@dv@handle@endscope{% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\endgroup)% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\endgroup)}% \endgroup% \afterassignment\tikz@lib@dv@parse@loop% \let\tikz@dummy=%get rid of \egroup } -\def\tikz@lib@dv@handle@data data{\pgfdata} +\def\tikz@lib@dv@handle@data data{% + \pgfutil@ifnextchar g{\tikz@lib@dv@handle@data@group}{% + \pgfutil@ifnextchar p{\tikz@lib@dv@handle@data@point}{% + \pgfdata}}} + +\def\tikz@lib@dv@handle@data@group group{\pgfutil@ifnextchar[{\tikz@lib@dv@handle@data@group@opt}{\tikz@lib@dv@handle@data@group@opt[]}}%} + +\def\tikz@lib@dv@handle@data@group@opt[#1]#2{% + \pgfutil@ifnextchar={\tikz@lib@dv@handle@data@group@def{#1}{#2}}{% + \pgfutil@ifnextchar+{\tikz@lib@dv@handle@data@group@extend{#1}{#2}}{% + \tikz@lib@dv@handle@data@group@use{#1}{#2}}}} + +\def\tikz@lib@dv@handle@data@group@def#1#2={% + \pgfkeys{/pgf/data/new group=#2}% + \tikz@lib@dv@handle@data@group@extend{#1}{#2}+=% +} + +\def\tikz@lib@dv@handle@data@group@extend#1#2+={% + \pgfutil@ifnextchar\bgroup{ + \begingroup% + \pgfkeys{/pgf/data/store in group=#2}% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\begingroup\pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}}})}% + \afterassignment\tikz@lib@dv@parse@loop% + \let\tikz@dummy=%get rid of \bgroup + }{% + \tikzerror{Opening brace expected}% + \tikz@lib@dv@parse@loop% + }% +} + +\def\tikz@lib@dv@handle@data@group@use#1#2{% + \pgfdata[#1,use group=#2]% +} + +\def\tikz@lib@dv@handle@data@point point{\pgfutil@ifnextchar[{\tikz@lib@dv@handle@data@point@opt}{\tikz@lib@dv@handle@data@point@opt[]}}%] +\def\tikz@lib@dv@handle@data@point@opt[#1]{% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\bgroup\pgfkeys{/data point/.cd,#1}\pgfdatapoint\egroup}})}% + \tikz@lib@dv@parse@loop% +} -\def\tikz@lib@dv@handle@info info{ +\def\tikz@lib@dv@handle@info info{% + \pgfutil@ifnextchar'{\tikz@lib@dv@handle@info@prime}{\tikz@lib@dv@handle@info@noprime}} +\def\tikz@lib@dv@handle@info@noprime{% \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt}{\tikz@lib@dv@handle@info@block@opt[]}}%} \def\tikz@lib@dv@handle@info@block@opt[#1]#2{% - \tikz@main@dv.after visualization({{\scope[#1]#2\endscope}})% + \tikz@main@dv.after visualization({\scope[#1]#2\endscope})% + \tikz@lib@dv@parse@loop +} +\def\tikz@lib@dv@handle@info@prime'{% + \pgfutil@ifnextchar[{\tikz@lib@dv@handle@info@block@opt@prime}{\tikz@lib@dv@handle@info@block@opt@prime[]}}%} +\def\tikz@lib@dv@handle@info@block@opt@prime[#1]#2{% + \tikz@main@dv.before visualization({\scope[#1]#2\endscope})% \tikz@lib@dv@parse@loop } @@ -229,17 +294,31 @@ % \tikzdatavisualizationset{ - before survey/.code=\tikz@main@dv.before survey({{#1}}), - after survey/.code=\tikz@main@dv.after survey({{#1}}), - before visualization/.code=\tikz@main@dv.before visualization({{#1}}), - after visualization/.code=\tikz@main@dv.after visualization({{#1}}), - at start survey/.code=\tikz@main@dv.at start survey({{#1}}), - at end survey/.code=\tikz@main@dv.at end survey({{#1}}), - at start visualization/.code=\tikz@main@dv.at start visualization({{#1}}), - at end visualization/.code=\tikz@main@dv.at end visualization({{#1}}), + before survey/.code=\tikz@main@dv.before survey({#1}), + after survey/.code=\tikz@main@dv.after survey({#1}), + before visualization/.code=\tikz@main@dv.before visualization({#1}), + after visualization/.code=\tikz@main@dv.after visualization({#1}), + at start survey/.code=\tikz@main@dv.at start survey({#1}), + at end survey/.code=\tikz@main@dv.at end survey({#1}), + at start visualization/.code=\tikz@main@dv.at start visualization({#1}), + at end visualization/.code=\tikz@main@dv.at end visualization({#1}), } +\def\tikz@lib@dv@alias@dv@bb{ + \pgfnodealias{data bounding box}{data visualization bounding box}% + \pgfkeys{/pgf/freeze local bounding box=data bounding box}% +} + +% +% The data point key +% +\tikzdatavisualizationset{ + data point/.code={ + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{\bgroup\pgfkeys{/data point/.cd,#1}\pgfdatapoint\egroup}})}% + } +} + % % Object setup @@ -409,7 +488,7 @@ % \tikzdatavisualizationset{% - new axis/.style={ + new axis base/.style={ new object={ class=scaling mapper, store=/tikz/data visualization/#1/scaling mapper, @@ -462,8 +541,6 @@ node styling/.style={% /utils/exec={\pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@temp\expandafter\tikzset\expandafter{\tikz@temp}}}, node style/.style={/tikz/data visualization/@node styling/.append={,#1}}, - grid styling/.style=, - grid style/.style={grid styling/.append style={#1}}, % General extends (both axes, grid and ticks) low/.initial=0, high/.initial=0, @@ -483,20 +560,31 @@ @setup at setters, % Tick keys direction axis/.initial=, - value/.initial=, - pos/.initial=, + % Tick text modifiers + tick text low even padding/.initial=0pt, + tick text high even padding/.initial=0pt, + tick text low odd padding/.initial=0pt, + tick text high odd padding/.initial=0pt, + tick text odd padding/.style={tick text low odd padding={-#1},tick text high odd padding={#1}}, + tick text even padding/.style={tick text low even padding={-#1},tick text high even padding={#1}}, + tick text padding/.style={tick text odd padding={#1},tick text even padding={#1}}, + stack/.style={tick text even padding={#1}}, + stack'/.style={tick text odd padding={#1}}, + stack/.default=1em, + stack'/.default=1em, tick text at low/.is if=tikz@dv@min@tick@node, tick text at high/.is if=tikz@dv@max@tick@node, no tick text/.style={tick text at low=false,tick text at high=false}, + % every major ticks/.style={style={line cap=round},tick length=2pt}, - every minor ticks/.style={style={help lines,thin,line cap=round},tick length=1.4pt}, - every subminor ticks/.style={style={help lines,line cap=round},tick length=0.8pt}, + every minor ticks/.style={style={solid, help lines,thin,line cap=round},tick length=1.4pt}, + every subminor ticks/.style={style={solid, help lines,line cap=round},tick length=0.8pt}, clean ticks/.style={node style={fill=white}}, % Default grid styles - grid style={high=max,low=min}, - every major grid/.style={style={help lines,thin,black!25}}, - every minor grid/.style={style={help lines,black!25}}, - every subminor grid/.style={style={help lines,black!10}}, + every grid/.style={high=max,low=min}, + every major grid/.style={style={solid, help lines,thin,black!25}}, + every minor grid/.style={style={solid, help lines,black!25}}, + every subminor grid/.style={style={solid, help lines,black!10}}, at default ticks/.code={% \expandafter\pgfkeysalso\expandafter{\tikz@lib@dv@ticks@default@at}}, at ticks/.code={% @@ -549,21 +637,21 @@ rounded corners=1.5pt } }, - every visualizer label/.style={ + every data set label/.style={ every ticks, node style={ - font=\pgfutil@font@small + font=\pgfutil@font@small, } }, @color of visualizer labels/.style={text=black}, - every visualizer legend label/.style={ + every label in legend/.style={ node style={ - fill=none + fill=none, } }, every axis label/.style={ node style={% - font=\pgfutil@font@small + font=\pgfutil@font@small, } } } @@ -580,7 +668,15 @@ padding min/.style={\tikz@dv@axis/padding min={#1}}, padding max/.style={\tikz@dv@axis/padding max={#1}}, padding/.style={padding min={-#1},padding max={#1}}, - label/.style={\tikz@dv@axis/label={#1}}, + label/.code={% + \def\pgf@temp{#1}% + \ifx\pgf@temp\tikz@lib@dv@auto@attribute% + \tikzdatavisualizationset{\tikz@dv@axis/label/.expanded=$\noexpand\mathit{\pgfkeysvalueof{\tikz@dv@axis/attribute}}$}% + \else + \tikzdatavisualizationset{\tikz@dv@axis/label={#1}}% + \fi + }, + label/.default=\tikz@lib@dv@auto@attribute, % % Strategies % @@ -590,17 +686,9 @@ % Attribute setter % goto/.code={\tikz@dv@goto{\tikz@dv@axis}{#1}}, - % - % Modification of the range - % - include values/.style={% - /tikz/data visualization/before survey/.expanded={% - \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% - \noexpand\foreach \noexpand\tikz@lib@dv@temp in {#1} {% - \noexpand\tikz@dv@axis@mapper.include in value(\noexpand\tikz@lib@dv@temp)% - }% - }% - }, + goto pos/.code={\tikz@dv@goto@pos{\tikz@dv@axis}{#1}}, + anchor at min/.code={\tikz@lib@dv@special@at{\tikz@dv@axis}{\tikz@dv@min@anchor}}, + anchor at max/.code={\tikz@lib@dv@special@at{\tikz@dv@axis}{\tikz@dv@max@anchor}}, % % Visualization setters % @@ -609,6 +697,7 @@ % Ticks settings % ticks/.style={\tikz@dv@axis/ticks at/.append={,#1}}, + ticks/.default=some, visualize ticks/.code=\expandafter\tikz@lib@dv@tv\expandafter{\tikz@dv@axis}{#1}, % % Grid settings @@ -617,11 +706,52 @@ grid/.default=at default ticks, visualize grid/.code=\expandafter\tikz@lib@dv@gv\expandafter{\tikz@dv@axis}{#1}, % + ticks and grid/.style={\tikz@dv@axis/ticks at/.append={,#1},\tikz@dv@axis/grid at/.append={,#1}}, + % % Visualizing axis labels % visualize label/.code=\expandafter\tikz@lib@dv@lv\expandafter{\tikz@dv@axis}{#1}, } +\def\tikz@lib@dv@auto@attribute{\tikz@lib@dv@auto@attribute} + + +% Range options +\tikzdatavisualizationset{ + axis options/.cd, + % + % Including a value in the range + % + include value/.style={% + /tikz/data visualization/before survey/.expanded={% + \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% + \noexpand\foreach \noexpand\tikz@lib@dv@temp in {#1} {% + \noexpand\tikz@dv@axis@mapper.include in value(\noexpand\tikz@lib@dv@temp)% + }% + }% + }, + % + % Directly setting the min or max + % + min value/.style={ + /tikz/data visualization/at end survey/.expanded={% + \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% + \noexpand\tikz@lib@dv@set\noexpand\tikz@dv@axis@mapper{#1}{min}% + } + }, + max value/.style={ + /tikz/data visualization/at end survey/.expanded={% + \noexpand\pgfkeysgetvalue{\tikz@dv@axis/scaling mapper}\noexpand\tikz@dv@axis@mapper% + \noexpand\tikz@lib@dv@set\noexpand\tikz@dv@axis@mapper{#1}{max}% + } + }, +} + +\def\tikz@lib@dv@set#1#2#3{% + \pgfdvmathenter{\pgf@dv@value}{#2}% + #1.get in range interval()% + \pgfdvinrangeinterval.let #3(\pgf@dv@value)% +} % Layer options \tikzdatavisualizationset{ @@ -664,15 +794,15 @@ } \def\tikz@dv@goto#1#2{% - \edef\pgf@temp{#2}% - \ifx\pgf@temp\tikz@lib@dv@padded@min@text% + \edef\pgf@@temp{#2}% + \ifx\pgf@@temp\tikz@lib@dv@padded@min@text% \pgfkeysvalueof{#1/scaling mapper}.set in to(min)% \pgfkeysvalueof{#1/scaling mapper}.get out()% \pgfkeysgetvalue{#1/padding min}\pgf@temp% \pgfmathparse{\pgf@temp}% \pgfkeyslet{/data point/\pgfdvout/offset}\pgfmathresult% \else% - \ifx\pgf@temp\tikz@lib@dv@padded@max@text% + \ifx\pgf@@temp\tikz@lib@dv@padded@max@text% \pgfkeysvalueof{#1/scaling mapper}.set in to(max)% \pgfkeysvalueof{#1/scaling mapper}.get out()% \pgfkeysgetvalue{#1/padding max}\pgf@temp% @@ -682,10 +812,21 @@ \pgfkeysvalueof{#1/scaling mapper}.set in to(#2)% \fi% \fi% -} +} + +\def\tikz@dv@goto@pos#1#2{% + \pgfkeyssetvalue{/data point/\pgfkeysvalueof{#1/attribute}/out pos}{#2}% +} \def\tikz@lib@dv@padded@min@text{padded min} \def\tikz@lib@dv@padded@max@text{padded max} + +\def\tikz@lib@dv@special@at#1#2{% + % Ok, calculate direction vector: + \tikzpointandanchordirection{\pgfkeysvalueof{#1/scaling mapper}.set in to(min)}{\pgfkeysvalueof{#1/scaling mapper}.set in to(max)} + \tikzset{anchor/.expanded=#2} +} + % Ticks visualization % @@ -743,19 +884,22 @@ {% \let\tikz@dv@at@list\pgfutil@empty% \let\tikz@dv@style@at@list\pgfutil@empty% + \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper + \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}% \scope[/tikz/data visualization/.cd,every ticks/.try,every #1 ticks/.try,#3]% % Setup options - \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper - \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}% \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp} \pgfkeysgetvalue{/tikz/data visualization/#1}\tikz@temp \expandafter\tikzdatavisualizationset\expandafter{\tikz@temp} \pgfkeysgetvalue{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/direction axis}/scaling mapper}\pgf@dv@tick@dir@mapper % Ok, now it's time to draw the ticks! - \foreach \tikz@dv@tick@pos in \tikz@dv@at@list + \foreach \tikz@dv@tick@pos[count=\tikz@dv@tick@count] in \tikz@dv@at@list { \ifx\tikz@dv@tick@pos\pgfutil@empty + \c@pgf@counta=\tikz@dv@tick@count\relax% + \advance\c@pgf@counta by-1\relax% + \edef\tikz@dv@tick@count{\the\c@pgf@counta}% \else \expandafter\tikz@lib@dv@parse\tikz@dv@tick@pos\pgf@stop% \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}% @@ -768,15 +912,40 @@ \xdef\pgf@dv@tick@dir{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} % Now, show something: \tikz@lib@handle@at@style% - \scope[/tikz/data visualization/styling] - \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\pgfkeysvalueof{/tikz/data visualization/high}}{\pgf@dv@tick@dir}}} - \xdef\tikz@dv@max@tick{\the\pgf@x,\the\pgf@y} - \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\pgfkeysvalueof{/tikz/data visualization/low}}{\pgf@dv@tick@dir}}} - \xdef\tikz@dv@min@tick{\the\pgf@x,\the\pgf@y} - \scope[data visualization/ticks layer] \draw (\tikz@dv@min@tick) -- (\tikz@dv@max@tick); \endscope - \iftikz@dv@min@tick@node \scope[data visualization/ticks node layer] \path (\tikz@dv@min@tick) \tikz@dv@handle@tick{\tikz@dv@min@anchor}; \endscope \fi - \iftikz@dv@max@tick@node \scope[data visualization/ticks node layer] \path (\tikz@dv@max@tick) \tikz@dv@handle@tick{\tikz@dv@max@anchor}; \endscope\fi + \pgfkeysgetvalue{/tikz/data visualization/high}\tikz@dv@max@val% + \pgfkeysgetvalue{/tikz/data visualization/low}\tikz@dv@min@val% + \iftikz@dv@max@tick@node\pgfmathsetmacro\tikz@dv@max@val{% + \tikz@dv@max@val+(\pgfkeysvalueof{% + /tikz/data visualization/tick text high + \ifodd\tikz@dv@tick@count odd \else even \fi padding}% + )}% + \fi% + \iftikz@dv@min@tick@node\pgfmathsetmacro\tikz@dv@min@val{% + \tikz@dv@min@val+(\pgfkeysvalueof{% + /tikz/data visualization/tick text low + \ifodd\tikz@dv@tick@count odd \else even \fi padding}% + )}% + \fi% + \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\tikz@dv@max@val}{\pgf@dv@tick@dir}}} + \xdef\tikz@dv@max@tick{\the\pgf@x,\the\pgf@y} + \pgf@process{\pgfpointadd{\pgf@dv@tick@origin}{\pgfpointscale{\tikz@dv@min@val}{\pgf@dv@tick@dir}}} + \xdef\tikz@dv@min@tick{\the\pgf@x,\the\pgf@y} + \scope[data visualization/ticks layer] + \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try} + \draw [/tikz/data visualization/styling] (\tikz@dv@min@tick) -- (\tikz@dv@max@tick); \endscope + \iftikz@dv@min@tick@node + \scope[data visualization/ticks node layer] + \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try} + \path [/tikz/data visualization/styling] (\tikz@dv@min@tick) \tikz@dv@handle@tick{\tikz@dv@min@anchor}; + \endscope + \fi + \iftikz@dv@max@tick@node + \scope[data visualization/ticks node layer] + \tikzdatavisualizationset{every \ifodd\tikz@dv@tick@count odd \else even \fi tick/.try} + \path [/tikz/data visualization/styling] (\tikz@dv@max@tick) \tikz@dv@handle@tick{\tikz@dv@max@anchor}; + \endscope + \fi \fi } \endscope @@ -808,7 +977,7 @@ \pgfdvmathenter{\tikz@lib@dv@typesetnum}{\tikz@dv@tick@pos}% \pgfdvmathexitbyscientificformat{\tikz@lib@dv@typesetnum}{\tikz@lib@dv@typesetnum}% hmm... not sure about this... \pgfkeysvalueof{/tikz/data visualization/tick prefix}% - \pgfkeysvalueof{/tikz/data visualization/tick typesetter}{\tikz@lib@dv@typesetnum}% + \pgfkeys{/tikz/data visualization/tick typesetter=\tikz@lib@dv@typesetnum}% \pgfkeysvalueof{/tikz/data visualization/tick suffix}% } @@ -860,7 +1029,7 @@ % Help function \def\tikzpointandanchordirection#1#2{% % This function works like pgfpointdvdirection, but also computes - % appriate "min" and "max" anchors. + % appropriate "min" and "max" anchors. \pgf@process{\pgfpointdvdirection{#1}{#2}} { \pgf@ya=\pgf@y @@ -907,10 +1076,10 @@ {% \let\tikz@dv@at@list\pgfutil@empty \let\tikz@dv@style@at@list\pgfutil@empty - \scope[data visualization/grid layer,/tikz/data visualization/.cd,every #1 grid/.try,grid styling,grid styling/.style=,#3] + \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper + \let\tikz@lib@dv@ticks@default@at\pgfutil@empty% + \scope[data visualization/grid layer,/tikz/data visualization/.cd,every grid,every #1 grid/.try,#3] % Setup options - \pgfkeysgetvalue{#2/scaling mapper}\tikz@lib@dv@mapper - \let\tikz@lib@dv@ticks@default@at\pgfutil@empty% \pgfkeysgetvalue{#2/ticks at}\tikz@lib@dv@ticks@at% \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@settings}% \pgfkeysgetvalue{/tikz/data visualization/common}\tikz@temp @@ -925,7 +1094,6 @@ \else \expandafter\tikz@lib@dv@parse\tikz@dv@grid@pos\pgf@stop% \expandafter\tikzdatavisualizationset\expandafter{\tikz@lib@dv@tick@opt}% - \tikzdatavisualizationset{grid styling}% \tikz@lib@dv@mapper.set in to(\tikz@dv@tick@pos)% \draw[/tikz/data visualization/styling] \pgfextra{ @@ -966,46 +1134,17 @@ \ifx\tikz@dv@lib@label\pgfutil@empty% % Great, nothing to do \else - \scope[/tikz/data visualization/.cd,every axis label/.try,#2] - \pgfkeysgetvalue{/tikz/data visualization/value}\tikz@lib@dv@at% - \pgfkeysgetvalue{/tikz/data visualization/pos}\tikz@lib@dv@pos% - \pgfkeysgetvalue{#1/scaling mapper}\tikz@dv@mapper - \ifx\tikz@lib@dv@pos\pgfutil@empty% - \ifx\tikz@lib@dv@at\pgfutil@empty% - % Well, hopefully the node options setup things correctly... - \else% - % Special treatment of "min" and "max" - \ifx\tikz@lib@dv@at\pgf@min@text% - \tikz@lib@dv@special@at{\tikz@dv@min@anchor} - \else \ifx\tikz@lib@dv@at\tikz@lib@dv@padded@min@text% - \tikz@lib@dv@special@at{\tikz@dv@min@anchor} - \else \ifx\tikz@lib@dv@at\pgf@max@text% - \tikz@lib@dv@special@at{\tikz@dv@max@anchor} - \else \ifx\tikz@lib@dv@at\tikz@lib@dv@padded@max@text% - \tikz@lib@dv@special@at{\tikz@dv@max@anchor} - \fi\fi\fi\fi% - \tikz@dv@goto{#1}{\tikz@lib@dv@at}% - \pgftransformshift{\pgfpointdvlocaldatapoint}% - \fi% - \else% - \tikz@dv@mapper.set in to(min)% - \pgftransformshift{\pgfpointscale{1-\tikz@lib@dv@pos}{\pgfpointdvlocaldatapoint}} - \tikz@dv@mapper.set in to(max)% - \pgftransformshift{\pgfpointscale{\tikz@lib@dv@pos}{\pgfpointdvlocaldatapoint}} - \fi + \scope[anchor=center,/tikz/data visualization/.cd,every axis label/.try,#2] \expandafter\tikz@lib@dv@parse@node\tikz@dv@lib@label\pgf@stop \endscope \fi } -\def\tikz@lib@dv@special@at#1{% - % Ok, calculate direction vector: - \tikzpointandanchordirection{\tikz@dv@mapper.set in to(min)}{\tikz@dv@mapper.set in to(max)} - \tikzset{anchor=#1} -} \def\tikz@lib@dv@parse@node{\pgfutil@ifnextchar[\tikz@lib@dv@parse@node@opt{\tikz@lib@dv@parse@node@opt[]}}%} \def\tikz@lib@dv@parse@node@opt[#1]#2\pgf@stop{ - \node [/tikz/data visualization/node styling,#1] {#2}; + \tikzdatavisualizationset{#1} + \pgftransformshift{\pgfpointdvlocaldatapoint}% + \node [/tikz/data visualization/node styling] {#2}; } @@ -1020,10 +1159,10 @@ minor steps between steps/.initial=, minor steps between steps/.default=9, phase/.initial=0, - tick typesetter/.initial=\pgfmathprintnumber, + tick typesetter/.code=\pgfmathprintnumber{#1}, tick prefix/.initial=, tick suffix/.initial=, - tick unit/.style={tick suffix={#1}},% this is an alias + tick unit/.style={tick suffix={$\,\rm#1$}},% this is an alias } \def\tikz@lib@dv@compute@at@linear{% @@ -1111,6 +1250,7 @@ standard about strategy/.style={about strategy={1.5/1.0,2.3/2.0,4/2.5,7/5,11/10}}, standard about strategy, euro about strategy/.style={about strategy={1.5/1.0,3/2.0,7/5,11/10}}, + decimal about strategy/.style={about strategy={3/1.0,11/10}}, half about strategy/.style={about strategy={2/1.0,7/5,11/10}}, quarter about strategy/.style={about strategy={1.8/1.0,4/2.5,7/5,11/10}}, int about strategy/.style={about strategy={1.5/1.0,2.5/2.0,3.5/3.0,4.5/4.0,7/5,11/10}}, @@ -1269,7 +1409,7 @@ \tikzdatavisualizationset{% new Cartesian axis/.style={ - new axis={#1}, + new axis base={#1}, new object={ class=linear transformer, store=/tikz/data visualization/#1/linear transformer, @@ -1277,7 +1417,7 @@ arg2 from key=/tikz/data visualization/#1/unit vector, }, #1/scaling/default/.initial=0 at 0 and 1 at 1cm, - #1/unit vector/.initial=, + #1/unit vector/.initial=\pgfqpoint{1pt}{0pt}, } } @@ -1285,8 +1425,6 @@ /tikz/data visualization/axis options/.cd, unit vector/.code=\tikz@scan@one@point\tikz@lib@dv@uv#1, length/.style={\tikz@dv@axis/scaling=min at 0 and max at #1}, - positive length/.style={\tikz@dv@axis/scaling=0 at 0 and max at #1}, - negative length/.style={\tikz@dv@axis/scaling=min at -#1 and 0 at 0}, unit length/.code={\tikz@dv@parse@unit@length{#1}}, power unit length/.style={\tikz@dv@axis/scaling=1 at 0 and 10 at #1} } @@ -1313,34 +1451,62 @@ % \tikzdatavisualizationset{ - new visualizer/.style 2 args={ - /pgf/data/#1/.style={/data point/visualizer=#1}, + new visualizer/.style n args={3}{ #1/.code={ \def\tikz@visualizer{#1}% \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1} + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgfkeys{/data point/set=#1})}% }, /utils/exec={ \advance\tikzdvvisualizercounter by 1\relax - \edef\tikz@temp{/data point/visualizer/#1/.initial=\the\tikzdvvisualizercounter} + \edef\tikz@temp{/data point/set/#1/.initial=\the\tikzdvvisualizercounter} \expandafter\tikzset\expandafter{\tikz@temp} }, /data point/#1/execute at begin/.initial={ - \pgfkeyssetvalue{/data point/visualizer}{#1} + \pgfkeyssetvalue{/data point/set}{#1} \scope[ - /tikz/data visualization/every visualizer/.try, #2, - /utils/exec=\pgf@signalstyle.emit(), + /tikz/data visualization/every visualizer/.try, + /tikz/data visualization/visualizers/#1/signal, /tikz/data visualization/visualizers/#1/styling/.try] }, /data point/#1/execute at end/.initial={ \path; % invokes every path implicitly \endscope }, + /tikz/data visualization/visualizers/#1/signal/.code=\pgf@signalstyle.emit(), /tikz/data visualization/visualizers/#1/styling/.style=, + /tikz/data visualization/visualizers/#1/label in legend options/.style={#3}, }, - visualizer style sheet/.style={/data point/visualizer/.style sheet={#1}} + style sheet/.style={/data point/set/.style sheet={#1}}, + /pgf/data/set/.style={/data point/set=#1}, +} + +\tikzdatavisualizationset{ + new sub visualizer/.style n args={4}{ + #4/#1/.code={ + \def\tikz@visualizer{#4/#1}% + \pgfkeys{/tikz/data visualization/visualizer options/.cd,##1} + }, + /data point/#4/#1/execute at begin/.initial={ + \pgfkeyssetvalue{/data point/set}{#4} + \scope[ + #2, + /tikz/data visualization/every visualizer/.try, + /tikz/data visualization/visualizers/#4/signal, + /tikz/data visualization/visualizers/#4/styling/.try, + /tikz/data visualization/visualizers/#4/#1/styling/.try] + }, + /data point/#4/#1/execute at end/.initial={ + \path; % invokes every path implicitly + \endscope + }, + /tikz/data visualization/visualizers/#4/#1/styling/.style=, + /tikz/data visualization/visualizers/#4/#1/label in legend options/.style={#3}, + } } + \def\tikz@do@visualizer#1#2{% \tikzdatavisualizationset{ #2=#1 @@ -1351,16 +1517,19 @@ \newif\iftikz@dv@visualizer@label@inline -\tikzset{ - @set plot handler/.code={\let\tikz@plot@handler=#1}, - no lines/.style={@set plot handler=\pgfplothandlerdiscard,/utils/exec=\tikzdatavisualizationset{default label in legend mark}}, - smooth line/.style={@set plot handler=\pgfplothandlercurveto,/utils/exec=\tikzdatavisualizationset{default label in legend path}}, - smooth cycle/.style={@set plot handler=\pgfplothandlerclosedcurve,/utils/exec=\tikzdatavisualizationset{default label in legend closed path}}, - straight line/.style={@set plot handler=\pgfplothandlerlineto,/utils/exec=\tikzdatavisualizationset{default label in legend path}}, - straight cycle/.style={@set plot handler=\pgfplothandlerpolygon,/utils/exec=\tikzdatavisualizationset{default label in legend closed path}}, - polygon/.style={straight cycle=cycle},% alias - gapped line/.style={@set plot handler=\pgfplothandlergaplineto,/utils/exec=\tikzdatavisualizationset{default label in legend path}}, - gapped cycle/.style={@set plot handler=\pgfplothandlergapcycle,/utils/exec=\tikzdatavisualizationset{gapped circular label in legend line}} +\tikzdatavisualizationset{visualizer options/.cd, + @set/.style 2 args={ + /tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={/utils/exec={\let\tikz@dv@plot@handler=#1}}, + /tikz/data visualization/visualizers/\tikz@visualizer/label in legend options/.append style={#2} + }, + no lines/.style={@set={\pgfplothandlerdiscard}{default label in legend mark}}, + smooth line/.style={@set={\pgfplothandlercurveto}{default label in legend path}}, + smooth cycle/.style={@set={\pgfplothandlerclosedcurve}{default label in legend closed path}}, + straight line/.style={@set={\pgfplothandlerlineto}{default label in legend path}}, + straight cycle/.style={@set={\pgfplothandlerpolygon}{default label in legend closed path}}, + polygon/.style={straight cycle},% alias + gap line/.style={@set={\pgfplothandlergaplineto}{default label in legend path}}, + gap cycle/.style={@set={\pgfplothandlergapcycle}{gap circular label in legend line}} } @@ -1378,16 +1547,17 @@ \begingroup \def\tikz@visualizer{#1}% \pgfkeys{/tikz/data visualization/visualizer label options/.cd, - /tikz/data visualization/every label visualizer/.try, #2} \pgfkeysgetvalue{/tikz/data visualization/visualizer label options/text}\tikz@dv@temp@lab \def\tikz@tempa{ - \scope[/tikz/data visualization/visualizer label options/.cd, - /tikz/data visualization/every label visualizer/.try, + \scope[ + /utils/exec=\def\tikz@visualizer{#1},% + /tikz/data visualization/visualizer label options/.cd, #2] + \tikzdatavisualizationset{every data set label/.try} \path [ - /data point/visualizer=#1,/utils/exec=\pgf@signalstyle.emit(), - /tikz/data visualization/.cd,every visualizer label] + /data point/set=#1,/utils/exec=\pgf@signalstyle.emit(), + /tikz/data visualization/.cd,every label in data/.try] (label visualizer coordinate') -- (label visualizer coordinate) node [ @@ -1405,7 +1575,7 @@ \endgroup }, arg1/.expand once=\tikz@dv@label@attribute, - arg2/.expand once=\tikz@dv@label@threshold, + arg2=\tikz@dv@label@threshold, arg3/.expand once=\tikz@dv@label@code, arg4=\pgfdvvisualizerfilter{#1} }, @@ -1418,40 +1588,45 @@ \def\tikz@create@label@count#1{ \tikzdatavisualizationset{ new object={ - when=after survey, + when=before survey, store=/tikz/data visualization/visualizers/#1/count/obj, class=count, - arg1=visualizers/#1/count, - after creation={ - \tikzdvobj.set filter({% - \pgfkeysgetvalue{/data point/visualizer}\pgf@tempa% - \def\pgf@tempb{#1}% - \ifx\pgf@tempa\pgf@tempb% - \else - \pgfdvfilterpassedfalse% - \fi - }) - } + arg1=set/#1/count, + after creation={\tikzdvobj.set filter(\pgfdvvisualizerfilter{#1})} } } } \pgfkeys{ /tikz/data visualization/visualizer label options/.cd, - at/.code args={#1>=#2}{% + when/.code args={#1 is#2}{% \def\tikz@dv@label@attribute{#1}% \def\tikz@dv@label@threshold{#2}% }, index/.code={% - \edef\tikz@dv@label@attribute{visualizers/\tikz@visualizer/count}% + \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}% \def\tikz@dv@label@threshold{#1}% }, + pos/.code={% + \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}% + \pgfkeysvalueof{/tikz/data visualization/visualizers/\tikz@visualizer/count/obj}.get max(\tikz@lib@max) + \edef\tikz@dv@label@threshold{(#1*\tikz@lib@max)}% + }, + auto/.code={% + \edef\tikz@dv@label@attribute{set/\tikz@visualizer/count}% + \pgfkeysvalueof{/tikz/data visualization/visualizers/\tikz@visualizer/count/obj}.get max(\tikz@lib@max) + \edef\tikz@dv@label@threshold{({(\pgfkeysvalueof{/data point/set/\tikz@visualizer}-0.5)/\the\tikzdvvisualizercounter*\tikz@lib@max})} + }, text/.initial=, - text'/.style={text={#1},node style=swap}, + text'/.style={text={#1},node style=swap,/utils/exec=\def\tikz@lib@dv@pin@sign{-}}, node style/.style={/tikz/data visualization/node style={#1}}, text colored/.style=/tikz/data visualization/text colored, + pin angle/.store in=\tikz@lib@dv@pin@dir, + pin length/.style={node style={pin distance={#1}}}, } +\let\tikz@lib@dv@pin@sign\pgfutil@empty + \let\tikz@dv@label@attribute\pgfutil@empty \let\tikz@dv@label@threshold\pgfutil@empty \let\tikz@dv@label@code\pgfutil@empty @@ -1486,7 +1661,7 @@ \let\pgfdvendrow=\pgfmatrixendrow% \def\pgf@marshal{ \matrix[at/.expand once=\pgf@dv@at,matrix anchor/.expand - once=\pgf@dv@anchor,/tikz/data visualization/#1/styling] + once=\pgf@dv@anchor,/tikz/data visualization/#1/matrix node styling] } \expandafter\pgf@marshal\expandafter{\pgf@dv@temp}; } @@ -1500,7 +1675,7 @@ #1/@strategy/.initial=down then right, #1/anchor/.initial=west, #1/at/.initial=(data visualization bounding box.east), - #1/styling/.style={row sep=0pt,column sep=.8em}, + #1/matrix node styling/.style={row sep=0pt,column sep=.8em}, % % % @@ -1511,7 +1686,11 @@ }, #1={every new legend} }}}, - legend/.style={new legend=legend,legend={#1}} + new legend/.default=main legend, + legend/.style={ + new legend, + main legend={#1} + } } \def\tikz@do@legend@options#1#2{ @@ -1545,38 +1724,187 @@ % anchor/.style={\tikz@dv@legend/anchor={#1}}, at/.style={\tikz@dv@legend/at={#1}}, - right/.style={ + % Outer placements + right/.style={east outside}, + left/.style={west outside}, + above/.style={north outside}, + below/.style={south outside}, + east outside/.style={ columns=1, at={([xshift=.8em]data visualization bounding box.east)}, anchor=west, }, - left/.style={ + north east outside/.style={ + columns=1, + at={([xshift=.8em]data visualization bounding box.north east|- + data bounding box.north)}, + anchor=north west, + }, + south east outside/.style={ + columns=1, + at={([xshift=.8em]data visualization bounding box.south east |- + data bounding box.south)}, + anchor=south west, + }, + west outside/.style={ columns=1, + label style=text left, at={([xshift=-.8em]data visualization bounding box.west)}, anchor=east, }, - below/.style={ + north west outside/.style={ + columns=1, + label style=text left, + at={([xshift=-.8em]data visualization bounding box.north west |- + data bounding box.north)}, + anchor=north east, + }, + south west outside/.style={ + columns=1, + label style=text left, + at={([xshift=-.8em]data visualization bounding box.south west |- + data bounding box.south)}, + anchor=south east, + }, + south outside/.style={ rows=1, at={([yshift=-.5em]data visualization bounding box.south)}, anchor=north, }, - above/.style={ + north outside/.style={ rows=1, at={([yshift=.5em]data visualization bounding box.north)}, anchor=south, }, - every new legend/.style={right,label style=text right}, + every new legend/.style={east outside,label style=text right}, + % + % Inner placements + % + % First, styling + every legend inside/.style={ + opaque=white, + label style={node style={font=\pgfutil@font@footnotesize}} + }, + opaque/.style={ + matrix node style={ + inner sep=.333ex, + outer sep=.5ex, + rounded corners=3pt, + execute at begin cell={\tikzset{sharp corners}}, % get rid of + % rounded corners in cells of the + % legend matrix + fill=#1 + }, + }, + opaque/.default=white, + transparent/.style={matrix node style={fill=none}}, + % Second, the placements + north east inside/.style={ + columns=1, + at={([xshift=-.3em]data bounding box.north east)}, + anchor=north east, + every legend inside + }, + south west inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.south west)}, + anchor=south west, + every legend inside + }, + north west inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.north west)}, + anchor=north west, + every legend inside + }, + south east inside/.style={ + columns=1, + at={([xshift=-.3em]data bounding box.south east)}, + anchor=south east, + every legend inside + }, + west inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.west)}, + anchor=west, + every legend inside + }, + east inside/.style={ + columns=1, + at={([xshift=.3em]data bounding box.east)}, + anchor=east, + every legend inside + }, + north inside/.style={ + rows=1, + at={(data bounding box.north)}, + anchor=north, + every legend inside + }, + south inside/.style={ + rows=1, + at={(data bounding box.south)}, + anchor=south, + every legend inside + }, + % Additional inner placements + at values/.style={ + at={(visualization cs:#1)}, + anchor=center, + every legend inside + }, + right of/.style={ + at={(visualization cs:#1)}, + anchor=west, + every legend inside + }, + left of/.style={ + at={(visualization cs:#1)}, + anchor=east, + every legend inside + }, + above of/.style={ + at={(visualization cs:#1)}, + anchor=south, + every legend inside + }, + below of/.style={ + at={(visualization cs:#1)}, + anchor=north, + every legend inside + }, + above right of/.style={ + at={(visualization cs:#1)}, + anchor=south west, + every legend inside + }, + above left of/.style={ + at={(visualization cs:#1)}, + anchor=south east, + every legend inside + }, + below right of/.style={ + at={(visualization cs:#1)}, + anchor=north west, + every legend inside + }, + below left of/.style={ + at={(visualization cs:#1)}, + anchor=north east, + every legend inside + }, + % + % % % Label text styling % label style/.style={ - style={/tikz/data visualization/legend entry options/every label - in legend/.append style={#1}} + matrix node style={/tikz/data visualization/every label in legend/.append style={#1}} }, % % Styling % - style/.style={\tikz@dv@legend/styling/.append style={#1}}, + matrix node style/.style={\tikz@dv@legend/matrix node styling/.append style={#1}}, } @@ -1593,30 +1921,30 @@ } \def\tikz@dv@add@legend@entry#1#2{ - \tikz@main@dv.at start survey({{ + \tikz@main@dv.at start survey({ \pgfkeysgetvalue{/tikz/data visualization/#1/obj}\pgf@temp \pgf@temp.add entry(\tikz@dv@render@legend@entry{legend=#1,#2}) - }}) + }) } \def\tikz@dv@render@legend@entry#1{ - \pgfkeys{/tikz/data visualization/.cd, - every visualizer label, - every visualizer legend label - } - \pgfkeys{/tikz/data visualization/legend entry options/.cd,#1} + \pgfkeys{/tikz/data visualization/.cd,every data set label} + \pgfkeys{/tikz/data visualization/legend entry options/.cd, + /tikz/data visualization/every label in legend,#1}% \pgfkeysgetvalue{/tikz/data visualization/legend entry options/text}\tikz@dv@temp@lab \pgfkeysgetvalue{/tikz/data visualization/@node styling}\tikz@dv@temp@style \pgfkeysgetvalue{/tikz/data visualization/legend entry options/setup}\tikz@dv@temp@setup - \pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer}\tikz@dv@temp@visual - \pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer styling}\tikz@dv@temp@visual@styling + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/visualizer in legend styling}\tikz@dv@temp@visual@styling \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@setup}, /utils/exec=\pgf@signalstyle.emit()] \node[/tikz/data visualization/node styling, /utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@style}] {\tikz@dv@pre@height\tikz@dv@temp@lab\tikz@dv@post@height}; \scope[/utils/exec=\expandafter\pgfkeysalso\expandafter{\tikz@dv@temp@visual@styling}] - \tikz@dv@temp@visual + \iftikz@lib@dv@text@only + \else + \pgfkeysvalueof{/tikz/data visualization/legend entry options/visualizer in legend} + \fi \endscope \endscope } @@ -1633,66 +1961,84 @@ % text/.initial=, node style/.style={/tikz/data visualization/node style={#1}}, - legend/.initial=legend, + legend/.initial=main legend, setup/.initial=, - value visualizer/.initial=, - value visualizer styling/.initial=, - value visualizer style/.style={value visualizer styling/.append={,#1}}, - value visualizer macro/.initial=, + visualizer in legend/.initial=, + visualizer in legend styling/.initial=, + visualizer in legend style/.style={visualizer in legend styling/.append={,#1}}, % % Legend visualizers for plots % text right/.style={ node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,xshift=.333em}, - value visualizer style={reset cm}, - value visualizer macro=\tikz@dv@legend@entry@as@example + visualizer in legend style={reset cm}, }, text left/.style={ node style={anchor=mid east,inner ysep=1pt,inner xsep=0pt,reset cm,xshift=-.333em,align=right}, - value visualizer style={reset cm,xscale=-1}, - value visualizer macro=\tikz@dv@legend@entry@as@example + visualizer in legend style={reset cm,xscale=-1}, }, text only/.style={ node style={anchor=mid west,inner ysep=1pt,inner xsep=0pt,reset cm,text=visualizer color}, - value visualizer style={}, - value visualizer macro=\relax, + /utils/exec=\tikz@lib@dv@text@onlytrue }, text colored/.style=/tikz/data visualization/text colored, } - +\let\tikz@lib@dv@pin@dir\pgfutil@empty +\newif\iftikz@lib@dv@text@only \pgfkeys{ /tikz/data visualization/visualizer options/.cd, label in legend/.code={\expandafter\tikz@dv@new@label@in@legend@for@visualizer\expandafter{\tikz@visualizer}{#1}}, - label in data/.code=\tikzdatavisualizationset{new label visualizer/.expand once=\expandafter{\tikz@visualizer}{#1}}, - style/.style={/tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={#1}}, + label in data/.code=\tikzdatavisualizationset{new label visualizer/.expand once=\expandafter{\tikz@visualizer}{auto,#1}}, + pin in data/.style={label in data={% + node style={% + /utils/exec={ + \ifx\tikz@lib@dv@pin@dir\pgfutil@empty + \pgf@process{\pgfpointnormalised{% + \pgfpointdiff% + {\pgfpointanchor{label visualizer coordinate}{center}}% + {\pgfpointanchor{label visualizer coordinate'}{center}}}}% + \pgf@x=-\pgf@x\relax% + \edef\tikz@lib@dv@temp@rot{\noexpand\pgfqpoint{\the\pgf@y}{\the\pgf@x}}% + \tikz@addtransform{\pgftransformshift{\pgfpointscale{\tikz@lib@dv@pin@sign\tikz@pin@distance}{\tikz@lib@dv@temp@rot}}} + \else% + \tikz@addtransform{\pgftransformshift{\pgfpointpolar{\tikz@lib@dv@pin@dir}{\tikz@lib@dv@pin@sign\tikz@pin@distance}}} + \fi% + }, + append after command={ + \bgroup + [current point is local=true] + (\tikzlastnode) edge [solid, every pin edge] (label visualizer coordinate) + \egroup% + }}, + ,#1}}, + style/.style={/tikz/data visualization/visualizers/\tikz@visualizer/styling/.append style={,#1}}, + label in legend options/.style={/tikz/data visualization/visualizers/\tikz@visualizer/label in legend options/.append style={,#1}}, + ignore style sheets/.style={/tikz/data visualization/visualizers/\tikz@visualizer/signal/.code=,/utils/exec=\advance\tikzdvvisualizercounter by -1\relax}, } \def\tikz@dv@new@label@in@legend@for@visualizer#1#2{ \tikzdatavisualizationset{ new legend entry={ - every legend entry/.try, - every label in legend/.try, - /tikz/data visualization/every label/.try, + visualizer in legend style={/tikz/data visualization/visualizers/#1/styling/.try}, + /tikz/data visualization/every label in legend/.try, + /tikz/.cd, + every label/.try, + /tikz/data visualization/legend entry options/.cd, + setup={/data point/set=#1}, + /tikz/data visualization/visualizers/#1/label in legend options/.try, #2, - setup={/data point/visualizer=#1}, - /utils/exec=\pgfkeysgetvalue{/tikz/data visualization/legend entry options/value visualizer macro}\tikz@dv@visualizer@macro, - value visualizer={ - \scope[/tikz/data visualization/visualizers/#1/styling/.try] - \def\tikz@visualizer{#1} - \tikz@dv@visualizer@macro - \endscope - } } } } \def\tikz@dv@legend@entry@as@example{ + \pgfkeysgetvalue{/data point/set}{\tikz@visualizer} \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin} - \tikz@plot@handler + \tikz@dv@plot@handler \pgfplotstreamstart - \pgfkeysgetvalue{/tikz/data visualization/label in legend line coordinates}{\tikz@dv@temp} + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend line coordinates}{\tikz@dv@temp} \foreach \coordinate in \tikz@dv@temp { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} } \pgfplotstreamend @@ -1700,7 +2046,7 @@ \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin} \tikz@dv@plot@mark@maker \pgfplotstreamstart - \pgfkeysgetvalue{/tikz/data visualization/label in legend mark coordinates}{\tikz@dv@temp} + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend mark coordinates}{\tikz@dv@temp} \foreach \coordinate in \tikz@dv@temp { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} } \pgfplotstreamend @@ -1709,7 +2055,9 @@ \tikzdatavisualizationset{ + legend entry options/.cd, label in legend line coordinates/.initial=, + label in legend rectangle coordinates/.initial={(-1ex,-.5ex),(-1ex,0.968ex),(0ex,0.968ex),(0ex,-.5ex)}, label in legend mark coordinates/.initial=, label in legend one mark/.style={ label in legend line coordinates={}, @@ -1720,7 +2068,7 @@ label in legend mark coordinates={(-3ex,-.3ex),(-1.5ex,.3ex),(0,0)}, }, straight label in legend line/.style={ - label in legend line coordinates={(-2em,0),(0,0)}, + label in legend line coordinates={(-2em,0),(-1.5em,0),(-.5em,0),(0,0)}, label in legend mark coordinates={(-1.5em,0),(-.5em,0)}, }, zig zag label in legend line/.style={ @@ -1730,20 +2078,16 @@ circular label in legend line/.style={ label in legend line coordinates={% ([xshift=-1em]0:.9em and .35ex),% - ([xshift=-1em]30:.9em and .35ex),% - ([xshift=-1em]60:.9em and .35ex),% + ([xshift=-1em]45:.9em and .35ex),% ([xshift=-1em]90:.9em and .35ex),% - ([xshift=-1em]120:.9em and .35ex),% - ([xshift=-1em]150:.9em and .35ex),% + ([xshift=-1em]135:.9em and .35ex),% ([xshift=-1em]180:.9em and .35ex),% - ([xshift=-1em]210:.9em and .35ex),% - ([xshift=-1em]240:.9em and .35ex), + ([xshift=-1em]225:.9em and .35ex),% ([xshift=-1em]270:.9em and .35ex),% - ([xshift=-1em]300:.9em and .35ex),% - ([xshift=-1em]330:.9em and .35ex)}, + ([xshift=-1em]315:.9em and .35ex)},% label in legend mark coordinates={([xshift=-1em]120:.9em and .35ex),([xshift=-1em]-60:.9em and .35ex)}, }, - gapped circular label in legend line/.style={ + gap circular label in legend line/.style={ label in legend line coordinates={% ([xshift=-1em,yshift=.2ex]90:1.4ex and 0.9ex),% ([xshift=-1em,yshift=.2ex]162:1.4ex and 0.9ex),% @@ -1779,30 +2123,40 @@ store=/tikz/data visualization/visualizers/#1, class=plot handler visualizer, arg1=#1, - arg2={\tikz@plot@handler,\tikz@dv@plot@mark@maker} + arg2={\tikz@dv@plot@handler,\tikz@dv@plot@mark@maker} }, new visualizer={#1}{% every path/.style={draw}, style={every mark/.append style={color=visualizer color}}, - straight line, + mark size=2pt, semithick, color=visualizer color, mark=none, /tikz/data visualization/every visualize as line/.try, - }, - /data point/visualizer=#1 + }{visualizer in legend=\tikz@dv@legend@entry@as@example}, + #1={straight line} }, visualize as line/.default=line, visualize as smooth line/.style={ visualize as line={#1}, - #1={style=smooth line} + #1={smooth line} }, visualize as smooth line/.default=line, visualize as scatter/.style={ - visualize as line={#1}, - #1={style=no lines, - /tikz/data visualization/every visualize as scatter/.try}, - visualizer style sheet=cross marks + new object={ + when=after survey, + store=/tikz/data visualization/visualizers/#1, + class=plot handler visualizer, + arg1=#1, + arg2={\tikz@dv@plot@mark@maker} + }, + new visualizer={#1}{% + mark=x, + mark size=2pt, + style={every mark/.append style={color=visualizer color}}, + /tikz/data visualization/every visualize as scatter/.try, + }{visualizer in legend=\tikz@dv@legend@entry@as@example}, + #1={no lines} }, visualize as scatter/.default=scatter } @@ -1812,32 +2166,62 @@ \let\tikz@transform=\pgfutil@empty% \tikzset{solid,shift only,every mark}% \tikz@options% - \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}} + \ifx\tikz@plot@mark\pgfutil@empty% + \pgfplothandlerdiscard + \else + \pgfplothandlermark{\tikz@transform\pgfuseplotmark{\tikz@plot@mark}} + \fi } +% +% Rectangle visualizers +% + -% The following needs to be fixed... \tikzdatavisualizationset{ - new rectangles visualizer/.style={ + visualize as rectangles/.style={ new object={ + when=before survey, store=/tikz/data visualization/visualizers/#1, class=rectangle visualizer, - arg1 from key=/tikz/data visualization/#1/attribute 1, - arg2 from key=/tikz/data visualization/#1/attribute 2, - arg3=#1/use path + arg1=#1 }, - #1/attribute 1/.initial=x, - #1/attribute 2/.initial=y, - /data point/#1/use path/.initial=\pgfusepath{stroke}, - /data point/#1/style/.code=\pgfkeysalso{/data point/#1/use path={\path[every rectangles/.try,##1];}} + /data point/#1/attribute 1/.initial=x, + /data point/#1/attribute 2/.initial=y, + new visualizer={#1}{% + every path/.style={draw}, + semithick, + color=visualizer color, + /tikz/data visualization/every visualize as rectangles/.try, + }{visualizer in legend=\tikz@dv@legend@entry@as@rectangle}, + #1={} }, - rectangle visualizer/.default=rectangles + visualize as rectangles/.default=rectangles, + % + % + % + visualizer options/.cd, + attribute 1/.style={/data point/\tikz@visualizer/attribute 1=#1}, + attribute 2/.style={/data point/\tikz@visualizer/attribute 2=#1}, } +\def\tikz@dv@legend@entry@as@rectangle{ + \pgfkeysgetvalue{/data point/set}{\tikz@visualizer} + \pgfkeysvalueof{/data point/\tikz@visualizer/execute at begin} + \pgfplothandlerpolygon + \pgfplotstreamstart + \pgfkeysgetvalue{/tikz/data visualization/legend entry options/label in legend rectangle coordinates}{\tikz@dv@temp} + \foreach \coordinate in \tikz@dv@temp + { \pgfplotstreampoint{\expandafter\tikz@scan@one@point\expandafter\pgfutil@firstofone\coordinate} } + \pgfplotstreamend + \pgfkeysvalueof{/data point/\tikz@visualizer/execute at end} +} + + % @@ -1946,7 +2330,7 @@ \pgfdvdeclarestylesheet{strong colors} { - default style/.style={black}, + default style/.style={visualizer color=black}, 1/.style={visualizer color=black}, 2/.style={visualizer color=red!80!black}, 3/.style={visualizer color=blue!80!black}, @@ -1958,13 +2342,30 @@ \pgfdvdeclarestylesheet{cross marks} { - default style/.style={mark=x,every mark/.append style=thin,mark size=1.8pt}, - 1/.style={mark=x,every mark/.append style=thin,mark size=1.8pt}, - 2/.style={mark=+,every mark/.append style=thin,mark size=1.8pt}, - 3/.style={mark=Mercedes star,every mark/.append style=thin,mark size=1.8pt}, - 4/.style={mark=Mercedes star flipped,every mark/.append style=thin,mark size=1.8pt}, - 5/.style={mark=star,every mark/.append style=thin,mark size=1.8pt}, - 6/.style={mark=10-pointed star,every mark/.append style={line width=.3pt,mark size=1.6pt}} + default style/.style={mark=x,every mark/.append style=thin,mark size=2pt}, + 1/.style={mark=x,every mark/.append style=thin,mark size=2pt}, + 2/.style={mark=+,every mark/.append style=thin,mark size=2pt}, + 3/.style={mark=Mercedes star,every mark/.append style=thin,mark size=2pt}, + 4/.style={mark=Mercedes star flipped,every mark/.append style=thin,mark size=2pt}, + 5/.style={mark=star,every mark/.append style=thin,mark size=2pt}, + 6/.style={mark=10-pointed star,every mark/.append style={line width=.3pt,mark size=1.8pt}} +} + + +\pgfdvdeclarestylesheet{* mark} +{ + default style/.style={mark=*,every mark/.append style=thin,mark size=1.4pt}, +} + +\pgfdvdeclarestylesheet{dot mark} +{ + default style/.style={mark=*,every mark/.append style=thin,mark size=0.6pt}, +} + + +\pgfdvdeclarestylesheet{o mark} +{ + default style/.style={mark=o,every mark/.append style=thin,mark size=1.4pt}, } @@ -1994,9 +2395,10 @@ } } -\tikzdvdeclarestylesheetcolorseries{varying hue}{hsb}{.4,0.9,0.8}{.213,0,0} +\tikzdvdeclarestylesheetcolorseries{vary hue}{hsb}{.4,0.9,0.8}{.213,0,0} \tikzdvdeclarestylesheetcolorseries{shades of blue}{hsb}{.65,1.4,1}{0,-.4,-.0} \tikzdvdeclarestylesheetcolorseries{shades of red}{hsb}{0,1.4,1}{0,-.4,-.0} +\tikzdvdeclarestylesheetcolorseries{gray scale}{hsb}{0,0,-.34}{0,0,.34} @@ -2020,7 +2422,7 @@ new Cartesian axis=y axis, y axis={attribute=y,unit vector={(0cm,1pt)}} }, - xy axes/.style={x axis={#1},y axis={#1}}, + Xy axes/.style={x axis={#1},y axis={#1}}, uv Cartesian/.style={ new Cartesian axis=u axis, u axis={attribute=u,unit vector={(1pt,0cm)}}, @@ -2047,6 +2449,24 @@ +% +% Create a new axis system +% + +\tikzdatavisualizationset{ + new axis system/.style n args={4}{ + #1/.style={ + #2, + #1/.cd, + #3, + /tikz/data visualization/every #1/.try, + ##1, + /tikz/data visualization/.cd, + #4, + } + } +} + % The school book axes % @@ -2062,56 +2482,67 @@ % instance. \tikzdatavisualizationset{ - school book axes/.style={ + new axis system={school book axes}{% xy Cartesian, x axis={ - include values=0, + include value=0, + scaling=0 at 0 and \pgfkeysvalueof{/tikz/data visualization/school book axes/unit} at 1cm, visualize axis={y axis={goto=0},style=->,padded}, visualize ticks={common={y axis={goto=0},direction axis=y axis}, major={tick text at low, options at=0 as [{style={draw=none},no tick text}] }}, visualize grid={common={direction axis=y axis,padded}}, - ticks={step=1}, - padding=0.75em, - visualize label={visualize x axis label} + ticks={step=\pgfkeysvalueof{/tikz/data visualization/school book axes/unit}}, + padding=0.75em }, y axis={ - include values=0, + include value=0, + scaling=0 at 0 and \pgfkeysvalueof{/tikz/data visualization/school book axes/unit} at 1cm, visualize axis={x axis={goto=0},style=->,padded}, visualize ticks={ common={x axis={goto=0},direction axis=x axis}, major={tick text at low,options at=0 as [{high=0,low=0,style={draw=none},node style={anchor=north east}}]} }, visualize grid={common={direction axis=x axis,padded}}, - ticks={step=1}, - padding=0.75em, - visualize label={visualize y axis label} - }, - school book axes standard labels, - every school book axes/.try - } -} - - -% Possible axis positionings: - -\tikzdatavisualizationset{ - % + ticks={step=\pgfkeysvalueof{/tikz/data visualization/school book axes/unit}}, + padding=0.75em + } + }{% + standard labels + }{% + @make labels + }, + school book axes/.cd, + % Possible axis positionings: + % % Place labels at the ends of the axes - school book axes standard labels/.style={ - visualize x axis label/.style={ - value=padded max, - y axis={goto=0} - }, - visualize y axis label/.style={ - value=padded max, - x axis={goto=0} + % + standard labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + x axis={goto=padded max, anchor at max}, + y axis={goto=0} + } + }, + y axis={ + visualize label={ + y axis={goto=padded max, anchor at max}, + x axis={goto=0} + } + } } - } + }, + % + % Basic unit + % + unit/.initial=1, } + + % The scientific axes % % The scientific axes is a 2d plot that has a predetermined width and @@ -2119,154 +2550,163 @@ % this given rectangle. \tikzdatavisualizationset{ - scientific axes/width/.initial=5cm, - scientific axes/height/.initial=0.618*\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},% golden ratio... - scientific axes/.style={ + new axis system={scientific axes}{% xy Cartesian, every axis/.append style={style={draw=black!50}}, every ticks/.append style={style={draw=black!50}}, x axis={ length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}, - ticks={some}, - visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, - visualize ticks={common={y axis={goto=padded max},direction axis=y axis,low=0pt}}, - visualize axis={y axis={goto=padded min},padded}, - visualize axis={y axis={goto=padded max},padded}, - visualize grid={common={direction axis=y axis,padded}}, - visualize label=visualize x axis label + ticks }, y axis={ length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}, - ticks={some}, - visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, - visualize ticks={common={x axis={goto=padded max},direction axis=x axis,low=0pt}}, - visualize axis={x axis={goto=padded min},padded}, - visualize axis={x axis={goto=padded max},padded}, - visualize grid={common={direction axis=x axis,padded}}, - visualize label=visualize y axis label - }, - scientific axes standard labels, - every scientific axes/.try + ticks + } + }{% + standard labels, + outer ticks, + }{% + @make axes, + @make labels }, - scientific inner axes/.style={ - xy Cartesian, - every axis/.append style={style={draw=black!50}}, - every ticks/.append style={style={draw=black!50}}, - x axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}, - ticks={some}, - visualize ticks={common={y axis={goto=padded min},direction axis=y axis,low=0pt},major={tick text at low}}, - visualize ticks={common={y axis={goto=padded max},direction axis=y axis,high=0pt}}, - visualize axis={y axis={goto=padded min},padded}, - visualize axis={y axis={goto=padded max},padded}, - visualize grid={common={direction axis=y axis,padded}}, - visualize label=visualize x axis label - }, - y axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}, - ticks={some}, - visualize ticks={common={x axis={goto=padded min},direction axis=x axis,low=0pt},major={tick text at low}}, - visualize ticks={common={x axis={goto=padded max},direction axis=x axis,high=0pt}}, - visualize axis={x axis={goto=padded min},padded}, - visualize axis={x axis={goto=padded max},padded}, - visualize grid={common={direction axis=x axis,padded}}, - visualize label=visualize y axis label - }, - scientific axes standard labels, - every scientific axes/.try + scientific axes/.cd, + width/.initial=5cm, + height/.initial=0.618*\pgfkeysvalueof{/tikz/data visualization/scientific axes/width},% golden ratio... + outer ticks/.style={ + /tikz/data visualization/@make axes/.style={ + x axis={ + visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, + visualize ticks={common={y axis={goto=padded max},direction axis=y axis,low=0pt}}, + visualize axis={y axis={goto=padded min},padded}, + visualize axis={y axis={goto=padded max},padded}, + visualize grid={common={direction axis=y axis,padded}}, + }, + y axis={ + visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, + visualize ticks={common={x axis={goto=padded max},direction axis=x axis,low=0pt}}, + visualize axis={x axis={goto=padded min},padded}, + visualize axis={x axis={goto=padded max},padded}, + visualize grid={common={direction axis=x axis,padded}}, + } + } }, - scientific clean axes/.style={ - xy Cartesian, - x axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/width}, - ticks={some}, - visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, - visualize axis={y axis={goto=padded min}}, - visualize grid={common={direction axis=y axis}}, - visualize label=visualize x axis label, - grid={major={also at=min,also at=max}}, - }, - y axis={ - length=\pgfkeysvalueof{/tikz/data visualization/scientific axes/height}, - ticks={some}, - visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, - visualize axis={x axis={goto=padded min}}, - visualize grid={common={direction axis=x axis}}, - visualize label=visualize y axis label, - grid={major={also at=min,also at=max}}, - }, - all axes={padding=.5em}, - scientific axes standard labels, - every scientific axes/.try + inner ticks/.style={ + /tikz/data visualization/@make axes/.style={ + x axis={ + visualize ticks={common={y axis={goto=padded min},direction axis=y axis,low=0pt},major={tick text at low}}, + visualize ticks={common={y axis={goto=padded max},direction axis=y axis,high=0pt}}, + visualize axis={y axis={goto=padded min},padded}, + visualize axis={y axis={goto=padded max},padded}, + visualize grid={common={direction axis=y axis,padded}}, + }, + y axis={ + visualize ticks={common={x axis={goto=padded min},direction axis=x axis,low=0pt},major={tick text at low}}, + visualize ticks={common={x axis={goto=padded max},direction axis=x axis,high=0pt}}, + visualize axis={x axis={goto=padded min},padded}, + visualize axis={x axis={goto=padded max},padded}, + visualize grid={common={direction axis=x axis,padded}}, + } + } }, -} - - - -% Possible axis positionings: - -\tikzdatavisualizationset{ + clean/.style={ + /tikz/data visualization/@make axes/.style={ + x axis={ + visualize ticks={common={y axis={goto=padded min},direction axis=y axis,high=0pt},major={tick text at low}}, + visualize axis={y axis={goto=padded min}}, + visualize axis={y axis={goto=min}, style={black!25, line cap=rect}}, + visualize axis={y axis={goto=max}, style={black!25, line cap=rect}}, + visualize grid={common={direction axis=y axis}}, + padding=.5em, + }, + y axis={ + visualize ticks={common={x axis={goto=padded min},direction axis=x axis,high=0pt},major={tick text at low}}, + visualize axis={x axis={goto=padded min}}, + visualize axis={x axis={goto=min}, style={black!25, line cap=rect}}, + visualize axis={x axis={goto=max}, style={black!25, line cap=rect}}, + visualize grid={common={direction axis=x axis}}, + padding=.5em + }, + } + }, + % Possible axis positionings: % % Place axes labels below and left, where left label is rotated % - scientific axes standard labels/.style={ - visualize x axis label/.style={ - % Horizontal position is middle of axis: - pos=0.5, - y axis={goto=padded min}, - % Vertical position comes from bounding box: - node style={ - at={(0,0 |- data visualization bounding box.south)}, - below + standard labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + x axis={goto pos=.5}, + % Vertical position comes from bounding box: + node style={ + at={(0,0 |- data visualization bounding box.south)}, + below + } + } + }, + y axis={ + visualize label={ + y axis={goto pos=.5}, + % Horizontal position comes from bounding box: + node style={ + at={(0,0 -| data visualization bounding box.west)}, + rotate=90, + above} + } } - }, - visualize y axis label/.style={% - % Vertical position is middle of axis: - pos=0.5, - x axis={goto=padded min}, - % Horizontal position comes from bounding box: - node style={ - at={(0,0 -| data visualization bounding box.west)}, - rotate=90, - above} } }, % % Place axes labels below and left, no rotation % - scientific axes upright labels/.style={ - scientific axes standard labels, - visualize y axis label/.style={% - % Vertical position is middle of axis: - pos=0.5, - x axis={goto=padded min}, - % Horizontal position comes from bounding box: - node style={ - at={(0,0 -| data visualization bounding box.west)}, - left + upright labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + x axis={goto pos=.5}, + % Vertical position comes from bounding box: + node style={ + at={(0,0 |- data visualization bounding box.south)}, + below + } + } + }, + y axis={ + visualize label={ + y axis={goto pos=.5}, + % Horizontal position comes from bounding box: + node style={ + at={(0,0 -| data visualization bounding box.west)}, + left + } + } } } }, % % Place axes at the ends of the axes % - scientific axes end labels/.style={ - visualize x axis label/.style={ - value=max, - y axis={goto=padded min}, - % Vertical position comes from bounding box: - node style={ - at={(0,0 -| data visualization bounding box.east)}, - right - } - }, - visualize y axis label/.style={ - value=max, - x axis={goto=padded min}, - % Horizontal position comes from bounding box: - node style={ - at={(0,0 |- data visualization bounding box.north)}, - above + end labels/.style={ + /tikz/data visualization/@make labels/.style={ + x axis={ + visualize label={ + y axis={goto=padded min}, + % Vertical position comes from bounding box: + node style={ + at={(0,0 -| data visualization bounding box.east)}, + right + } + } + }, + y axis={ + visualize label={ + x axis={goto=padded min}, + % Horizontal position comes from bounding box: + node style={ + at={(0,0 |- data visualization bounding box.north)}, + above + } + } } } } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex index 8b4d99f49dd..1615f0d1bfc 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex @@ -7,21 +7,21 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex,v 1.3 2008/11/24 18:31:22 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/datavisualization/tikzlibrarydatavisualization.polar.code.tex,v 1.8 2011/05/06 11:15:33 tantau Exp $ \usetikzlibrary{datavisualization} \usepgflibrary{datavisualization.polar} \tikzdatavisualizationset{% - new polar/.style={ - new axis=angle axis, - angle axis={attribute=angle}, - new axis=radius axis, - radius axis={attribute=radius}, - radius axis/scaling/default=0 at 0 and 1 at 1cm, + new polar axes/.style 2 args={ + new axis base=#1, + #1={attribute=angle}, + new axis base=#2, + #2={attribute=radius}, + #2/scaling/default=0 at 0 and 1 at 1cm, new object={ - store=/tikz/data visualization/polar transformer, + store=/tikz/data visualization/#1/polar transformer, class=polar transformer, arg1/.expanded=\pgfkeysvalueof{/tikz/data visualization/angle axis/attribute}/scaled, arg2/.expanded=\pgfkeysvalueof{/tikz/data visualization/radius axis/attribute}/scaled, @@ -30,28 +30,530 @@ }, /tikz/data visualization/#1/unit vector 0 degrees/.initial=\pgfqpoint{1pt}{0pt}, /tikz/data visualization/#1/unit vector 90 degrees/.initial=\pgfqpoint{0pt}{1pt}, - /tikz/data visualization/#1/unit vectors/.code 2 args={ - \def\tikz@dv@polar{/tikz/data visualization/#1} - \tikz@scan@one@point\tikz@lib@dv@polar@a##1 - \tikz@scan@one@point\tikz@lib@dv@polar@b##2 - } }, - new polar/.default=polar + new polar axes/.default={angle axis}{radius axis} } \def\tikz@lib@dv@polar@a#1{ - \pgfkeyssetvalue{\tikz@dv@polar/unit vector 0 degrees}{#1} + \pgfkeyssetvalue{\tikz@dv@axis/unit vector 0 degrees}{#1} } \def\tikz@lib@dv@polar@b#1{ - \pgfkeyssetvalue{\tikz@dv@polar/unit vector 90 degrees}{#1} + \pgfkeyssetvalue{\tikz@dv@axis/unit vector 90 degrees}{#1} +} + + + +% +% Scientific polar axes +% + +\tikzset{ + /tikz/data visualization/axis options/.cd, + unit vectors/.code 2 args={ + \tikz@scan@one@point\tikz@lib@dv@polar@a#1 + \tikz@scan@one@point\tikz@lib@dv@polar@b#2 + }, + degrees/.style={\tikz@dv@axis/scaling=0 at 0 and 1 at 1}, + radians/.style={\tikz@dv@axis/scaling=0 at 0 and 0.03141592653589793 at 1.8}, +} + + + +\tikzdatavisualizationset{ + new axis system={scientific polar axes}{% + new polar axes, + angle axis={attribute=angle}, + radius axis={attribute=radius}, + every axis/.append style={style={draw=black!50}}, + every ticks/.append style={style={draw=black!50}}, + }{% + 0 to 360,% + outer ticks, + }{% + @make axes, + scientific polar axes/@setup axes, + /utils/exec={ + \edef\pgf@marshal{\noexpand\tikzdatavisualizationset{\pgfkeysvalueof{/tikz/data visualization/@which visualize radius axis}/.list={\pgfkeysvalueof{/tikz/data visualization/\pgfkeysvalueof{/tikz/data visualization/@which radius axes at}}}}} + \pgf@marshal + }, + @make labels + }, + @which radius axes at/.initial=@inner radius axes at, + @which visualize radius axis/.initial=@visualize radius axis, + @inner radius axes at/.initial=, + @clean radius axes at/.initial=, + @visualize radius axis/.style 2 args={ + radius axis={ + visualize axis={angle axis={goto=#1},high=padded max,low=0}, + visualize ticks={ + common={angle axis={goto=#1}, direction axis=angle axis}, + major={tick text at #2, + options at=0 as [{style={draw=none},no tick text}] + } + } + } + }, + @visualize clean radius axis/.style n args={5}{ + radius axis={ + visualize axis={angle + axis={goto=#1},high=max,low=0,style={black!25,line cap=rect}}, + visualize axis={angle + axis={goto=#1},high=max,low=0,style={line cap=rect,#4}}, + visualize ticks={ + style={#4}, + common={angle axis={goto=#1}, direction axis=angle axis, #3=0}, + major={tick text at #2,#5} + } + } + }, + @visualize zero/.style={@inner visualize zero={#1}}, + @clean visualize zero/.style={}, + @inner visualize zero/.style={ + radius axis={ + visualize ticks={ + common={angle axis={goto=0}, direction axis=angle axis}, + major={tick text at low,low=0,high=0,at=0 as + [{style={draw=none},node style={anchor=#1}}] + } + } + } + }, + @degrees/.style={ + angle axis={degrees, ticks={step=15, tick suffix=$^\circ$, major={ + options at=360 as [{style={draw=none},no tick text}], + options at=-180 as [{style={draw=none},no tick text}]}}} + }, + @rad/.style={ + angle axis={radians, ticks={ + step=(pi/12), + node style={ + /pgf/number format/frac, + /pgf/number format/frac shift={1} + }, + tick typesetter/.code={% + \pgfmathsetmacro{\tikz@lib@dv@pol}{round(####1*3.819718634205488)/12}% + \pgfmathapproxequalto{\tikz@lib@dv@pol}{0}% + \ifdim\pgfmathresult pt=1.0pt% + $0$% + \else% + \pgfmathapproxequalto{\tikz@lib@dv@pol}{1}% + \ifdim\pgfmathresult pt=1.0pt% + $\pi$% + \else + \pgfmathapproxequalto{\tikz@lib@dv@pol}{-1}% + \ifdim\pgfmathresult pt=1.0pt% + $-\pi$% + \else% + \pgfmathprintnumber{\tikz@lib@dv@pol}$\pi$% + \fi% + \fi% + \fi% + }, + major={ + options at=6.2831985e0 as [{style={draw=none},no tick text}], + options at=6.2831192e0 as [{style={draw=none},no tick text}], + options at=6.2830794e0 as [{style={draw=none},no tick text}], + options at=6.2828787e0 as [{style={draw=none},no tick text}], + options at=6.2831598e0 as [{style={draw=none},no tick text}], + options at=-3.1415991e0 as [{style={draw=none},no tick text}], + options at=-3.1415802e0 as [{style={draw=none},no tick text}], + options at=-3.1415602e0 as [{style={draw=none},no tick text}], + options at=-3.14153961e0 as [{style={draw=none},no tick text}], + options at=-3.1414406e0 as [{style={draw=none},no tick text}], + } + } + } + }, + @make labels/.style={}, +} + +\tikzdatavisualizationset{ + scientific polar axes/.cd, + % + % + % + outer ticks/.style={ + /tikz/data visualization/@make axes/.style={ + radius axis={ + min value=0, + length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius}, + padding=0em, + ticks={few}, + visualize grid={common={direction axis=angle axis,low=min,high=max}}, + }, + angle axis={ + visualize axis={radius axis={goto=padded max},low=min,high=max}, + visualize ticks={common={radius axis={goto=padded max},direction + axis=radius axis},common={low=0},major={tick text at high}}, + visualize grid={common={direction axis=radius axis},low=0,high=padded max}, + } + }, + /tikz/data visualization/@which radius axes at=@inner radius axes at, + /tikz/data visualization/@which visualize radius axis=@visualize radius axis, + /tikz/data visualization/@visualize zero/.style={@inner visualize zero={##1}}, + }, + inner ticks/.style={ + /tikz/data visualization/@make axes/.style={ + radius axis={ + min value=0, + length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius}, + padding=0em, + ticks={few}, + visualize grid={common={direction axis=angle axis,low=min,high=max}}, + }, + angle axis={ + visualize axis={radius axis={goto=padded max},low=min,high=max}, + visualize ticks={common={radius axis={goto=padded max},direction + axis=radius axis},common={high=0},major={tick text at high}}, + visualize grid={common={direction axis=radius axis},low=0,high=padded max}, + } + }, + /tikz/data visualization/@which radius axes at=@inner radius axes at, + /tikz/data visualization/@which visualize radius axis=@visualize radius axis, + /tikz/data visualization/@visualize zero/.style={@inner visualize zero={##1}}, + }, + clean/.style={ + /tikz/data visualization/@make axes/.style={ + radius axis={ + min value=0, + length=\pgfkeysvalueof{/tikz/data visualization/scientific polar axes/radius}, + padding=.5em, + ticks={few}, + visualize grid={common={direction axis=angle axis,low=min,high=max}}, + }, + angle axis={ + padding=.5em, + visualize axis={radius axis={goto=max}, style={black!25, line cap=rect},low=min,high=max}, + visualize axis={radius axis={goto=padded max}, style={line cap=rect}, low=min,high=max}, + visualize ticks={common={radius axis={goto=padded max}, direction axis=radius axis},common={low=0},major={tick text at high}}, + visualize grid={common={direction axis=radius axis},low=0,high=max}, + } + }, + /tikz/data visualization/@which radius axes at=@clean radius axes at, + /tikz/data visualization/@which visualize radius axis=@visualize clean radius axis, + /tikz/data visualization/@visualize zero/.style={@clean visualize zero={##1}}, + }, + radius/.initial=3.25cm, + % + % First quadrant + % + 0 to pi half/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=1.570796326794897}, + @rad, + @visualize zero=north east, + @inner radius axes at={{0}{low},{1.570796326794897}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {1.570796326794897}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + 0 to 90/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=90}, + @degrees, + @visualize zero=north east, + @inner radius axes at={{0}{low},{90}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {90}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + quadrant/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at 90, ticks}, + @visualize zero=north east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + quadrant clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 90 and max at 0, ticks}, + @visualize zero=north east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + % + % Fourth quadrant + % + -pi half to 0/.style={ + @setup axes/.style={ + angle axis={min value=-1.570796326794897, max value=0}, + @rad, + @visualize zero=south east, + @inner radius axes at={{-1.570796326794897}{low},{0}{high}}, + @clean radius axes at={% + {-1.570796326794897}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {0}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + -90 to 0/.style={ + @setup axes/.style={ + angle axis={min value=-90, max value=0}, + @degrees, + @visualize zero=south east, + @inner radius axes at={{-90}{low},{0}{high}}, + @clean radius axes at={% + {-90}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {0}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + fourth quadrant/.style={ + @setup axes/.style={ + angle axis={scaling=min at -90 and max at 0, ticks}, + @visualize zero=south east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + fourth quadrant clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at -90, ticks}, + @visualize zero=south east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding max}}{} + } + } + }, + % + % Upper half + % + 0 to pi/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=3.141592653589793}, + @rad, + @visualize zero=north, + @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {3.141592653589793}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + 0 to 180/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=180}, + @degrees, + @visualize zero=north, + @inner radius axes at={{0}{low},{90}{high},{180}{high}}, + @clean radius axes at={% + {0}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {180}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + upper half/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at 180, ticks}, + @visualize zero=north, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + upper half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 180 and max at 0, ticks}, + @visualize zero=north, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Lower half + % + lower half/.style={ + @setup axes/.style={ + angle axis={scaling=min at -180 and max at 0, ticks}, + @visualize zero=south, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + lower half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 0 and max at -180, ticks}, + @visualize zero=south, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{yshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{yshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Right half + % + -pi half to pi half/.style={ + @setup axes/.style={ + @rad, + angle axis={min value=-1.570796326794897, max value=1.570796326794897}, + @visualize zero=east, + @inner radius axes at={{0}{low},{1.570796326794897}{low},{-1.570796326794897}{high}}, + @clean radius axes at={% + {-1.570796326794897}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {1.570796326794897}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + -90 to 90/.style={ + @setup axes/.style={ + angle axis={min value=-90, max value=90}, + @degrees, + @visualize zero=east, + @inner radius axes at={{-90}{low},{0}{low},{90}{high}}, + @clean radius axes at={% + {-90}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {90}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + right half/.style={ + @setup axes/.style={ + angle axis={scaling=min at -90 and max at 90, ticks}, + @visualize zero=east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + right half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 90 and max at -90, ticks}, + @visualize zero=east, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=-\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Left half + % + left half/.style={ + @setup axes/.style={ + angle axis={scaling=min at 90 and max at 270, ticks}, + @visualize zero=west, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + left half clockwise/.style={ + @setup axes/.style={ + angle axis={scaling=min at 270 and max at 90, ticks}, + @visualize zero=west, + @inner radius axes at={{min}{low},{max}{high}}, + @clean radius axes at={% + {min}{low}{high}{xshift=-\pgfkeysvalueof{/tikz/data visualization/angle axis/padding min}}{},% + {max}{high}{low}{xshift=\pgfkeysvalueof{/tikz/data + visualization/angle axis/padding max}}{options at=0 as + [{style={draw=none}, no tick text}]} + } + } + }, + % + % Full circle + % + 0 to 2pi/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=6.283185307179586}, + @rad, + @visualize zero=north east, + @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high},{4.71238898038469}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, + -pi to pi/.style={ + @setup axes/.style={ + angle axis={min value=-3.141592653589793, max value=3.141592653589793}, + @rad, + @visualize zero=north east, + @inner radius axes at={{0}{low},{1.570796326794897}{high},{3.141592653589793}{high},{-1.57079632679489}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, + 0 to 360/.style={ + @setup axes/.style={ + angle axis={min value=0, max value=360}, + @degrees, + @visualize zero=north east, + @inner radius axes at={{0}{low},{90}{high},{180}{high},{270}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, + -180 to 180/.style={ + @setup axes/.style={ + angle axis={min value=-180, max value=180}, + @degrees, + @visualize zero=north east, + @inner radius axes at={{0}{low},{90}{high},{180}{high},{-90}{low}}, + @clean radius axes at={{0}{low}{high}{}{}} + } + }, } + + +% +% Pie-charts -- still under construction... +% + \tikzset{ /tikz/data visualization/axis options/.cd, - deg/.style={\tikz@dv@axis/scaling=0 at 0 and 360 at 360}, - rad/.style={\tikz@dv@axis/scaling=0 at 0 and pi at 180}, - grad/.style={\tikz@dv@axis/scaling=0 at 0 and 400 at 360}, - percent/.style={\tikz@dv@axis/scaling=0 at 0 and 100 at 360}, + percent/.style={\tikz@dv@axis/scaling=0 at 0 and 1 at 3.6}, full circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 360}, half circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 180}, quarter circle/.style={\tikz@dv@axis/scaling=min at 0 and max at 90} @@ -59,4 +561,5 @@ + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex deleted file mode 100644 index 7464369161c..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex +++ /dev/null @@ -1,29 +0,0 @@ -% Copyright 2010 by Till Tantau -% -% This file may be distributed and/or modified -% -% 1. under the LaTeX Project Public License and/or -% 2. under the GNU Public License. -% -% See the file doc/generic/pgf/licenses/LICENSE for more details. - -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.basic.code.tex,v 1.1 2010/10/23 16:35:41 tantau Exp $ - - - -% -% This is jsut a place-holder -% - -\tikzset{graphs/n/.initial=1} - -\tikzdefgraph{K} -{ - \pgfkeysgetvalue{/tikz/graphs/n}\tikz@lib@graph@temp@n -} -{ - [connect as=clique] - \foreach \tikz@lib@graph@temp@i in {1,...,\tikz@lib@graph@temp@n} - { \tikz@lib@graph@temp@i [at=(\tikz@lib@graph@temp@i*360/\tikz@lib@graph@temp@n:2cm)] } -} - diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex index 32fd3a374a7..c82c98c7db7 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex @@ -1,4 +1,5 @@ % Copyright 2010 by Till Tantau +% Copyright 2011 by Jannis Pohlmann % % This file may be distributed and/or modified % @@ -7,19 +8,63 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex,v 1.1 2010/10/23 16:35:41 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.code.tex,v 1.43 2013/10/10 09:08:58 tantau Exp $ % % Interface keys % -\tikzset{ - graphs/new edge directed/.code n args={3}{\path (#1) edge[->,#3] (#2);}, - graphs/new edge undirected/.code n args={3}{\path (#1) edge[-,#3] (#2);}, - graphs/new edge bidirected/.code n args={3}{\path (#1) edge[<->,#3] (#2);}, - graphs/new edge back directed/.style n args={3}{new edge directed={#2}{#1}{#3}}, - graphs/default edge kind/.initial=undirected +\def\tikzgraphsset{\pgfqkeys{/tikz/graphs}} + +\tikzgraphsset{ + new ->/.code n args={4}{% + \path [->,every new ->/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor);}, + new --/.code n args={4}{ + \path [-,every new --/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor);}, + new <->/.code n args={4}{ + \path [<->,every new <->/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor);}, + new -!-/.code n args={4}{}, + new <-/.code n args={4}{% + \path [<-,every new <-/.try] + (#1\tikzgraphleftanchor) + edge[#3] #4 + (#2\tikzgraphrightanchor); + } +} + + +\def\tikz@lib@graph@store@anchor#1#2{% + \def\tikz@temp{#1} + \ifx\tikz@temp\pgfutil@empty% + \let#2\tikz@temp% + \else% + \def\tikz@temp{.#1} + \let#2\tikz@temp% + \fi% +} + +\tikzgraphsset{ + default edge kind/.initial=--, + --/.style={default edge kind=--}, + ->/.style={default edge kind=->}, + <-/.style={default edge kind=<-}, + <->/.style={default edge kind=<->}, + -!-/.style={default edge kind=-!-}, + default edge operator/.initial=matching and star, + left anchor/.code=\tikz@lib@graph@store@anchor{#1}{\tikzgraphleftanchor}, + right anchor/.code=\tikz@lib@graph@store@anchor{#1}{\tikzgraphrightanchor}, + left anchor=, + right anchor= } @@ -28,8 +73,8 @@ % it were declared there % -\tikzset{ - graphs/use existing nodes/.code=\tikz@lib@graph@alltrue +\tikzgraphsset{ + use existing nodes/.is if=tikz@lib@graph@all } \tikzset{ @@ -37,6 +82,7 @@ \expandafter\global\expandafter\let\csname tikz@lg@node@set #1\endcsname\pgfutil@empty% }, set/.code={ + \tikz@fig@mustbenamed% \expandafter\def\expandafter\tikz@alias\expandafter{\tikz@alias% \expandafter\def\expandafter\pgf@temp\expandafter{\csname tikz@lg@node@set #1\endcsname}% \expandafter\expandafter\expandafter\pgfutil@g@addto@macro\expandafter\pgf@temp\expandafter{\expandafter\tikz@lg@do\expandafter{\tikz@fig@name}}% @@ -47,17 +93,97 @@ \newif\iftikz@lib@graph@all +% +% Simple versus multi graphs +% +\tikzgraphsset{ + simple/.code={ + \iftikz@lib@graph@simple% + % is already simple, ignore + \else + \tikz@lib@graph@simpletrue% + \pgfkeysalso{operator=\tikz@lib@graph@simple@done}% + \fi% + }, + multi/.code={ + \tikz@lib@graph@simplefalse% + } +} + +\newif\iftikz@lib@graph@simple + +\def\tikz@lib@graph@set@simple@edge#1#2#3#4#5{% + % #1 = kind (<-, ->, ...) + % #2 = from + % #3 = to + % #4 = options + % #5 = edge nodes + % + % Ok, first, test, whether edge exists: + \ifcsname tikz@lg@e@#3@#2\endcsname% + \expandafter\global\expandafter\let\csname tikz@lg@e@#3@#2\endcsname\relax% reset + \fi% + \expandafter\gdef\csname tikz@lg@e@#2@#3\endcsname{\tikz@lib@graph@make@simple@edge{#1}{#2}{#3}{#4}{#5}}% +} + +\def\tikz@lib@graph@make@simple@edge#1#2#3#4#5{% + \pgfqkeys{/tikz/graphs}{new #1={#2}{#3}{#4}{#5}}% +} + + +\def\tikz@lib@graph@simple@done{% + \tikz@lib@graph@pack@node@list% + {% + \let\tikz@lg@do\tikz@lib@graph@simple@node% + \tikz@lib@graph@node@list + }% +} + +\def\tikz@lib@graph@simple@node#1{% + {% + \def\tikz@lib@graph@simple@from@node{#1}% + \let\tikz@lg@do\tikz@lib@graph@simple@other@node% + \tikz@lib@graph@node@list% + }% +} + +\def\tikz@lib@graph@simple@other@node#1{% + \ifcsname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname% + \csname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname% + \expandafter\global\expandafter\let\csname tikz@lg@e@\tikz@lib@graph@simple@from@node @#1\endcsname\relax% + \fi% +} + + % % Basic options % -\tikzset{ - graphs/@nodes styling/.style=, - graphs/nodes/.style={/tikz/graphs/@nodes styling/.append style={,#1}}, - graphs/@edges styling/.initial=, - graphs/edges/.style={/tikz/graphs/@edges styling/.append={,#1}}, - graphs/join/.initial=match, - graphs/connect as/.initial=, +\tikzgraphsset{ + @nodes styling/.style=, + nodes/.style={/tikz/graphs/@nodes styling/.append style={,#1}}, + @edges styling/.initial=, + edges/.style={/tikz/graphs/@edges styling/.append={,#1}}, + edge/.style={edges={#1}}, + @edges node/.initial=, + edge node/.style={/tikz/graphs/@edges node/.append={#1}}, + edge label/.style={/tikz/graphs/@edges node/.append={node[auto]{#1}}}, + edge label'/.style={/tikz/graphs/@edges node/.append={node[auto,swap]{#1}}}, + @operators/.initial=, + operator/.style={/tikz/graphs/@operators/.append={#1}}, + @extra group options/.style=, +} + + +\def\tikzgraphinvokeoperator#1{% + {% + \pgfkeyslet{/tikz/graphs/@operators}\pgfutil@empty% + \pgfkeys{/tikz/graphs/.cd,#1}% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@temp% + \global\let\tikz@lib@graph@temp\tikz@lib@graph@temp% + }% + \tikz@lib@graph@temp% + \global\let\tikz@lib@graph@temp\relax% } @@ -69,25 +195,159 @@ \pgfutil@ifnextchar[{\tikz@lib@graph@parser@}{\tikz@lib@graph@parser@[]}%] } -\long\def\tikz@lib@graph@parser@[#1]#2{% - \scope[graphs/.cd,every graph/.try,#1]% - \let\tikz@lib@graph@options\pgfutil@empty% - \let\tikz@lib@graph@node@list\pgfutil@empty% - \tikz@lib@graph@parse@group{#2}% - \let\tikz@lg@do=\tikz@lib@graph@cleanup% - \tikz@lib@graph@node@list% - \endscope% +\def\tikz@lib@graph@parser@[#1]{% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \scope[graphs/.cd,@graph drawing setup/.try,@operators=,every graph/.try,#1]% + \begingroup% + \iftikz@graph@quick% + \expandafter\tikz@lib@graphs@parse@quick@graph% + \else% + \expandafter\tikz@lib@graphs@normal@main% + \fi% +} + +\long\def\tikz@lib@graphs@normal@main#1{% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@outer@operators% + \let\tikz@lib@graph@options\pgfutil@empty% + \let\tikz@lib@graph@node@list\pgfutil@empty% + \pgfkeyssetvalue{/tikz/graphs/placement/depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/width}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/level}{0}% + \tikz@lib@graph@start@hint@group% + \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@end@hint@group + \tikz@lib@graph@outer@operators% + \let\tikz@lg@do=\tikz@lib@graph@cleanup% + \tikz@lib@graph@node@list% + \tikz@lib@graph@main@done% +} + +\def\tikz@lib@graph@main@done{% + \endgroup% + \endscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% \tikz@lib@graph@parser@done% } -\long\def\tikz@lib@graph@parse@group#1{% + +\def\tikz@lib@graph@start@hint@group{% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/element count}{0}% +} + +\def\tikz@lib@graph@end@hint@group{% + % Get local depth and width outside + \xdef\tikz@lib@graph@group@depth{\pgfkeysvalueof{/tikz/graphs/placement/local depth}} + \xdef\tikz@lib@graph@group@width{\pgfkeysvalueof{/tikz/graphs/placement/local width}} +} + +\def\tikz@lib@graph@hint@aftergroup{% + \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw% + \pgfmathsetmacro\tikz@temp@h{\tikz@lib@graph@group@width+\tikz@temp@h} + \pgfmathsetmacro\tikz@temp@lh{\tikz@lib@graph@group@width+\tikz@temp@lh} + \pgfmathsetmacro\tikz@temp@lw{max(\tikz@lib@graph@group@depth,\tikz@temp@lw)} + \pgfkeyslet{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw% + % + \pgfkeysgetvalue{/tikz/graphs/placement/element count}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/element count}\tikz@temp% +} + +\def\tikz@lib@graph@placement@update{% + \pgfkeys{/tikz/graphs/placement/logical node depth/.expand once=\tikz@lib@graph@name} + \let\tikz@lib@graph@node@depth\pgfmathresult + \pgfkeys{/tikz/graphs/placement/logical node width/.expand once=\tikz@lib@graph@name} + \let\tikz@lib@graph@node@width\pgfmathresult + % This is a single node, so update the lengths accordingly + \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw% + \pgfmathsetmacro\tikz@temp@h{\tikz@lib@graph@node@width+\tikz@temp@h} + \pgfmathsetmacro\tikz@temp@lh{\tikz@lib@graph@node@width+\tikz@temp@lh} + \pgfmathsetmacro\tikz@temp@lw{max(\tikz@lib@graph@node@depth,\tikz@temp@lw)} + \pgfkeyslet{/tikz/graphs/placement/width}\tikz@temp@h% + \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw% + % + \pgfkeysgetvalue{/tikz/graphs/placement/element count}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/element count}\tikz@temp% +} + +\def\tikz@lib@graph@placement@after@chain@update{% + \pgfkeysgetvalue{/tikz/graphs/placement/depth}\tikz@temp@w% + \pgfkeysgetvalue{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeysgetvalue{/tikz/graphs/placement/local depth}\tikz@temp@lw% + \pgfmathsetmacro\tikz@temp@w{\tikz@lib@graph@chain@depth+\tikz@temp@w}% + \pgfmathsetmacro\tikz@temp@lw{\tikz@lib@graph@chain@depth+\tikz@temp@lw}% + \pgfmathsetmacro\tikz@temp@lh{max(\tikz@lib@graph@chain@width,\tikz@temp@lh)}% + \pgfkeyslet{/tikz/graphs/placement/depth}\tikz@temp@w% + \pgfkeyslet{/tikz/graphs/placement/local width}\tikz@temp@lh% + \pgfkeyslet{/tikz/graphs/placement/local depth}\tikz@temp@lw% + % + \pgfkeysgetvalue{/tikz/graphs/placement/chain count}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/chain count}\tikz@temp% +} + + +% +% Parse a group +% + +\long\def\tikz@lib@graph@parse@group#1{ + \let\tikz@lib@graph@group@qa\pgfutil@empty% + \let\tikz@lib@graph@group@q\pgfutil@empty% \let\tikz@lib@graph@group@c\pgfutil@empty% \let\tikz@lib@graph@group@cont\pgfutil@empty% \let\tikz@lib@graph@group@conta\pgfutil@empty% - \tikz@lib@graph@par#1\par\pgf@stop@eogroup% + \tikz@lib@graph@group@check#1\par\pgf@stop@eogroup% +} + + + +% +% Start of a group +% +\def\tikz@lib@graph@group@check{% + \pgfutil@ifnextchar[\tikz@lib@graph@group@opt{\tikz@lib@graph@group@opt[]}%] +} + +\def\tikz@lib@graph@group@opt[#1]{% + \let\tikz@lib@graph@parse@extras\pgfutil@empty% + \tikzgraphsset{ + @operators=, + every group/.try, + @extra group options, + @extra group options/.style=,% + #1}% + \expandafter\tikz@lib@graph@par\tikz@lib@graph@parse@extras% +} + +\tikzgraphsset{ + parse/.code={\expandafter\def\expandafter\tikz@lib@graph@parse@extras\expandafter{\tikz@lib@graph@parse@extras#1}}, } @@ -96,19 +356,95 @@ % Remove \par % -\long\def\tikz@lib@graph@par#1\par{% +\def\tikz@lib@graph@par{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@par@@}{\tikz@lib@graph@par@}% +} +\long\def\tikz@lib@graph@par@#1\par{% \pgfutil@ifnextchar\pgf@stop@eogroup{% - \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@c#1[}{% + \expandafter\tikz@lib@graph@quotes\tikz@lib@graph@group@c#1"}{% \expandafter\def\expandafter\tikz@lib@graph@group@c\expandafter{\tikz@lib@graph@group@c#1}% \tikz@lib@graph@par% }% } +\long\def\tikz@lib@graph@par@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@c\expandafter{\tikz@lib@graph@group@c{#1}}% + \tikz@lib@graph@par +} + + + +% +% Replace ..."..."... by ..."{...}"... +% +\def\tikz@lib@graph@quotes{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@quotes@@}{\tikz@lib@graph@quotes@}% +}% +\def\tikz@lib@graph@quotes@#1"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \tikz@lib@graph@passon{#1}% + }{% + \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q#1"}% + \tikz@lib@graph@quotes@cont% + }% +} + +\def\tikz@lib@graph@quotes@cont#1"#2"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \tikz@lib@graph@passon{{#1}"#2}}{% + \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q{#1}"#2"}% + \tikz@lib@graph@quotes@cont}% +} + +\def\tikz@lib@graph@quotes@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@q\expandafter{\tikz@lib@graph@group@q{#1}}% + \tikz@lib@graph@quotes% +} + + + +% +% Replace ..."..."... by ..."{...}"... (active version) +% +{ + \catcode`\"=13\relax + + \gdef\tikz@lib@graph@passon#1{\expandafter\tikz@lib@graph@quotesactive\tikz@lib@graph@group@q#1"}% + + \gdef\tikz@lib@graph@quotesactive{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@quotesactive@@}{\tikz@lib@graph@quotesactive@}% + }% + \gdef\tikz@lib@graph@quotesactive@#1"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@qa#1[% + }{% + \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa#1"}% + \tikz@lib@graph@quotesactive@cont% + }% + } + + \gdef\tikz@lib@graph@quotesactive@cont#1"#2"{% + \pgfutil@ifnextchar\pgf@stop@eogroup{% + \expandafter\tikz@lib@graph@encloser\tikz@lib@graph@group@qa{#1}"#2[}{% + \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa{#1}"#2"}% + \tikz@lib@graph@quotesactive@cont}% + } + + \gdef\tikz@lib@graph@quotesactive@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@qa\expandafter{\tikz@lib@graph@group@qa{#1}}% + \tikz@lib@graph@quotesactive% + } +} + + % % Replace ...[...]... by ...[{...}]... % -\def\tikz@lib@graph@encloser#1[{% +\def\tikz@lib@graph@encloser{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@encloser@@}{\tikz@lib@graph@encloser@}% +}% +\def\tikz@lib@graph@encloser@#1[{% \pgfutil@ifnextchar\pgf@stop@eogroup{% \expandafter\tikz@lib@graph@semi\tikz@lib@graph@group@cont#1;% }{% @@ -124,31 +460,31 @@ \tikz@lib@graph@encloser@cont}% } +\def\tikz@lib@graph@encloser@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@cont\expandafter{\tikz@lib@graph@group@cont{#1}}% + \tikz@lib@graph@encloser% +} + + + % % Replace ; by , % -\def\tikz@lib@graph@semi#1;{% +\def\tikz@lib@graph@semi{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@semi@@}{\tikz@lib@graph@semi@}% +} +\def\tikz@lib@graph@semi@#1;{% \pgfutil@ifnextchar\pgf@stop@eogroup{% - \expandafter\tikz@lib@graph@start@group\tikz@lib@graph@group@conta#1,}{% + \expandafter\tikz@lib@graph@main@parser\tikz@lib@graph@group@conta#1,}{% \expandafter\def\expandafter\tikz@lib@graph@group@conta\expandafter{\tikz@lib@graph@group@conta#1,}% \tikz@lib@graph@semi% }% } - - - -% -% Start of a group -% -\def\tikz@lib@graph@start@group{% - \pgfutil@ifnextchar[\tikz@lib@graph@start@group@opt{\tikz@lib@graph@start@group@opt[]}%] -} - -\def\tikz@lib@graph@start@group@opt[#1]{% - \pgfkeys{/tikz/graphs/.cd,connect as=,every group/.try,#1}% - \tikz@lib@graph@main@parser% +\def\tikz@lib@graph@semi@@#1{% + \expandafter\def\expandafter\tikz@lib@graph@group@conta\expandafter{\tikz@lib@graph@group@conta{#1}}% + \tikz@lib@graph@semi% } @@ -156,13 +492,26 @@ % Main parse % -\def\tikz@lib@graph@main@parser#1,{% +\def\tikz@lib@graph@main@parser{% \begingroup% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}% \let\tikz@lib@graph@stored@actions\pgfutil@empty% \let\tikz@lib@graph@node@list\pgfutil@empty% reset - \tikz@lib@graph@parse@one#1-\pgf@stop@eodashes% + \tikz@lib@graph@main@parser@start% +} +\def\tikz@lib@graph@main@parser@start{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@protect@group}{\tikz@lib@graph@main@parser@cont}% +} + +\def\tikz@lib@graph@protect@group#1{% skip space + \pgfutil@ifnextchar\relax{\tikz@lib@graph@main@parser@cont{{#1}}}{\tikz@lib@graph@main@parser@cont{{#1}}}% } +\def\tikz@lib@graph@main@parser@cont{\tikz@lib@graph@check@quotes\tikz@lib@graph@main@parser@cont@normal} +\def\tikz@lib@graph@main@parser@cont@normal#1,{% + \tikz@lib@graph@parse@one#1-\pgf@stop@eodashes% +} \def\tikz@lib@graph@parse@one{% \pgfutil@ifnextchar\bgroup\tikz@lib@graph@scope\tikz@lib@graph@node% @@ -170,10 +519,134 @@ +% Special quoted nodes + +\def\tikz@lib@graph@check@quotes#1{% + \let\tikz@lib@graph@cont@quote#1% + \pgfutil@ifnextchar"{\begingroup\pgfkeys@temptoks{}\pgfutil@empty\tikz@lib@graph@quote@parser}{\tikz@lib@graph@check@quotes@active}% +} +{ + \catcode`\"=13\relax + \gdef\tikz@lib@graph@check@quotes@active{% + \pgfutil@ifnextchar"{\begingroup\pgfkeys@temptoks{}\pgfutil@empty\tikz@lib@graph@quote@parser@active}{\tikz@lib@graph@cont@quote}% + } + \gdef\tikz@lib@graph@quote@parser@active"#1"{% + \pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks #1}% + \pgfutil@ifnextchar"{\pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks "}\tikz@lib@graph@quote@parser@active}{\tikz@lib@graph@quote@parser@done}% + } +} + +\def\tikz@lib@graph@quote@parser"#1"{% + \pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks #1}% + \pgfutil@ifnextchar"{\pgfkeys@temptoks\expandafter{\the\pgfkeys@temptoks "}\tikz@lib@graph@quote@parser}{\tikz@lib@graph@quote@parser@done}% +} + +\def\tikz@lib@graph@quote@parser@done{% + {\expandafter\scantokens\expandafter{% + \expandafter\expandafter\expandafter\tikzlibgraphactivations\expandafter\expandafter\expandafter\tikzlibgraphdoedef\expandafter{\the\pgfkeys@temptoks}% + }}% + {\expandafter\scantokens\expandafter{\expandafter\tikzlibgraphactivationsbrace\expandafter\xdef\expandafter\tikzlibgraphreplaced\expandafter<\tikzlibgraphreplaced>\catcode`\}=2\relax}}% + \edef\tikzlibgraphreplaced{\expandafter\detokenize\expandafter{\tikzlibgraphreplaced}} + \pgfutil@ifnextchar/\tikz@lib@graph@quotes@slash\tikz@lib@graph@quotes@no@slash% +} +\def\tikz@lib@graph@quotes@no@slash{% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \tikz@smuggle\expandafter\expandafter\expandafter{\expandafter\tikzlibgraphreplaced\expandafter/\expandafter{\the\pgfkeys@temptoks}}% + \expandafter\endgroup\expandafter\tikz@lib@graph@cont@quote\tikz@smuggle% +} +\def\tikz@lib@graph@quotes@slash/{% + \pgfutil@ifnextchar/% Ah, double slash... + {\tikz@lib@graph@quotes@no@slash/}{\expandafter\endgroup\expandafter\tikz@lib@graph@cont@quote\tikzlibgraphreplaced/}% +} +\def\tikzlibgraphdoedef{\xdef\tikzlibgraphreplaced} + +\def\tikz@lib@prepare@active#1#2#3{% + {% + \catcode`#1=13\relax% + \scantokens{\gdef\tikzlibgraphactivator{\def#2{@#3@}}}% + } + \pgfutil@g@addto@macro\tikzlibgraphactivations{\catcode`#1=13\relax} + \expandafter\pgfutil@g@addto@macro\expandafter\tikzlibgraphactivations\expandafter{\tikzlibgraphactivator} +} + +\let\tikzlibgraphactivations\pgfutil@empty + +% +% Remove \outer from \+ for plain TeX +% + +\outer\def\tikz@lib@outer@test{\tabalign} +\ifx\+\tikz@lib@outer@test + \def\+{\tabalign} +\fi + +\tikz@lib@prepare@active{\$}{$}{DOLLAR SIGN}% $ +\tikz@lib@prepare@active{\&}{&}{AMPERSAND}% +\tikz@lib@prepare@active{\^}{^}{CIRCUMFLEX ACCENT}% +\tikz@lib@prepare@active{\~}{~}{TILDE}% +\tikz@lib@prepare@active{\_}{_}{LOW LINE}% +\tikz@lib@prepare@active{\|}{|}{VERTICAL LINE}% +\tikz@lib@prepare@active{\[}{[}{LEFT SQUARE BRACKET}% +\tikz@lib@prepare@active{\]}{]}{RIGHT SQUARE BRACKET}% +\tikz@lib@prepare@active{\(}{(}{LEFT PARENTHESIS}% +\tikz@lib@prepare@active{\)}{)}{RIGHT PARENTHESIS}% +\tikz@lib@prepare@active{\/}{/}{SOLIDUS}% +\tikz@lib@prepare@active{\.}{.}{FULL STOP}% +\tikz@lib@prepare@active{\-}{-}{HYPHEN MINUS}% +\tikz@lib@prepare@active{\,}{,}{COMMA}% +\tikz@lib@prepare@active{\+}{+}{PLUS SIGN}% +\tikz@lib@prepare@active{\*}{*}{ASTERISK}% +\tikz@lib@prepare@active{\'}{'}{APOSTROPHE}% +\tikz@lib@prepare@active{\!}{!}{EXCLAMATION MARK}% +\tikz@lib@prepare@active{\"}{"}{QUOTATION MARK}% +\tikz@lib@prepare@active{\:}{:}{COLON}% +\tikz@lib@prepare@active{\;}{;}{SEMINCOLON}% +\tikz@lib@prepare@active{\<}{<}{LESS THAN SIGN}% +\tikz@lib@prepare@active{\=}{=}{EQUALS SIGN}% +\tikz@lib@prepare@active{\>}{>}{GREATER THAN SIGN}% +\tikz@lib@prepare@active{\?}{?}{QUESTION MARK}% +%\tikz@lib@prepare@active{\@}{@}{COMMERCIAL AT}% +\tikz@lib@prepare@active{\`}{`}{GRAVE ACCENT}% +{\catcode`\%=11\catcode`\#=11 +\tikz@lib@prepare@active{\%}{%}{PERCENT SIGN} +\tikz@lib@prepare@active{\#}{#}{NUMBER SIGN} +} + +\pgfutil@g@addto@macro\tikzlibgraphactivations{\catcode`\\=13\relax} +{ + \catcode`\|=0\relax + \catcode`\\=13\relax + |pgfutil@g@addto@macro|tikzlibgraphactivations{|def\{@REVERSE SOLIDUS@}} +} +{ + \gdef\tikzlibgraphscommercialat{@COMMERCIAL AT@} + \let\g=\pgfutil@g@addto@macro + \catcode`\@=13\relax + \g\tikzlibgraphactivations{\catcode`\@=13\relax\let@=\tikzlibgraphscommercialat} +} + +\def\tikzlibgraphactivationsbrace{% + \catcode`\{=13\relax% + \catcode`\}=13\relax% + \catcode`\<=1\relax% + \catcode`\>=2\relax% +} +{ + \catcode`\{=13\relax% + \catcode`\}=13\relax% + \catcode`\<=1\relax% + \catcode`\>=2\relax% + \pgfutil@g@addto@macro\tikzlibgraphactivationsbrace<\def{<@LEFT CURLY BRACE@>> %} + \pgfutil@g@addto@macro\tikzlibgraphactivationsbrace<\def}<@RIGHT CURLY BRACE@>> %{ +> % A normal node -\def\tikz@lib@graph@node#1-{% +% First, check for special quote syntax: + +\def\tikz@lib@graph@node{\tikz@lib@graph@check@quotes\tikz@lib@graph@node@normal} + +\def\tikz@lib@graph@node@normal#1-{% % Detect trailing < \tikz@lib@graph@@node#1<\pgf@stop% } @@ -186,7 +659,7 @@ % Syntax: node name [options] % % Grab node name - \tikz@lib@graph@grab@name#1[\pgf@stop% + \tikz@lib@graph@grab@name#1\pgf@stop% \tikz@lib@graph@stored@actions% \pgfutil@ifnextchar\pgf@stop@eodashes{% \tikz@lib@graph@graph@done% @@ -194,7 +667,7 @@ % % Now, get arrow kind % - \def\pgf@test{#2}% + \def\pgf@test{#2}% \ifx\pgf@test\pgfutil@empty% \expandafter\tikz@lib@graph@no@back@arrow% \else% @@ -206,30 +679,37 @@ \def\tikz@lib@graph@no@back@arrow{% \pgfutil@ifnextchar>\tikz@lib@graph@forward@arrow{% \pgfutil@ifnextchar-\tikz@lib@graph@undirected@arrow{% - \PackageError{graphs library}{One of the arrow types <-, --, ->, or <-> expected}{}% - \tikz@lib@graph@undirected@arrow% + \pgfutil@ifnextchar!\tikz@lib@graph@no@arrow{% + \tikzerror{One of the arrow types <-, --, ->, -!- or <-> expected}% + \tikz@lib@graph@undirected@arrow% + }% }% }% } \def\tikz@lib@graph@undirected@arrow-{% - \def\tikz@lib@graph@arrow@type{undirected}% + \def\tikz@lib@graph@arrow@type{--}% \tikz@lib@graph@after@arrow% } \def\tikz@lib@graph@forward@arrow>{% - \def\tikz@lib@graph@arrow@type{directed}% + \def\tikz@lib@graph@arrow@type{->}% \tikz@lib@graph@after@arrow% } \def\tikz@lib@graph@bi@arrow>{% - \def\tikz@lib@graph@arrow@type{bidirected}% + \def\tikz@lib@graph@arrow@type{<->}% + \tikz@lib@graph@after@arrow% +} + +\def\tikz@lib@graph@no@arrow!-{% + \def\tikz@lib@graph@arrow@type{-!-}% \tikz@lib@graph@after@arrow% } \def\tikz@lib@graph@back@arrow{% \pgfutil@ifnextchar>{\tikz@lib@graph@bi@arrow}{% - \def\tikz@lib@graph@arrow@type{back directed}% + \def\tikz@lib@graph@arrow@type{<-}% \tikz@lib@graph@after@arrow% }% } @@ -241,46 +721,62 @@ \def\tikz@lib@graph@after@arrow@opt[#1]{% % % Ok, first recolor - % - \pgfkeys{/tikz/graph node/recolor in by=in''} - \pgfkeys{/tikz/graph node/recolor out by=out'} + % + \tikzgraphinvokeoperator{recolor source by=source''} + \tikzgraphinvokeoperator{recolor target by=target'} % Save action for next node \expandafter\def\expandafter\tikz@lib@graph@stored@actions\expandafter{% \expandafter\tikz@lib@graph@joiner\expandafter{\tikz@lib@graph@arrow@type}{#1}}% + % + \tikzgdeventgroupcallback{descendants}% \tikz@lib@graph@parse@one% } \def\tikz@lib@graph@joiner#1#2{% - \pgfkeys{/tikz/graph node/recolor in by=in'} - \pgfkeys{/tikz/graph node/recolor in'' by=in} + \tikzgraphinvokeoperator{recolor source by=source'} + \tikzgraphinvokeoperator{recolor source'' by=source} {% + \tikz@enable@edge@quotes% \pgfkeyssetvalue{/tikz/graphs/default edge kind}{#1}% - \pgfkeys{/tikz/graphs/.cd,#2}% - \pgfkeysgetvalue{/tikz/graphs/join}\pgf@temp% - \expandafter\tikz@lg@do@connector\expandafter{\pgf@temp}% + \pgfkeys{/tikz/graphs/.cd,@operators=,% + /tikz/graphs/.unknown/.code=\tikz@lib@graph@unknown@edge@option{##1},#2}% + \pgfkeysgetvalue{/tikz/graphs/@operators}\pgf@temp% + \ifx\pgf@temp\pgfutil@empty% + \edef\pgf@temp{\noexpand\pgfkeys{/tikz/graphs/.cd,\pgfkeysvalueof{/tikz/graphs/default edge operator}}}% + \pgf@temp% + \pgfkeysgetvalue{/tikz/graphs/@operators}\pgf@temp% + \fi% + \pgf@temp% }% - \pgfkeys{/tikz/graph node/!in',/tikz/graph node/!out'} + \tikzgraphinvokeoperator{not source',not target'} +} + +\def\tikz@lib@graph@unknown@edge@option#1{% + \def\tikz@temp{/tikz/graphs/@edges styling/.append=} + \expandafter\expandafter\expandafter\pgfkeys% + \expandafter\expandafter\expandafter{\expandafter\tikz@temp\expandafter{\expandafter,\pgfkeyscurrentname={#1}}} } \def\tikz@lib@graph@graph@done\pgf@stop@eodashes{% + % Get local depth and width outside + \xdef\tikz@lib@graph@chain@depth{\pgfkeysvalueof{/tikz/graphs/placement/local depth}} + \xdef\tikz@lib@graph@chain@width{\pgfkeysvalueof{/tikz/graphs/placement/local width}} % Get node list outside... \expandafter% \endgroup% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% + % Compute new local depth and width of group... + \tikz@lib@graph@placement@after@chain@update + % \pgfutil@ifnextchar\pgf@stop@eogroup% \tikz@lib@graph@graph@group@done% \tikz@lib@graph@main@parser% } \def\tikz@lib@graph@graph@group@done\pgf@stop@eogroup{% - \pgfkeysgetvalue{/tikz/graphs/connect as}\tikz@lib@graph@group@connector - \expandafter\tikz@lg@do@connector\expandafter{\tikz@lib@graph@group@connector} -} - -\def\tikz@lg@do@connector#1{% - \tikzset{/tikz/connectors/.cd,#1} + \pgfkeysvalueof{/tikz/graphs/@operators}% } @@ -289,18 +785,42 @@ % Handle node % \def\tikz@lib@graph@grab@name{% - \pgfutil@ifnextchar\foreach\tikz@lib@graph@do@foreach\tikz@lib@graph@grab@name@@% + \pgfutil@ifnextchar\foreach\tikz@lib@graph@do@foreach\tikz@lib@graph@parse@node@text% +} + +\def\tikz@lib@graph@do@foreach\foreach#1in{% + \pgfutil@ifnextchar\bgroup{\tikz@lib@graph@do@foreach@normal{#1}}{\def\tikz@temp{#1}\tikz@lib@graph@do@foreach@macro}% +} +\def\tikz@lib@graph@do@foreach@macro#1{% + \expandafter\expandafter\expandafter\tikz@lib@graph@do@foreach@normal\expandafter\tikz@temp\expandafter{#1}% } -\def\tikz@lib@graph@do@foreach\foreach#1in#2#3[\pgf@stop{% +\def\tikz@lib@graph@do@foreach@normal#1#2#3\pgf@stop{% % Ok, we do a parse on a foreach loop. - % We have to make sure that we \begingroup \let\tikz@lib@graph@node@list@saved\pgfutil@empty% + \xdef\tikz@lib@graph@saved@placement{% + {\pgfkeysvalueof{/tikz/graphs/placement/local depth}}% + {\pgfkeysvalueof{/tikz/graphs/placement/local width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/chain count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/element count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/depth}}% + }% \foreach #1 in {#2}% {% \let\tikz@lib@graph@node@list\tikz@lib@graph@node@list@saved% + \expandafter\tikz@lib@graph@setup@placement\tikz@lib@graph@saved@placement% \tikz@lib@graph@parse@group{#3}% + \xdef\tikz@lib@graph@saved@placement{% + {\pgfkeysvalueof{/tikz/graphs/placement/local depth}}% + {\pgfkeysvalueof{/tikz/graphs/placement/local width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/chain count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/element count}}% + {\pgfkeysvalueof{/tikz/graphs/placement/width}}% + {\pgfkeysvalueof{/tikz/graphs/placement/depth}}% + }% + % TODO: Need to also save hints! \global\let\tikz@lib@graph@node@list@saved\tikz@lib@graph@node@list% }% \expandafter% @@ -308,37 +828,179 @@ \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list@saved}% + \expandafter\tikz@lib@graph@setup@placement\tikz@lib@graph@saved@placement% +} + +\def\tikz@lib@graph@setup@placement#1#2#3#4#5#6{% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{#1}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{#2}% + \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{#3}% + \pgfkeyssetvalue{/tikz/graphs/placement/element count}{#4}% + \pgfkeyssetvalue{/tikz/graphs/placement/width}{#5}% + \pgfkeyssetvalue{/tikz/graphs/placement/depth}{#6}% +} + +\def\tikz@lib@graph@parse@node@text#1\pgf@stop{% + % + % Ok, first test whether #1 contains "//" + % + \pgfutil@in@{//}{#1 } + \ifpgfutil@in@% + % Ok, a layout node: + \tikz@lib@parse@layout@node#1\pgf@stop% + \else% + \tikz@lib@graph@fake@nodefalse + \let\tikz@lib@graph@node@parsed\tikz@lib@graph@node@opt@normal% + \def\tikz@lib@graph@empty@node@parsed{\tikzgdeventcallback{node}{}}% + \tikz@lib@parse@normal@node#1[\pgf@stop% + \fi% +} + + +% +% Parse the normal part of a node (name and, possibly, text after slash) +% + +\def\tikz@lib@parse@normal@node#1[{ + % + % Test whether #1 contains "/" or "__" + % + \pgfutil@in@{/}{#1}% + \ifpgfutil@in@% + \tikz@lib@parse@node@with@slash#1\pgf@stop% + \else + \pgfutil@in@{__}{#1}% + \ifpgfutil@in@% + \tikz@lib@parse@node@with@doubleunder#1\pgf@stop% + \else + \pgfkeys@spdef\tikz@lib@graph@name@only{#1}% + \let\tikz@lib@graph@node@text\tikz@lib@graph@name@only% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \fi% + \fi% + \tikz@lib@graph@handle@node@cont% +} + +\def\tikz@lib@parse@node@with@slash#1/{ + \pgfkeys@spdef\tikz@lib@graph@name@only{#1}% + \ifx\tikz@lib@graph@name@only\pgfutil@empty% + \global\advance\tikz@fig@count by1\relax + \edef\tikz@lib@graph@name@only{tikz@f@\the\tikz@fig@count}% + \fi% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \pgfutil@ifnextchar"\tikz@lg@slash@quote{\pgfutil@ifnextchar\tikz@active@quotes@token\tikz@lg@slash@quote@active\tikz@lg@slash@cont} +} +\def\tikz@lg@slash@quote"#1"#2\pgf@stop{% + \iftikz@handle@active@nodes% + \def\tikz@lib@graph@node@text{\scantokens{#1}}% + \else + \def\tikz@lib@graph@node@text{#1}% + \fi% +} +{\catcode`\"=13\relax + \gdef\tikz@lg@slash@quote@active"#1"#2\pgf@stop{% + \iftikz@handle@active@nodes% + \def\tikz@lib@graph@node@text{\scantokens{#1}}% + \else + \def\tikz@lib@graph@node@text{#1}% + \fi% + } +} +\def\tikz@lg@slash@cont#1\pgf@stop{% + \iftikz@handle@active@nodes% + \def\tikz@lib@graph@node@text{\scantokens{#1}}% + \else + \def\tikz@lib@graph@node@text{#1}% + \fi% } +\def\tikz@lib@parse@node@with@doubleunder#1__{\tikz@lib@parse@node@with@slash{#1}/} -\def\tikz@lib@graph@grab@name@@#1[{% - \tikz@lib@graph@read#1\pgf@stop% - \let\tikz@lib@graph@as\tikz@lib@graph@as@default% +\def\tikz@lg@find@fresh@name{% + \edef\tikz@lib@graph@name@only{\tikz@lib@graph@name@only'}% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \tikz@lg@if@local@node{\tikz@lib@graph@name}{\tikz@lg@find@fresh@name}{}% +} + + +% +% We have now parsed everything up to the opening "[". We continue +% + +\def\tikz@lib@graph@handle@node@cont{% + \iftikz@lib@graph@fresh@node% + \tikz@lg@if@local@node{\tikz@lib@graph@name}{\tikz@lg@find@fresh@name}{}% + \fi% + \let\tikzgraphnodeas\tikzgraphnodeas@default% \pgfutil@ifnextchar\pgf@stop{% - \ifx\tikz@lib@graph@name\pgfutil@empty% + \ifx\tikz@lib@graph@name@only\pgfutil@empty% + \expandafter\tikz@lib@graph@node@empty@done% \else - \expandafter\tikz@lib@graph@noskip% + \expandafter\tikz@lib@graph@node@opt\expandafter[\expandafter]\expandafter[% \fi% }{\tikz@lib@graph@node@opt[}% } -\def\tikz@lib@graph@noskip{\tikz@lib@graph@node@opt[][}%] -\def\tikz@lib@graph@as@default{% - \let\tikzgraphnodename\tikz@lib@graph@name% +\def\tikzgraphnodeas@default{% \tikz@lib@graph@typesetter% } -\def\tikz@lib@graph@read#1\pgf@stop{% - \pgfkeys@spdef\tikz@lib@graph@name{#1}% - \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name}% +\let\tikz@lib@graph@empty@node@parsed\relax% + +\def\tikz@lib@graph@node@opt[#1]#2[\pgf@stop{% + \tikz@lib@graph@node@parsed{#1}% } +\def\tikz@lib@graph@node@empty@done\pgf@stop{\tikz@lib@graph@empty@node@parsed} -\def\tikz@lib@graph@node@opt[#1]#2[\pgf@stop{% - \ifx\tikz@lib@graph@name\tikz@lib@graph@usetext +% +% Parse a layout node +% + +\def\tikz@lib@parse@layout@node#1//{% + \pgf@lib@graph@empty@layout@nodefalse% + \let\tikz@lib@graph@node@parsed\tikz@lib@layout@node@parsed% + \let\tikz@lib@graph@empty@node@parsed\tikz@lib@graph@empty@layout@node@parsed + \tikz@lib@parse@normal@node#1[\pgf@stop% +} + +\newif\ifpgf@lib@graph@empty@layout@node + +\def\tikz@lib@layout@node@parsed{% + \tikz@lib@layout@parse@rest% +} + +\def\tikz@lib@graph@empty@layout@node@parsed{% + \pgf@lib@graph@empty@layout@nodetrue + \tikz@lib@layout@parse@rest{}% +} + +\def\tikz@lib@layout@parse@rest#1{% + \def\tikz@lib@layout@node@options{#1}% + \pgfutil@ifnextchar[{\tikz@lib@layout@node@opt}{\tikz@lib@layout@node@opt[]}%} +} + +\def\tikz@lib@layout@node@parsed#1{% + \def\tikz@lib@layout@node@options{#1}% + \pgfutil@ifnextchar[{\tikz@lib@layout@node@opt}{\tikz@lib@layout@node@opt[]}%} +} + +\def\tikz@lib@layout@node@opt[#1]{% + \def\tikz@lib@layout@options{#1}% + \pgfutil@ifnextchar\bgroup{\tikz@lib@layout@start}{\tikzerror{Opening brace at beginning of sublayout expected}}% +} + + +% +% Typeset a normal node +% + +\def\tikz@lib@graph@node@opt@normal#1{% + \expandafter\tikz@lib@graph@test@use@list\tikz@lib@graph@name@only\pgf@stop + \iftikz@lib@graph@use@list% % Ok, make a list of the nodes stored in #1: \let\tikz@lg@temp\pgfutil@empty% - \foreach \tikz@lg@node@name in {#1} {\expandafter\tikz@lib@graph@handle@use\expandafter{\tikz@lg@node@name}} + \foreach \tikz@lg@node@name in \tikz@lib@graph@use@list {\expandafter\tikz@lib@graph@handle@use\expandafter{\tikz@lg@node@name}} % Ok, now add the nodes to the node list \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% @@ -348,26 +1010,70 @@ \let\tikz@lg@do\tikz@lib@graph@do@use% \tikz@lg@temp% \else% - \expandafter\ifx\csname tikz@lib@graph@def@\tikz@lib@graph@name\endcsname\relax% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + \expandafter\ifx\csname tikz@lib@graph@def@\tikz@lib@graph@name@only\endcsname\relax% + \pgfkeysgetvalue{/tikz/graphs/placement/level}\tikz@temp% + \c@pgf@counta=\tikz@temp\relax% + \advance\c@pgf@counta by1\relax% + \edef\tikz@temp{\the\c@pgf@counta}% + \pgfkeyslet{/tikz/graphs/placement/level}\tikz@temp% + \tikzgraphsset{ + level/.try=\pgfkeysvalueof{/tikz/graphs/placement/level}, + level \pgfkeysvalueof{/tikz/graphs/placement/level}/.try + } {% \edef\tikz@lib@graph@node@list{\noexpand\tikz@lg@do{\tikz@lib@graph@name}}% + \global\tikz@lib@graph@node@createdfalse% + \pgfkeyslet{/tikz/graphs/@operators}\pgfutil@empty% + \tikz@lib@activate@source@target@edge@syntax% \tikz@lg@if@local@node{\tikz@lib@graph@name}% - {\tikzset{/tikz/graph node/.cd,in,out,#1}}% + {\tikz@lg@local@node@handle{#1}}% {% - \tikz@lg@init@color{\tikz@lib@graph@name}{\tikz@lgc@all@true\tikz@lgc@in@true\tikz@lgc@out@true}% + \tikz@lg@init@color{\tikz@lib@graph@name}{\tikz@lgc@all@true\tikz@lgc@source@true\tikz@lgc@target@true}% \iftikz@lib@graph@all% - \tikzset{/tikz/graph node/.cd,#1}% + \tikzgraphsset{#1}\pgfkeysvalueof{/tikz/graphs/@operators}% \else% - \node [name=\tikz@lib@graph@name,/tikz/graph - node/.cd,/tikz/graphs/@nodes styling,#1] - {\tikz@lib@graph@as};% + \pgfkeys{/tikz/graphs/placement/place}% + \let\tikzgraphnodetext\tikz@lib@graph@node@text% + \let\tikzgraphnodename\tikz@lib@graph@name@only% + \let\tikzgraphnodepath\tikz@lib@graph@path% + \let\tikzgraphnodefullname\tikz@lib@graph@name% + \iftikz@lib@graph@fake@node% + {% run options in protected mode... + \pgfkeys{ + /tikz/graphs/.cd,% + .unknown/.code=, + /tikz/graphs/@nodes styling,% + #1}% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@op@save% + \global\let\tikz@lib@graph@op@save\tikz@lib@graph@op@save% + }% + \else% + \node [% + name=\tikz@lib@graph@name,% + execute at end node={% + \pgfkeysgetvalue{/tikz/graphs/@operators}\tikz@lib@graph@op@save% + \global\let\tikz@lib@graph@op@save\tikz@lib@graph@op@save% + },% + graphs/redirect unknown to tikz, + /tikz/graphs/.cd,% + /tikz/graphs/@nodes styling,% + #1]% + {% + \tikzgraphnodeas% + };% + \fi% + \tikz@lib@graph@op@save\global\let\tikz@lib@graph@op@save\relax%% + \global\tikz@lib@graph@node@createdtrue% \fi }% }% + \iftikz@lib@graph@node@created\tikz@lib@graph@placement@update\fi% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{% \expandafter\tikz@lib@graph@node@list\expandafter\tikz@lg@do\expandafter{\tikz@lib@graph@name}}% + \iftikz@lib@graph@trie\tikzgraphsset{name=\tikz@lib@graph@name@only}\fi% \else % The name of the node is a graph name \tikz@lib@graph@handle@graph{#1}% @@ -375,51 +1081,227 @@ \fi% } -\def\tikz@lib@graph@handle@use#1{% - % Is #1 the name of a node set? - \expandafter\let\expandafter\pgf@temp\csname tikz@lg@node@set #1\endcsname - \ifx\pgf@temp\relax - \pgfutil@g@addto@macro\tikz@lg@temp{\tikz@lg@do{#1}} - \else% - \expandafter\pgfutil@g@addto@macro\expandafter\tikz@lg@temp\expandafter{\pgf@temp} - \fi -} - -\def\tikz@lib@graph@do@use#1{% - \tikz@lg@init@color{#1}{\tikz@lgc@all@true\tikz@lgc@in@true\tikz@lgc@out@true}% -} - -\def\tikz@lib@graph@usetext{use} +\newif\iftikz@lib@graph@fake@node -\def\tikz@lib@graph@typeset@def#1 as #2\pgf@stop{ - \def\tikz@lib@graph@typesetter#1\pgf@stop{#2} +\newif\iftikz@lib@graph@use@list +\def\tikz@lib@graph@test@use@list{% + \pgfutil@ifnextchar({\tikz@lib@graph@use@list@grap}{\tikz@lib@graph@test@use@list@done}%) } -\tikzset{ - graphs/typeset/.store in=\tikz@lib@graph@typesetter, - graphs/math nodes/.style={/tikz/graphs/typeset=$\tikzgraphnodename$}, - graphs/empty nodes/.style={/tikz/graphs/typeset=}, - graphs/typeset=\tikzgraphnodename -} +\def\tikz@lib@graph@test@use@list@done#1\pgf@stop{\tikz@lib@graph@use@listfalse} +\def\tikz@lib@graph@use@list@grap(#1)\pgf@stop{\def\tikz@lib@graph@use@list{#1}\tikz@lib@graph@use@listtrue} % -% Handle scope +% Typeset a layout node % -\def\tikz@lib@graph@scope#1{ + +\def\tikz@lib@layout@start#1#2\pgf@stop{% + \tikz@lib@ensure@gd@loaded% + % Parameters are: + % + % Node name is \tikz@lib@graph@name@only + % Node text is \tikz@lib@graph@node@text + % Node options are \tikz@lib@layout@node@options + % Layout options are \tikz@lib@layout@options + % Layout is #1 + % Rest is #2 (should be empty or just whitespace) + \tikz@lib@graph@fake@nodefalse% + \ifpgf@lib@graph@empty@layout@node% + \else% + \ifx\tikz@lib@graph@name\pgfutil@empty% + \tikzerror{Internal error: Node has no name, but it should!}% + \else + \tikz@lib@graph@fake@nodetrue% + \expandafter\tikz@lib@graph@node@opt@normal\expandafter{\tikz@lib@layout@node@options}% + \fi% + \fi% + \edef\tikz@lib@graph@name{\tikz@lib@graph@path\tikz@lib@graph@name@only}% + % + % Prepare tikz node options + % + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\tikz@lib@layout@node@options\expandafter\expandafter\expandafter{\expandafter\tikz@lib@layout@startup@node@options\tikz@lib@layout@node@options,}% \begingroup + % Create a subgraph node, if name is given. + \iftikz@lib@graph@fake@node% + \expandafter\expandafter\expandafter% + \expandafter\expandafter\expandafter\expandafter\tikz@lib@make@subgraph@node% + \expandafter\expandafter\expandafter% + \expandafter\expandafter\expandafter\expandafter{% + \expandafter\expandafter\expandafter\tikz@lib@graph@name% + \expandafter\expandafter\expandafter}% + \expandafter\expandafter\expandafter{% + \expandafter\tikz@lib@graph@node@text\expandafter}\expandafter{\tikz@lib@layout@node@options} + \fi% + % + % Here comes the scope: + % + \expandafter\expandafter\expandafter\scope\expandafter\expandafter\expandafter[\expandafter\tikz@lib@layout@node@options@prefix\tikz@lib@layout@options] + \tikzgdeventgroupcallback{array}% \let\tikz@lib@graph@node@list\pgfutil@empty% - \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@start@hint@group% + \tikz@lib@graph@parse@group{#1}% + \tikz@lib@graph@end@hint@group% + \def\tikz@lg@old@col{\tikz@lgc@source@true}% + \let\tikz@lg@new@col\pgfutil@empty% + \let\tikz@lg@do\tikz@lg@change@color% + \tikz@lib@graph@node@list% + \def\tikz@lg@old@col{\tikz@lgc@target@true}% + \tikz@lib@graph@node@list% \expandafter% + \endscope\expandafter% \endgroup% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% - \tikz@lib@graph@stored@actions% - \pgfutil@ifnextchar-{\tikz@lib@graph@scope@minus}{% + \tikz@lib@graph@hint@aftergroup% +} +\def\tikz@lib@make@subgraph@node#1#2#3{% + \pgfgdsubgraphnode{#1}{#3}{\pgfgdsubgraphnodecontents{#2}}% +} +\def\tikz@lib@layout@startup@node@options{% + /utils/exec=\tikzlibignorecomparisonsINTERNAL, + /tikz/graphs/.cd,% + redirect unknown to tikz,% + anchor=base,% + /tikz/every subgraph node/.try,% +} +\def\tikzlibignorecomparisonsINTERNAL{% + \pgfkeys{/handlers/first char syntax=true} + \pgfkeyssetvalue{/handlers/first char syntax/the character >}{\pgfutil@gobble}% + \pgfkeyssetvalue{/handlers/first char syntax/the character <}{\pgfutil@gobble}% +} +\def\tikz@lib@layout@node@options@prefix{graphs/.cd,} + +\ifx\tikz@lib@ensure@gd@loaded\pgfutil@undefined% +\def\tikz@lib@ensure@gd@loaded{\tikzerror{You must say \string\usetikzlibrary{graphdrawing} to use the (sub)layout syntax}} +\fi + +\def\tikz@lg@local@node@handle#1{% + % + % Handle late options and operators + \tikzgraphsset{source,target,.unknown/.code=,#1}% + \tikzgdlatenodeoptionacallback{\tikz@lib@graph@name}% + \node also[graphs/redirect unknown to tikz,/tikz/graphs/.cd,#1](\tikz@lib@graph@name);% + \pgfkeysvalueof{/tikz/graphs/@operators}% +} + +\tikzgraphsset{redirect unknown to tikz/.style={ + /tikz/graphs/.unknown/.code={% + \let\tikz@key\pgfkeyscurrentname% + \pgfkeys{tikz/.cd,\tikz@key={##1},/tikz/graphs/.cd}% + }} +} + +\def\tikz@lib@activate@source@target@edge@syntax{% + \pgfkeys{/handlers/first char syntax=true} + \pgfkeyssetvalue{/handlers/first char syntax/the character >}{\tikz@lg@parse@more}% + \pgfkeyssetvalue{/handlers/first char syntax/the character <}{\tikz@lg@parse@less}% +} + +\def\tikz@lg@parse@less#1{\tikz@lg@parse@less@#1\pgf@stop} +\def\tikz@lg@parse@less@<{\pgfutil@ifnextchar"{\tikz@lg@parse@quote{source}}{\tikz@lg@parse@noquote{source}}} +\def\tikz@lg@parse@more#1{\tikz@lg@parse@more@#1\pgf@stop} +\def\tikz@lg@parse@more@>{\pgfutil@ifnextchar"{\tikz@lg@parse@quote{target}}{\tikz@lg@parse@noquote{target}}} + +\def\tikz@lg@parse@noquote#1#2\pgf@stop{{\tikzgraphsset{#1 edge style={#2}}}} +\def\tikz@lg@parse@quote#1#2\pgf@stop{% + {\tikzgraphsset{/tikz/node quotes mean={#1 edge node={node [every edge quotes,##2]{##1}}},/utils/exec=\tikz@enable@node@quotes,#2}}% +} + +\tikzgraphsset{ + clear >/.style=target edge clear, + clear , - or <-> expected}{}% + \tikzerror{One of the arrow types <-, --, ->, -!-, or <-> expected}% }% }% } @@ -427,9 +1309,11 @@ \def\tikz@lib@graph@scope@minus-{ \pgfutil@ifnextchar>\tikz@lib@graph@forward@arrow{% \pgfutil@ifnextchar-\tikz@lib@graph@undirected@arrow{% - \pgfutil@ifnextchar\pgf@stop@eodashes\tikz@lib@graph@graph@done{% - \PackageError{graphs library}{One of the arrow types <-, --, ->, or <-> expected}{}% - \tikz@lib@graph@undirected@arrow% + \pgfutil@ifnextchar!\tikz@lib@graph@no@arrow{% + \pgfutil@ifnextchar\pgf@stop@eodashes\tikz@lib@graph@graph@done{% + \tikzerror{One of the arrow types <-, --, ->, -!-, or <-> expected}% + \tikz@lib@graph@undirected@arrow% + }% }% }% }% @@ -444,31 +1328,36 @@ % Predefining graphs % -\def\tikzdefgraph#1#2#3{% - \expandafter\def\csname tikz@lib@graph@def@#1\endcsname{\tikz@lib@graph@do@graph{#2}{#3}}% +\tikzgraphsset{ + declare/.code 2 args={\expandafter\def\csname tikz@lib@graph@def@#1\endcsname{\tikz@lib@graph@do@graph{#2}}}% } \def\tikz@lib@graph@handle@graph#1{% \begingroup% \let\tikz@lib@graph@node@list\pgfutil@empty% - \tikzset{graphs/.cd,#1}% - \csname tikz@lib@graph@def@\tikz@lib@graph@name\endcsname% + \tikzgraphsset{@extra group options/.style={#1}}% + \tikz@lib@graph@start@hint@group% + \csname tikz@lib@graph@def@\tikz@lib@graph@name@only\endcsname% + \tikz@lib@graph@end@hint@group% \expandafter% \endgroup% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\tikz@lib@graph@node@list% \expandafter\expandafter\expandafter{\expandafter\tikz@lib@graph@node@list\tikz@lib@graph@node@list}% + \tikz@lib@graph@hint@aftergroup% } -\def\tikz@lib@graph@do@graph#1#2{% - #1% - \tikz@lib@graph@parse@group{#2}% +\def\tikz@lib@graph@do@graph#1{% + \tikz@lib@graph@parse@group{#1}% } \let\tikz@lib@graph@path\pgfutil@empty -\tikzset{graphs/name/.code={% - \edef\tikz@lib@graph@path{#1\space\tikz@lib@graph@path}% +\tikzgraphsset{ + name separator/.store in=\tikz@lib@graph@name@separator, + name separator=\space, + name/.code={% + \edef\tikz@lib@graph@path{\tikz@lib@graph@path#1\tikz@lib@graph@name@separator}% }% } @@ -476,44 +1365,36 @@ % % Colors % - -\tikzset{ - graph node/.unknown/.code={% - \let\tikz@key\pgfkeyscurrentname% - \pgfkeys{/tikz/\tikz@key={#1}}% - }, - graph node/as/.code=\def\tikz@lib@graph@as{#1}% -} - - -\tikzset{% - new graph color/.style={% - /utils/exec=\expandafter\newif\csname iftikz@lgc@#1@\endcsname, - graph node/#1/.code={% +\def\tikz@lg@newif{\csname newif\endcsname} +\tikzgraphsset{ + as/.code=\def\tikzgraphnodeas{#1},% + color class/.style={% + /utils/exec=\expandafter\tikz@lg@newif\csname iftikz@lgc@#1@\endcsname, + #1/.style={operator={% \edef\tikz@lg@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}% \let\tikz@lg@do\tikz@lg@colorize% \tikz@lib@graph@node@list% - }, - graph node/!#1/.code={% + }}, + not #1/.style={operator={% \edef\tikz@lg@old@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}% - \def\tikz@lg@new@col{}% + \let\tikz@lg@new@col\pgfutil@empty% \let\tikz@lg@do\tikz@lg@change@color% \tikz@lib@graph@node@list% - }, - graph node/recolor #1 by/.code={% + }}, + recolor #1 by/.style={operator={% \edef\tikz@lg@old@col{\expandafter\noexpand\csname tikz@lgc@#1@true\endcsname}% \edef\tikz@lg@new@col{\expandafter\noexpand\csname tikz@lgc@##1@true\endcsname}% \let\tikz@lg@do\tikz@lg@change@color% \tikz@lib@graph@node@list% - }, - graph node/not #1/.style=!#1, + }}, + !#1/.style=not #1, }, - new graph color=in, - new graph color=in', - new graph color=in'', - new graph color=out, - new graph color=out', - new graph color=all + color class=source, + color class=source', + color class=source'', + color class=target, + color class=target', + color class=all } \def\tikz@lg@init@color#1#2{% @@ -522,6 +1403,8 @@ \def\tikz@lib@graph@cleanup#1{% \expandafter\global\expandafter\let\csname tikz@lgc@#1\endcsname\relax% + \ifcsname tikz@lgca@@#1\endcsname\expandafter\global\expandafter\let\csname tikz@lgca@@#1\endcsname\relax\fi% + \ifcsname tikz@lgcb@@#1\endcsname\expandafter\global\expandafter\let\csname tikz@lgcb@@#1\endcsname\relax\fi% } \def\tikz@lg@colorize#1{% @@ -583,7 +1466,54 @@ \def\tikz@lib@reset@temp{\let\pgf@temp\iffalse} +% +% Handle connection annotations +% +\def\tikz@lib@annotate@#1#2#3#4{% + \expandafter\ifx\csname tikz@lgc#1@@#2\endcsname\relax% + \expandafter\gdef\csname tikz@lgc#1@@#2\endcsname{{#3}{#4}}% + \else% + \expandafter\expandafter\expandafter\tikz@lib@annotate@read\csname tikz@lgc#1@@#2\endcsname{#3}{#4}% + \expandafter\global\expandafter\let\csname tikz@lgc#1@@#2\endcsname\pgf@temp% + \fi% +} +\def\tikz@lib@annotate@read#1#2#3#4{\def\pgf@temp{{#1,#3}{#2#4}}} +\tikzgraphsset{ + source edge style/.code=\tikz@lib@annotate@{a}{\tikz@lib@graph@name}{#1}{}, + source edge node/.code=\tikz@lib@annotate@{a}{\tikz@lib@graph@name}{}{#1}, + source edge clear/.code={ + \expandafter\global\expandafter\let\csname tikz@lgca@@\tikz@lib@graph@name\endcsname\relax% + }, + target edge style/.code=\tikz@lib@annotate@{b}{\tikz@lib@graph@name}{#1}{}, + target edge node/.code=\tikz@lib@annotate@{b}{\tikz@lib@graph@name}{}{#1}, + target edge clear/.code={% + \expandafter\global\expandafter\let\csname tikz@lgcb@@\tikz@lib@graph@name\endcsname\relax% + } +}% + + + +% Packing a node list: Replace the node list by a new node list where +% each node is mentioned at most once. + +\def\tikz@lib@graph@pack@node@list{% + {% + \let\tikz@lg@packed\pgfutil@empty% + \let\tikz@lg@do\tikz@lg@packer% + \tikz@lib@graph@node@list% + \expandafter + }\expandafter% + \def\expandafter\tikz@lib@graph@node@list\expandafter{\tikz@lg@packed}% +} + +\def\tikz@lg@packer#1{% + \expandafter\ifx\csname tikz@lg@p@#1\endcsname\pgf@stop% + \else% + \expandafter\let\csname tikz@lg@p@#1\endcsname\pgf@stop% + \expandafter\def\expandafter\tikz@lg@packed\expandafter{\tikz@lg@packed\tikz@lg@do{#1}} + \fi +} % % Color functions @@ -600,7 +1530,8 @@ % macro should take a single parameter, which will be set % to the node's name. -\def\tikzlibgraphforeachcolorednode#1#2{% +\def\tikzgraphforeachcolorednode#1#2{% + \tikz@lib@graph@pack@node@list% \expandafter\def\expandafter\iftikz@lib@graph@color@picker\expandafter{\csname iftikz@lgc@#1@\endcsname}% \let\tikz@lib@graph@action#2% \let\tikz@lg@do\tikz@lg@pick% @@ -619,6 +1550,7 @@ } + % Prepare a color % % #1 is the color name @@ -639,18 +1571,19 @@ % The bottom line of all this is that after a preparation you can % easily iterate over nodes having a certain color. If you wish to % iterate over a single color, it will be quicker and easier to call -% \tikzlibgraphforeachcolorednode, but if you need to iterate over two +% \tikzgraphforeachcolorednode, but if you need to iterate over two % colors simultaneously, it will be better to first prepare the color. -\def\tikzlibgraphpreparecolor#1#2#3{% +\def\tikzgraphpreparecolor#1#2#3{% \let\tikz@lib@graph@count#2% + \tikz@lib@graph@count0\relax \def\tikz@lib@graph@prefix{#3}% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@prepare% + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@prepare% } \def\tikz@lib@graph@prepare#1{% \advance\tikz@lib@graph@count by1\relax% - \expandafter\def\csname \tikz@lib@graph@prefix\the\tikz@lib@graph@count\endcsname{#1}% + \expandafter\def\csname\tikz@lib@graph@prefix\the\tikz@lib@graph@count\endcsname{#1}% } @@ -660,18 +1593,24 @@ % The bipartite connector % -\tikzset{ - connectors/bipartite/.code 2 args={ +\tikzgraphsset{ + complete bipartite/.style 2 args={operator={ \def\tikz@lg@shoreb{#2}% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@bipartite@outer + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@bipartite@outer + }}, + complete bipartite/.default={target'}{source'}, + induced complete bipartite/.style 2 args={ + induced independent set={#1}, + induced independent set={#2}, + complete bipartite={#1}{#2} }, - connectors/bipartite/.default={out'}{in'} + induced complete bipartite/.default={target'}{source'}, } \def\tikz@lib@graph@bipartite@outer#1{% \def\tikz@lib@graph@from{#1}% {% - \tikzlibgraphforeachcolorednode{\tikz@lg@shoreb}\tikz@lib@graph@bipartite@inner% + \tikzgraphforeachcolorednode{\tikz@lg@shoreb}\tikz@lib@graph@bipartite@inner% }% } @@ -682,25 +1621,51 @@ \fi% } -\def\tikz@lib@graph@default@new@edge{% +\def\tikz@lib@graph@default@new@edge#1#2{% \pgfkeysgetvalue{/tikz/graphs/@edges styling}\pgf@temp - \expandafter\tikz@lib@graph@default@new@edge@\expandafter{\pgf@temp}% + \pgfkeysgetvalue{/tikz/graphs/@edges node}\pgf@temp@b + \let\tikz@lib@add@temp\pgfutil@empty% + \tikz@lib@graph@add@edge@annotations{a}{#1} + \tikz@lib@graph@add@edge@annotations{b}{#2} + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgf@temp% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp\tikz@lib@add@temp}% + \expandafter\expandafter\expandafter\tikz@lib@graph@default@new@edge@% + \expandafter\expandafter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{\pgf@temp@b}{#1}{#2}% +} +\def\tikz@lib@graph@default@new@edge@#1#2#3#4{% + \iftikz@lib@graph@simple% + \edef\tikz@temp{{\pgfkeysvalueof{/tikz/graphs/default edge kind}}{#3}{#4}} + \expandafter\tikz@lib@graph@set@simple@edge\tikz@temp{#1}{#2}% + \else% + \pgfkeys{/tikz/graphs/.cd,new \pgfkeysvalueof{/tikz/graphs/default edge kind}={#3}{#4}{#1}{#2}}% + \fi% } -\def\tikz@lib@graph@default@new@edge@#1#2#3{% - \pgfkeys{/tikz/graphs/.cd,new edge \pgfkeysvalueof{/tikz/graphs/default edge kind}={#2}{#3}{#1}}% +\def\tikz@lib@graph@add@edge@annotations#1#2{% + \ifcsname tikz@lgc#1@@#2\endcsname% + \expandafter\let\expandafter\tikz@lg@temp@\csname tikz@lgc#1@@#2\endcsname% + \ifx\tikz@lg@temp@\relax\else + \expandafter\tikz@lib@graph@add@edge@annotations@\tikz@lg@temp@% + \let\tikz@lib@add@temp\tikz@lib@final@edge@style + \fi% + \fi% } +\def\tikz@lib@graph@add@edge@annotations@#1#2{ + \expandafter\def\expandafter\pgf@temp\expandafter{\pgf@temp,#1}% + \expandafter\def\expandafter\pgf@temp@b\expandafter{\pgf@temp@b#2}% +} +\def\tikz@lib@final@edge@style{,after source and target edge/.try} - % % The clique connector % -\tikzset{ - connectors/clique/.code={ - \tikzlibgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% - \tikz@lg@clique@loop% - }, - connectors/clique/.default=all +\tikzgraphsset{ + clique/.style={operator={ + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% + \tikz@lg@clique@loop% + }}, + clique/.default=all } \def\tikz@lg@clique@loop{% @@ -716,22 +1681,58 @@ \def\tikz@lg@clique@loop@inner{% \advance\c@pgf@countb by-1\relax% \ifnum\c@pgf@countb>0\relax% - \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@counta\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\csname tikz@lg\the\c@pgf@counta\endcsname}% \expandafter\tikz@lg@clique@loop@inner% \fi% } +% +% The independent set connector +% + +\tikzgraphsset{ + induced independent set/.style={operator={ + \pgfkeysgetvalue{/tikz/graphs/default edge kind}\tikz@lg@default% + \pgfkeyssetvalue{/tikz/graphs/default edge kind}{-!-}% + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% + \tikz@lg@indep@loop% + \pgfkeyslet{/tikz/graphs/default edge kind}\tikz@lg@default% + }}, + induced independent set/.default=all +} + +\def\tikz@lg@indep@loop{% + \ifnum\c@pgf@counta=0\relax% + \else + \c@pgf@countb=\c@pgf@counta\relax% + \tikz@lg@indep@loop@inner% + \advance\c@pgf@counta by-1\relax% + \expandafter\tikz@lg@indep@loop% + \fi% +} + +\def\tikz@lg@indep@loop@inner{% + \advance\c@pgf@countb by-1\relax% + \ifnum\c@pgf@countb>0\relax% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@counta\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}% + \expandafter\tikz@lg@indep@loop@inner% + \fi% +} + + % % The path connector % -\tikzset{ - connectors/path/.code={% - \let\tikz@lg@prev\relax% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@path@do% - }, - connectors/path/.default=all +\tikzgraphsset{ + path/.style={operator={% + \let\tikz@lg@prev\relax% + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@path@do% + }}, + path/.default=all, + induced path/.style={induced independent set={#1},path={#1}}, + induced path/.default=all, } \def\tikz@lib@graph@path@do#1{% @@ -747,17 +1748,19 @@ % The cycle connector % -\tikzset{ - connectors/cycle/.code={% +\tikzgraphsset{ + cycle/.style={operator={% \let\tikz@lg@prev\relax% \let\tikz@lg@first\relax% - \tikzlibgraphforeachcolorednode{#1}\tikz@lib@graph@cycle@do% + \tikzgraphforeachcolorednode{#1}\tikz@lib@graph@cycle@do% \ifx\tikz@lg@first\relax% \else% \tikz@lib@graph@default@new@edge{\tikz@lg@prev}{\tikz@lg@first}% \fi% - }, - connectors/cycle/.default=all + }}, + cycle/.default=all, + induced cycle/.style={induced independent set={#1},cycle={#1}}, + induced cycle/.default=all, } \def\tikz@lib@graph@cycle@do#1{% @@ -774,68 +1777,98 @@ % -% The match connector +% The matching and star connector % -\tikzset{ - connectors/match/.code 2 args={ +\tikzgraphsset{ + matching and star/.style 2 args={operator=% {% - \tikzlibgraphpreparecolor{#1}\c@pgf@counta{tikz@lg} + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg} \c@pgf@countb=0\relax% \let\tikz@lg@prev\relax - \tikzlibgraphforeachcolorednode{#2}\tikz@lib@graph@match@do% - \tikz@lib@graph@match@rest% + \tikzgraphforeachcolorednode{#2}\tikz@lib@graph@flow@do% + \tikz@lib@graph@flow@rest% }% }, - connectors/match/.default={out'}{in'} + matching and star/.default={target'}{source'} } -\def\tikz@lib@graph@match@do#1{% +\def\tikz@lib@graph@flow@do#1{% \advance\c@pgf@countb by1\relax% \ifnum\c@pgf@countb>\c@pgf@counta\relax% \c@pgf@countb=\c@pgf@counta\relax% \fi% - \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}% + \ifnum\c@pgf@countb>0\relax% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}% + \fi% \def\tikz@lg@prev{#1}% } -\def\tikz@lib@graph@match@rest{% +\def\tikz@lib@graph@flow@rest{% \ifnum\c@pgf@countb<\c@pgf@counta\relax% - \advance\c@pgf@countb by1\relax% - \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\tikz@lg@prev}% - \expandafter\tikz@lib@graph@match@rest% + \ifnum\c@pgf@countb>0\relax% + \advance\c@pgf@countb by1\relax% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\tikz@lg@prev}% + \expandafter\tikz@lib@graph@flow@rest% + \fi% \fi% } +% +% The matching connector +% + +\tikzgraphsset{ + matching/.style 2 args={operator= + {% + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg} + \c@pgf@countb=0\relax% + \tikzgraphforeachcolorednode{#2}\tikz@lib@graph@matching@do% + }% + }, + matching/.default={target'}{source'} +} + +\def\tikz@lib@graph@matching@do#1{% + \advance\c@pgf@countb by1\relax% + \ifnum\c@pgf@countb>\c@pgf@counta\relax% + \else% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{#1}% + \fi% +} + + + + + % % The butterfly connector % -\tikzset{ - connectors/butterfly/.code={ +\tikzgraphsset{ + butterfly/.style={operator= {}{% - \pgfkeys{/tikz/connectors/butterfly/.cd,#1}% - \ifnum\pgfkeysvalueof{/tikz/connectors/butterfly/level}=0\relax% - \pgfkeysalso{/tikz/connectors/match={\pgfkeysvalueof{/tikz/connectors/butterfly/from}}{\pgfkeysvalueof{/tikz/connectors/butterfly/to}}}% + \pgfkeys{/tikz/graphs/butterfly/.cd,#1}% + \ifnum\pgfkeysvalueof{/tikz/graphs/butterfly/level}=0\relax% + \tikzgraphinvokeoperator{matching and star={\pgfkeysvalueof{/tikz/graphs/butterfly/from}}{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}}% \else% {% - \tikzlibgraphpreparecolor{\pgfkeysvalueof{/tikz/connectors/butterfly/from}}\c@pgf@counta{tikz@lg} + \tikzgraphpreparecolor{\pgfkeysvalueof{/tikz/graphs/butterfly/from}}\c@pgf@counta{tikz@lg} \c@pgf@countb=0\relax% - \tikzlibgraphforeachcolorednode{\pgfkeysvalueof{/tikz/connectors/butterfly/to}}\tikz@lib@graph@butterfly@do% + \tikzgraphforeachcolorednode{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}\tikz@lib@graph@butterfly@do% }% - \iftikz@butterfly@prime\else\pgfkeysalso{/tikz/connectors/match={\pgfkeysvalueof{/tikz/connectors/butterfly/from}}{\pgfkeysvalueof{/tikz/connectors/butterfly/to}}}\fi% + \iftikz@butterfly@prime\else\tikzgraphinvokeoperator{matching and star={\pgfkeysvalueof{/tikz/graphs/butterfly/from}}{\pgfkeysvalueof{/tikz/graphs/butterfly/to}}}\fi% \fi% }% }, - connectors/butterfly/.default=, - connectors/butterfly/level/.initial=1, - connectors/butterfly/from/.initial=out', - connectors/butterfly/to/.initial=in', - connectors/butterfly'/.code={% - {}{\tikz@butterfly@primetrue\pgfkeysalso{butterfly={#1}}}}, - connectors/butterfly'/.default=, + butterfly/.default=, + butterfly/level/.initial=1, + butterfly/from/.initial=target', + butterfly/to/.initial=source', + butterfly'/.style={operator={}{\tikz@butterfly@primetrue\pgfkeysalso{butterfly={#1}}}}, + butterfly'/.default=, } \newif\iftikz@butterfly@prime @@ -843,7 +1876,7 @@ \def\tikz@lib@graph@butterfly@do#1{% \advance\c@pgf@countb by1\relax% % Compute other side... - \c@pgf@countc=\pgfkeysvalueof{/tikz/connectors/butterfly/level}\relax% + \c@pgf@countc=\pgfkeysvalueof{/tikz/graphs/butterfly/level}\relax% {% % Computer countb mod (2level) \count0=\c@pgf@countc\relax% @@ -875,3 +1908,733 @@ + +% +% The no edges connector +% +\tikzgraphsset{no edges/.style={operator=\relax}} + + + + +% +% The grid connector +% +\tikzgraphsset{ + grid/.style={operator={ + \tikzgraphpreparecolor{#1}\c@pgf@counta{tikz@lg}% + \c@pgf@countb=0\relax% + \tikzgraphpreparewrapafter% + \tikz@lg@grid@loop% + }% + }, + grid/.default=all +} + +\def\tikzgraphpreparewrapafter{% + \pgfkeysgetvalue{/tikz/graphs/wrap after}\tikz@temp% + \ifnum\tikz@temp=0\relax% + \pgfmathparse{sqrt(\tikzgraphVnum)}% + \pgfmathint{\pgfmathresult}% + \edef\tikzgraphwrapafter{\pgfmathresult}% + \else% + \edef\tikzgraphwrapafter{\tikz@temp} + \fi% +} + +\def\tikz@lg@grid@loop{% + \ifnum\c@pgf@counta=0\relax% + \else% + \advance\c@pgf@countb by 1\relax% + \pgfmathmod{\c@pgf@countb-1}{\tikzgraphwrapafter}% + \pgfmathint{\pgfmathresult}% + \ifnum\pgfmathresult>0% + \pgfmathsubtract{\c@pgf@countb}{1}% + \pgfmathint{\pgfmathresult}% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\the\c@pgf@countb\endcsname}{\csname tikz@lg\pgfmathresult\endcsname}% + \fi% + \pgfmathparse{\c@pgf@countb <= \tikzgraphwrapafter}% + \ifnum\pgfmathresult=0% + \pgfmathsubtract{\c@pgf@countb}{\tikzgraphwrapafter}% + \pgfmathint{\pgfmathresult}% + \tikz@lib@graph@default@new@edge{\csname tikz@lg\pgfmathresult\endcsname}{\csname tikz@lg\the\c@pgf@countb\endcsname}% + \fi% + \advance\c@pgf@counta by-1\relax% + \expandafter\tikz@lg@grid@loop% + \fi% +} + + + + +% Positioning +% +% It is not the job of the graph library to compute good positions for +% nodes in a graph. However, some basic support is provided for simple +% cases. +% +% The idea is at follows: Graphs are specified hierarchically. For +% instance, consider the following graph specification: +% +% graph { a, b, c -> d -> {e -> f -> g, h} -> i, j -> k } +% +% Here, we have the *group* {e->f->g,h} inside the larger graph +% specification. Each group consists of sequence of *chains* like +% e->f->g or j->k. +% +% In order to facilitate the automatic positioning of nodes, the graph +% library will provide you with information about the position of +% nodes inside their groups and chains. +% +% As a chain is being parsed, a counter stored in +% /tikz/graphs/placement/element count is available that is advanced for +% each element in the chain. +% +% Additionally, a counter stored in placement/width is +% available. This "logical" width is defined recursively as follows: The +% width of a single node is computed by calling the key +% placement/logical node width, which should return a real or logical +% width of the node passed as a parameter in the macor \pgfmathresult. The +% width of a chain is the sum of the widths of its elements. The +% width of a group is the maximum of the widths of its elements. +% +% +% Symmetrically, as a group is being constructed, a counter stored in +% placement/chain count is available that is advanced for each chain +% in the group. The number placement/depth is the defined +% recursively as follows: For a single node, the depth is +% computed by the key placement/logical node depth. The depth +% of a group is the sum of the depths of its elements. The depth of a +% chain is the maximum of the depth of its elements. +% +% +% The above keys get updated automatically. You should setup the key +% placement/compute position such that it uses the above keys to +% compute a good position for a new node based on the above +% keys. Typically, this key should execute node={shift=(...)} to setup +% the necessary shift for a new node. +% +% The key placement/compute position should not be called +% directly. Instead, the key placement/place should be used. This key +% has two effects: First, it calls placement/compute position. Second, +% it resets the length and normal counters. It will setup a completely +% new counting of lengths and counters inside the current scope. +% +% The placmenet/place key is executed automatically whenever a new +% node is automatically created. Furthermore, placement strategies +% will call this key. + +\tikzgraphsset{ + placement/.cd, + compute position/.code=\tikz@lib@graph@linear@pos, + place/.code={% + \pgfkeys{/tikz/graphs/placement/compute position}% + \aftergroup\tikz@lib@graph@reset@locals% + \pgfkeyssetvalue{/tikz/graphs/placement/element count}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/chain count}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/width}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local depth}{0}% + \pgfkeyssetvalue{/tikz/graphs/placement/local width}{0}% + }, + element count/.initial=0, + chain count/.initial=0, + depth/.initial=0, + width/.initial=0, + level/.initial=0, + logical node depth/.code=\def\pgfmathresult{1}, + logical node width/.code=\def\pgfmathresult{1}, +} + +\def\tikz@lib@graph@reset@locals{% + \gdef\tikz@lib@graph@group@depth{0}% + \gdef\tikz@lib@graph@group@width{0}% +} + + +% Arrange nodes evenly +% +% This strategy works as follows: You specify a "chain shift vector" +% and a "group shift vector". Then each new element on a chain is +% shifted by the chain shift vector relative to the previous element +% on the chain. Similarly for each new element of a group. + +\tikzgraphsset{ + Cartesian placement/.style={ + placement/place, + placement/compute position/.code=\tikz@lib@graph@linear@pos% + }, + chain shift/.initial={(1,0)}, + group shift/.initial={(0,-1)}, + grow right/.style={ + placement/place, + chain shift={(#1,0)}, + @auto anchor horizontal=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow right/.default=1, + grow left/.style={ + placement/place, + chain shift={(-#1,0)}, + @auto anchor horizontal=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow left/.default=1, + grow up/.style={ + placement/place, + chain shift={(0,#1)}, + @auto anchor horizontal=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow up/.default=1, + grow down/.style={ + placement/place, + chain shift={(0,-#1)}, + @auto anchor vertical=center, + placement/logical node width/.code=\def\pgfmathresult{1} + }, + grow down/.default=1, + branch right/.style={ + placement/place, + group shift={(#1,0)}, + @auto anchor horizontal=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch right/.default=1, + branch left/.style={ + placement/place, + group shift={(-#1,0)}, + @auto anchor horizontal=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch left/.default=1, + branch up/.style={ + placement/place, + group shift={(0,#1)}, + @auto anchor vertical=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch up/.default=1, + branch down/.style={ + placement/place, + group shift={(0,-#1)}, + @auto anchor vertical=center, + placement/logical node depth/.code=\def\pgfmathresult{1} + }, + branch down/.default=1, + % + % Sep shifts + % + grow right sep/.style={ + Cartesian placement, + chain shift={(1pt,0)}, + @auto anchor horizontal=west, + placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + grow right sep/.default=1em, + grow left sep/.style={ + Cartesian placement, + chain shift={(-1pt,0)}, + @auto anchor horizontal=east, + placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + grow left sep/.default=1em, + grow up sep/.style={ + Cartesian placement, + chain shift={(0,1pt)}, + @auto anchor vertical=south, + placement/logical node width/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + grow up sep/.default=1em, + grow down sep/.style={ + Cartesian placement, + chain shift={(0,-1pt)}, + @auto anchor vertical=north, + placement/logical node width/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + grow down sep/.default=1em, + grow right sep/.style={ + Cartesian placement, + chain shift={(1pt,0)}, + @auto anchor horizontal=west, + placement/logical node width/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + % + branch right sep/.style={ + Cartesian placement, + group shift={(1pt,0)}, + @auto anchor horizontal=west, + placement/logical node depth/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + branch right sep/.default=1em, + branch left sep/.style={ + Cartesian placement, + group shift={(-1pt,0)}, + @auto anchor horizontal=east, + placement/logical node depth/.code=\tikz@lib@graph@width@sep{##1}{#1} + }, + branch left sep/.default=1em, + branch up sep/.style={ + Cartesian placement, + group shift={(0,1pt)}, + @auto anchor vertical=south, + placement/logical node depth/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + branch up sep/.default=1em, + branch down sep/.style={ + Cartesian placement, + group shift={(0,-1pt)}, + @auto anchor vertical=north, + placement/logical node depth/.code=\tikz@lib@graph@depth@sep{##1}{#1} + }, + branch down sep/.default=1em, + % + @auto anchor horizontal/.style={ + nodes={anchor=\csname tikz@lib@graph@auto@\tikz@lib@graph@auto@h @\tikz@lib@graph@auto@v\endcsname}, + /utils/exec=\def\tikz@lib@graph@auto@h{#1} + }, + @auto anchor vertical/.style={ + nodes={anchor=\csname tikz@lib@graph@auto@\tikz@lib@graph@auto@h @\tikz@lib@graph@auto@v\endcsname}, + /utils/exec=\def\tikz@lib@graph@auto@v{#1} + }, + % + % + no placement/.style={ + placement/place, + placement/compute position/.code=% + } +} + +\def\tikz@lib@graph@auto@h{center} +\def\tikz@lib@graph@auto@v{center} + +\def\tikz@lib@graph@auto@center@center{center} +\def\tikz@lib@graph@auto@west@center{west} +\def\tikz@lib@graph@auto@east@center{east} +\def\tikz@lib@graph@auto@center@north{north} +\def\tikz@lib@graph@auto@west@north{north west} +\def\tikz@lib@graph@auto@east@north{north east} +\def\tikz@lib@graph@auto@center@south{south} +\def\tikz@lib@graph@auto@west@south{south west} +\def\tikz@lib@graph@auto@east@south{south east} + +\def\tikz@lib@graph@linear@pos{% + \pgfkeysgetvalue{/tikz/graphs/chain shift}\tikz@temp + \expandafter\tikz@scan@one@point\expandafter\pgf@process\tikz@temp + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/width}}{}}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgfkeysgetvalue{/tikz/graphs/group shift}\tikz@temp + \expandafter\tikz@scan@one@point\expandafter\pgf@process\tikz@temp + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/depth}}{}}% + \advance\pgf@xa by\pgf@x% + \advance\pgf@ya by\pgf@y% + \edef\tikz@lib@graph@shift{(\the\pgf@xa,\the\pgf@ya)} + \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}} +} + + +\def\tikz@lib@graph@width@sep#1#2{% + \pgf@process{\pgfpointdiff{\pgfpointanchor{#1}{west}}{\pgfpointanchor{#1}{east}}}% + \pgfmathparse{#2+\the\pgf@x}% +} + +\def\tikz@lib@graph@depth@sep#1#2{% + \pgf@process{\pgfpointdiff{\pgfpointanchor{#1}{south}}{\pgfpointanchor{#1}{north}}}% + \pgfmathparse{#2+\the\pgf@y}% +} + + +% Circular arrangements +% +% This strategy works a bit like the arrange evenly strategy, but in +% polar coordinates. Both for the chains and the groups you specify a +% polar shift, which must be in the form "(delta degree:delta +% distance)". For each element in a chain, the delta degree is added +% to the chain degree, likewise for each element the delta distance is +% added. Similarly for groups. +% +% There is an initial degree and radius, stored in the key "phase" and +% "radius". + +\tikzgraphsset{, + circular placement/.style={ + placement/place, + placement/compute position/.code=\tikz@lib@graph@circular@pos,% + placement/logical node depth/.code=\def\pgfmathresult{1}, + placement/logical node width/.code=\def\pgfmathresult{1}, + }, + clockwise/.style={ + circular placement, + group polar shift={(-360/#1:0)} + }, + clockwise/.default=\tikzgraphVnum, + counterclockwise/.style={ + circular placement, + group polar shift={(360/#1:0)} + }, + counterclockwise/.default=\tikzgraphVnum, + chain polar shift/.initial={(0:1cm)}, + group polar shift/.initial={(60:0)}, + radius/.initial=1cm, + phase/.initial=90, +} + +\def\tikz@lib@graph@circular@pos{% + \pgfkeysgetvalue{/tikz/graphs/chain polar shift}\tikz@temp + \expandafter\tikz@lib@graph@decompose@polar\tikz@temp% + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/width}}{}}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgfkeysgetvalue{/tikz/graphs/group polar shift}\tikz@temp + \expandafter\tikz@lib@graph@decompose@polar\tikz@temp% + \pgf@process{\pgfpointscale{\pgfkeysvalueof{/tikz/graphs/placement/depth}}{}}% + \advance\pgf@xa by\pgf@x% + \advance\pgf@ya by\pgf@y% + \pgfmathparse{\pgfkeysvalueof{/tikz/graphs/radius}}% + \advance\pgf@ya by\pgfmathresult pt% + \pgfmathsetmacro\tikz@temp{\the\pgf@xa+\pgfkeysvalueof{/tikz/graphs/phase}}% + \edef\tikz@lib@graph@shift{(\tikz@temp:\the\pgf@ya)} + \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}} +} + + +\def\tikz@lib@graph@decompose@polar(#1:#2){% + \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@y{#2}% +} + + +% Grid arrangements +% +\tikzgraphsset{ + grid placement/.style={ + placement/place, + placement/compute position/.code=\tikz@lib@graph@grid@pos,% + }, +} + + +\def\tikz@lib@graph@grid@pos{% + % + % Make sure to set \tikzgraphwrapafter before we compute + % the positions of nodes in the grid + % + \tikzgraphpreparewrapafter% + % + % find out the coordinate in the grid + % + \pgfkeysgetvalue{/tikz/graphs/placement/depth}\tikz@temp@depth% + \pgfkeysgetvalue{/tikz/graphs/placement/width}\tikz@temp@width% + \pgfmathsetmacro{\tikz@temp}{max(\tikz@temp@depth, \tikz@temp@width)}% + \pgfmathsetmacro{\tikz@temp@col}{mod(\tikz@temp,\tikzgraphwrapafter)}% + \pgfmathsetmacro{\tikz@temp@row}{div(\tikz@temp,\tikzgraphwrapafter)}% + % + % multiply row by the group shift and col by the chain shift + % + \pgfkeysgetvalue{/tikz/graphs/group shift}\tikz@temp% + \expandafter\tikz@scan@one@point\expandafter\tikz@lib@graph@grid@pos@a\tikz@temp% + \pgfkeysgetvalue{/tikz/graphs/chain shift}\tikz@temp% + \expandafter\tikz@scan@one@point\expandafter\tikz@lib@graph@grid@pos@b\tikz@temp% + % + % apply the shift + % + \edef\tikz@lib@graph@shift{(\the\pgf@xa,\the\pgf@ya)} + \pgfkeys{/tikz/graphs/nodes/.expanded={shift={\tikz@lib@graph@shift}}} +} + +\def\tikz@lib@graph@grid@pos@a#1{\pgf@process{\pgfpointscale{\tikz@temp@row}{#1}}\pgf@xa=\pgf@x\relax\pgf@ya=\pgf@y\relax} +\def\tikz@lib@graph@grid@pos@b#1{\pgf@process{\pgfpointscale{\tikz@temp@col}{#1}}% + \advance\pgf@xa by\pgf@x\relax + \advance\pgf@ya by\pgf@y\relax} + +\tikzgraphsset{ + % Grids: + wrap after/.initial=0, + % Node sets: + V/.code={% + \def\tikzgraphV{#1} + \c@pgf@counta=0\foreach \tikz@dummy in {#1} {\global\advance\c@pgf@counta by1\relax} + \edef\tikzgraphVnum{\the\c@pgf@counta} + }, + V={1}, + n/.style={V={1,...,#1},name shore V/.style={name=V}}, + W/.code={% + \def\tikzgraphW{#1} + \c@pgf@counta=0\foreach \tikz@dummy in {#1} {\global\advance\c@pgf@counta by1\relax} + \edef\tikzgraphWnum{\the\c@pgf@counta} + }, + W={1}, + m/.style={W={1,...,#1},name shore W/.style={name=W}}, + % Shores: + name shore V/.style=, + name shore W/.style=, +} + + + +% +% Quick graphs +% +% Parsing the graph syntax can take a lot of time for large +% graphs. This is mainly due to the transformation of commas and +% semicolons and all the internal bookkeeping. +% +% For large graphs, the quick graph syntax offers a greatly reduced +% syntax that will be processed much more quickly. This syntax is +% compatible with the normal graph syntax in the sense that all +% specifications written in the reduced syntax are also legal in the +% normal syntax, but not the other way round. +% +% The following rules apply: +% +% 1) A quick graph consists of a sequence of either nodes, edges sequences, or +% groups. These are separated by commas or semicolons. +% +% 2) Every node is of the form +% +% "node name"/"node text"[options] +% +% Here, the quotation marks are mandatory. The part '/"node text"' may +% be missing, in which case the node name is used as the node +% text. The options may also be missing. The node name may not contain +% any "funny" characters (unlike in the normal graph command). +% +% 3) Every edge is of the form +% +% ... ; +% +% Here, the are node specifications as described above, +% the is one of the four connectors "->", "<-", "--", and +% "<->", followed by optional options in square +% brackets. The semicolon may be replaced by a comma. +% +% 4) Every group is of the form +% +% { [options] lines }; +% +% The options are compulsory, the lines must be a sequence of nodes, +% edges, and groups as described above. The semicolon can, again, be +% replaced by a comma. +% +% +% Things that are allowed in the normal syntax, but not in the quick +% syntax, include: +% +% - Connecting a node and a group as in a->{b,c}. +% - Node names without quotation marks. +% - Using subgraphs (graph macros). +% - Using graph sets. +% - Using graph color classes. +% - Using anonymous nodes. +% - Using the "fresh nodes" option. +% - Using sublayouts. +% - Using the -!- edge connector. +% - Using the "simple" option. +% - Using edge annotations. +% +% Example: +% +% \graph [quick] { +% "a"/"$a$"[red] -> "b"[blue] -> "c"; +% "b" -> "d"; +% "c" ->[thick] "e"; +% { [same layer] "c", "d" }; +% }; +% +% + +\tikzgraphsset{quick/.is if=tikz@graph@quick} +\newif\iftikz@graph@quick + +\def\tikz@lib@graphs@parse@quick@graph{ + % Ok, we are before the initial brace. We open a group and start + % setting up some bookkeeping + \begingroup% + \global\tikz@qnode@count0\relax% + \let\tikzgraphnodepath\pgfutil@empty% + \tikz@q@outertrue% + \afterassignment\tikz@lib@graphs@quick@main\let\pgf@temp=% +} + +\newcount\tikz@qnode@count +\newif\iftikz@q@outer + +\def\tikz@lib@graphs@quick@main{% + \afterassignment\tikz@lib@graphs@quick@handle\let\pgf@let@token=% +} +\def\tikz@lib@graphs@quick@handle{% + \ifx\pgf@let@token"% + \expandafter\tikz@lib@graphs@quick@first@node% + \else% + \expandafter\tikz@lib@graphs@quick@other% + \fi% +} +\def\tikz@lib@graphs@quick@other{% + \let\tikz@next\tikz@lib@graphs@quick@error% + \ifx\pgf@let@token\egroup% + \let\tikz@next\tikz@lib@graphs@quick@end@group% + \else% + \ifx\pgf@let@token\bgroup% + \let\tikz@next\tikz@lib@graphs@quick@start@group% + \else% + \ifx\pgf@let@token\par% + \let\tikz@next\tikz@lib@graphs@quick@main% + \fi% + \fi + \fi% + \tikz@next% +} + +\def\tikz@lib@graphs@quick@error#1{\tikzerror{Unexpected token '\string#1' in quick graph syntax}\tikz@lib@graphs@quick@main} +\def\tikz@lib@graphs@quick@start@group{% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@start@group@{\tikzerror{Group + in quick graph syntax must start with options.}} +} + +\def\tikz@lib@graphs@quick@start@group@[#1]{% + \begingroup% + \tikz@q@outerfalse% + \tikzgraphsset{#1}% + \tikz@lib@graphs@quick@main% +} +\def\tikz@lib@graphs@quick@end@group{% + \iftikz@q@outer% + \endgroup% + % Ok, cleanup! + \pgfutil@loop% + \ifnum\tikz@qnode@count>0\relax% + \expandafter\global\expandafter\let\csname tikz@gr@q@@\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\endcsname\relax% + \expandafter\global\expandafter\let\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\relax% + \global\advance\tikz@qnode@count by-1\relax% + \pgfutil@repeat% + \expandafter\tikz@lib@graph@main@done% + \else% + \endgroup% + \expandafter\tikz@lib@graphs@end@group@% + \fi% +} +\def\tikz@lib@graphs@end@group@{% + \pgfutil@ifnextchar;{\expandafter\tikz@lib@graphs@quick@main\pgfutil@gobble}{% + \pgfutil@ifnextchar,{\expandafter\tikz@lib@graphs@quick@main\pgfutil@gobble}{% + \tikzerror{Graph groups in quick syntax must be followed by a semicolon or a comma.}% + }% + }% +} + + +\def\tikz@lib@graphs@quick@first@node{% + \let\tikz@quick@prev@node\relax% + \tikz@lib@graphs@quick@node% +} + +\def\tikz@lib@graphs@quick@node#1"{% + \def\tikzgraphnodename{#1}% + \pgfutil@ifnextchar/\tikz@lib@graphs@quick@text\tikz@lib@graphs@quick@notext% +} +\def\tikz@lib@graphs@quick@text/"#1"{% + \def\tikzgraphnodetext{#1}% + \tikz@lib@graphs@quick@opt% +} +\def\tikz@lib@graphs@quick@notext{% + \let\tikzgraphnodetext\tikzgraphnodename% + \tikz@lib@graphs@quick@opt% +} +\def\tikz@lib@graphs@quick@opt{% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@withopt{\tikz@lib@graphs@quick@withopt[]}%] +} +\def\tikz@lib@graphs@quick@withopt[#1]{% + % Test, whether node already exists + \expandafter\ifx\csname tikz@gr@q@@\tikzgraphnodename\endcsname\relax% + % New node + \global\advance\tikz@qnode@count by1\relax% + \expandafter\global\expandafter\let\csname tikz@gr@q@@\tikzgraphnodename\endcsname\pgfutil@empty% not relax + \expandafter\global\expandafter\let\csname tikz@gr@qn@@\the\tikz@qnode@count\endcsname\tikzgraphnodename% back pointer + \let\tikzgraphnodefullname\tikzgraphnodename% + \let\tikzgraphnodeas\tikzgraphnodeas@default% + \node [% + name=\tikzgraphnodename,% + graphs/redirect unknown to tikz, + /tikz/graphs/.cd,% + /tikz/graphs/@nodes styling,% + #1]% + {% + \tikzgraphnodeas% + };% + \else% + % + % Handle late options and operators + \tikzgdlatenodeoptionacallback{\tikzgraphnodename}% + \node also[graphs/redirect unknown to tikz,/tikz/graphs/.cd,#1](\tikzgraphnodename);% + \fi% + % Connect, if necessary + \tikz@lig@graph@quikc@make@edge@if@necessary% + \tikz@lib@graphs@quick@scan@after@node% +} + +\def\tikz@lig@graph@quikc@make@edge@if@necessary{% + \ifx\tikz@quick@prev@node\relax% + \else% + \tikz@lib@graphs@quick@make@edge% + \fi% +} + +\def\tikz@lib@graphs@quick@scan@after@node{% + \pgfutil@ifnextchar,\tikz@lib@graphs@quick@comma{% + \pgfutil@ifnextchar;\tikz@lib@graphs@quick@semi{% + \pgfutil@ifnextchar\egroup{\tikz@lib@graphs@quick@semi;}{% + \pgfutil@ifnextchar\par{\expandafter\tikz@lib@graphs@quick@scan@after@node\tikz@lib@graphs@quick@gobble@par}% + \tikz@lib@graphs@quick@connector}}}% +} +\long\def\tikz@lib@graphs@quick@gobble@par#1{}% + +\def\tikz@lib@graphs@quick@comma,{\tikz@lib@graphs@quick@main} +\def\tikz@lib@graphs@quick@semi;{\tikz@lib@graphs@quick@main} +\def\tikz@lib@graphs@quick@connector#1#2{% + \def\tikz@lib@graphs@quick@edge@kind{#1#2}% + \pgfutil@ifnextchar>\tikz@lib@graphs@back@edge{% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@connector@handle@opt{\tikz@lib@graphs@quick@connector@handle@opt[]}%] + }% +} +\def\tikz@lib@graphs@back@edge#1{% + \expandafter\def\expandafter\tikz@lib@graphs@quick@edge@kind\expandafter{\tikz@lib@graphs@quick@edge@kind#1}% + \pgfutil@ifnextchar[\tikz@lib@graphs@quick@connector@handle@opt{\tikz@lib@graphs@quick@connector@handle@opt[]}%] +} +\def\tikz@lib@graphs@quick@connector@handle@opt[#1]{% + \def\tikz@lib@graphs@quick@edge@options{#1}% + \let\tikz@quick@prev@node\tikzgraphnodename% + \tikz@lib@graphs@quick@scan@after@connector% +} +\def\tikz@lib@graphs@quick@scan@after@connector{% + \pgfutil@ifnextchar\par{\expandafter\tikz@lib@graphs@quick@scan@after@connector\tikz@lib@graphs@quick@gobble@par}{% + \pgfutil@ifnextchar"{\expandafter\tikz@lib@graphs@quick@node\pgfutil@gobble}{% + \tikzerror{Quotation marks expected after edge connector}% + }% + }% +} + +\def\tikz@lib@graphs@quick@make@edge{% + { + \expandafter\tikz@lib@graphs@quick@make@edge@styling\expandafter{\tikz@lib@graphs@quick@edge@options}% + \expandafter\expandafter\expandafter\tikz@lib@graphs@quick@make@edge@for% + \expandafter\expandafter\expandafter{\expandafter\tikz@quick@prev@node\expandafter}\expandafter{\tikzgraphnodename}% + } +} + +\def\tikz@lib@graphs@quick@make@edge@styling#1{% + \tikz@enable@edge@quotes% + \tikzgraphsset{.unknown/.code=\tikz@lib@graph@unknown@edge@option{##1},#1}% +} + +\def\tikz@lib@graphs@quick@make@edge@for#1#2{% + \pgfkeysgetvalue{/tikz/graphs/@edges styling}\pgf@tempa + \pgfkeysgetvalue{/tikz/graphs/@edges node}\pgf@temp@b + \expandafter\expandafter\expandafter\tikz@lib@graphs@quick@make@edge@for@with% + \expandafter\expandafter\expandafter{\expandafter\pgf@tempa\expandafter}\expandafter{\pgf@temp@b}{#1}{#2}% +} + +\def\tikz@lib@graphs@quick@make@edge@for@with#1#2#3#4{% + \tikzgraphsset{new \tikz@lib@graphs@quick@edge@kind={#3}{#4}{#1}{#2}}% +} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex new file mode 100644 index 00000000000..a56702bcf96 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex @@ -0,0 +1,112 @@ +% Copyright 2010 by Till Tantau +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/graphs/tikzlibrarygraphs.standard.code.tex,v 1.9 2012/02/27 20:00:11 tantau Exp $ + + +% +% Basic graphs +% + + +\tikzgraphsset{ + % + % An independent set $V$ of nodes. + % + declare={subgraph I_n}% + { + \foreach \tikz@lib@graph@node@num in \tikzgraphV + { \tikz@lib@graph@node@num } + }, + % + % An two-shore independent set $V$ with shores V and W. + % + declare={subgraph I_nm}% + { + subgraph I_n [name shore V] -- [no edges] + subgraph I_n [name shore W, V/.expand once=\tikzgraphW] + }, + % + % The complete clique on $V$. + % + declare={subgraph K_n}% + { + [clique] + subgraph I_n + }, + % + % A complete bipartite graph with shores V and W. + % + declare={subgraph K_nm}% + { + [color class=shore V, + color class=shore W, + complete bipartite={shore V}{shore W}] + subgraph I_n [name shore V, shore V] -- [no edges] + subgraph I_n [name shore W, V/.expand once=\tikzgraphW, shore W] + }, + % + % A cycle with n nodes. + % + declare={subgraph C_n}% + { + [cycle] + subgraph I_n + }, + % + % A path with n nodes. + % + declare={subgraph P_n}% + { + [path] + subgraph I_n + }, + % + % A grid with n nodes. + % + declare={subgraph Grid_n}% + { + [grid] + subgraph I_n + }, + % + % A random graph according to the G_{n,p} model: For each pair of + % vertices there is an edge between them with probability p. + % + p/.initial=0.5, + declare={subgraph G_np}% + { + [/utils/exec={ + \pgfmathsetmacro\tikz@lib@lg@p{\pgfkeysvalueof{/tikz/graphs/p}} + \let\tikz@lib@gnp@edges\pgfutil@empty% + \foreach \tikz@lib@graph@node@a [count=\tikz@lib@g@count@a] in \tikzgraphV + \foreach \tikz@lib@graph@node@b [count=\tikz@lib@g@count@b] in \tikzgraphV + { + \ifnum\tikz@lib@g@count@a<\tikz@lib@g@count@b\relax + \pgfmathparse{rnd} + \ifdim\pgfmathresult pt<\tikz@lib@lg@p pt% + \ifx\tikz@lib@gnp@edges\pgfutil@empty + \xdef\tikz@lib@gnp@edges{\tikz@lib@graph@node@a--\tikz@lib@graph@node@b}% + \else + \xdef\tikz@lib@gnp@edges{\tikz@lib@gnp@edges,\tikz@lib@graph@node@a--\tikz@lib@graph@node@b}% + \fi + \fi + \fi + } + }] + \foreach \tikz@lg@temp in \tikz@lib@gnp@edges { + [parse/.expand once=\tikz@lg@temp] + } + }, +} + + + + diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex index 8c22215eda4..fc01637466b 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzexternalshared.code.tex @@ -26,8 +26,8 @@ \toksdef\t@tikzexternal@tmpa=0 \toksdef\t@tikzexternal@tmpb=1 -\newwrite\tikzexternal@outfile \newif\iftikzexternal@nestedflag +\newif\iftikzexternal@verboseuptodate \newif\iftikzexternal@verboseio \newif\iftikzexternal@genfigurelist \newif\iftikzexternal@onlynamed @@ -112,6 +112,9 @@ \pgfqkeys{/tikz/external}{ figure list/.is if=tikzexternal@genfigurelist, aux in dpth/.style={/pgf/images/aux in dpth=#1},% + disable dependency files/.code={% + \let\tikzexternalfiledependsonfile@ACTIVE=\tikzexternalfiledependsonfile + }, % 'mode' applies only if \jobname==real job name. mode/.is choice, mode/only graphics/.code = {% @@ -148,9 +151,11 @@ verbose IO/.default=true, verbose IO=true, verbose optimize/.is if=tikzexternal@verbose@optimize, + verbose up to date/.is if=tikzexternal@verboseuptodate, verbose/.style={ verbose IO=#1, verbose optimize=#1, + verbose up to date=#1, }, shell escape/.initial=-shell-escape, read main aux/.is if=pgfexternalreadmainaux, @@ -249,6 +254,12 @@ \expandafter\gdef\csname c@tikzext@no@#1\endcsname{0}% },% prefix/.code={\tikzsetexternalprefix{#1}}, + up to date check/.is choice, + up to date check/simple/.code={\def\tikzexternal@uptodate@mode{0}}, + % md5 relies on \pdfmdfivesum of pdftex. It uses 'diff' as fallback if we do not have that command. + up to date check/md5/.code={\def\tikzexternal@uptodate@mode{1}}, + up to date check/diff/.code={\def\tikzexternal@uptodate@mode{2}}, + up to date check=md5, } \def\tikzsetfigurename#1{\pgfkeyssetvalue{/tikz/external/figure name}{#1}}% @@ -325,6 +336,14 @@ } \def\tikzexternalize@hasbeencalled{0}% +\def\tikzifexternalizehasbeencalled#1#2{% + \if1\tikzexternalize@hasbeencalled + #1% + \else + #2% + \fi +}% + % If mode=`convert with system call', the boolean \ifpgfexternalreadmainaux % will be set depending on the current lock file. % @@ -710,6 +729,7 @@ \def\tikzexternalgetnextfilename#1{% \begingroup \let\tikzexternal@getnextfilename@advancecount\relax% NOP + \let\tikzexternal@getnextfilename@resetglobals=\relax% NOP \def\tikzexternal@protocol@to@file##1{}% NOP \tikzexternal@getnextfilename#1% \pgfmath@smuggleone#1% @@ -774,11 +794,15 @@ \fi \fi % + \tikzexternal@getnextfilename@resetglobals% + % + \tikzexternal@protocol@to@file#1% +}% + +\def\tikzexternal@getnextfilename@resetglobals{% % Reset global flags: \global\let\tikzexternal@nextfile=\pgfutil@empty \global\tikzexternalexportnexttrue - % - \tikzexternal@protocol@to@file#1% }% % #1: the image file name which should be protocolled. (can be a @@ -792,6 +816,11 @@ \else \pgfutil@ifundefined{tikzexternal@listmode@openedfile}{% \message{Opening '\tikzexternal@realjob.figlist' for writing.}% + \begingroup + \globaldefs=1 + % this gets round '\outer\newwrite' in plain TeX: + \csname newwrite\endcsname\tikzexternal@outfile + \endgroup \immediate\openout\tikzexternal@outfile=\tikzexternal@realjob.figlist\relax \gdef\tikzexternal@listmode@openedfile{1}% \if\tikzexternal@opmode5% mode='list and make' @@ -812,6 +841,9 @@ \def\tikzexternal@list@and@make@gentarget#1{% \tikzexternal@assemble@systemcall{#1}{\pgf@tempa}% + \def\tikzexternal@tempb{\pgfutilstrreplace{^^J}{^^J\tikzexternal@TABchar}}% + \expandafter\tikzexternal@tempb\expandafter{\pgf@tempa}% + \let\pgf@tempa=\pgfretval \iftikzexternal@verboseio \immediate\write16{Writing '#1' to '\tikzexternal@realjob.makefile'.}% \fi @@ -856,6 +888,7 @@ \def\tikzexternalmakefiledefaultdeprule{% \immediate\write\tikzexternal@outmakefile{\tikzexternal@PERCENTchar.\tikzexternaldepext:}% + \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar mkdir -p $(dir $@)}% \immediate\write\tikzexternal@outmakefile{\tikzexternal@TABchar touch $@ \tikzexternal@HASHchar\space will be filled later.}% }% @@ -868,14 +901,16 @@ % Will write something to the make file. If the makefile is not yet % opened, #1 will be written as soon as it *is* opened. \def\tikzexternalwritetomakefile#1{% - \pgfutil@ifundefined{tikzexternal@outmakefile}{% - \expandafter\gdef\expandafter\tikzexternal@outmakefile@pendingcommands\expandafter{% - \tikzexternal@outmakefile@pendingcommands + \if\tikzexternal@opmode5% mode='list and make' + \pgfutil@ifundefined{tikzexternal@outmakefile}{% + \expandafter\gdef\expandafter\tikzexternal@outmakefile@pendingcommands\expandafter{% + \tikzexternal@outmakefile@pendingcommands + \immediate\write\tikzexternal@outmakefile{#1}% + }% + }{% \immediate\write\tikzexternal@outmakefile{#1}% }% - }{% - \immediate\write\tikzexternal@outmakefile{#1}% - }% + \fi }% \def\tikzexternal@dep@file@name{} @@ -896,33 +931,67 @@ % could be auto-generated: empty file name means "picture % won't be externalized". Skip it. \else - \edef\tikzpicturedependsonfile@name{#1.\tikzexternaldepext}% - \ifx\tikzexternal@dep@file@name\tikzpicturedependsonfile@name - % file is open and ready. - \else - % create new output file. - \pgfutil@ifundefined{tikzexternal@dep@file}{% - \begingroup - % this makes \tikzexternal@dep@file global: - \globaldefs=1 - % this gets round '\outer\newwrite' in plain TeX: - \csname newwrite\endcsname\tikzexternal@dep@file - \endgroup - }{}% - \ifx\tikzexternal@dep@file@name\pgfutil@empty - \else - % it is already open. Close it. - \immediate\closeout\tikzexternal@dep@file - \fi - \global\let\tikzexternal@dep@file@name=\tikzpicturedependsonfile@name - \immediate\openout\tikzexternal@dep@file=\tikzexternal@dep@file@name\relax - \fi - \immediate\write\tikzexternal@dep@file{#1\tikzexternalimgextension: #2}% + % if we encounter any dependencies while we externalize a + % picture, we have to write these things into the image's .dep + % file. + \tikzifexternalizingcurrent + {\tikzexternalfiledependsonfile@append@to@dep@file{#1}{#2}}% + {\tikzexternalfiledependsonfile@append@to@makefile{#1}{#2}}% \fi \endgroup }% \def\tikzexternalfiledependsonfile#1#2{}% NO-OP until \tikzexternalize has been called. +% sub-routine of \tikzexternalfiledependsonfile which appends stuff to +% the pictures .dep file. +% +% The file #1.dep is generated during the externalization of #1. If +% you change and/or overwrite it in any other context, its information +% might get lost (because #1 won't be regenerated). +% +% Consequently, this here has to be called if and only if #1 is about +% to be externalized. +\def\tikzexternalfiledependsonfile@append@to@dep@file#1#2{% + % write every dependency which is defined *INSIDE* of the current + % picture into the .dep file of the current picture: + \tikzexternalgetcurrentfilename\tikzpicturedependsonfile@name + \edef\tikzpicturedependsonfile@name{\tikzpicturedependsonfile@name.\tikzexternaldepext}% + %\edef\tikzpicturedependsonfile@name{#1.\tikzexternaldepext}% + \ifx\tikzexternal@dep@file@name\tikzpicturedependsonfile@name + % file is open and ready. + \else + % create new output file. + \pgfutil@ifundefined{tikzexternal@dep@file}{% + \begingroup + % this makes \tikzexternal@dep@file global: + \globaldefs=1 + % this gets round '\outer\newwrite' in plain TeX: + \csname newwrite\endcsname\tikzexternal@dep@file + \endgroup + }{}% + \ifx\tikzexternal@dep@file@name\pgfutil@empty + \else + % it is already open. Close it. + \immediate\closeout\tikzexternal@dep@file + \fi + \global\let\tikzexternal@dep@file@name=\tikzpicturedependsonfile@name + \immediate\openout\tikzexternal@dep@file=\tikzexternal@dep@file@name\relax + \fi + \immediate\write\tikzexternal@dep@file{#1\tikzexternalimgextension: #2}% +} + +% sub-routine of \tikzexternalfiledependsonfile which appends stuff to +% the makefile of the current \jobname . +% +% This is used for dependencies which are recomputed by every run of +% tex; we must not write them into #1.dep (for reasons explained in +% the documentation of +% \tikzexternalfiledependsonfile@append@to@dep@file) +\def\tikzexternalfiledependsonfile@append@to@makefile#1#2{% + \edef\tikzexternal@temp{#1\tikzexternalimgextension: #2}% + \expandafter\tikzexternalwritetomakefile\expandafter{\tikzexternal@temp}% +} + % Adds a dependency for the NEXT picture which is about to be % externalized. If we are currently inside of a picture, the % dependency is added for this current picture. @@ -1064,7 +1133,7 @@ }% \long\def\tikzexternal@optimize@away@latex@env@close#1{% \iftikzexternal@verbose@optimize - \immediate\write16{The complete contents of \string\begin{tikzexternal@optimize@away@latex@env@} up to the next \end{tikzexternal@optimize@away@latex@env@} has been optimized away because it does not contribute to exported PDF. Use '/tikz/external/optimize=false' to disable this.}% + \immediate\write16{The complete contents of \string\begin{tikzexternal@optimize@away@latex@env@} up to the next \end{tikzexternal@optimize@away@latex@env@} has been optimized away because it does not contribute to the exported PDF. Use '/tikz/external/optimize=false' to disable this.}% \fi \endgroup % we still need to invoke \end{} in latex because \begin{} @@ -1104,6 +1173,7 @@ \immediate\write16{A tikzpicture has been optimized away. Use '/tikz/external/optimize=false' to disable this.}% \fi \tikzexternal@closeenvironments + \pgfkeysvalueof{/tikz/external/optimize away text/.@cmd}tikzpicture\pgfeov% } % Processes tikzpicture normally; without any externalization. @@ -1142,17 +1212,32 @@ \def\tikzexternal@forcegraphics{% \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@forcegraphics@@ } -\long\def\tikzexternal@forcegraphics@@#1{% +\long\def\tikzexternal@forcegraphics@@#1{\tikzexternal@forcegraphics@@@}% +\def\tikzexternal@forcegraphics@@@{% + \if5\tikzexternal@opmode + \let\tikz@refundefinedtrue@@=\G@refundefinedtrue + \gdef\G@refundefinedtrue{% + \tikz@refundefinedtrue@@ + \tikzexternal@forceremake@undefined@reference@handler + }% + \fi \expandafter\pgfincludeexternalgraphics\expandafter{\tikzexternal@curfilename}% + \global\let\G@refundefinedtrue=\tikz@refundefinedtrue@@ \tikzexternal@closeenvironments } +\def\tikzexternal@forceremake@undefined@reference@handler{% + \immediate\write16{===== 'mode=list and make': encountered undefined reference in current picture. Adding dependency to FORCEREMAKE. Rerun make to update the picture.' ========^^J}% + \tikzpicturedependsonfile{FORCEREMAKE}% +}% + % Simply replaces the complete picture by some placeholder text. % It is used by 'mode=list only' to reduce runtime. \def\tikzexternal@listmodepicture{% \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@listmodepicture@@ } -\long\def\tikzexternal@listmodepicture@@#1{% +\long\def\tikzexternal@listmodepicture@@#1{\tikzexternal@listmodepicture@@@} +\def\tikzexternal@listmodepicture@@@{% \pgfkeysvalueof{/tikz/external/image discarded text}% \tikzexternal@closeenvironments } @@ -1160,15 +1245,21 @@ % check if there is already a file. % In that case, use it. If not, skip it. \def\tikzexternal@list@and@makefile@mode@picture{% + \tikzexternal@TEXDIALECT@collectpicture\tikzexternal@list@and@makefile@mode@picture@ +}% +\long\def\tikzexternal@list@and@makefile@mode@picture@#1{% + % + \tikzexternal@check@uptodate@mode{#1}% + % \gdef\pgf@filename{}% \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}% \pgf@tempa \ifx\pgf@filename\pgfutil@empty% % Note: since we have no 'GRAB' mode, we do not have to deal with optimization. % there is no graphics. - \expandafter\tikzexternal@listmodepicture + \expandafter\tikzexternal@listmodepicture@@@ \else - \expandafter\tikzexternal@forcegraphics + \expandafter\tikzexternal@forcegraphics@@@ \fi }% @@ -1193,6 +1284,9 @@ \def\endtikzpicture{% \tikzexternal@origendpicture \pgf@externalend + % + \tikzexternal@ensure@nonempty@floats + % \let\tikzpicture=\tikzexternal@tikzpicture@replacement \let\endtikzpicture=\tikzexternal@origendpicture \iftikzexternal@optimize @@ -1204,6 +1298,21 @@ \tikzpicture }% +% If a sequence of floats containing JUST tikzpictures is +% externalized, this results in EMPTY floats. Empty floats, in turn, +% can confuse latex; it thinks it did something wrong. +% +% Solution: Avoid empty floats by writing junk into it. +% +% Note that this method is only invoked if \ifpgf@external@grabshipout +% is true and if the text is OUTSIDE of the original shipout routine. +% In other words: this text is being thrown away. +% +% see +% http://tex.stackexchange.com/questions/54625/why-is-fixltx2e-incompatible-with-tikzexternalize +\def\tikzexternal@ensure@nonempty@floats{% + tikzexternal: picture has been externalized. This text is required to avoid empty floats. +}% % 1. Discards the current picture in this document. % 2. Checks whether an image exists already. If that is the case: acquire it. @@ -1270,7 +1379,7 @@ \endgroup }% \long\def\tikzexternal@externalizefig@systemcall@@#1{% - \tikzexternal@externalizefig@systemcall@uptodatecheck% + \tikzexternal@externalizefig@systemcall@uptodatecheck{#1}% \iftikzexternal@file@isuptodate \iftikzexternal@verboseio \immediate\write16{===== Image '\tikzexternal@curfilename' is up-to-date. ======}% @@ -1337,6 +1446,124 @@ \fi } +\pgfutil@IfUndefined{pdfmdfivesum}{% +}{% + % predefine to this value. This does only make sense for pdftex. + % note that the latex library for 'external' loads \usepackage{pdftexcmds} which \let's this to \pdf@mdfivesum: + \let\tikzexternal@mdfivesum=\pdfmdfivesum +}% + +\long\def\tikzexternal@computemdfivesum#1{% + \t@tikzexternal@tmpb={#1}% + \edef\tikzexternal@temp{\the\t@tikzexternal@tmpb}% + % \meaning results in a string of catcode 12 - which is expandable. + \edef\pgfretval{\tikzexternal@mdfivesum{\meaning\tikzexternal@temp}}% +} +\long\def\tikzexternal@computemdfivesum@diff@fallback#1{% + \t@tikzexternal@tmpb={#1}% + \edef\tikzexternal@temp{\the\t@tikzexternal@tmpb}% + % \meaning results in a string of catcode 12 - which is expandable. + \edef\pgfretval{\meaning\tikzexternal@temp}% +} + +% Will be set dynamically, depending on 'up to date check'. +% +% It expands to code such that \tikzexternallastkey contains the +% serialized version of '#1'. +% +% It is used as argument for \write{..} +% +% #1 the hash key to serialize. +% \def\tikzexternal@hashfct@serialize +\long\def\tikzexternal@hashfct@serialize@std#1{% + \noexpand\def\noexpand\tikzexternallastkey{#1}% +}% + +% serializes using temporary token registers. Necessary if #1 contains +% executable code. +\long\def\tikzexternal@hashfct@serialize@tok#1{% + \noexpand\begingroup + % in order to allow '#' inside of the body, we have to use token registers: + \noexpand\toks0={#1}% + \noexpand\xdef\noexpand\tikzexternallastkey{\noexpand\the\noexpand\toks0 }% + \noexpand\endgroup +}% + +\def\tikzexternal@check@uptodate@ext{.md5} + +\def\tikzexternal@check@uptodate@mode@warn@fallback{% + \message{! Package tikz Warning: The key 'up to date check=md5' is impossible, there is no macro to compute MD5. Falling back to 'up to date check=diff'.}% + % + % warn only once: + \global\let\tikzexternal@check@uptodate@mode@warn@fallback=\relax +}% + +% assigns the boolean \iftikzexternal@file@isuptodate +\long\def\tikzexternal@check@uptodate@mode#1{% + \if1\tikzexternal@uptodate@mode + % up to date check=md5: + % check if we CAN compute MD5 sums: + \pgfutil@IfUndefined{tikzexternal@mdfivesum}{% + % we cannot compute md5 sums - fallback to diff. + \tikzexternal@check@uptodate@mode@warn@fallback + \def\tikzexternal@uptodate@mode{2}% + }{}% + \fi + % + \ifcase\tikzexternal@uptodate@mode + % up to date check=simple + % nothing to do -- file existance is checked anyway. + \let\tikzexternal@hashfct=\pgfutil@empty + \let\tikzexternal@hashfct@serialize=\pgfutil@empty + \or + % up to date check=md5 + \let\tikzexternal@hashfct=\tikzexternal@computemdfivesum + \let\tikzexternal@hashfct@serialize=\tikzexternal@hashfct@serialize@std + \or + \let\tikzexternal@hashfct=\tikzexternal@computemdfivesum@diff@fallback + \let\tikzexternal@hashfct@serialize=\tikzexternal@hashfct@serialize@tok + \fi + \ifx\tikzexternal@hashfct\pgfutil@empty + \else + \tikzpicturedependsonfile{\tikzexternal@curfilename\tikzexternal@check@uptodate@ext}% + \tikzexternal@hashfct{#1}% + \let\tikzexternal@lastkey@new=\pgfretval + \begingroup + % no '@' token in this macro: avoid messing up the catcodes in input files: + \global\let\tikzexternallastkey=\pgfutil@empty + \openin\r@pgf@reada=\tikzexternal@curfilename\tikzexternal@check@uptodate@ext\relax % + \ifeof\r@pgf@reada + \else + % read first line... + \endlinechar=-1 % older versions did not have a '%' at the end-of-line. Avoid spurious spaces. + \read\r@pgf@reada to\pgf@tempa + % ... and execute it. + \pgf@tempa + % it should contain a definition of \tikzexternallastkey. + \fi + \closein\r@pgf@reada + % + \let\tikzexternal@lastkey=\tikzexternallastkey + \pgfmath@smuggleone\tikzexternal@lastkey + \endgroup + % normalize catcodes. Unfortunately, they cannot be expected to be the same. + % \meaning will use catcode 12 for each token: + \edef\tikzexternal@lastkey@normalized{\meaning\tikzexternal@lastkey}% + \edef\tikzexternal@lastkey@new@normalized{\meaning\tikzexternal@lastkey@new}% + \iftikzexternal@verboseuptodate + \immediate\write16{Up-to-date check of \tikzexternal@curfilename: new \tikzexternal@lastkey@new@normalized; old \tikzexternal@lastkey@normalized.^^J}% + \fi + \ifx\tikzexternal@lastkey@normalized\tikzexternal@lastkey@new@normalized + \tikzexternal@file@isuptodatetrue + \else + \tikzexternal@file@isuptodatefalse + \immediate\openout\w@pgf@writea=\tikzexternal@curfilename\tikzexternal@check@uptodate@ext\relax% + \immediate\write\w@pgf@writea{\tikzexternal@hashfct@serialize{\tikzexternal@lastkey@new}\tikzexternal@PERCENTchar}% + \immediate\closeout\w@pgf@writea + \fi + \fi +} + % Checks whether the current picture needs to be externalized. % % This is the case if @@ -1344,8 +1571,12 @@ % b) the picture has been invalidated manually. % % It returns \iftikzexternal@file@isuptodate accordingly. -\def\tikzexternal@externalizefig@systemcall@uptodatecheck{% +% #1: the picture-content +\long\def\tikzexternal@externalizefig@systemcall@uptodatecheck#1{% \tikzexternal@checkforceremake + \iftikzexternal@file@isuptodate + \tikzexternal@check@uptodate@mode{#1}% + \fi \iftikzexternal@file@isuptodate % check if there is already a file. % In that case, use it. If that is not the case, generate it and include it afterwards. @@ -1365,7 +1596,7 @@ \xdef\pgf@tempa{\noexpand\pgf@findfile\pgfsys@imagesuffixlist:+{\tikzexternal@curfilename}}% \pgf@tempa \ifx\pgf@filename\pgfutil@empty% - \PackageError{tikz}{Sorry, the system call '#1' did NOT result in a usable output file '\tikzexternal@curfilename' (expected one of \pgfsys@imagesuffixlist). Please verify that you have enabled system calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is also named 'write 18' or something like that. Or maybe the command simply failed? Error messages can be found in '\tikzexternal@curfilename.log'. If you continue now, I'll try to typeset the picture}% + \tikzerror{Sorry, the system call '#1' did NOT result in a usable output file '\tikzexternal@curfilename' (expected one of \pgfsys@imagesuffixlist). Please verify that you have enabled system calls. For pdflatex, this is 'pdflatex -shell-escape'. Sometimes it is also named 'write 18' or something like that. Or maybe the command simply failed? Error messages can be found in '\tikzexternal@curfilename.log'. If you continue now, I'll try to typeset the picture}{}% \fi }% @@ -1375,18 +1606,18 @@ \begingroup \tikzexternal@assemble@systemcall{\pgfactualjobname}{\pgf@tempa}% \toks0=\expandafter{\pgf@tempa}% - \PackageError{tikz}{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname', but it seems there is no such image in the document!? + \tikzerror{Sorry, image externalization failed: the resulting image was EMPTY. I tried to externalize '\pgfactualjobname', but it seems there is no such image in the document!? \if\tikzexternal@opmode4 ^^J \space\space You are currently using 'mode=convert with system call'. This problem can happen if the image (or one of the images preceeding it) was declared inside of a \string\label{} (i.e. in the .aux file): 'convert with system call' has no access to the main aux file.^^J \space\space Possible solutions in this case:^^J -\space\space a) Try using 'mode=list and make',^^J -\space\space b) Issue the externalization command '\the\toks0' *manually* (also check the preceeding externalized images, perhaps the file name sequence is not correct).^^J +\space\space (a) Try using 'mode=list and make',^^J +\space\space (b) Issue the externalization command '\the\toks0' *manually* (also check the preceeding externalized images, perhaps the file name sequence is not correct).^^J \space\space Repeat: the resulting image was EMPTY, your attention is required \else \if\tikzexternal@opmode5 ^^J \space\space You are currently using 'mode=list and make'. Possible solutions:^^J -\space\space a) Try to delete `\tikzexternal@realjob.makefile'. Perhaps it is not up-to-date.^^J -\space\space b) Perhaps pictures are declared inside of \string\label{} and the .aux file is not up-to-date. Re-run latex, perhaps re-generate the graphics as well.^^J +\space\space (a) Try to delete `\tikzexternal@realjob.makefile'. Perhaps it is not up-to-date.^^J +\space\space (b) Perhaps pictures are declared inside of \string\label{} and the .aux file is not up-to-date. Re-run latex, perhaps re-generate the graphics as well.^^J \space\space Repeat: the resulting image was EMPTY, your attention is required \fi \fi}% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex index 3d2cecc732f..c6c998e4b6a 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex,v 1.1 2008/01/09 17:57:15 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrary3d.code.tex,v 1.2 2013/07/17 10:36:34 tantau Exp $ @@ -16,13 +16,13 @@ \tikzdeclarecoordinatesystem{xyz cylindrical} {% \pgfset{/tikz/cs/.cd,angle=0,radius=0,z=0,#1}% - \pgfpointcylindrical{\tikz@cs@angle}{\tikz@cs@radius}{\tikz@cs@z}% + \pgfpointcylindrical{\tikz@cs@angle}{\tikz@cs@xradius}{\tikz@cs@z}% } \tikzdeclarecoordinatesystem{xyz spherical} {% \pgfset{/tikz/cs/.cd,angle=0,radius=0,latitude=0,longitude=0,#1}% - \pgfpointspherical{\tikz@cs@angle}{\tikz@cs@latitude}{\tikz@cs@radius}% + \pgfpointspherical{\tikz@cs@angle}{\tikz@cs@latitude}{\tikz@cs@xradius}% } \pgfset{/tikz/cs/longitude/.store in=\tikz@cs@angle} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex new file mode 100644 index 00000000000..2ac3ebc7b22 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex @@ -0,0 +1,72 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryangles.code.tex,v 1.1 2013/08/28 15:24:27 tantau Exp $ + + +\tikzset{ + pics/angle/.style = { + setup code = \tikz@lib@angle@parse#1\pgf@stop, + background code = \tikz@lib@angle@background#1\pgf@stop, + foreground code = \tikz@lib@angle@foreground#1\pgf@stop, + }, + pics/angle/.default=A--B--C, + angle eccentricity/.initial=.6, + angle radius/.initial=5mm +} + +\def\tikz@lib@angle@background#1--#2--#3\pgf@stop{% + \path [name prefix ..] [pic actions, draw=none] (#2.center) + -- ++(\tikz@start@angle@temp:\tikz@lib@angle@rad pt) + arc [start angle=\tikz@start@angle@temp, end + angle=\tikz@end@angle@temp, radius=\tikz@lib@angle@rad pt] -- cycle; +} + +\def\tikz@lib@angle@foreground#1--#2--#3\pgf@stop{% + \path [name prefix ..] [pic actions, fill=none, shade=none] + ([shift={(\tikz@start@angle@temp:\tikz@lib@angle@rad pt)}]#2.center) + arc [start angle=\tikz@start@angle@temp, end + angle=\tikz@end@angle@temp, radius=\tikz@lib@angle@rad pt]; + \ifx\tikzpictext\relax\else% + \def\pgf@temp{\node()[name prefix + ..,at={([shift={({.5*\tikz@start@angle@temp+.5*\tikz@end@angle@temp}:\pgfkeysvalueof{/tikz/angle + eccentricity}*\tikz@lib@angle@rad pt)}]#2.center)}]} + \expandafter\pgf@temp\expandafter[\tikzpictextoptions]{\tikzpictext};% + \fi +} + + +\def\tikz@lib@angle@parse#1--#2--#3\pgf@stop{% + % Compute radius: + \pgfmathsetmacro\tikz@lib@angle@rad{\pgfkeysvalueof{/tikz/angle radius}} + \ifdim\tikz@lib@angle@rad pt>0pt\else\def\tikz@lib@angle@rad{12}\fi% + % Compute first coordinate: + \pgf@process{\pgfpointanchor{#2}{center}}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@process{\pgfpointanchor{#1}{center}}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@process{\pgfpointanchor{#3}{center}}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \advance\pgf@xc by-\pgf@xa% + \advance\pgf@yc by-\pgf@ya% + \pgfmathsetmacro{\tikz@start@angle@temp}{atan2(\the\pgf@yb,\the\pgf@xb)} + \pgfmathsetmacro{\tikz@end@angle@temp}{atan2(\the\pgf@yc,\the\pgf@xc)} + \ifdim\tikz@end@angle@temp pt<\tikz@start@angle@temp pt% + \pgfmathsetmacro{\tikz@start@angle@temp}{\tikz@start@angle@temp-360}% + \fi% +} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex new file mode 100644 index 00000000000..37b5ae20231 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex @@ -0,0 +1,17 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybabel.code.tex,v 1.1 2013/06/24 11:49:06 tantau Exp $ + +\tikzset{ + handle active characters in code, + handle active characters in nodes +} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex index cd68855bbab..6302b629ae4 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex,v 1.2 2010/02/08 11:21:46 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex,v 1.3 2013/07/18 17:07:38 tantau Exp $ % Layers @@ -18,8 +18,14 @@ % Switch command \tikzset{on background layer/.style={ - execute at begin scope={\pgfonlayer{background}}, - execute at end scope={\endpgfonlayer}}} + execute at begin scope={% + \pgfonlayer{background}% + \let\tikz@options=\pgfutil@empty% + \tikzset{every on background layer/.try,#1}% + \tikz@options}, + execute at end scope={\endpgfonlayer} + } +} % Main style diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex new file mode 100644 index 00000000000..42a410ce4f5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex @@ -0,0 +1,15 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybending.code.tex,v 1.2 2013/09/17 22:00:21 tantau Exp $ + +\usepgfmodule{bending} +\tikzset{arrows=[flex]} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex index 1a0ea356c24..703494d2a64 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex,v 1.6 2009/09/04 17:22:59 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalc.code.tex,v 1.9 2013/07/15 12:05:31 tantau Exp $ % % @@ -48,7 +48,7 @@ \pgfutil@ifnextchar\n{% \tikz@cc@handle@num% }{% - \PackageError{tikz}{``\string\p'' or ``\string\n'' expected}{}% + \tikzerror{``\string\p'' or ``\string\n'' expected}% }% }% } @@ -112,7 +112,7 @@ \pgfutil@ifnextchar-{% \tikz@cc@sub% }{% - \PackageError{tikz}{+ or - expected}{}% + \tikzerror{+ or - expected}% \tikz@cc@end$%$ }% }% @@ -177,24 +177,52 @@ % A coordinate can be followed by !...!(...) % -\def\tikz@cc@mid@checks{ +\def\tikz@cc@mid@checks{% + \ifnum\the\catcode`\!=\active\relax + \expandafter\tikz@cc@mid@checks@active + \else + \expandafter\tikz@cc@mid@checks@nonactive + \fi} + +\def\tikz@cc@mid@checks@nonactive{% \pgfutil@ifnextchar!{% - \tikz@cc@mid% + \tikz@cc@mid@nonactive% }{% - \advance\pgf@xa by\tikz@cc@factor\pgf@xb% - \advance\pgf@ya by\tikz@cc@factor\pgf@yb% - \tikz@cc@parse% continue + \advance\pgf@xa by\tikz@cc@factor\pgf@xb + \advance\pgf@ya by\tikz@cc@factor\pgf@yb + \tikz@cc@parse% }% } -\def\tikz@cc@mid!{% +\def\tikz@cc@mid@nonactive!{% \pgfutil@ifnextchar({% \tikz@scan@one@point\tikz@cc@project% }{% - \tikz@cc@mid@num% + \tikz@cc@mid@num@nonactive% }% } +\begingroup + \catcode`\!=\active + \gdef\tikz@cc@mid@checks@active{% + \pgfutil@ifnextchar!{% + \tikz@cc@mid@active% + }{% + \advance\pgf@xa by\tikz@cc@factor\pgf@xb + \advance\pgf@ya by\tikz@cc@factor\pgf@yb + \tikz@cc@parse% + }% + } + + \gdef\tikz@cc@mid@active!{% + \pgfutil@ifnextchar({% + \tikz@scan@one@point\tikz@cc@project% + }{% + \tikz@cc@mid@num@active% + }% + } +\endgroup + % % Partway case: (coord a)!number!(coord b) % @@ -202,7 +230,15 @@ % to b. This, (a)!0!(b) is (a), (a)!.5!(b) is the middle and (a)!1!(b) % is (b) % -\def\tikz@cc@mid@num#1!{% + +\def\tikz@cc@mid@num@nonactive#1!{\tikz@cc@mid@num{#1}} + +\begingroup + \catcode`\!=\active + \gdef\tikz@cc@mid@num@active#1!{\tikz@cc@mid@num{#1}} +\endgroup + +\def\tikz@cc@mid@num#1{% \pgfmathparse{#1}% \ifpgfmathunitsdeclared% \let\tikz@cc@mid@unit=\pgfmathresult% @@ -253,10 +289,27 @@ % Save in c \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% - \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project\tikz@cc@scan@ex% + \begingroup + \ifnum\the\catcode`\!=\active + \def\tikz@next{% + \endgroup + \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project + \tikz@cc@scan@ex@active}% + \else + \def\tikz@next{% + \endgroup + \expandafter\tikz@cc@scan@rot\expandafter\tikz@cc@after@project + \tikz@cc@scan@ex@nonactive}% + \fi + \tikz@next% } -\def\tikz@cc@scan@ex!{} +\def\tikz@cc@scan@ex@nonactive!{} + +\begingroup + \catcode`\!=\active + \gdef\tikz@cc@scan@ex@active!{} +\endgroup \def\tikz@cc@after@project#1{% \pgf@process{#1}% @@ -284,16 +337,28 @@ \tikz@scan@one@point#1% normal }% { - \def\tikz@cc@scan@rot@cmd{#1} - \tikz@cc@scan@one@rot% + \def\tikz@cc@scan@rot@cmd{#1}% + \ifnum\the\catcode`\:=\active\relax + \expandafter\tikz@cc@scan@one@rot@active% + \else + \expandafter\tikz@cc@scan@one@rot@nonactive% + \fi }% } -\def\tikz@cc@scan@one@rot#1:{% +\def\tikz@cc@scan@one@rot@nonactive#1:{% \def\tikz@cc@scan@rot@angle{#1}% \tikz@scan@one@point\tikz@cc@handle@rot% } +\begingroup + \catcode`\:=\active + \gdef\tikz@cc@scan@one@rot@active#1:{% + \def\tikz@cc@scan@rot@angle{#1}% + \tikz@scan@one@point\tikz@cc@handle@rot% + } +\endgroup + \def\tikz@cc@handle@rot#1{% \pgf@process{#1}% % Ok, now we need to rotate x/y around xb/xb by ...rot@angle @@ -328,8 +393,8 @@ {% \tikzset{cs/.cd,#1}% \expandafter\ifx\csname tikz@tangent@\tikz@cs@type\endcsname\relax% - \PackageError{tikz}{I do not know how to compute the tangent to - a \tikz@cs@type}{}% + \tikzerror{I do not know how to compute the tangent to + a \tikz@cs@type}% \pgfpointorigin% \else% \expandafter\tikz@scan@one@point\expandafter\tikz@lib@do@tangent\tikz@cs@point% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex index 09729059297..02b4f00bb6f 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex,v 1.1 2008/01/09 17:57:15 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarycalendar.code.tex,v 1.3 2013/07/15 12:05:31 tantau Exp $ \pgfutil@usemodule{pgfcalendar} @@ -366,24 +366,24 @@ execute before day scope={\ifdate{day of month=1}{% } \def\tikz@lib@cal@scanner{% - \afterassignment\tikz@lib@cal@handle\let\@let@token=% + \afterassignment\tikz@lib@cal@handle\let\pgf@let@token=% } \def\tikz@lib@cal@handle{% \let\@next=\tikz@lib@cal@expand% - \ifx\@let@token;% + \ifx\pgf@let@token;% \let\@next=\tikz@lib@cal@stop% \else% - \ifx\@let@token(%) + \ifx\pgf@let@token(%) \let\@next=\tikz@lib@cal@name% \else% - \ifx\@let@token a% + \ifx\pgf@let@token a% \let\@next=\tikz@lib@cal@at% \else% - \ifx\@let@token[% + \ifx\pgf@let@token[% \let\@next=\tikz@lib@cal@option% \else% - \ifx\@let@token i% + \ifx\pgf@let@token i% \let\@next=\tikz@lib@cal@if% \fi% \fi% @@ -395,14 +395,14 @@ execute before day scope={\ifdate{day of month=1}{% \def\tikz@lib@cal@expand{% \advance\tikz@expandcount by -1% \ifnum\tikz@expandcount<0\relax% - \PackageError{tikz}{Giving up on this calendar}{}% + \tikzerror{Giving up on this calendar}% \let\@next=\tikz@lib@cal@end% \else% \let\@next=\tikz@lib@cal@@expand \fi% \@next} -\def\tikz@lib@cal@@expand{\expandafter\tikz@lib@cal@scanner\@let@token} +\def\tikz@lib@cal@@expand{\expandafter\tikz@lib@cal@scanner\pgf@let@token} \def\tikz@lib@cal@name#1){% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex index 24019031a36..e2d12a0931a 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex,v 1.5 2008/02/27 09:14:09 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarychains.code.tex,v 1.6 2013/07/15 12:05:31 tantau Exp $ \usetikzlibrary{positioning} @@ -29,7 +29,7 @@ \let\tikz@lib@current@chain=\tikz@lib@chain@name% \let\chainin=\tikz@lib@chainin% \else% - \PackageError{tikz}{Chain ``\tikz@lib@chain@name'' is already active}{}% + \tikzerror{Chain ``\tikz@lib@chain@name'' is already active}% \fi% }, continue chain/.default=, @@ -39,7 +39,7 @@ \let\tikz@lib@chain@name\tikz@lib@current@chain% \fi% \expandafter\ifx\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname\relax% - \PackageError{tikz}{Unknown chain ``#1''}{}% + \tikzerror{Unknown chain ``#1''}% \else% \let\tikz@lib@current@chain=\tikz@lib@chain@name% \expandafter\let\csname tikz@lib@chain@active@\tikz@lib@chain@name\endcsname=\pgfutil@empty% does not matter @@ -120,7 +120,7 @@ \let\tikz@lib@chain@name\tikz@lib@current@chain% \fi% \expandafter\ifx\csname tikz@lib@chain@exists@\tikz@lib@chain@name\endcsname\relax% - \PackageError{tikz}{Unknown chain ``\tikz@lib@chain@name''}{}% + \tikzerror{Unknown chain ``\tikz@lib@chain@name''}% \else% \c@pgf@counta\csname tikz@lib@chain@count@\tikz@lib@chain@name\endcsname\relax% \ifnum\c@pgf@counta=0\relax% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex index 4ab723f711c..b27783b0009 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.code.tex @@ -55,14 +55,17 @@ \pgfdeclaremetadecoration{tikz@internal}{pre}{ \state{pre}[width=\pgfkeysvalueof{/pgf/decoration/pre length}, next state=main] { + \tikz@dec@trans \decoration{\pgfkeysvalueof{/pgf/decoration/pre}} } \state{main}[width=\pgfmetadecoratedremainingdistance-\pgfkeysvalueof{/pgf/decoration/post length}, next state=final] { + \tikz@dec@trans \decoration{\tikz@decoration@name} } \state{final} { + \tikz@dec@trans \decoration{\pgfkeysvalueof{/pgf/decoration/post}} } } @@ -87,12 +90,13 @@ % Now, we expect a brace. \pgfutil@ifnextchar\bgroup{% \begingroup% + \tikz@auto@end@pathfalse% \aftergroup\tikz@enddecoration% \afterassignment\tikz@scan@next@command% \let\tikz@lib@next% gobble \bgroup% }% {% - \PackageError{tikz}{A decoration must begin with a brace}{}% + \tikzerror{A decoration must begin with a brace}% \tikz@enddecoration% }% } @@ -103,8 +107,8 @@ {% \pgfifdecoration{\tikz@decoration@name}% {\tikz@lib@dec@startdecoration}% - {\PackageError{tikz}{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps you - misspelled it?}{}}% + {\tikzerror{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps you + misspelled it?}}% }% \ifx\pgfdecorateexistingpath\pgfutil@empty% \pgfpathmoveto{\pgfqpoint{\the\tikz@lastxsaved}{\the\tikz@lastysaved}}% @@ -147,8 +151,8 @@ \tikz@lib@dec@stopdecoration% } { - \PackageError{tikz}{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps - you misspelled it?}{} + \tikzerror{Unknown (meta-)decoration '\tikz@decoration@name'. Perhaps + you misspelled it?} } } \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex index e063ba185f0..b75fcc6a562 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarydecorations.text.code.tex @@ -1,4 +1,4 @@ -% Copyright 2008 by Mark Wibrow +% Copyright 2013 by Mark Wibrow % % This file may be distributed and/or modified % @@ -10,4 +10,695 @@ \usetikzlibrary{decorations} \usepgflibrary{decorations.text} + +% Code for the `text effects along path' decoration + +% Some text constants +% To do: merge these with existing text constants +\def\tikz@lib@dec@te@space@text{space} +\def\tikz@lib@dec@align@left@text{left} +\def\tikz@lib@dec@align@right@text{right} +\def\tikz@lib@dec@align@center@text{center} +\def\tikz@lib@dec@te@none@text{none} + +% Some ifs +\newif\iftikz@lib@dec@te@pathfromtext +\newif\iftikz@lib@dec@te@segmentfromwidth +\newif\iftikz@lib@dec@te@scaletexttopath +\newif\iftikz@lib@dec@te@fittexttopath +\newif\iftikz@lib@dec@te@wordsep +\newif\iftikz@lib@dec@te@finalletter + + +% Utility macros +% To do: integrate with exisiting pgf macros +\def\tikz@lib@dec@te@addto@macro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +\def\tikz@lib@dec@te@namelet#1#2{% + \expandafter\expandafter\expandafter\let\expandafter\expandafter\csname\expandafter#1\expandafter\endcsname\expandafter=\csname#2\endcsname% +} + +\def\tikz@lib@dec@te@advancecountmacro#1#2{% + \pgfutil@tempcnta=#1\relax% + \advance\pgfutil@tempcnta by#2\relax% + \edef#1{\the\pgfutil@tempcnta}% +} + +\def\tikz@lib@dec@te@advancedimenmacro#1#2{% + \pgf@x=#1\relax% + \advance\pgf@x by#2\relax% + \edef#1{\the\pgf@x}% +} + +% Macros for defining and updating text parameters +\def\tikz@lib@dec@te@start@parameters#1{% + \expandafter\let\csname tikz@lib@dec@te@character@#1\endcsname=\pgfutil@empty% +} + +\def\tikz@lib@dec@te@addto@parameters#1#2{% + \expandafter\tikz@lib@dec@te@addto@macro\expandafter% + {\csname tikz@lib@dec@te@character@#1\endcsname}{#2}% +} +\def\tikz@lib@dec@te@addmacroto@parameters#1#2{% + \def\tikz@lib@dec@te@marshal{\expandafter\tikz@lib@dec@te@addto@macro\expandafter% + {\csname tikz@lib@dec@te@character@#1\endcsname}}% + \expandafter\tikz@lib@dec@te@marshal\expandafter{\expandafter\def\expandafter#2\expandafter{#2}}% +} + +\def\tikz@lib@dec@te@getparameters#1{\csname tikz@lib@dec@te@character@#1\endcsname} + + + +\let\tikz@lib@dec@te@textoptions=\pgfutil@empty +\let\tikz@lib@dec@te@widthoptions=\pgfutil@empty +\let\tikz@lib@dec@te@charactercountvar=\pgfutil@empty +\let\tikz@lib@dec@te@charactertotalvar=\pgfutil@empty +\let\tikz@lib@dec@te@lettercountvar=\pgfutil@empty +\let\tikz@lib@dec@te@lettertotalvar=\pgfutil@empty +\let\tikz@lib@dec@te@wordcountvar=\pgfutil@empty +\let\tikz@lib@dec@te@wordctotalvar=\pgfutil@empty +\let\tikz@lib@dec@te@transformtext=\pgfutil@empty% + + +% Keys... lots of them... +\pgfkeys{/pgf/decoration/text effects/.cd, + .unknown/.code={\let\tikz@lib@dec@te@key@tmp=\pgfkeyscurrentname% + \pgfkeysalso{/tikz/\tikz@lib@dec@te@key@tmp={#1}}}, + path from text/.is if=tikz@lib@dec@te@pathfromtext, + path from text angle/.store in=\tikz@lib@dec@te@pathfromtextangle, + path from text angle=0, + fit text to path/.is if=tikz@lib@dec@te@fittexttopath, + characters/.style={/pgf/decoration/text effects/every character/.style={#1}}, + characters/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character/.append style={#1}}}, + character widths/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.style={#1}}}, + character widths/.append/.code={\pgfkeysalso{/pgf/decoration/text effects/every character width/.append style={#1}}}, + character count/.store in=\tikz@lib@dec@te@charactercountvar, + character count=, + character total/.store in=\tikz@lib@dec@te@charactertotalvar, + character total=, + letter count/.store in=\tikz@lib@dec@te@lettercountvar, + letter count=, + letter total/.store in=\tikz@lib@dec@te@lettertotalvar, + letter total=, + word count/.store in=\tikz@lib@dec@te@wordcountvar, + word count=, + word total/.store in=\tikz@lib@dec@te@wordtotalvar, + word total=, + % + style characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@stylecharacters{#1}{#2}}, + text along path/.style={ + inner xsep=0pt, + anchor=base, + transform shape + }, + segment from width/.is if=tikz@lib@dec@te@segmentfromwidth, + segment from width=true, + word separator/.code={% + \def\tikz@lib@dec@te@tmp{#1}% + \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@space@text% + \let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken% + \else% + \def\tikz@lib@dec@te@wordsep{#1} + \fi}, + word separator=space, + character command/.code={% + \def\tikz@lib@dec@te@tmp{#1}% + \ifx\tikz@lib@dec@te@tmp\pgfutil@empty% + \def\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@charactertypesetonly}% + \else% + \def\tikz@lib@dec@te@charactercommand{#1}% + \fi% + }, + character command=, + every character width/.style={/pgf/decoration/text effects/every character/.try}, + every character/.style={}, + reverse text/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% + {\tikz@lib@dec@te@reversetext}}, + group letters into words/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% + {\tikz@lib@dec@te@groupletters}}, + group letters/.code={\tikz@lib@dec@te@addto@macro\tikz@lib@dec@te@transformtext% + {\tikz@lib@dec@te@groupletters}}, + replace characters/.code args={#1 with #2}{\tikz@lib@dec@te@parse@replacecharacters{#1}{#2}}, + scale text to path/.is if=tikz@lib@dec@te@scaletexttopath, + fit text to path/.is if=tikz@lib@dec@te@fittexttopath, + repeat text/.store in=\tikz@lib@dec@te@repeattext, + repeat text/.default=-1, + repeat text=0, +} + + +\def\tikz@lib@dec@te@charactertypesetonly#1{#1} + +\tikzset{% + text effects/.code={\pgfkeysalso{/pgf/decoration/text effects/.cd,#1}}, +} + + + + + + +% Prepare the decoration text +% +% This sets up all the character/letter/word, counts/totals +% and caluclates the default width of the characters/text +% (which may be modified later). +% +\def\tikz@lib@dec@te@preparetext{% + % Step 1: scan all the characters in the decoration text + \let\tikz@lib@dec@te@text=\pgfdecorationtext% + \tikz@lib@dec@te@scancharacters{% + \expandafter\let\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@scancount @token\endcsname=% + \tikz@lib@dec@te@character% + }% + \let\tikz@lib@dec@te@charactertotalcount=\tikz@lib@dec@te@scancount% + % Step 2: reverse and/or group characters/letters. + \ifx\tikz@lib@dec@te@transformtext\pgfutil@empty% + \else% + \tikz@lib@dec@te@transformtext% + \fi% + % Step 3: get the character/letter/word counts + \def\tikz@lib@dec@te@charactercount{0}% + \def\tikz@lib@dec@te@wordcount{0}% + \def\tikz@lib@dec@te@wordsepcount{0}% + \def\tikz@lib@dec@te@lettercount{0}% + \def\tikz@lib@dec@te@lastcharacter{0}% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \ifnum\tikz@lib@dec@te@lettercount>0\relax% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}% + \fi + \else% + \expandafter\let\expandafter\tikz@lib@dec@te@character\expandafter=\csname tikz@lib@dec@te@character@\pgfmathcounter @token\endcsname% + \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@charactercount}{1}% + \tikz@lib@dec@te@start@parameters{\tikz@lib@dec@te@charactercount}% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@charactercount}% + \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep% + \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@wordsepcount}{1}% + \ifnum\tikz@lib@dec@te@lettercount>0\relax% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@lastcharactercount}{\tikz@lib@dec@te@finallettertrue}% + \fi + \def\tikz@lib@dec@te@lettercount{0}% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordseptrue}% + \else + \ifnum\tikz@lib@dec@te@lettercount=0\relax% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@wordcount{1}% + \fi% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@finalletterfalse}% + \tikz@lib@dec@te@advancecountmacro{\tikz@lib@dec@te@lettercount}{1}% + \tikz@lib@dec@te@addto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordsepfalse}% + \expandafter\let\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname=\tikz@lib@dec@te@lettercount% + \fi% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@lettercount}% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@wordcount}% + \tikz@lib@dec@te@addmacroto@parameters{\tikz@lib@dec@te@charactercount}{\tikz@lib@dec@te@character}% + \let\tikz@lib@dec@te@lastcharactercount=\pgfmathcounter% + \repeatpgfmathloop% + \let\tikz@lib@dec@te@wordtotal=\tikz@lib@dec@te@wordcount% + % Step 4: add character/letter/word totals + \pgfmathloop + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@charactertotalcount}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@wordtotal}% + \expandafter\let\expandafter\tikz@lib@dec@te@lettertotalcount\expandafter=\csname tikz@lib@dec@te@word \tikz@lib@dec@te@wordcount @lettercount\endcsname% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@lettertotalcount}% + \repeatpgfmathloop% + % Step 5: calculate the the text and character width + % but do not add to the parameters yet. + \def\tikz@lib@dec@te@textwidth{0pt}% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \def\tikz@lib@dec@te@characterwidth{0pt}% + \tikz@lib@dec@te@getcharacterwidth{\pgfmathcounter}% + \expandafter\let\csname tikz@lib@dec@te@character@\pgfmathcounter @width\endcsname=\tikz@lib@dec@te@characterwidth% + \pgf@x=\tikz@lib@dec@te@characterwidth\relax% + \pgf@x=0.5\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% + \tikz@lib@dec@te@advancedimenmacro{\tikz@lib@dec@te@textwidth}{\tikz@lib@dec@te@characterwidth}% + \repeatpgfmathloop% +} + +% Does the category code of the space matter? +\def\tikz@lib@dec@te@spacetoken{ } + +\let\tikz@lib@dec@te@wordsep=\tikz@lib@dec@te@spacetoken + + +% Scan and count the characters in \tikz@lib@dec@te@text +% +% Create macros \tikz@lib@dec@te@character@@token containing +% the nth character. +% +% Total number of characters is store in +% \tikz@lib@dec@te@chractertotal@count +% +\def\tikz@lib@dec@te@scancharacters#1{% + \def\tikz@lib@dec@te@@@scancharacters@process{#1}% + \def\tikz@lib@dec@te@scancount{0}% + \expandafter\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@text\tikz@lib@dec@te@scancharacters}% + +\def\tikz@lib@dec@te@@scancharacters{% + \futurelet\tikz@lib@dec@te@token\tikz@lib@dec@te@@@scancharacters} + +\def\tikz@lib@dec@te@@@scancharacters{% + \ifx\tikz@lib@dec@te@token\tikz@lib@dec@te@scancharacters% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@@scancharacters% + \else% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@scancount{1}% + \ifx\tikz@lib@dec@te@token\pgfutil@sptoken% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@space% + \else% + \ifx\tikz@lib@dec@te@token\bgroup% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@bgroup% + \else% + \let\tikz@lib@dec@te@next=\tikz@lib@dec@te@@@scancharacters@normal% + \fi% + \fi% + \fi% + \tikz@lib@dec@te@next% +} + +\def\tikz@lib@dec@te@@@scancharacters@space{% + \let\tikz@lib@dec@te@character=\tikz@lib@dec@te@spacetoken% + \tikz@lib@dec@te@@@scancharacters@process% + \pgfutil@ifnextchar x\tikz@lib@dec@te@@scancharacters\tikz@lib@dec@te@@scancharacters% +} + +\def\tikz@lib@dec@te@@@scancharacters@bgroup#1{% + \def\tikz@lib@dec@te@character{{#1}}% + \tikz@lib@dec@te@@@scancharacters@process% + \tikz@lib@dec@te@@scancharacters% +} + +\def\tikz@lib@dec@te@@@scancharacters@normal#1{% + \def\tikz@lib@dec@te@character{#1}% + \tikz@lib@dec@te@@@scancharacters@process% + \tikz@lib@dec@te@@scancharacters% +} + + +\def\tikz@lib@dec@te@@@@scancharacters#1\tikz@lib@dec@te@scancharacters{} + + +% Reverse the order of the scanned chracters in the text +% (Actually reverse the ordering of the macros containing the characters) +\def\tikz@lib@dec@te@reversetext{% + \c@pgf@counta=\tikz@lib@dec@te@charactertotalcount% + \pgfmathloop% + \ifnum\pgfmathcounter>\c@pgf@counta% + \else% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\pgfmathcounter @token}{tikz@lib@dec@te@character@\the\c@pgf@counta @token}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@tmp}% + \advance\c@pgf@counta by-1\relax% + \repeatpgfmathloop% +} + +% Group letters (i.e., anything that isn't the word separator) +% as single characters (words). +\def\tikz@lib@dec@te@groupletters{% + \c@pgf@counta=0\relax% + \let\tikz@lib@dec@te@tmp=\pgfutil@empty% + \let\tikz@lib@dec@te@@tmp=\pgfutil@empty% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \ifx\tikz@lib@dec@te@@tmp\pgfutil@empty% + \else% + \advance\c@pgf@counta by1\relax% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}% + \fi% + \else% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@tmp}{tikz@lib@dec@te@character@\pgfmathcounter @token}% + \ifx\tikz@lib@dec@te@tmp\tikz@lib@dec@te@wordsep% + \advance\c@pgf@counta by1\relax% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@@tmp}% + \let\tikz@lib@dec@te@@tmp=\pgfutil@empty% + \advance\c@pgf@counta by1\relax% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@character@\the\c@pgf@counta @token}{tikz@lib@dec@te@wordsep}% + \else% + \expandafter\tikz@lib@dec@te@addto@macro\expandafter{\expandafter\tikz@lib@dec@te@@tmp\expandafter}\expandafter{\tikz@lib@dec@te@tmp}% + \fi% + \repeatpgfmathloop% + \edef\tikz@lib@dec@te@charactertotalcount{\the\c@pgf@counta}% +} + + +% Get width of node containing only the current character. +\def\tikz@lib@dec@te@getcharacterwidth#1{% + \csname tikz@lib@dec@te@character@#1\endcsname% + \tikz@lib@dec@te@getoptions{every character width/.try}% + \let\tikz@lib@dec@te@lastcharacterwidth=\tikz@lib@dec@te@characterwidth% + \pgfpositionnodelater\tikz@lib@dec@te@@getcharacterwidth% + \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{% + \expandafter\node\expandafter[\tikz@lib@dec@te@options,scale=\tikz@lib@dec@scaledcharacterwidthfactor]% + {\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};% + \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@characterwidth@tmp% + }{% + \tikz@lib@dec@te@getcharacter@replacementwidth{\tikz@lib@dec@te@character}% + \let\tikz@lib@dec@te@characterwidth=\tikz@lib@dec@te@character@replacementwidth% + }% +} + +% Update the character parameters with the widths. +\def\tikz@lib@dec@te@addwidthstoparameters{% + \pgfmathloop% + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterwidth}{tikz@lib@dec@te@character@\pgfmathcounter @width}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterprewidth}{tikz@lib@dec@te@character@\pgfmathcounter @prewidth}% + \tikz@lib@dec@te@namelet{tikz@lib@dec@te@characterpostwidth}{tikz@lib@dec@te@character@\pgfmathcounter @postwidth}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterwidth}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterprewidth}% + \tikz@lib@dec@te@addmacroto@parameters{\pgfmathcounter}{\tikz@lib@dec@te@characterpostwidth}% + \repeatpgfmathloop% +} + +% Get the options to applied to a character node. + +\def\tikz@lib@dec@te@addoptions#1{% + \expandafter\def\expandafter\tikz@lib@dec@te@options\expandafter{\tikz@lib@dec@te@options,#1}% +} + +\def\tikz@lib@dec@te@getoptions#1{% + \let\tikz@lib@dec@te@lastcharactercommand=\tikz@lib@dec@te@charactercommand% + \def\tikz@lib@dec@te@options{/pgf/decoration/text effects/.cd}% + \tikz@lib@dec@te@addoptions{#1}% + \let\tikzdecorationcharactercount=\tikz@lib@dec@te@charactercount% + \let\tikzdecorationcharactertotal=\tikz@lib@dec@te@charactertotalcount% + \let\tikzdecorationlettercount=\tikz@lib@dec@te@lettercount% + \let\tikzdecorationlettertotal=\tikz@lib@dec@te@lettertotalcount% + \let\tikzdecorationwordcount=\tikz@lib@dec@te@wordcount% + \let\tikzdecorationwordtotal=\tikz@lib@dec@te@wordtotal% + \let\tikzdecorationcharacter=\tikz@lib@dec@te@character% + % + % Define the count variables (if required) + \ifx\tikz@lib@dec@te@charactercountvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@charactercountvar=\tikz@lib@dec@te@charactercount% + \fi% + % + \ifx\tikz@lib@dec@te@charactertotalvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@charactertotalvar=\tikz@lib@dec@te@charactertotalcount% + \fi% + % + \ifx\tikz@lib@dec@te@wordcountvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@wordcountvar=\tikz@lib@dec@te@wordcount% + \fi% + % + \ifx\tikz@lib@dec@te@wordtotalvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@wordtotalvar=\tikz@lib@dec@te@wordtotal% + \fi% + % + \ifx\tikz@lib@dec@te@lettercountvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@lettercountvar=\tikz@lib@dec@te@lettercount% + \fi% + % + \ifx\tikz@lib@dec@te@lettertotalvar\pgfutil@empty% + \else% + \expandafter\let\tikz@lib@dec@te@lettertotalvar=\tikz@lib@dec@te@lettetotal% + \fi% + % + \edef\tikz@lib@dec@te@tmp{character \tikz@lib@dec@te@charactercount/.try,% + character {\meaning\tikz@lib@dec@te@character}/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \ifx\tikz@lib@dec@te@character\tikz@lib@dec@te@wordsep% + \tikz@lib@dec@te@addoptions{/pgf/decoration/text effects/every word separator/.try}% + \else% + \ifnum\tikz@lib@dec@te@wordcount>0\relax% + \edef\tikz@lib@dec@te@tmp{every word/.try, word \tikz@lib@dec@te@wordcount/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \ifnum\tikz@lib@dec@te@lettercount>0\relax% + \edef\tikz@lib@dec@te@tmp{every letter/.try,every \tikz@lib@dec@te@lettercount\space letter/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \ifnum\tikz@lib@dec@te@lettercount=1\relax% + \edef\tikz@lib@dec@te@tmp{every first letter/.try}% + \expandafter\tikz@lib@dec@te@addoptions\expandafter{\tikz@lib@dec@te@tmp}% + \fi% + \iftikz@lib@dec@te@finalletter% + \tikz@lib@dec@te@addoptions{every final letter/.try}% + \fi% + \fi% + \fi% + \fi% +} + +% Called by `late positioning' of the node +% to get the width of the bounding box +% of a character. +\def\tikz@lib@dec@te@@getcharacterwidth{% + \iftikz@lib@dec@te@segmentfromwidth% + \pgf@x=\pgfpositionnodelatermaxx\relax% + \advance\pgf@x by-\pgfpositionnodelaterminx\relax% + \else% + \pgf@x=\pgfpositionnodelatermaxy\relax% + \advance\pgf@x by-\pgfpositionnodelaterminy\relax% + \fi% + \xdef\tikz@lib@dec@te@characterwidth@tmp{\the\pgf@x}% +} + + +\def\tikz@lib@dec@te@drawcharacter{% + \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname% + \tikz@lib@dec@te@getoptions{every character/.try}% + \pgfpositionnodelater\relax% + \pgfutil@ifundefined{tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code}{% + \expandafter\node\expandafter[\tikz@lib@dec@te@options, scale=\tikz@lib@dec@scaledcharacterwidthfactor]{\hbox{\tikz@lib@dec@te@charactercommand{\tikz@lib@dec@te@character}}};% + }{\tikz@lib@dec@te@drawcharacter@replacement{\tikz@lib@dec@te@character}}% +} + +% Replace the character #1 with a character@replacement +% +\def\tikz@lib@dec@te@drawcharacter@replacement#1{% + \pgfscope% + \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}% + \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname% + \endpgfscope% +} + +% Get the width of the character@replacement associated with +% the character #1 +% +\newbox\tikz@lib@dec@te@box +\def\tikz@lib@dec@te@getcharacter@replacementwidth#1{% + \pgfinterruptpicture% + \setbox\tikz@lib@dec@te@box=\hbox{% + \pgfpicture + \expandafter\tikzset\expandafter{\tikz@lib@dec@te@options}% + \csname tikz@lib@dec@te@character@replacements@\meaning#1@code\endcsname% + \endpgfpicture}% + \xdef\tikz@lib@dec@te@character@replacementwidth{\the\wd\tikz@lib@dec@te@box}% + \endpgfinterruptpicture% +} + +\def\tikz@lib@dec@scaledcharacterwidthfactor{1}% + +% Set up the decoration +\def\tikz@lib@dec@te@state@setup@precomputation{% + \def\tikz@lib@te@alignshift{0pt}% + \iftikz@lib@dec@te@pathfromtext% + % The width of the text and characters has already been calculated. + \else% + \let\tikz@lib@dec@te@text=\pgfdecorationtext% + % Get the chracter tokens and the total number of characters. + \tikz@lib@dec@te@preparetext% + \iftikz@lib@dec@te@scaletexttopath% + % OK, *scaling* text to path is easy. + % Simply divide the path length by the text width to + % obtain the scaling factor which will be applied + % "at the last minute"... + \pgfmathdivide{\pgfdecoratedpathlength}{\tikz@lib@dec@te@textwidth}% + \let\tikz@lib@dec@scaledcharacterwidthfactor=\pgfmathresult% + \expandafter\pgfkeys\expandafter{\tikz@lib@dec@te@tmp}% + % ... and recalulate the (pre and post) widths. + \pgfmathloop + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount% + \else% + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% + % + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@scaledcharacterwidthfactor\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% + \repeatpgfmathloop% + % Update parameters with thewidths. + \tikz@lib@dec@te@addwidthstoparameters% + \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength% + \else% + \iftikz@lib@dec@te@fittexttopath% + % *Fitting* text is less easy. + % The pre and post width of all except the first and last characters + % must be recalculated. + % Only the post width of the first character and the pre width + % of the final character are scaled as these characters should be + % fixed and the start and end of the path, respectively. + % + % We hope that the decoration engine is accurate enough to position + % the last word correctly. + \pgf@x=\pgfdecoratedpathlength% + \pgf@xa=\csname tikz@lib@dec@te@character@1@postwidth\endcsname\relax% + \pgf@xb=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @prewidth\endcsname\relax% + \advance\pgf@x by-\pgf@xa% + \advance\pgf@x by-\pgf@xb% + \pgf@y=\tikz@lib@dec@te@textwidth\relax% + \advance\pgf@y by-\pgf@xa% + \advance\pgf@y by-\pgf@xb% + % + \pgfmathdivide{\the\pgf@x}{\the\pgf@y}% + \let\tikz@lib@dec@characterwidthscale=\pgfmathresult% + \pgfmathloop + \ifnum\pgfmathcounter>\tikz@lib@dec@te@charactertotalcount\relax% + \else% + \ifnum\pgfmathcounter>1\relax% + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @prewidth\endcsname{\the\pgf@x}% + \fi% + \ifnum\pgfmathcounter<\tikz@lib@dec@te@charactertotalcount\relax% + \pgf@x=\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname\relax% + \pgf@x=\tikz@lib@dec@characterwidthscale\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\pgfmathcounter @postwidth\endcsname{\the\pgf@x}% + \fi% + \repeatpgfmathloop% + % Update parameters with widths. + \tikz@lib@dec@te@addwidthstoparameters% + \let\tikz@lib@dec@te@textwidth=\pgfdecoratedpathlength% + \else% + % Calculate the distance to move along the path for alignment. + \pgfkeysgetvalue{/pgf/decoration/text align/align}{\tikz@lib@dec@align}% + \ifx\tikz@lib@dec@align\tikz@lib@dec@align@center@text% + \pgf@x=\pgfdecoratedpathlength\relax% + \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax% + \ifdim\pgf@x<0pt\relax% + \pgf@x=0pt\relax% + \fi% + \divide\pgf@x by2\relax% + % Adjust the pre-width of the first character... + \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax% + \advance\pgf@xa by\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}% + % ...and the post-width of the last character. + \pgf@xa=\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname\relax% + \advance\pgf@xa by\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactertotalcount @postwidth\endcsname{\the\pgf@xa}% + \else% + \ifx\tikz@lib@dec@align\tikz@lib@dec@align@right@text% + \pgf@x=\pgfdecoratedpathlength\relax% + \advance\pgf@x by-\tikz@lib@dec@te@textwidth\relax% + \ifdim\pgf@x<0pt\relax% + \pgf@x=0pt\relax% + \fi% + % Adjust the pre-width of the first character... + \pgf@xa=\csname tikz@lib@dec@te@character@1@prewidth\endcsname\relax% + \advance\pgf@xa by\pgf@x% + \expandafter\edef\csname tikz@lib@dec@te@character@1@prewidth\endcsname{\the\pgf@xa}% + \fi% + \fi% + \tikz@lib@dec@te@addwidthstoparameters% + \fi% + \fi% + \fi% +} + + +% Evil hack into the decoration code. +% +% If the path contains single move to and the `path from text' +% key is set to true. The width of the text is calcuated here +% and the (straight line) path automatically calculated. +% +\def\pgf@decorate@path@check@moveto#1{% + \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} + +\def\pgf@decorate@token@stop{\pgf@decorate@stop}% +\def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{% + \def\pgf@decorate@temp{#4}% + \pgf@x=#2\relax% + \pgf@y=#3\relax% + \ifx\pgf@decorate@temp\pgf@decorate@token@stop% + \iftikz@lib@dec@te@pathfromtext% + % Get the start position... + \pgfextract@process\tikz@lib@dec@te@pathstart{}% + \tikz@lib@dec@te@preparetext% + \tikz@lib@dec@te@addwidthstoparameters% + % ... and create a lineto path of the correct length. + \pgfsetpath\pgfutil@empty% + \pgfpathmoveto{\tikz@lib@dec@te@pathstart}% + \pgfpathlineto{\pgfpointadd{\tikz@lib@dec@te@pathstart}% + {\pgfpointpolar{\tikz@lib@dec@te@pathfromtextangle}{\tikz@lib@dec@te@textwidth}}}% + \pgfgetpath\pgfdecoratedpath% + \pgfsetpath\pgfutil@empty% + \else% + #5% + \fi% + \else% + \tikz@lib@dec@te@pathfromtextfalse% + #6% + \fi% +} + + +\pgfdeclaredecoration{text effects along path}{setup}{ + \state{setup}[width=+0pt, next state=scan, persistent precomputation={% + \tikz@lib@dec@te@state@setup@precomputation% + \def\tikz@lib@dec@te@charactercount{0}% + }]{} + % +\state{scan}[width=+0pt, next state=pre token, persistent precomputation={% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@charactercount{1}% + % Usual switch to final state is based on distance. + % Here we also need it to be on the number of the + % current character. + \ifnum\tikz@lib@dec@te@charactercount>\tikz@lib@dec@te@charactertotalcount\relax% + \ifnum\tikz@lib@dec@te@repeattext=0\relax% + \def\pgf@decorate@next@state{final}% + \else% + \tikz@lib@dec@te@advancecountmacro\tikz@lib@dec@te@repeattext{-1}% + \def\tikz@lib@dec@te@charactercount{1}% + \fi% + \fi% + % Install parameters for this character. + \csname tikz@lib@dec@te@character@\tikz@lib@dec@te@charactercount\endcsname% +}]{} +% +\state{pre token}[width=+\tikz@lib@dec@te@characterprewidth, next state=token]{} +\state{token}[width=+0pt, next state=post token] +{% + \tikz@lib@dec@te@drawcharacter% +} +\state{post token}[width=+\tikz@lib@dec@te@characterpostwidth, next state=scan]{} +} + + +% Parse styles for individual characters +% #1 a string of characters (e.g., aieou{\"U}{\"a"}) +% #2 the options for to apply to each character. +% +\def\tikz@lib@dec@te@parse@stylecharacters#1#2{% + \def\tikz@lib@dec@te@text{#1}% + \tikz@lib@dec@te@scancharacters{% + \pgfkeysalso{/pgf/decoration/text effects/character {\meaning\tikz@lib@dec@te@character}/.style={#2}}% + }% +} + +% Parse replacment code for for individual characters +% #1 a string of characters (e.g., aieou{\"U}{\"a"}) +% #2 the code to execute to each character. +% +\def\tikz@lib@dec@te@parse@replacecharacters#1#2{% + \def\tikz@lib@dec@te@text{#1}% + \tikz@lib@dec@te@scancharacters{% + \expandafter\def\csname tikz@lib@dec@te@character@replacements@\meaning\tikz@lib@dec@te@character @code\endcsname{#2}% + }% +} + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex index 2ae21de0420..ef6a88dc1a9 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex @@ -7,10 +7,10 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex,v 1.3 2008/06/21 18:59:25 vibrovski Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfit.code.tex,v 1.5 2013/07/12 17:33:49 tantau Exp $ \pgfkeys{/tikz/fit/.code=\tikz@lib@fit{#1}, - /tikz/rotate fit/.code=\def\tikz@lib@fit@rotate{#1}\pgfkeysalso{/tikz/rotate=#1} + /tikz/rotate fit/.code=\def\tikz@lib@fit@rotate{#1}\pgfkeysalso{/tikz/rotate=#1} } \def\tikz@lib@fit@rotate{0} @@ -37,31 +37,33 @@ \advance\pgf@xa by.5\pgf@x% \advance\pgf@ya by.5\pgf@y% \ifdim\tikz@lib@fit@rotate pt=0pt\relax% - \edef\tikz@node@at{\noexpand\pgfpoint{\the\pgf@xa}{\the\pgf@ya}}% + {% + \pgftransforminvert% + \pgf@pos@transform{\pgf@xa}{\pgf@ya}% + \global\pgf@xa\pgf@xa + \global\pgf@ya\pgf@ya + } \else% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - {% - \pgf@xc=\pgf@xa% - \pgf@yc=\pgf@ya% - \pgfgettransform\tikz@lib@fit@transform% - \pgftransforminvert% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgftransformreset% - \pgftransformrotate{\tikz@lib@fit@rotate}% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgfsettransform\tikz@lib@fit@transform% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \global\pgf@x=\pgf@xc% - \global\pgf@y=\pgf@yc% - }% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% - \pgf@x=\pgf@xc% - \pgf@y=\pgf@yc% - \fi% - \edef\tikz@node@at{\noexpand\pgfpoint{\the\pgf@xa}{\the\pgf@ya}}% - \pgfkeysalso{/tikz/anchor=center,/tikz/text centered}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + {% + \pgf@xc=\pgf@xa% + \pgf@yc=\pgf@ya% + \pgftransforminvert% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \pgftransformreset% + \pgftransformrotate{\tikz@lib@fit@rotate}% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \global\pgf@x=\pgf@xc% + \global\pgf@y=\pgf@yc% + }% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \fi% + \edef\tikz@node@at{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \pgfkeysalso{/tikz/anchor=center,/tikz/text badly centered}% \pgfkeysalso{/tikz/text width/.expanded=\the\pgf@x}% \pgf@x=\pgf@y% \pgf@y=.5\pgf@y% @@ -90,25 +92,25 @@ } \def\tikz@lib@fit@adjust#1{% - \ifdim\tikz@lib@fit@rotate pt=0pt\relax% - \pgf@process{#1}% - \else% - {% - #1% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \pgfgettransform\tikz@lib@fit@transform% - \pgftransforminvert% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgftransformreset% - \pgftransformrotate{-\tikz@lib@fit@rotate}% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \pgfsettransform\tikz@lib@fit@transform% - \pgf@pos@transform{\pgf@xc}{\pgf@yc}% - \global\pgf@x=\pgf@xc% - \global\pgf@y=\pgf@yc% - }% - \fi% + \ifdim\tikz@lib@fit@rotate pt=0pt\relax% + \pgf@process{\pgfpointtransformed{#1}}% + \else% + {% + \pgf@process{\pgfpointtransformed{#1}}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgfgettransform\tikz@lib@fit@transform% + \pgftransforminvert% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \pgftransformreset% + \pgftransformrotate{-\tikz@lib@fit@rotate}% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \pgfsettransform\tikz@lib@fit@transform% + \pgf@pos@transform{\pgf@xc}{\pgf@yc}% + \global\pgf@x=\pgf@xc% + \global\pgf@y=\pgf@yc% + }% + \fi% \ifdim\pgf@x<\pgf@xa% \pgf@xa=\pgf@x% \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex index 2ecdfeb11c7..1c45b6eac4d 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex @@ -1,4 +1,5 @@ % Copyright 2006 by Till Tantau +% Copyright 2013 by Nico Van Cleemput % % This file may be distributed and/or modified % @@ -7,7 +8,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex,v 1.1 2008/01/09 17:57:16 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryfolding.code.tex,v 1.3 2013/08/28 11:00:54 tantau Exp $ % @@ -18,6 +19,41 @@ \newdimen\tikz@lib@fold@length \tikz@lib@fold@length=2cm +% Faces +% ----- + +\def\tikz@lib@fold@triangle#1#2#3#4{% + \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=.28868\tikz@lib@fold@length] + #1 + \end{scope} + \begin{scope}[shift={(60:\tikz@lib@fold@length)},rotate=-60] + #2 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,rotate=180] + #3 + \end{scope} + \begin{scope}[rotate=60] + #4 + \end{scope} +} + +\def\tikz@lib@fold@square#1#2#3#4#5{% + \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=.5\tikz@lib@fold@length] + #1 + \end{scope} + \begin{scope}[yshift=\tikz@lib@fold@length] + #2 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,yshift=\tikz@lib@fold@length,rotate=-90] + #3 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,rotate=180] + #4 + \end{scope} + \begin{scope}[rotate=90] + #5 + \end{scope} +} \def\tikz@lib@fold@pentagon#1#2#3#4#5#6{% \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=0.68819\tikz@lib@fold@length] @@ -40,13 +76,165 @@ \end{scope} } +\def\tikz@lib@fold@hexagon#1#2#3#4#5#6#7{% + \begin{scope} + [shift={(60:\tikz@lib@fold@length)}] + #1 + \end{scope} + \begin{scope} + [shift={(120:\tikz@lib@fold@length)}, + shift={(60:\tikz@lib@fold@length)}] + #2 + \end{scope} + \begin{scope} + [shift={(120:\tikz@lib@fold@length)}, + shift={(60:\tikz@lib@fold@length)}, + xshift=\tikz@lib@fold@length, + rotate=-60] + #3 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(60:\tikz@lib@fold@length)}, + rotate=-120] + #4 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + rotate=180] + #5 + \end{scope} + \begin{scope} + [rotate=120] + #6 + \end{scope} + \begin{scope} + [shift={(120:\tikz@lib@fold@length)}, + rotate=60] + #7 + \end{scope} +} + +\def\tikz@lib@fold@octagon#1#2#3#4#5#6#7#8#9{% + \begin{scope}[xshift=.5\tikz@lib@fold@length,yshift=1.20711\tikz@lib@fold@length] + #1 + \end{scope} + \begin{scope}[yshift=2.41421\tikz@lib@fold@length] + #2 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,yshift=2.41421\tikz@lib@fold@length,rotate=-45] + #3 + \end{scope} + \begin{scope}[xshift=1.70711\tikz@lib@fold@length,yshift=1.70711\tikz@lib@fold@length,rotate=-90] + #4 + \end{scope} + \begin{scope}[xshift=1.70711\tikz@lib@fold@length,yshift=.70711\tikz@lib@fold@length,rotate=-135] + #5 + \end{scope} + \begin{scope}[xshift=\tikz@lib@fold@length,rotate=180] + #6 + \end{scope} + \begin{scope}[rotate=135] + #7 + \end{scope} + \begin{scope}[xshift=-.70711\tikz@lib@fold@length,yshift=.70711\tikz@lib@fold@length,rotate=90] + #8 + \end{scope} + \begin{scope}[xshift=-.70711\tikz@lib@fold@length,yshift=1.70711\tikz@lib@fold@length,rotate=45] + #9 + \end{scope} +} + +\def\tikz@lib@fold@decagon#1#2#3#4#5#6#7{% + \begin{scope}[shift={(72:1.61803\tikz@lib@fold@length)}] %decagon inside a circle with radius the golden ratio has side length 1 + #1 + \end{scope} + \begin{scope} + [shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + shift={(144:\tikz@lib@fold@length)}] + #2 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + shift={(144:\tikz@lib@fold@length)}, + rotate=-36] + #3 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + rotate=-72] + #4 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + rotate=-108] + #5 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + shift={(36:\tikz@lib@fold@length)}, + rotate=-144] + #6 + \end{scope} + \begin{scope} + [xshift=\tikz@lib@fold@length, + rotate=180] + #7 + \end{scope} + \tikz@lib@fold@decagonbis +} + +\def\tikz@lib@fold@decagonbis#1#2#3#4{% + \begin{scope} + [rotate=144] + #1 + \end{scope} + \begin{scope} + [shift={(144:\tikz@lib@fold@length)}, + rotate=108] + #2 + \end{scope} + \begin{scope} + [shift={(144:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + rotate=72] + #3 + \end{scope} + \begin{scope} + [shift={(144:\tikz@lib@fold@length)}, + shift={(108:\tikz@lib@fold@length)}, + shift={(72:\tikz@lib@fold@length)}, + rotate=36] + #4 + \end{scope} +} \def\tikz@lib@fold@path{\draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt);} \def\tikz@lib@fold@cut@path{\draw[every cut](0,0) -- (\tikz@lib@fold@length,0pt);} \def\tikz@lib@fold@ear@path{ + \path[every ear] (0,0) -- (.5\tikz@lib@fold@length,.2\tikz@lib@fold@length) --(\tikz@lib@fold@length,0pt) --(0,0) -- cycle; \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt); \draw[every cut] (0,0) -- (.5\tikz@lib@fold@length,.2\tikz@lib@fold@length) --(\tikz@lib@fold@length,0pt);} +\def\tikz@lib@fold@ear@custom@left@path#1{ + \path[every ear] (0,0) -- (#1:.66\tikz@lib@fold@length) -- (\tikz@lib@fold@length,0pt) --(0,0) -- cycle; + \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt); + \draw[every cut] (0,0) -- (#1:.66\tikz@lib@fold@length) -- (\tikz@lib@fold@length,0pt);} +\def\tikz@lib@fold@ear@custom@right@path#1{ + \path[every ear] (0,0) -- (\tikz@lib@fold@length,0pt) -- ++(-#1:-.66\tikz@lib@fold@length) --(0,0) -- cycle; + \draw[every fold](0,0) -- (\tikz@lib@fold@length,0pt); + \draw[every cut] (\tikz@lib@fold@length,0pt) -- ++(-#1:-.66\tikz@lib@fold@length) -- (0,0);} +\tikzstyle{every ear}=[] \tikzstyle{every cut}=[] \tikzstyle{every fold}=[help lines] @@ -62,6 +250,87 @@ \tikzoption{face 10}{\def\tikz@lib@fold@face@J{#1}} \tikzoption{face 11}{\def\tikz@lib@fold@face@K{#1}} \tikzoption{face 12}{\def\tikz@lib@fold@face@L{#1}} +\tikzoption{face 13}{\def\tikz@lib@fold@face@M{#1}} +\tikzoption{face 14}{\def\tikz@lib@fold@face@N{#1}} +\tikzoption{face 15}{\def\tikz@lib@fold@face@O{#1}} +\tikzoption{face 16}{\def\tikz@lib@fold@face@P{#1}} +\tikzoption{face 17}{\def\tikz@lib@fold@face@Q{#1}} +\tikzoption{face 18}{\def\tikz@lib@fold@face@R{#1}} +\tikzoption{face 19}{\def\tikz@lib@fold@face@S{#1}} +\tikzoption{face 20}{\def\tikz@lib@fold@face@T{#1}} +\tikzoption{face 21}{\def\tikz@lib@fold@face@U{#1}} +\tikzoption{face 22}{\def\tikz@lib@fold@face@V{#1}} +\tikzoption{face 23}{\def\tikz@lib@fold@face@W{#1}} +\tikzoption{face 24}{\def\tikz@lib@fold@face@X{#1}} +\tikzoption{face 25}{\def\tikz@lib@fold@face@Y{#1}} +\tikzoption{face 26}{\def\tikz@lib@fold@face@Z{#1}} +\tikzoption{face 27}{\def\tikz@lib@fold@face@AA{#1}} +\tikzoption{face 28}{\def\tikz@lib@fold@face@AB{#1}} +\tikzoption{face 29}{\def\tikz@lib@fold@face@AC{#1}} +\tikzoption{face 30}{\def\tikz@lib@fold@face@AD{#1}} +\tikzoption{face 31}{\def\tikz@lib@fold@face@AE{#1}} +\tikzoption{face 32}{\def\tikz@lib@fold@face@AF{#1}} +\tikzoption{face 33}{\def\tikz@lib@fold@face@AG{#1}} +\tikzoption{face 34}{\def\tikz@lib@fold@face@AH{#1}} +\tikzoption{face 35}{\def\tikz@lib@fold@face@AI{#1}} +\tikzoption{face 36}{\def\tikz@lib@fold@face@AJ{#1}} +\tikzoption{face 37}{\def\tikz@lib@fold@face@AK{#1}} +\tikzoption{face 38}{\def\tikz@lib@fold@face@AL{#1}} +\tikzoption{face 39}{\def\tikz@lib@fold@face@AM{#1}} +\tikzoption{face 40}{\def\tikz@lib@fold@face@AN{#1}} +\tikzoption{face 41}{\def\tikz@lib@fold@face@AO{#1}} +\tikzoption{face 42}{\def\tikz@lib@fold@face@AP{#1}} +\tikzoption{face 43}{\def\tikz@lib@fold@face@AQ{#1}} +\tikzoption{face 44}{\def\tikz@lib@fold@face@AR{#1}} +\tikzoption{face 45}{\def\tikz@lib@fold@face@AS{#1}} +\tikzoption{face 46}{\def\tikz@lib@fold@face@AT{#1}} +\tikzoption{face 47}{\def\tikz@lib@fold@face@AU{#1}} +\tikzoption{face 48}{\def\tikz@lib@fold@face@AV{#1}} +\tikzoption{face 49}{\def\tikz@lib@fold@face@AW{#1}} +\tikzoption{face 50}{\def\tikz@lib@fold@face@AX{#1}} +\tikzoption{face 51}{\def\tikz@lib@fold@face@AY{#1}} +\tikzoption{face 52}{\def\tikz@lib@fold@face@AZ{#1}} +\tikzoption{face 53}{\def\tikz@lib@fold@face@BA{#1}} +\tikzoption{face 54}{\def\tikz@lib@fold@face@BB{#1}} +\tikzoption{face 55}{\def\tikz@lib@fold@face@BC{#1}} +\tikzoption{face 56}{\def\tikz@lib@fold@face@BD{#1}} +\tikzoption{face 57}{\def\tikz@lib@fold@face@BE{#1}} +\tikzoption{face 58}{\def\tikz@lib@fold@face@BF{#1}} +\tikzoption{face 59}{\def\tikz@lib@fold@face@BG{#1}} +\tikzoption{face 60}{\def\tikz@lib@fold@face@BH{#1}} +\tikzoption{face 61}{\def\tikz@lib@fold@face@BI{#1}} +\tikzoption{face 62}{\def\tikz@lib@fold@face@BJ{#1}} +\tikzoption{face 63}{\def\tikz@lib@fold@face@BK{#1}} +\tikzoption{face 64}{\def\tikz@lib@fold@face@BL{#1}} +\tikzoption{face 65}{\def\tikz@lib@fold@face@BM{#1}} +\tikzoption{face 66}{\def\tikz@lib@fold@face@BN{#1}} +\tikzoption{face 67}{\def\tikz@lib@fold@face@BO{#1}} +\tikzoption{face 68}{\def\tikz@lib@fold@face@BP{#1}} +\tikzoption{face 69}{\def\tikz@lib@fold@face@BQ{#1}} +\tikzoption{face 70}{\def\tikz@lib@fold@face@BR{#1}} +\tikzoption{face 71}{\def\tikz@lib@fold@face@BS{#1}} +\tikzoption{face 72}{\def\tikz@lib@fold@face@BT{#1}} +\tikzoption{face 73}{\def\tikz@lib@fold@face@BU{#1}} +\tikzoption{face 74}{\def\tikz@lib@fold@face@BV{#1}} +\tikzoption{face 75}{\def\tikz@lib@fold@face@BW{#1}} +\tikzoption{face 76}{\def\tikz@lib@fold@face@BX{#1}} +\tikzoption{face 77}{\def\tikz@lib@fold@face@BY{#1}} +\tikzoption{face 78}{\def\tikz@lib@fold@face@BZ{#1}} +\tikzoption{face 79}{\def\tikz@lib@fold@face@CA{#1}} +\tikzoption{face 80}{\def\tikz@lib@fold@face@CB{#1}} +\tikzoption{face 81}{\def\tikz@lib@fold@face@CC{#1}} +\tikzoption{face 82}{\def\tikz@lib@fold@face@CD{#1}} +\tikzoption{face 83}{\def\tikz@lib@fold@face@CE{#1}} +\tikzoption{face 84}{\def\tikz@lib@fold@face@CF{#1}} +\tikzoption{face 85}{\def\tikz@lib@fold@face@CG{#1}} +\tikzoption{face 86}{\def\tikz@lib@fold@face@CH{#1}} +\tikzoption{face 87}{\def\tikz@lib@fold@face@CI{#1}} +\tikzoption{face 88}{\def\tikz@lib@fold@face@CJ{#1}} +\tikzoption{face 89}{\def\tikz@lib@fold@face@CK{#1}} +\tikzoption{face 90}{\def\tikz@lib@fold@face@CL{#1}} +\tikzoption{face 91}{\def\tikz@lib@fold@face@CM{#1}} +\tikzoption{face 92}{\def\tikz@lib@fold@face@CN{#1}} + \let\tikz@lib@fold@face@A=\pgfutil@empty \let\tikz@lib@fold@face@B=\pgfutil@empty @@ -75,69 +344,1734 @@ \let\tikz@lib@fold@face@J=\pgfutil@empty \let\tikz@lib@fold@face@K=\pgfutil@empty \let\tikz@lib@fold@face@L=\pgfutil@empty +\let\tikz@lib@fold@face@M=\pgfutil@empty +\let\tikz@lib@fold@face@N=\pgfutil@empty +\let\tikz@lib@fold@face@O=\pgfutil@empty +\let\tikz@lib@fold@face@P=\pgfutil@empty +\let\tikz@lib@fold@face@Q=\pgfutil@empty +\let\tikz@lib@fold@face@R=\pgfutil@empty +\let\tikz@lib@fold@face@S=\pgfutil@empty +\let\tikz@lib@fold@face@T=\pgfutil@empty +\let\tikz@lib@fold@face@U=\pgfutil@empty +\let\tikz@lib@fold@face@V=\pgfutil@empty +\let\tikz@lib@fold@face@W=\pgfutil@empty +\let\tikz@lib@fold@face@X=\pgfutil@empty +\let\tikz@lib@fold@face@Y=\pgfutil@empty +\let\tikz@lib@fold@face@Z=\pgfutil@empty +\let\tikz@lib@fold@face@AA=\pgfutil@empty +\let\tikz@lib@fold@face@AB=\pgfutil@empty +\let\tikz@lib@fold@face@AC=\pgfutil@empty +\let\tikz@lib@fold@face@AD=\pgfutil@empty +\let\tikz@lib@fold@face@AE=\pgfutil@empty +\let\tikz@lib@fold@face@AF=\pgfutil@empty +\let\tikz@lib@fold@face@AG=\pgfutil@empty +\let\tikz@lib@fold@face@AH=\pgfutil@empty +\let\tikz@lib@fold@face@AI=\pgfutil@empty +\let\tikz@lib@fold@face@AJ=\pgfutil@empty +\let\tikz@lib@fold@face@AK=\pgfutil@empty +\let\tikz@lib@fold@face@AL=\pgfutil@empty +\let\tikz@lib@fold@face@AM=\pgfutil@empty +\let\tikz@lib@fold@face@AN=\pgfutil@empty +\let\tikz@lib@fold@face@AO=\pgfutil@empty +\let\tikz@lib@fold@face@AP=\pgfutil@empty +\let\tikz@lib@fold@face@AQ=\pgfutil@empty +\let\tikz@lib@fold@face@AR=\pgfutil@empty +\let\tikz@lib@fold@face@AS=\pgfutil@empty +\let\tikz@lib@fold@face@AT=\pgfutil@empty +\let\tikz@lib@fold@face@AU=\pgfutil@empty +\let\tikz@lib@fold@face@AV=\pgfutil@empty +\let\tikz@lib@fold@face@AW=\pgfutil@empty +\let\tikz@lib@fold@face@AX=\pgfutil@empty +\let\tikz@lib@fold@face@AY=\pgfutil@empty +\let\tikz@lib@fold@face@AZ=\pgfutil@empty +\let\tikz@lib@fold@face@BA=\pgfutil@empty +\let\tikz@lib@fold@face@BB=\pgfutil@empty +\let\tikz@lib@fold@face@BC=\pgfutil@empty +\let\tikz@lib@fold@face@BD=\pgfutil@empty +\let\tikz@lib@fold@face@BE=\pgfutil@empty +\let\tikz@lib@fold@face@BF=\pgfutil@empty +\let\tikz@lib@fold@face@BG=\pgfutil@empty +\let\tikz@lib@fold@face@BH=\pgfutil@empty +\let\tikz@lib@fold@face@BI=\pgfutil@empty +\let\tikz@lib@fold@face@BJ=\pgfutil@empty +\let\tikz@lib@fold@face@BK=\pgfutil@empty +\let\tikz@lib@fold@face@BL=\pgfutil@empty +\let\tikz@lib@fold@face@BM=\pgfutil@empty +\let\tikz@lib@fold@face@BN=\pgfutil@empty +\let\tikz@lib@fold@face@BO=\pgfutil@empty +\let\tikz@lib@fold@face@BP=\pgfutil@empty +\let\tikz@lib@fold@face@BQ=\pgfutil@empty +\let\tikz@lib@fold@face@BR=\pgfutil@empty +\let\tikz@lib@fold@face@BS=\pgfutil@empty +\let\tikz@lib@fold@face@BT=\pgfutil@empty +\let\tikz@lib@fold@face@BU=\pgfutil@empty +\let\tikz@lib@fold@face@BV=\pgfutil@empty +\let\tikz@lib@fold@face@BW=\pgfutil@empty +\let\tikz@lib@fold@face@BX=\pgfutil@empty +\let\tikz@lib@fold@face@BY=\pgfutil@empty +\let\tikz@lib@fold@face@BZ=\pgfutil@empty +\let\tikz@lib@fold@face@CA=\pgfutil@empty +\let\tikz@lib@fold@face@CB=\pgfutil@empty +\let\tikz@lib@fold@face@CC=\pgfutil@empty +\let\tikz@lib@fold@face@CD=\pgfutil@empty +\let\tikz@lib@fold@face@CE=\pgfutil@empty +\let\tikz@lib@fold@face@CF=\pgfutil@empty +\let\tikz@lib@fold@face@CG=\pgfutil@empty +\let\tikz@lib@fold@face@CH=\pgfutil@empty +\let\tikz@lib@fold@face@CI=\pgfutil@empty +\let\tikz@lib@fold@face@CJ=\pgfutil@empty +\let\tikz@lib@fold@face@CK=\pgfutil@empty +\let\tikz@lib@fold@face@CL=\pgfutil@empty +\let\tikz@lib@fold@face@CM=\pgfutil@empty +\let\tikz@lib@fold@face@CN=\pgfutil@empty + + +\tikzstyle{numbered faces}=[% + face 1={\node{1};}, + face 2={\node{2};}, + face 3={\node{3};}, + face 4={\node{4};}, + face 5={\node{5};}, + face 6={\node{6};}, + face 7={\node{7};}, + face 8={\node{8};}, + face 9={\node{9};}, + face 10={\node{10};}, + face 11={\node{11};}, + face 12={\node{12};}, + face 13={\node{13};}, + face 14={\node{14};}, + face 15={\node{15};}, + face 16={\node{16};}, + face 17={\node{17};}, + face 18={\node{18};}, + face 19={\node{19};}, + face 20={\node{20};}, + face 21={\node{21};}, + face 22={\node{22};}, + face 23={\node{23};}, + face 24={\node{24};}, + face 25={\node{25};}, + face 26={\node{26};}, + face 27={\node{27};}, + face 28={\node{28};}, + face 29={\node{29};}, + face 30={\node{30};}, + face 31={\node{31};}, + face 32={\node{32};}, + face 33={\node{33};}, + face 34={\node{34};}, + face 35={\node{35};}, + face 36={\node{36};}, + face 37={\node{37};}, + face 38={\node{38};}, + face 39={\node{39};}, + face 40={\node{40};}, + face 41={\node{41};}, + face 42={\node{42};}, + face 43={\node{43};}, + face 44={\node{44};}, + face 45={\node{45};}, + face 46={\node{46};}, + face 47={\node{47};}, + face 48={\node{48};}, + face 49={\node{49};}, + face 50={\node{50};}, + face 51={\node{51};}, + face 52={\node{52};}, + face 53={\node{53};}, + face 54={\node{54};}, + face 55={\node{55};}, + face 56={\node{56};}, + face 57={\node{57};}, + face 58={\node{58};}, + face 59={\node{59};}, + face 60={\node{60};}, + face 61={\node{61};}, + face 62={\node{62};}, + face 63={\node{63};}, + face 64={\node{64};}, + face 65={\node{65};}, + face 66={\node{66};}, + face 67={\node{67};}, + face 68={\node{68};}, + face 69={\node{69};}, + face 70={\node{70};}, + face 71={\node{71};}, + face 72={\node{72};}, + face 73={\node{73};}, + face 74={\node{74};}, + face 75={\node{75};}, + face 76={\node{76};}, + face 77={\node{77};}, + face 78={\node{78};}, + face 79={\node{79};}, + face 80={\node{80};}, + face 81={\node{81};}, + face 82={\node{82};}, + face 83={\node{83};}, + face 84={\node{84};}, + face 85={\node{85};}, + face 86={\node{86};}, + face 87={\node{87};}, + face 88={\node{88};}, + face 89={\node{89};}, + face 90={\node{90};}, + face 91={\node{91};}, + face 92={\node{92};}] + +% The foldings defined here: + +\tikzset{ + pics/dodecahedron folding/.style = {code=\tikzfoldingdodecahedron[];}, + pics/tetrahedron folding/.style = {code=\tikzfoldingtetrahedron[];}, + pics/tetrahedron truncated folding/.style = {code=\tikzfoldingtruncatedtetrahedron[];}, + pics/cube folding/.style = {code=\tikzfoldingcube[];}, + pics/cube truncated folding/.style = {code=\tikzfoldingtruncatedcube[];}, + pics/octahedron folding/.style = {code=\tikzfoldingoctahedron[];}, + pics/octahedron truncated folding/.style = {code=\tikzfoldingtruncatedoctahedron[];}, + pics/dodecahedron folding/.style = {code=\tikzfoldingdodecahedron[];}, + pics/dodecahedron' folding/.style = {code=\tikzfoldingalternatedodecahedron[];}, + pics/cuboctahedron folding/.style = {code=\tikzfoldingoctahedron[];}, + pics/cuboctahedron truncated folding/.style = {code=\tikzfoldingtruncatedoctahedron[];}, + pics/icosahedron folding/.style = {code=\tikzfoldingicosahedron[];}, + pics/rhombicuboctahedron folding/.style = {code=\tikzfoldingrhombicuboctahedron[];}, + pics/snub cube folding/.style = {code=\tikzfoldingsnubcube[];}, + pics/icosidodecahedron folding/.style = {code=\tikzfoldingicosahedron[];} +} + + +% Platonic solids +% --------------- + \def\tikzfoldingdodecahedron#1[#2]#3;{% \begingroup% \tikzset{#2}% - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@A} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@B} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@C}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@ear@path} + \tikz@lib@fold@pentagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%alternative dodecahedron: larger format possible + +\def\tikzfoldingalternatedodecahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@pentagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + } + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@pentagon + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + \endgroup +} + + +%tetrahedron + +\def\tikzfoldingtetrahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@triangle + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%cube + +\def\tikzfoldingcube#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square{\tikz@lib@fold@face@A} { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@D} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@E}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + \tikz@lib@fold@square{\tikz@lib@fold@face@B} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} } { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@F} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@G}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + \tikz@lib@fold@square{\tikz@lib@fold@face@C} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} } { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@H} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@I}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@ear@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@ear@path} - } - {\tikz@lib@fold@ear@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + \tikz@lib@fold@square{\tikz@lib@fold@face@D} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} } { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@J} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@K} + \tikz@lib@fold@square{\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + + +%octahedron + +\def\tikzfoldingoctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@triangle + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + \endgroup +} + + +%icosahedron + +\def\tikzfoldingicosahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@triangle + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@O} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@P} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@Q} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@R} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@S} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + \endgroup +} + +% Archimedean solids +% ------------------ + +%truncated tetrahedron + +\def\tikzfoldingtruncatedtetrahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@hexagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%cuboctahedron + +\def\tikzfoldingcuboctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} + +%truncated cube + +\def\tikzfoldingtruncatedcube#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@octagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } {\tikz@lib@fold@cut@path} - { - \tikz@lib@fold@pentagon{\tikz@lib@fold@face@L}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@path}{\tikz@lib@fold@cut@path}{\tikz@lib@fold@cut@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + \endgroup +} + + +%truncated octahedron + +\def\tikzfoldingtruncatedoctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@hexagon + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + \endgroup +} + + +%rhombicuboctahedron + +\def\tikzfoldingrhombicuboctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@O} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@P} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@Q} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@R} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@S} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@U} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@V} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@W} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@triangle + {\tikz@lib@fold@face@X} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@square + {\tikz@lib@fold@face@Y} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@Z} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + \endgroup +} + +%truncated cuboctahedron + +\def\tikzfoldingtruncatedcuboctahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square + {\tikz@lib@fold@face@A} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@B} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@C} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@D} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@E} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@F} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@J} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@L} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@M} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} } - } - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@path} - {\tikz@lib@fold@cut@path} - {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@O} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@P} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@Q} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@R} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@S} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@U} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@V} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@W} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@square + {\tikz@lib@fold@face@X} + {\tikz@lib@fold@octagon + {\tikz@lib@fold@face@Y} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@hexagon + {\tikz@lib@fold@face@Z} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{15}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@custom@left@path{15}} + {\tikz@lib@fold@ear@path} + } + \endgroup +} + +%snub cube + +\def\tikzfoldingsnubcube#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@square{\tikz@lib@fold@face@A} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@B} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@C} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@E} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@F} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@J} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@K} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@L} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@M} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@N} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@O} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@P} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Q} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@R} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@S} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@T} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@U} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@V} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@W} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@X} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Y} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Z} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AA} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AB} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AC} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AD} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AE} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@AF} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AG} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AH} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AI} + { + \tikz@lib@fold@square{\tikz@lib@fold@face@AJ} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AK} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AL} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} } \endgroup } - +% icosidodecahedron + +\def\tikzfoldingicosidodecahedron#1[#2]#3;{% + \begingroup% + \tikzset{#2}% + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@A} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@B} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@C} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@D} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@E} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@F} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@G} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@H} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@I} + {\tikz@lib@fold@ear@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@J} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@K} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@L} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@M} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@N} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@O} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@P} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Q} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@R} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@S} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@T} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@U} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@V} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@ear@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@W} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@X} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@Y} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@Z} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + } + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AA} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@AB} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AC} + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + { + \tikz@lib@fold@pentagon{\tikz@lib@fold@face@AD} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AE} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + {\tikz@lib@fold@ear@path} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + { + \tikz@lib@fold@triangle{\tikz@lib@fold@face@AF} + {\tikz@lib@fold@ear@custom@right@path{24}} + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + } + {\tikz@lib@fold@path} + {\tikz@lib@fold@cut@path} + } + \endgroup +} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex index dd842033fc8..e35633fc20d 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex @@ -9,23 +9,30 @@ \usepgflibrary{intersections} -\let\tikz@intersect@def=\def - \pgfkeys{% /tikz/name path global/.code={% - % it might have been more efficient to eliminate the storage macro - % \tikz@intersect@namedpaths. But I keep it maintain compatibility - % with mixed occurances of local/global names. - \let\tikz@intersect@def=\gdef - \pgfkeys{/tikz/name path={#1}}% + % reset any "old" variables inheritted from some other path + % - we do not accidentally want to append to an old path with the + % same name (or if someone provided the option twice)... + \expandafter\global\expandafter\let\csname tikz@intersect@path@name@#1\endcsname=\relax + \tikz@key@name@path{#1}{\gdef}% }, /tikz/name path local/.code={% - \let\tikz@intersect@def=\def \pgfkeys{/tikz/name path={#1}}% }, /tikz/name path/.code={% + % hm. Do we need this "reset old option" as in 'name path global' + % for this case as well? + \tikz@key@name@path{#1}{\def}% + }, +} + +% #1: the name to assign. +% #2: one of '\def' or '\gdef'. +\def\tikz@key@name@path#1#2{% \tikz@addmode{% - \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath% + \pgfsyssoftpath@getcurrentpath\tikz@intersect@temppath@round% + \pgfprocessround\tikz@intersect@temppath@round\tikz@intersect@temppath% \ifx\tikz@intersect@namedpaths\pgfutil@empty% \else% \tikz@intersect@namedpaths% @@ -37,28 +44,16 @@ \expandafter\expandafter\expandafter{\expandafter\tikz@intersect@temppath\tikz@intersect@temppath}% }% \fi% - \tikz@intersect@addto@path@names{#1}% + \tikz@intersect@addto@path@names{#1}{#2}% }% - } -} +}% -\def\tikz@intersect@addto@path@names#1{% - % FIXME : I have the impression that something is not correct - % here... the \tikz@intersect@def is not used correctly! - % if I am not mistaken, the \tikz@intersect@def will NOT be - % invoked until \tikz@intersect@namedpaths. CHECK IT - % It seems it works, but only partially. - \def\tikz@marshal{\expandafter\tikz@intersect@def\csname tikz@intersect@path@name@#1\endcsname}% +% #1: the name to assign. +% #2: one of '\def' or '\gdef'. +\def\tikz@intersect@addto@path@names#1#2{% + \edef\tikz@marshal{#2\expandafter\noexpand\csname tikz@intersect@path@name@#1\endcsname}% \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\tikz@marshal% \expandafter\expandafter\expandafter{\expandafter\tikz@marshal\expandafter{\tikz@intersect@temppath}}% - \ifx\tikz@intersect@def\gdef - % This here is to *ensure* that the \gdef is invoked. - % - % I think this solves the problem. - % - % Please revise this routine such that it works better. - \tikz@marshal - \fi \expandafter\pgfutil@g@addto@macro\expandafter\tikz@intersect@namedpaths\expandafter{\tikz@marshal}% } @@ -89,9 +84,9 @@ by=, #1}% \pgfutil@ifundefined{tikz@intersect@path@name@\tikz@intersect@path@a}{% - \PackageError{tikz}{I do not know the path named `\tikz@intersect@path@a'. Perhaps you misspelt it}{}}% + \tikzerror{I do not know the path named `\tikz@intersect@path@a'. Perhaps you misspelt it}}% {\pgfutil@ifundefined{tikz@intersect@path@name@\tikz@intersect@path@b}{% - \PackageError{tikz}{I do not know the path named `\tikz@intersect@path@b'. Perhaps you misspelt it}{}}% + \tikzerror{I do not know the path named `\tikz@intersect@path@b'. Perhaps you misspelt it}}% {% \pgfintersectionofpaths% {% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex new file mode 100644 index 00000000000..8ccdc64493a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymath.code.tex @@ -0,0 +1,725 @@ +% Copyright 2013 by Mark Wibrow +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + + +\edef\tikz@math@at@catcode{\the\catcode`\@} +\catcode`\@=11 + +\def\tikz@math@gobblespaces#1{\pgfutil@ifnextchar x{#1}{#1}} + +\def\tikz@math@meaning@macro{macro} +\def\tikz@math@meaning@dimen{dimen} +\def\tikz@math@meaning@count{count} +\def\tikz@math@meaning@null{null} + +\def\tikz@math@getmeaning#1{\expandafter\tikz@math@@getmeaning\meaning#1\tikz@math@getmeaning@stop} + +\def\tikz@math@@getmeaning#1#2#3#4#5\tikz@math@getmeaning@stop{% + \if#1u% undefined + \let\tikz@math@meaning=\tikz@math@meaning@macro% + \else% + \if#1m% + \let\tikz@math@meaning=\tikz@math@meaning@macro% + \else% + \if#2d% + \let\tikz@math@meaning=\tikz@math@meaning@dimen% + \else% + \if#2c% + \let\tikz@math@meaning=\tikz@math@meaning@count% + \else% + \if#3k% A skip. Treat like a dimen. + \let\tikz@math@meaning=\tikz@math@meaning@dimen% + \else% + \let\tikz@math@meaning=\tikz@math@meaning@null% + \fi% + \fi% + \fi% + \fi% + \fi% +} + +\def\tikz@math@firstoftwo#1#2{#1} +\def\tikz@math@secondoftwo#1#2{#2} + + +\def\tikz@math@getvarstring#1{% + \begingroup% + \escapechar=-1\relax% + \expandafter\tikz@math@@getvarstring\string#1\tikz@math} + +\def\tikz@math@@getvarstring#1\tikz@math#2{% + \endgroup% + \def#2{#1}% +} + +\long\def\tikz@math@collecttosemicolon@other#1#2;{% + \def\tikz@math@collected{#2}#1} +\def\tikz@math@semicolon@other{;}% + +{\catcode`\;=13 +\long\gdef\tikz@math@collecttosemicolon@active#1#2;{% + \def\tikz@math@collected{#2}#1} +\gdef\tikz@math@semicolon@active{;}% +} + + +\def\tikz@math@setvartype#1#2{% + \expandafter\let\csname tikz@math@var@vartype@\string#1\endcsname=#2% +} + + +\def\tikz@math@getvartype#1#2{% + \def\tikz@math@marshal{\let#1=}% + \expandafter\tikz@math@marshal\csname + tikz@math@var@vartype@\string#2\endcsname% +} + + + +\def\tikz@math@ifvarcoordinate#1{% + \expandafter\ifx\csname + tikz@math@var@vartype@\string#1\endcsname\tikz@math@keyword@coordinate% + \let\tikz@math@next=\tikz@math@firstoftwo% + \else% + \let\tikz@math@next=\tikz@math@secondoftwo% + \fi% + \tikz@math@next% +} + +\def\tikz@math@ifvarinteger#1{% + \expandafter\ifx\csname + tikz@math@var@vartype@\string#1\endcsname\tikz@math@keyword@integer% + \let\tikz@math@next=\tikz@math@firstoftwo% + \else% + \let\tikz@math@next=\tikz@math@secondoftwo% + \fi% + \tikz@math@next% +} + + +\def\tikz@math@setvarindexed#1{% + \expandafter\let\csname + tikz@math@var@subtype@\string#1\endcsname=\tikz@math@subtype@indexed% +} + +\def\tikz@math@clearvarindexed#1{% + \expandafter\let\csname tikz@math@var@subtype@\string#1\endcsname=\relax% +} + +\def\tikz@math@ifvarindexed#1{% + \expandafter\ifx\csname tikz@math@var@subtype@\string#1\endcsname\relax% + \let\tikz@math@next=\tikz@math@secondoftwo% + \else% + \let\tikz@math@next=\tikz@math@firstoftwo% + \fi% + \tikz@math@next% +} + +\def\tikz@math@stop{@} + +\let\tikz@math@parse@hook@before=\pgfutil@empty +\let\tikz@math@parse@hook@after=\pgfutil@empty + +\def\tikz@math{% + \ifnum\catcode`\;=13\relax% + \let\tikz@math@semicolon=\tikz@math@semicolon@active% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@active% + \else% + \let\tikz@math@semicolon=\tikz@math@semicolon@other% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@other% + \fi% + \tikz@math@parse@hook@before% + \tikz@@math} + + + + +\long\def\tikz@@math#1{% + \def\tikz@math@marshal{\tikz@math@parse#1}% + \expandafter\expandafter\expandafter\tikz@math@marshal\expandafter\tikz@math@stop\tikz@math@semicolon} + +\def\tikz@math@parse{\pgfutil@ifnextchar\bgroup\tikz@math@@parse@bgroup\tikz@math@@parse@nobgroup} + + +\def\tikz@math@@parse@bgroup{% + \tikz@math@collecttosemicolon{% + % MW: Don't know how reliable this test is. + \ifx\pgf@selectfontorig\tikz@math@undefined% + \begingroup\tikz@math@collected\endgroup% + \else% + \begingroup\csname nullfont\endcsname\tikz@math@collected\endgroup% + \fi\tikz@math@parse}} + + + +\def\tikz@math@@parse@nobgroup{\tikz@math@collecttosemicolon{\tikz@math@@parse@@nobgroup}} + +\def\tikz@math@@parse@@nobgroup{% + \let\tikz@math@tmp=\tikz@math@collected% + \ifx\tikz@math@tmp\tikz@math@stop% + \def\tikz@math@next{\expandafter\tikz@math@parse@finish\tikz@math@semicolon}% + \else% + \def\tikz@math@next{\expandafter\expandafter\expandafter\tikz@math@parse@keyword@check\expandafter\tikz@math@tmp\tikz@math@semicolon}% + \fi% + \tikz@math@next% +} + +\def\tikz@math@parse@finish{% + \tikz@math@collecttosemicolon{\tikz@math@parse@hook@after}% +} + + + +\newif\iftikz@math@let +\def\tikz@math@parse@keyword@check#1{% + \tikz@math@letfalse% + \tikz@math@getmeaning{#1}% + \ifx\tikz@math@meaning\tikz@math@meaning@null% + \let\tikz@math@next=\tikz@math@parse@keyword% + \else% + \let\tikz@math@next=\tikz@math@parse@nokeyword% + \fi% + \tikz@math@next#1} + + +\def\tikz@math@parse@keyword{% + \let\tikz@math@parsed@keyword=\pgfutil@empty% + \futurelet\tikz@math@parse@token\tikz@math@@parse@keyword} + +\def\tikz@math@@parse@keyword{% + \ifx\tikz@math@parse@token\pgfutil@sptoken% + \let\tikz@math@next=\tikz@math@@@parse@keyword% + \else% + \ifx\tikz@math@parse@token(% + \let\tikz@math@next=\tikz@math@@@parse@keyword% + \else% + \ifx\tikz@math@parse@token\bgroup% + \let\tikz@math@next=\tikz@math@@@parse@keyword% + \else% + \let\tikz@math@next=\tikz@math@@@@parse@keyword% + \fi% + \fi% + \fi% + \tikz@math@next} + +\def\tikz@math@error#1{\pgfutil@packageerror{tikz}{tikz math library: #1}{}} + +\def\tikz@math@@@parse@keyword{% + \expandafter\ifx\csname tikz@math@process@keyword@\tikz@math@parsed@keyword\endcsname\relax% + \expandafter\ifx\csname pgfmath\tikz@math@parsed@keyword\endcsname\relax% + \tikz@math@error{Unknown function or keyword '\tikz@math@parsed@keyword'}% + \else% + \def\tikz@math@next{\tikz@math@collecttosemicolon{\tikz@math@function@noassign}}% + \fi% + \else% + \expandafter\def\expandafter\tikz@math@next\expandafter{\csname tikz@math@process@keyword@\tikz@math@parsed@keyword\endcsname}% + \fi% + \tikz@math@next} + +\def\tikz@math@@@@parse@keyword#1{% + \edef\tikz@math@parsed@keyword{\tikz@math@parsed@keyword#1}% + \futurelet\tikz@math@parse@token\tikz@math@@parse@keyword% +} + +\def\tikz@math@function@noassign{% + \pgfmathparse{\tikz@math@parsed@keyword\tikz@math@collected}% + \tikz@math@parse% +} + + + + +\def\tikz@math@process@keyword@count{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@count}} +\def\tikz@math@process@keyword@@count{% +\def\tikz@math@assign@register{\csname newcount\endcsname}% +\expandafter\tikz@math@gobblespaces\expandafter\tikz@math@process@registers\tikz@math@collected,@,} + +\def\tikz@math@process@keyword@length{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@length}} +\def\tikz@math@process@keyword@@length{% +\def\tikz@math@assign@register{\csname newdimen\endcsname}% +\show\tikz@math@collected +\expandafter\tikz@math@gobblespaces\expandafter\tikz@math@process@registers\tikz@math@collected,@,} + + +\def\tikz@math@process@registers#1#2,{% + \def\tikz@math@var{#1}% + \ifx\tikz@math@var\tikz@math@stop% + \let\tikz@math@next=\tikz@math@parse% + \else% + \tikz@math@assign@register#1\relax% + \let\tikz@math@next=\tikz@math@process@registers% + \fi% + \tikz@math@gobblespaces\tikz@math@next% +} + + +\def\tikz@math@process@keyword@if#1then{% + \def\tikz@math@if@condition{#1}% + \tikz@math@gobblespaces\tikz@math@parse@if@iftrue% +} +\def\tikz@math@parse@if@iftrue#1{% + \def\tikz@math@if@trueaction{#1}% + \pgfutil@ifnextchar e{\tikz@math@parse@else}{\tikz@math@if@doif}} + +\def\tikz@math@parse@else else{\tikz@math@gobblespaces\tikz@math@if@doifelse} + +\def\tikz@math@if@doif{\tikz@math@collecttosemicolon{\tikz@math@if@@doif}} + +\def\tikz@math@if@@doif{% + \pgfmathparse{\tikz@math@if@condition}% + \ifdim\pgfmathresult pt=0pt\relax% + \else% + \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}% + \fi% + \tikz@math@parse% +} +\def\tikz@math@if@doifelse{\tikz@math@collecttosemicolon{\tikz@math@if@@doifelse}} +\def\tikz@math@if@@doifelse{% + \pgfmathparse{\tikz@math@if@condition}% + \let\tikz@math@if@falseaction=\tikz@math@collected% + \ifdim\pgfmathresult pt=0pt\relax% + \expandafter\tikz@math\expandafter{\tikz@math@if@falseaction}% + \else% + \expandafter\tikz@math\expandafter{\tikz@math@if@trueaction}% + \fi% + \tikz@math@parse% +} +\def\tikz@math@process@keyword@let{% + \tikz@math@lettrue% + \tikz@math@gobblespaces\tikz@math@parse@nokeyword% +} + + +\def\tikz@math@parse@nokeyword#1{% + \def\tikz@math@var{#1}% + \tikz@math@getvarstring{#1}\tikz@math@varstring% + \let\tikz@math@vartype=\pgfutil@empty% + \ifx\tikz@math@var\tikz@math@stop% + \let\tikz@math@next=\tikz@math@parse@finish% + \else% + \ifx\tikz@math@semicolon\tikz@math@var% + \let\tikz@math@next=\tikz@math@parse% + \else% + \let\tikz@math@next=\tikz@math@parse@index@check% + \fi% + \fi% + \tikz@math@next} + +\def\tikz@math@parse@index@check{% + \pgfutil@ifnextchar={\tikz@math@parse@noindex}{\tikz@math@parse@index}} + +\def\tikz@math@parse@noindex{% + \expandafter\tikz@math@clearvarindexed\tikz@math@var% + \let\tikz@math@current@index=\pgfutil@empty% + \tikz@math@parse@afterindex% +} + +\def\tikz@math@parse@index#1{% + \def\tikz@math@tmp{#1}% + \expandafter\tikz@math@setvarindexed\tikz@math@var% {} + \edef\tikz@math@current@index{#1}% + \tikz@math@parse@afterindex% +} +\def\tikz@math@parse@afterindex#1={\tikz@math@gobblespaces\tikz@math@parse@assignment}% + +\def\tikz@math@parse@assignment{\tikz@math@collecttosemicolon{\tikz@math@parse@@assignment}} +\def\tikz@math@parse@@assignment{% + \expandafter\expandafter\expandafter\tikz@math@doassignment\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@var\expandafter}\expandafter{\tikz@math@collected}% + \tikz@math@parse% +} + +\def\tikz@math@dollar@char{$} +\def\tikz@math@dollar@char{$}% For annoying syntax highlighters + +\def\tikz@math@doassignment#1#2{% + \tikz@math@ifvarcoordinate{#1}{% + \def\tikz@math@var{#1}% Unfortunately, we must do this again. + \tikz@math@getvarstring{#1}\tikz@math@varstring% And this + \expandafter\pgfutil@in@\tikz@math@dollar@char{#2}% + \edef\tikz@math@expression{#2}% + \ifpgfutil@in@% + \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\tikz@math@expression% + \else% + \expandafter\ifx\csname tikz@library@calc@loaded\endcsname\relax% + \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\tikz@math@expression% + \else% + \expandafter\tikz@scan@one@point\expandafter\tikz@math@assign@coordinate\expandafter% + (\expandafter$\tikz@math@expression$)% + \fi% + \fi% + }{% + \iftikz@math@let% Not really a let + \ifx\tikz@math@current@index\pgfutil@empty% + \edef#1{#2}% + \else% + \edef\tikz@math@tmp{#2}% + \expandafter\expandafter\expandafter\tikz@math@assign@index\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@varstring\expandafter}\expandafter{\tikz@math@tmp}% + \fi% + \tikz@math@letfalse% + \else% + \ifx\tikz@math@current@index\pgfutil@empty% + \tikz@math@getmeaning{#1}% + \ifx\tikz@math@meaning\tikz@math@meaning@dimen% + \pgfmathsetlength{#1}{#2}% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \else% + \ifx\tikz@math@meaning\tikz@math@meaning@count% + \pgfmathsetcount{#1}{#2}% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \else% + \tikz@math@ifvarinteger{#1}{\pgfmathparse{int(#2)}}{\pgfmathparse{#2}}% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \let#1=\pgfmathresult% + \fi% + \fi% + \else% + \tikz@math@ifvarinteger{#1}{\pgfmathparse{int(#2)}}{\pgfmathparse{#2}}% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring}\pgfmathresult% + \let\tikz@math@last@assigned@value=\pgfmathresult% + \fi% + \fi% + }% +} + + + +\def\tikz@math@assign@index#1#2{% + \expandafter\def\csname#1\endcsname##1{\csname + tikz@math@var@indexed@#1@##1\endcsname}% + \expandafter\edef\csname + tikz@math@var@indexed@#1@\tikz@math@current@index\endcsname{#2}\relax% +} + + + +\def\tikz@math@assign@coordinate#1{% + \pgf@process{#1}% + \ifx\tikz@math@current@index\pgfutil@empty% + \expandafter\edef\csname\tikz@math@varstring\endcsname{\the\pgf@x,\the\pgf@y}% + \expandafter\edef\csname\tikz@math@varstring x\endcsname{\the\pgf@x}% + \expandafter\edef\csname\tikz@math@varstring y\endcsname{\the\pgf@y}% + \else% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring}{\the\pgf@x,\the\pgf@y}% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring x}{\the\pgf@x}% + \expandafter\tikz@math@assign@index\expandafter{\tikz@math@varstring y}{\the\pgf@y}% + \fi% +} + + + +\def\tikz@math@keyword@coordinate{coordinate} +\def\tikz@math@process@keyword@coordinate{% + \let\tikz@math@vartype=\tikz@math@keyword@coordinate% + \tikz@math@gobblespaces\tikz@math@process@vartypes% +} + +\def\tikz@math@keyword@integer{integer} +\def\tikz@math@process@keyword@integer{% + \let\tikz@math@vartype=\tikz@math@keyword@integer% + \tikz@math@gobblespaces\tikz@math@process@vartypes% +} +\def\tikz@math@process@keyword@int{% + \tikz@math@process@keyword@integer% +} + +\def\tikz@math@keyword@real{real} +\def\tikz@math@process@keyword@real{% + \let\tikz@math@vartype=\tikz@math@keyword@real% + \tikz@math@gobblespaces\tikz@math@process@vartypes% +} + +\def\tikz@math@process@keyword@point{\tikz@math@process@keyword@coordinate} + + +\def\tikz@math@process@vartypes{\tikz@math@collecttosemicolon{\tikz@math@process@@vartypes}} + +\def\tikz@math@process@@vartypes{% + \expandafter\tikz@math@@process@vartypes\tikz@math@collected,@,\tikz@math% +} + +\def\tikz@math@@process@vartypes#1#2,{% + \def\tikz@math@var{#1}% + \tikz@math@getvarstring{#1}\tikz@math@varstring% + \ifx\tikz@math@var\tikz@math@stop% + \let\tikz@math@next=\tikz@math@@@process@vartypes% + \else% + \expandafter\tikz@math@setvartype\tikz@math@var\tikz@math@vartype% + \def\tikz@math@next{\tikz@math@gobblespaces\tikz@math@@process@vartypes}% + \fi% + \tikz@math@next% +} + +\def\tikz@math@process@keyword@print{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@print}} +\def\tikz@math@process@keyword@@print{% + \begingroup\tikz@math@collected\endgroup\tikz@math@parse% +} + +\def\tikz@math@@@process@vartypes#1\tikz@math{% + \tikz@math@parse% +} + +\newcount\tikz@math@for@depth + +\def\tikz@math@for@namedef#1{\expandafter\def\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} +\def\tikz@math@for@nameedef#1{\expandafter\edef\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} +\def\tikz@math@for@namelet#1{\expandafter\let\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} + +\def\tikz@math@for@namegetvalue#1#2{% + \def\tikz@math@marshal{\let#2=}% + \expandafter\tikz@math@marshal\csname tikz@math@for@def@#1@\the\tikz@math@for@depth\endcsname} + +\def\tikz@math@process@keyword@for{% + \tikz@math@for% +} + +\def\tikz@math@for@external{% + \ifnum\catcode`\;=13\relax% + \let\tikz@math@semicolon=\tikz@math@semicolon@active% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@active% + \else% + \let\tikz@math@semicolon=\tikz@math@semicolon@other% + \let\tikz@math@collecttosemicolon=\tikz@math@collecttosemicolon@other% + \fi + \advance\tikz@math@for@depth by1\relax% + \tikz@math@for@namedef{execute}{\tikz@math@for@external@execute}% + \tikz@math@for@namedef{finished}{\relax}% + \tikz@math@gobblespaces\tikz@math@for@parsevar} + +\def\tikz@math@for@external@execute#1{#1} + +\def\tikz@math@for{% + \advance\tikz@math@for@depth by1\relax% + \tikz@math@for@namedef{execute}{\tikz@math}% + \tikz@math@for@namedef{finished}{\tikz@math@parse}% + \tikz@math@gobblespaces\tikz@math@for@parsevar} + + +\def\tikz@math@for@parsevar#1{% + \tikz@math@for@namedef{var}{#1}% + \tikz@math@for@parsein} + +\def\tikz@math@getindex#1{% + \tikz@math@@getindex#1\tikz@math@getindex\tikz@math@@getindex% +} + +\def\tikz@math@@getindex#1#2\tikz@math@@getindex{#1} + +\def\tikz@math@for@parsein#1in{% + \def\tikz@math@tmp{#1}% + \ifx\tikz@math@tmp\pgfutil@empty% + \tikz@math@for@namedef{index}{}% + \else% + \tikz@math@for@nameedef{index}{\tikz@math@getindex{#1}}% + \fi% + \tikz@math@gobblespaces\tikz@math@for@parselist% +} + + +\long\def\tikz@math@for@parselist#1{% + \edef\tikz@math@for@list{#1}% + \tikz@math@collecttosemicolon{\tikz@math@for@parseaction}} + +\def\tikz@math@for@parseaction{% + \tikz@math@for@namedef{prevvalue}{}% + \tikz@math@for@namedef{prevprevvalue}{}% + \tikz@math@for@namelet{action}=\tikz@math@collected% + \expandafter\tikz@math@for@scan\tikz@math@for@list,\tikz@math,\tikz@@math% +} + +\def\tikz@math@token{\tikz@math} + + +\def\tikz@math@for@scan#1,{% + \def\tikz@math@for@value{#1}% + \ifx\tikz@math@for@value\tikz@math@token% + \let\tikz@math@next=\tikz@math@for@scan@end% + \else% + \ifx\tikz@math@for@value\pgfutil@empty% + \let\tikz@math@next=\tikz@math@for@scan@end% + \else% + \pgfutil@in@{...}{#1}% + \ifpgfutil@in@% + \let\tikz@math@next=\tikz@math@for@scan@dots% + \else% + \tikz@math@for@namegetvalue{var}{\tikz@math@var}% + \tikz@math@for@namegetvalue{index}{\tikz@math@current@index}% + \tikz@math@for@namegetvalue{action}{\tikz@math@action}% + \expandafter\tikz@math@getvarstring\expandafter{\tikz@math@var}\tikz@math@varstring% + \expandafter\tikz@math@doassignment\expandafter{\tikz@math@var}{#1}% + \tikz@math@for@namelet{value}=\tikz@math@last@assigned@value% + \tikz@math@for@namegetvalue{execute}{\tikz@math@execute}% + \expandafter\tikz@math@execute\expandafter{\tikz@math@action}% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namelet{prevprevvalue}=\tikz@math@prevvalue% + \tikz@math@for@namegetvalue{value}{\tikz@math@value}% + \tikz@math@for@namelet{prevvalue}=\tikz@math@value% + \let\tikz@math@next=\tikz@math@for@scan% + \fi% + \fi% + \fi% + \tikz@math@next% +} + +\newdimen\tikz@math@dimen + +\def\tikz@math@for@scan@dots#1,{% + \pgfmathparse{#1}\let\tikz@math@value=\pgfmathresult% + \tikz@math@for@nameedef{endvalue}{\tikz@math@value}% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namegetvalue{prevprevvalue}{\tikz@math@prevprevvalue}% + \tikz@math@dimen=\tikz@math@prevvalue pt\relax% + \ifx\tikz@math@prevprevvalue\pgfutil@empty% + \ifdim\tikz@math@prevvalue pt<\tikz@math@value pt\relax%% + \def\tikz@math@step{1pt}% + \else% + \def\tikz@math@step{-1pt}% + \fi% + \else% + \tikz@math@dimen=\tikz@math@prevvalue pt\relax% + \advance\tikz@math@dimen by-\tikz@math@prevprevvalue pt\relax% + \edef\tikz@math@step{\the\tikz@math@dimen}% + \fi% + \ifdim\tikz@math@step<0pt\relax% + \tikz@math@for@namedef{comparitor}{<}% + \else% + \tikz@math@for@namedef{comparitor}{>}% + \fi% + \tikz@math@for@nameedef{step}{\tikz@math@step}% + \tikz@math@for@doloop% +} + +\def\tikz@math@for@doloop{% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namegetvalue{step}{\tikz@math@step}% + \tikz@math@for@namegetvalue{comparitor}{\tikz@math@comparitor}% + \tikz@math@for@namegetvalue{endvalue}{\tikz@math@endvalue}% + \tikz@math@dimen=\tikz@math@prevvalue pt\relax% + \advance\tikz@math@dimen by\tikz@math@step\relax% + \ifdim\tikz@math@dimen\tikz@math@comparitor\tikz@math@endvalue pt\relax% + \let\tikz@math@next=\tikz@math@for@endloop% + \else% + \tikz@math@for@nameedef{value}{\pgfmath@tonumber{\tikz@math@dimen}}% + \tikz@math@for@namegetvalue{var}{\tikz@math@var}% + \expandafter\tikz@math@getvarstring\expandafter{\tikz@math@var}\tikz@math@varstring% + \tikz@math@for@namegetvalue{index}{\tikz@math@current@index}% + \tikz@math@for@namegetvalue{action}{\tikz@math@action}% + \tikz@math@for@namegetvalue{value}{\tikz@math@value}% + \expandafter\expandafter\expandafter\tikz@math@doassignment\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@var\expandafter}\expandafter{\tikz@math@value}% + \tikz@math@for@namegetvalue{execute}{\tikz@math@execute}% + \expandafter\tikz@math@execute\expandafter{\tikz@math@action}% + \tikz@math@for@namegetvalue{prevvalue}{\tikz@math@prevvalue}% + \tikz@math@for@namelet{prevprevvalue}=\tikz@math@prevvalue% + \tikz@math@for@namegetvalue{value}{\tikz@math@value}% + \tikz@math@for@namelet{prevvalue}=\tikz@math@value% + \let\tikz@math@next=\tikz@math@for@doloop% + \fi% + \tikz@math@next% +} + +\def\tikz@math@for@endloop{% +\tikz@math@for@scan} + + + + +\def\tikz@math@for@scan@end#1\tikz@@math{% +\tikz@math@for@namegetvalue{finished}{\tikz@math@next}% +\advance\tikz@math@for@depth by-1\relax% +\tikz@math@next} + + + + + +\def\tikz@math@process@keyword@return{% + \tikz@math@collecttosemicolon{\pgfmathparse{\tikz@math@collected}\tikz@math@parse}} + +\def\tikz@math@process@keyword@function{\tikz@math@collecttosemicolon{\tikz@math@process@keyword@@function}} +\def\tikz@math@process@keyword@@function{% + \let\tikz@math@function@name=\pgfutil@empty% + \let\tikz@math@function@arguments=\pgfutil@empty% + \let\tikz@math@function@body=\pgfutil@empty% + \expandafter\expandafter\expandafter\tikz@math@@declarefunction\expandafter\tikz@math@collected\tikz@math@semicolon% +} + +\def\tikz@math@@declarefunction{% + \pgfutil@ifnextchar\bgroup\tikz@math@@@collectbody\tikz@math@@@declarefunction} + + +\def\tikz@math@@@declarefunction#1{% + \if#1(%) + \let\tikz@math@next=\tikz@math@@@collectarguments% + \else% + \expandafter\def\expandafter\tikz@math@function@name\expandafter{\tikz@math@function@name#1}% + \let\tikz@math@next=\tikz@math@@declarefunction% + \fi% + \tikz@math@next% +} +\def\tikz@math@@@collectarguments#1){% + \def\tikz@math@function@arguments{#1}% + \tikz@math@@declarefunction% +} + +\newtoks\tikz@math@toks +\tikz@math@toks={#} +\edef\tikz@math@char@hash{\the\tikz@math@toks} +\tikz@math@toks={} + +\def\tikz@math@@@collectbody{\tikz@math@collecttosemicolon{\tikz@math@@@@collectbody}} + +\def\tikz@math@@@@collectbody{% + \tikz@math@toks={}% + \c@pgf@counta=0\relax% + \ifx\tikz@math@function@arguments\pgfutil@empty% + \else% + \expandafter\tikz@math@createargumentlist\tikz@math@function@arguments,,% + \expandafter\tikz@math@addto@toks\expandafter{\tikz@math@collected}% + \fi% + \edef\tikz@math@local@temp{% + \noexpand\pgfmathdeclarefunction{\tikz@math@function@name}{\the\c@pgf@counta}% + {\noexpand\def\noexpand\return{0}\noexpand\tikz@math{\the\tikz@math@toks}}% + }% + \tikz@math@local@temp + \tikz@math@parse% +} + +\def\tikz@math@addto@toks#1{% + \expandafter\tikz@math@toks\expandafter{\the\tikz@math@toks#1}} + +\def\tikz@math@createargumentlist{% + \pgfutil@ifnextchar + x\tikz@math@@createargumentlist\tikz@math@@createargumentlist} + +\def\tikz@math@comma{,} +\def\tikz@math@@createargumentlist#1,{% + \def\tikz@math@tmp{#1}% + \ifx\tikz@math@tmp\pgfutil@empty% + \let\tikz@math@next=\relax% + \else% + \advance\c@pgf@counta by1\relax% + \tikz@math@addto@toks{#1=}% + \expandafter\expandafter\expandafter\tikz@math@addto@toks\expandafter\expandafter\expandafter% + {\expandafter\tikz@math@char@hash\the\c@pgf@counta;}% + \let\tikz@math@next=\tikz@math@createargumentlist% + \fi% + \tikz@math@next% +} + + + +\let\tikzmath=\tikz@math +\tikzset{evaluate/.code={\tikz@math{#1}}} +\let\tikzmathfor=\tikz@math@for@external + + +\catcode`\@=\tikz@math@at@catcode\relax diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex index f1f03c457dd..eb2d65a33fc 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex,v 1.2 2008/06/18 23:34:49 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymatrix.code.tex,v 1.4 2013/07/12 22:01:58 tantau Exp $ % A matrix of nodes contains a node in each cell. @@ -15,30 +15,29 @@ \tikzstyle{matrix of nodes}=[% matrix,% cells={anchor=base},% - nodes={% - execute at begin node=,% - execute at end node=, - name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn% - }, execute at begin cell=\tikz@lib@matrix@start@cell,% execute at end cell=\tikz@lib@matrix@end@cell,% - execute at empty cell=\tikz@lib@matrix@empty@cell + execute at empty cell=\tikz@lib@matrix@empty@cell, + execute at begin matrix=\iftikz@handle@active@code\tikz@orig@shorthands\fi,% ] -\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node{};\fi} +\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]{};\fi} \newif\iftikz@lib@matrix@plain \def\tikz@lib@matrix@start@cell{% \pgfutil@ifnextchar|{\tikz@lib@matrix@with@options}{\tikz@lib@matrix@normal@start@cell}} -\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node#1\bgroup\tikz@lib@matrix@startup} +\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node% + [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]#1\bgroup\tikz@lib@matrix@startup} -\def\tikz@lib@matrix@normal@start@cell{\pgfutil@ifnextchar\let{\tikz@lib@matrix@check}{\tikz@lib@matrix@plainfalse\node\bgroup\tikz@lib@matrix@startup}}% +\def\tikz@lib@matrix@normal@start@cell{\pgfutil@ifnextchar\let{\tikz@lib@matrix@check}{\tikz@lib@matrix@plainfalse\node + [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup}}% \def\tikz@lib@matrix@check#1{% evil hackery to find out about start of path - \pgfutil@ifnextchar\tikz@signal@path{\tikz@lib@matrix@plaintrue\let}{\tikz@lib@matrix@plainfalse\node\bgroup\tikz@lib@matrix@startup\let}% + \pgfutil@ifnextchar\tikz@signal@path{\tikz@lib@matrix@plaintrue\let}{\tikz@lib@matrix@plainfalse\node + [name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup\let}% } \def\tikz@lib@matrix@end@cell{% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex index 981d747a3e5..4b6a952ac13 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex,v 1.9 2009/11/12 09:53:02 ludewich Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarymindmap.code.tex,v 1.10 2013/07/16 12:43:14 tantau Exp $ \usetikzlibrary{trees,decorations} @@ -98,7 +98,10 @@ \tikzstyle{circle connection bar}= [to path={ - \pgfextra{\tikz@compute@circle@radii\tikz@compute@segmentamplitude} + \pgfextra{% + \tikz@lib@mindmap@check{\tikztostart}% + \tikz@compute@circle@radii\tikz@compute@segmentamplitude% + } [every circle connection bar] decorate [decoration=circle connection bar] { -- (\tikztotarget) \tikztonodes} @@ -129,12 +132,31 @@ append after command={[fill=\tikz@concept@color,draw=none]} } + +% Check whether start and end are nodes! + +\def\tikz@lib@mindmap@check#1{% + \pgfutil@ifundefined{pgf@sh@ns@#1}% + {\tikzerror{You are attempting to connect two things by a circle + connection bar where one is not a node}}{% + \expandafter\ifx\csname pgf@sh@ns@#1\endcsname\tikz@lib@coordinate@text% + \tikzerror{You are attempting to connect node of shape + 'coordinate' by a circle connection bar. The shape should be + 'circle' or something similar, instead.} + \fi% + } +} + +\def\tikz@lib@coordinate@text{coordinate} + + % Switch color in a mindmap \tikzoption{circle connection bar switch color}{\tikz@parse@switch#1\pgf@unique} \def\tikz@parse@switch from (#1) to (#2)\pgf@unique{% \tikzset{to path={% \pgfextra{% + \tikz@lib@mindmap@check{\tikztostart}% \tikz@compute@circle@radii\tikz@compute@segmentamplitude% \global\let\tikz@lib@save@start=\tikztostart% \global\let\tikz@lib@save@target=\tikztotarget% diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex index 524bea7a28f..e67027eadfb 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex,v 1.2 2008/06/18 23:34:49 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarypetri.code.tex,v 1.3 2013/07/17 08:56:23 tantau Exp $ % Styles for places: @@ -59,7 +59,7 @@ \tikzoption{structured tokens}{% \tikzset{append after command={}% - {[children are tokens]child foreach \tikz@child@name in {#1} {node[token]{\tikz@child@name}}}}% + {[children are tokens]child foreach \tikzpetrichildname in {#1} {node[token]{\tikzpetrichildname}}}}% } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex new file mode 100644 index 00000000000..4369b7e2dc2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex @@ -0,0 +1,88 @@ +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryquotes.code.tex,v 1.3 2013/08/28 15:24:27 tantau Exp $ + +\def\tikz@quote@parser#1{\tikz@quote@@parser#1\pgf@stop} +\def\tikz@quote@@parser"#1"{% + \pgfutil@ifnextchar\bgroup{% + \tikz@quote@@parser@group{#1}}{% + \pgfutil@ifnextchar'{% + \tikz@quote@@parser@apo{#1}}{% + \tikz@quote@@parser@normal{#1}}}} +\def\tikz@quote@@parser@apo#1'{% + \pgfutil@ifnextchar\bgroup{\tikz@quote@@parser@apo@group{#1}}{\tikz@quote@@parser@apo@normal{#1}}} +\def\tikz@quote@@parser@group#1#2#3\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} +\def\tikz@quote@@parser@normal#1#2\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} +\def\tikz@quote@@parser@apo@group#1#2#3\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{',#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} +\def\tikz@quote@@parser@apo@normal#1#2\pgf@stop{% + \expandafter\def\expandafter\tikz@temp\expandafter{\tikz@quotes@as{#1}{',#2}}% + \expandafter\pgfkeysalso\expandafter{\tikz@temp}% +} + +\pgfkeys{/handlers/first char syntax=true} + +\def\tikz@enable@node@quotes{% + \pgfkeyssetvalue{/handlers/first char syntax/the character "}{\tikz@quote@parser}% + \let\tikz@quotes@as\tikz@node@quotes@as% +} +\def\tikz@enable@edge@quotes{% + \pgfkeyssetvalue{/handlers/first char syntax/the character "}{\tikz@quote@parser}% + \let\tikz@quotes@as\tikz@edge@quotes@as% +} +\def\tikz@enable@pic@quotes{% + \pgfkeyssetvalue{/handlers/first char syntax/the character "}{\tikz@quote@parser}% + \let\tikz@quotes@as\tikz@pic@quotes@as% +} + +\tikzset{ + node quotes mean/.code={\def\tikz@node@quotes@as##1##2{#1}}, + edge quotes mean/.code={\def\tikz@edge@quotes@as##1##2{#1}}, + pic quotes mean/.code={\def\tikz@pic@quotes@as##1##2{#1}}, + quotes mean pin/.style={node quotes mean={ + pin={[direction shorthands,every pin quotes/.try,##2]##1}}}, + quotes mean label/.style={node quotes mean={ + label={[direction shorthands,every label quotes/.try,##2]##1}}}, + quotes mean label, + edge quotes mean={edge node={node [every edge quotes,#2]{#1}}}, + pic quotes mean={pic text={#1},pic text options={every pic quotes/.try,#2}}, + every edge quotes/.style={auto}, + direction shorthands/.code={% + \pgfkeyslet{/tikz/above/.@cmd}\tikz@label@@above + \pgfkeyslet{/tikz/below/.@cmd}\tikz@label@@below + \pgfkeyslet{/tikz/left/.@cmd}\tikz@label@@left + \pgfkeyslet{/tikz/right/.@cmd}\tikz@label@@right + \pgfkeyslet{/tikz/above left/.@cmd}\tikz@label@@above@left + \pgfkeyslet{/tikz/above right/.@cmd}\tikz@label@@above@right + \pgfkeyslet{/tikz/below left/.@cmd}\tikz@label@@below@left + \pgfkeyslet{/tikz/below right/.@cmd}\tikz@label@@below@right + } +} + +\def\tikz@label@@above#1\pgfeov{\pgfkeysalso{label position=90,pin position=90}} +\def\tikz@label@@below#1\pgfeov{\pgfkeysalso{label position=-90,pin position=-90}} +\def\tikz@label@@left#1\pgfeov{\pgfkeysalso{label position=180,pin position=180}} +\def\tikz@label@@right#1\pgfeov{\pgfkeysalso{label position=0,pin position=0}} +\def\tikz@label@@above@left#1\pgfeov{\pgfkeysalso{label position=135,pin position=135}} +\def\tikz@label@@below@left#1\pgfeov{\pgfkeysalso{label position=-135,pin position=-135}} +\def\tikz@label@@above@right#1\pgfeov{\pgfkeysalso{label position=45,pin position=45}} +\def\tikz@label@@below@right#1\pgfeov{\pgfkeysalso{label position=-45,pin position=-45}} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex index 363beabe4c7..3fa9d3f8f46 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex @@ -7,9 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex,v 1.6 2008/02/05 13:08:05 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysnakes.code.tex,v 1.7 2013/07/15 12:05:31 tantau Exp $ -\PackageWarning{tikz}{Snakes have been superseded by +\pgfwarning{Snakes have been superseded by decorations. Please use the decoration libraries instead of the snakes library} diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex index fd45a761535..099448c5165 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex,v 1.2 2009/12/04 11:59:38 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryspy.code.tex,v 1.4 2011/05/19 08:56:54 tantau Exp $ @@ -43,10 +43,10 @@ width/.style={minimum width=##1}, execute at begin scope={% \let\tikz@lib@spy@save=\tikz@lib@spy@collection% - \setbox\tikz@lib@spybox=\hbox\bgroup% + \setbox\tikz@lib@spybox=\hbox\bgroup\bgroup% \let\spy=\tikz@lib@spy@parse}, execute at end scope={% - \egroup% + \egroup\egroup% {% \copy\tikz@lib@spybox% \tikz@lib@spy@collection% @@ -99,13 +99,15 @@ }]{}; \node [alias=tikzspyinnode,inner sep=0pt,outer sep=0pt,at={#2},every spy in node/.try, path picture={\node[anchor=center,tikz@lib@reset@gs]{\nullfont% + \pgfpicture\relax\pgfsetbaseline{default}\pgfsettrimleft{default}\pgfsettrimright{default}% \pgftransformreset% \let\tikz@transform=\relax% \expandafter\tikzset\expandafter{\tikz@lib@spy@lens}% \pgflowlevelsynccm% \tikz@scan@one@point\tikz@lib@spy@shift#2% \pgflowlevelsynccm% - \copy\tikz@lib@spybox};}]#3{}; + \copy\tikz@lib@spybox% + \endpgfpicture};}]#3{}; \tikz@lib@spy@path \endscope } diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex index 0cee69a2fde..f0eae010424 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex @@ -7,16 +7,18 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex,v 1.1 2009/01/24 17:07:14 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarysvg.path.code.tex,v 1.2 2013/09/23 18:04:35 tantau Exp $ \usepgflibrary{svg.path} \def\tikz@svg@path vg{\pgfutil@ifnextchar[\tikz@svg@@path{\tikz@svg@@path[]}}%} -\def\tikz@svg@@path[#1]#2"#3"{% +\def\tikz@svg@@path[#1]{\pgfutil@ifnextchar"{\tikz@svg@@path@old{#1}}{\tikz@svg@@path@new{#1}}} +\def\tikz@svg@@path@new#1#2{\tikz@svg@@path@old{#1}"#2"} +\def\tikz@svg@@path@old#1"#2"{ {% \tikzset{#1}% - \pgfpathsvg{#3}% + \pgfpathsvg{#2}% }% { \pgftransforminvert diff --git a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex index e2a9cb2d649..f8c1e8792f4 100644 --- a/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex @@ -7,9 +7,11 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/tikz.code.tex,v 1.76 2010/10/13 09:20:31 ludewich Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/frontendlayer/tikz/tikz.code.tex,v 1.142 2013/12/13 15:11:58 tantau Exp $ +\def\tikzerror#1{\pgfutil@packageerror{tikz}{#1}{}} + % Always-present libraries (|\usepgflibrary| defined in % \file{pgfutil-common.tex}). \usepgflibrary{plothandlers} @@ -23,7 +25,9 @@ \newdimen\tikzsiblingdistance \newbox\tikz@figbox +\newbox\tikz@figbox@bg \newbox\tikz@tempbox +\newbox\tikz@tempbox@bg \newcount\tikztreelevel \newcount\tikznumberofchildren @@ -190,6 +194,11 @@ \tikzoption{opacity}{\tikz@addoption{\pgfsetstrokeopacity{#1}\pgfsetfillopacity{#1}}} +% Blend mode + +\tikzset{blend mode/.code={\tikz@addoption{\pgfsetblendmode{#1}}}} + + % Main color options \tikzoption{color}{% \tikz@addoption{% @@ -207,6 +216,7 @@ \fi% \pgfutil@colorlet{tikz@color}{#1}% \pgfutil@colorlet{.}{tikz@color}% + % \pgfsetcolor{.}% \pgfsys@color@reset@inordertrue% }% @@ -295,6 +305,99 @@ }% } +\tikzset{turn/.code={% + \pgf@x=0pt% + \pgf@y\pgf@x% + \pgf@process{\tikz@tangent}% + \advance\pgf@x by-\tikz@lastx% + \advance\pgf@y by-\tikz@lasty% + \pgfpointnormalised{}% x/y = normalised vector + \pgf@x=-\pgf@x% + \pgf@ya=-\pgf@y% + \pgftransformcm% + {\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@ya}}% + {\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@x}}{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}% + }% +} + +\def\tikz@tangent@lookup{% + \pgfgetpath\tikz@temp% + \pgfprocesspathextractpoints\tikz@temp% + \pgfpointsecondlastonpath% +} + +% Code for rotating the xyz coordinate system +% around the x, y, or z vector. +% +\def\tikz@xyz@rotate@let{% + \let\pgf@z=\pgf@yc + \let\pgf@za=\pgf@xc% +} + +\def\tikz@xyz@rotate@xyz@xaxis#1#2#3#4{% + \tikz@xyz@rotate@let% + \pgf@x=#1\relax% + \pgf@ya=#2\relax% + \pgf@za=#3\relax% + \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult% + \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult% + \pgf@y=\tikz@xyz@cos\pgf@ya% + \advance\pgf@y by-\tikz@xyz@sin\pgf@za% + \pgf@z=\tikz@xyz@sin\pgf@ya% + \advance\pgf@z by\tikz@xyz@cos\pgf@za% +} + +\def\tikz@xyz@rotate@xyz@yaxis#1#2#3#4{% + \tikz@xyz@rotate@let% + \pgf@xa=#1\relax% + \pgf@y=#2\relax% + \pgf@za=#3\relax% + \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult% + \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult% + \pgf@x=\tikz@xyz@cos\pgf@xa% + \advance\pgf@x by\tikz@xyz@sin\pgf@za% + \pgf@z=-\tikz@xyz@sin\pgf@xa% + \advance\pgf@z by\tikz@xyz@cos\pgf@za% +} + +\def\tikz@xyz@rotate@xyz@zaxis#1#2#3#4{% + \tikz@xyz@rotate@let% + \pgf@xa=#1\relax% + \pgf@ya=#2\relax% + \pgf@z=#3\relax% + \pgfmathsin@{#4}\let\tikz@xyz@sin=\pgfmathresult% + \pgfmathcos@{#4}\let\tikz@xyz@cos=\pgfmathresult% + \pgf@x=\tikz@xyz@cos\pgf@xa% + \advance\pgf@x by-\tikz@xyz@sin\pgf@ya% + \pgf@y=\tikz@xyz@sin\pgf@xa% + \advance\pgf@y by\tikz@xyz@cos\pgf@ya% +} + +\tikzset{rotate around x/.code={% + \tikz@xyz@rotate@let% + \tikz@xyz@rotate@xyz@xaxis{0pt}{1pt}{0pt}{#1}% + \pgfextract@process\tikz@xyz@rotate@yvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \tikz@xyz@rotate@xyz@xaxis{0pt}{0pt}{1pt}{#1}% + \pgfsetzvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \pgfsetyvec{\tikz@xyz@rotate@yvec}% + }, + rotate around y/.code={% + \tikz@xyz@rotate@let% + \tikz@xyz@rotate@xyz@yaxis{1pt}{0pt}{0pt}{#1}% + \pgfextract@process\tikz@xyz@rotate@xvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \tikz@xyz@rotate@xyz@yaxis{0pt}{0pt}{1pt}{#1}% + \pgfsetzvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \pgfsetxvec{\tikz@xyz@rotate@xvec}% + }, + rotate around z/.code={% + \tikz@xyz@rotate@let% + \tikz@xyz@rotate@xyz@zaxis{1pt}{0pt}{0pt}{#1}% + \pgfextract@process\tikz@xyz@rotate@xvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \tikz@xyz@rotate@xyz@zaxis{0pt}{1pt}{0pt}{#1}% + \pgfsetyvec{\pgfpointxyz{\pgf@sys@tonumber{\pgf@x}}{\pgf@sys@tonumber{\pgf@y}}{\pgf@sys@tonumber{\pgf@z}}}% + \pgfsetxvec{\tikz@xyz@rotate@xvec}% + } +} % Grid options \tikzoption{xstep}{\def\tikz@grid@x{#1}} @@ -325,7 +428,14 @@ \def\tikz@nonetext{none} \tikzoption{path only}[]{\let\tikz@mode=\pgfutil@empty} -\tikzoption{shade}[]{\tikz@addmode{\tikz@mode@shadetrue}} +\tikzset{ + shade/.is choice, + shade/.default=true, + shade/true/.code=\tikz@addmode{\tikz@mode@shadetrue}, + shade/false/.code=\tikz@addmode{\tikz@mode@shadefalse}, + shade/none/.code=\tikz@addmode{\tikz@mode@shadefalse}, +} + \tikzoption{fill}[]{% \edef\tikz@temp{#1}% \ifx\tikz@temp\tikz@nonetext% @@ -364,7 +474,7 @@ \tikzset{insert path/.code=\tikz@scan@next@command#1\pgf@stop} % Pattern options -\tikzset{pattern/.code=\PackageError{tikz}{You need to say \string\usetikzlibrary{patterns}}{}, +\tikzset{pattern/.code=\tikzerror{You need to say \string\usetikzlibrary{patterns}}, pattern color/.style=pattern} % Path pictures @@ -412,8 +522,10 @@ % Transparency groups \newif\iftikz@transparency@group -\tikzset{/tikz/transparency group/.is if=tikz@transparency@group} +\tikzset{/tikz/transparency group/.code=\tikz@transparency@grouptrue\def\tikz@transparency@group@options{isolated=true,#1}\let\tikz@blend@group\pgfutil@empty} +\tikzset{/tikz/blend group/.code=\tikz@transparency@grouptrue\def\tikz@transparency@group@options{isolated=true}\def\tikz@blend@group{\pgfsetblendmode{#1}}} +\let\tikz@blend@group\pgfutil@empty % Shading options \tikzoption{shading}{\def\tikz@shading{#1}\tikz@addmode{\tikz@mode@shadetrue}} @@ -475,7 +587,6 @@ % Pin options \tikzset{ - pin/.code={\pgfutil@ifnextchar[{\tikz@parse@pin}{\tikz@parse@pin[]}#1:\pgf@nil},%} pin distance/.store in=\tikz@pin@distance, pin distance=3ex, pin position/.store in=\tikz@pin@default@pos, @@ -489,34 +600,90 @@ }% } -\long\def\tikz@parse@pin[#1]#2:#3\pgf@nil{% +\tikzset{% + pin/.code={% + \begingroup + \ifnum\the\catcode`\:=\active\relax + \def\tikz@next{% + \endgroup + \tikz@parse@pin@active@i{#1}}% + \else + \def\tikz@next{% + \endgroup + \pgfutil@ifnextchar[%] + {\tikz@parse@pin@nonactive} + {\tikz@parse@pin@nonactive[]}#1:\pgf@nil}% + \fi + \tikz@next}} + +\begingroup + \catcode`\:=\active\relax + + \gdef\tikz@parse@pin@active@i#1{% + \pgfutil@ifnextchar[%] + {\tikz@parse@pin@active} + {\tikz@parse@pin@active[]}#1:\pgf@nil} + + \long\gdef\tikz@parse@pin@active[#1]#2:#3\pgf@nil{% + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty + % no position, use default + \tikz@@parse@pin@active[#1]\tikz@pin@default@pos:#2:\pgf@nil% + \else + \tikz@@parse@pin@active[#1]#2:#3\pgf@nil% + \fi} + + \long\gdef\tikz@@parse@pin@active[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local = true] + \pgfextra{\let\tikz@save@last@node=\tikzlastnode\tikz@node@is@a@labelfalse}% + node [every pin, + tikz@label@angle = #2, + #1, + append after command = {% + (\tikz@save@last@node) + edge [every pin edge, + tikz@pre@pin@edge, + tikz@pin@options] + (\tikzlastnode)}, + tikz@label@post = \tikz@pin@distance, + tikz@pin@post] {#3} + \egroup}}} +\endgroup + +\long\def\tikz@parse@pin@nonactive[#1]#2:#3\pgf@nil{% \def\tikz@temp{#3}% - \ifx\tikz@temp\pgfutil@empty% + \ifx\tikz@temp\pgfutil@empty % no position, use default - \tikz@@parse@pin[#1]\tikz@pin@default@pos:#2:\pgf@nil% - \else% - \tikz@@parse@pin[#1]#2:#3\pgf@nil% - \fi% -} - -\long\def\tikz@@parse@pin[#1]#2:#3:\pgf@nil{% - \tikzset{append after command={% - \bgroup - [current point is local=true] - \pgfextra{\let\tikz@save@last@node=\tikzlastnode}% - node [every pin,tikz@label@angle=#2,#1,% - append after command={(\tikz@save@last@node) edge[every pin edge,tikz@pre@pin@edge,tikz@pin@options] (\tikzlastnode)}, - tikz@label@post=\tikz@pin@distance,tikz@pin@post] - {#3} - \egroup% - }} -} + \tikz@@parse@pin@nonactive[#1]\tikz@pin@default@pos:#2:\pgf@nil% + \else + \tikz@@parse@pin@nonactive[#1]#2:#3\pgf@nil% + \fi} +\long\def\tikz@@parse@pin@nonactive[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local = true] + \pgfextra{\let\tikz@save@last@node=\tikzlastnode\tikz@node@is@a@labelfalse}% + node [every pin, + tikz@label@angle = #2, + #1, + append after command = {% + (\tikz@save@last@node) + edge [every pin edge, + tikz@pre@pin@edge, + tikz@pin@options] + (\tikzlastnode)}, + tikz@label@post = \tikz@pin@distance, + tikz@pin@post] {#3} + \egroup}}} % Label and pin options \tikzset{ - label/.code={\pgfutil@ifnextchar[{\tikz@parse@label}{\tikz@parse@label[]}#1:\pgf@nil},%} label distance/.store in=\tikz@label@distance, label distance=0pt, label position/.store in=\tikz@label@default@pos, @@ -583,31 +750,86 @@ \newif\iftikz@label@simple% -\def\tikz@parse@label[#1]#2:#3\pgf@nil{% - \def\tikz@temp{#3}% - \ifx\tikz@temp\pgfutil@empty% +\tikzset{% + label/.code={% + \begingroup + \ifnum\the\catcode`\:=\active\relax + \def\tikz@next{% + \endgroup + \tikz@parse@label@active@i{#1}}% + \else + \def\tikz@next{% + \endgroup + \pgfutil@ifnextchar[%] + {\tikz@parse@label@nonactive} + {\tikz@parse@label@nonactive[]}#1:\pgf@nil}% + \fi + \tikz@next}} + +\begingroup + \catcode`\:=\active\relax + + \gdef\tikz@parse@label@active@i#1{% + \pgfutil@ifnextchar[%] + {\tikz@parse@label@active} + {\tikz@parse@label@active[]}#1:\pgf@nil} + + \gdef\tikz@parse@label@active[#1]#2:#3\pgf@nil{% + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty % no position, use default - \tikz@@parse@label[#1]\tikz@label@default@pos:#2:\pgf@nil% - \else% - \tikz@@parse@label[#1]#2:#3\pgf@nil% - \fi% -} + \tikz@@parse@label@active[#1]\tikz@label@default@pos:#2:\pgf@nil% + \else + \def\tikz@temp{#2}% + \ifx\tikz@temp\pgfutil@empty + \tikz@@parse@label@active[#1]\tikz@label@default@pos:#3\pgf@nil% + \else + \tikz@@parse@label@active[#1]#2:#3\pgf@nil% + \fi + \fi + } -\def\tikz@@parse@label[#1]#2:#3:\pgf@nil{% - \tikzset{append after command={ - \bgroup - [current point is local=true] - \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name}% - node - [every label,% - tikz@label@angle=#2,% - #1,% - tikz@label@post=\tikz@label@distance]% - {#3}% - \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name}% - \egroup% - }} -} + \gdef\tikz@@parse@label@active[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local=true] + \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse} + node [every label, + tikz@label@angle = #2, + #1, + tikz@label@post = \tikz@label@distance] {\iftikz@handle@active@nodes\expandafter\scantokens\else\expandafter\pgfutil@firstofone\fi{#3}} + \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name} + \egroup}}} +\endgroup + +\def\tikz@parse@label@nonactive[#1]#2:#3\pgf@nil{% + \def\tikz@temp{#3}% + \ifx\tikz@temp\pgfutil@empty + % no position, use default + \tikz@@parse@label@nonactive[#1]\tikz@label@default@pos:#2:\pgf@nil% + \else + \def\tikz@temp{#2}% + \ifx\tikz@temp\pgfutil@empty + \tikz@@parse@label@nonactive[#1]\tikz@label@default@pos:#3\pgf@nil% + \else + \tikz@@parse@label@nonactive[#1]#2:#3\pgf@nil% + \fi + \fi +} + +\def\tikz@@parse@label@nonactive[#1]#2:#3:\pgf@nil{% + \tikzset{% + append after command = {% + \bgroup + [current point is local=true] + \pgfextra{\let\tikz@save@last@fig@name=\tikz@last@fig@name\tikz@node@is@a@labelfalse} + node [every label, + tikz@label@angle = #2, + #1, + tikz@label@post = \tikz@label@distance] {\iftikz@handle@active@nodes\expandafter\scantokens\else\expandafter\pgfutil@firstofone\fi{#3}} + \pgfextra{\global\let\tikz@last@fig@name=\tikz@save@last@fig@name} + \egroup}}} \expandafter\def\csname tikz@label@angle@is@right\endcsname{\def\tikz@label@angle{0}} \expandafter\def\csname tikz@label@angle@is@above right\endcsname{\def\tikz@label@angle{45}} @@ -650,7 +872,24 @@ % General node options -\tikzoption{name}{\edef\tikz@fig@name{#1}} +\tikzset{ + name/.code={\edef\tikz@fig@name{\tikz@pp@name{#1}}},% + name prefix/.initial=,% + name suffix/.initial=% +} +\def\tikz@pp@name#1{\csname pgfk@/tikz/name prefix\endcsname#1\csname pgfk@/tikz/name suffix\endcsname} + + +\tikzset{ + node contents/.code=\def\tikz@node@content{#1}, + pic type/.code=\def\tikz@node@content{#1}, % alias +} + +\tikzset{ + behind path/.code=\def\tikz@whichbox{\tikz@figbox@bg}, + in front of path/.code=\def\tikz@whichbox{\tikz@figbox} +} +\def\tikz@whichbox{\tikz@figbox} \tikzoption{at}{\tikz@scan@one@point\tikz@set@at#1} \def\tikz@set@at#1{\def\tikz@node@at{#1}}% @@ -665,6 +904,17 @@ \def\tikzaddafternodepathoption#1{#1\tikzset{prefix after command={\pgfextra{#1}}}} \tikzset{after node path/.style={append after command={#1}}} + +% Pic options +\newif\iftikz@node@is@pic +\tikzset{pic text/.store in=\tikzpictext} +\let\tikzpictext\relax +\tikzset{pic text options/.store in=\tikzpictextoptions} +\let\tikzpictextoptions\pgfutil@empty + + +% Anchoring + \tikzoption{anchor}{\def\tikz@anchor{#1}\let\tikz@do@auto@anchor=\relax} \tikzoption{left}[]{\def\tikz@anchor{east}\tikz@possibly@transform{x}{-}{#1}} @@ -706,6 +956,14 @@ \def\tikz@extract@node@dist#1and#2\pgf@stop{% \def\tikz@extracted@node@distance{#1}} +\tikzset{ + transform shape nonlinear/.is choice, + transform shape nonlinear/.default=true, + transform shape nonlinear/true/.code=\let\tikz@nlt\relax, + transform shape nonlinear/false/.code=\def\tikz@nlt{\pgfapproximatenonlineartranslation}, + transform shape nonlinear=false +} + \tikzoption{transform shape}[true]{% \csname tikz@fullytransformed#1\endcsname% @@ -746,7 +1004,7 @@ \tikzoption{sloped}[true]{\csname pgfslopedattime#1\endcsname} \tikzoption{allow upside down}[true]{\csname pgfallowupsidedownattime#1\endcsname} -\tikzoption{pos}{\edef\tikz@time{#1}} +\tikzoption{pos}{\edef\tikz@time{#1}\ifx\tikz@time\pgfutil@empty\else\pgfmathsetmacro\tikz@time{\tikz@time}\fi} \tikzoption{auto}[]{\csname tikz@install@auto@anchor@#1\endcsname} \tikzoption{swap}[]{% @@ -757,6 +1015,8 @@ \def\tikz@auto@anchor@direction{left}% \fi% } +\tikzset{'/.style=swap} % shorthand + \def\tikz@install@auto@anchor@{\let\tikz@do@auto@anchor=\tikz@auto@anchor@on} \def\tikz@install@auto@anchor@false{\let\tikz@do@auto@anchor=\relax} @@ -775,30 +1035,34 @@ % Text options \tikzoption{text}{\def\tikz@textcolor{#1}} \tikzoption{font}{\def\tikz@textfont{#1}} +\tikzoption{node font}{\def\tikz@node@textfont{#1}} \tikzoption{text opacity}{\def\tikz@textopacity{#1}} \tikzoption{text width}{\def\tikz@text@width{#1}} \tikzoption{text height}{\def\tikz@text@height{#1}} \tikzoption{text depth}{\def\tikz@text@depth{#1}} \tikzoption{text ragged}[]% -{\def\tikz@text@action{\raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} -\tikzoption{text badly ragged}[]{\def\tikz@text@action{\raggedright\relax}} +{\def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} +\tikzoption{text badly ragged}[]{\def\tikz@text@action{\pgfutil@raggedright\relax}} \tikzoption{text ragged left}[]% -{\def\tikz@text@action{\raggedleft\leftskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} -\tikzoption{text badly ragged left}[]{\def\tikz@text@action{\raggedleft\relax}} +{\def\tikz@text@action{\pgfutil@raggedleft\leftskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax}} +\tikzoption{text badly ragged left}[]{\def\tikz@text@action{\pgfutil@raggedleft\relax}} \tikzoption{text justified}[]{\def\tikz@text@action{\leftskip0pt\rightskip0pt\relax}} \tikzoption{text centered}[]{\def\tikz@text@action{% \leftskip0pt plus2em% \rightskip0pt plus2em% \spaceskip.3333em \xspaceskip.5em% \parfillskip=0pt% + \iftikz@warn@for@narrow@centered\else\hbadness10000\fi% \let\\=\@centercr% for latex \relax}} \tikzoption{text badly centered}[]% {\def\tikz@text@action{% \let\\=\@centercr% for latex \parfillskip=0pt% - \rightskip\@flushglue% - \leftskip\@flushglue\relax}} + \rightskip\pgfutil@flushglue% + \leftskip\pgfutil@flushglue\relax}} +\tikzset{badness warnings for centered text/.is if=tikz@warn@for@narrow@centered} +\newif\iftikz@warn@for@narrow@centered \let\tikz@text@width=\pgfutil@empty \let\tikz@text@height=\pgfutil@empty @@ -806,8 +1070,9 @@ \let\tikz@textcolor=\pgfutil@empty \let\tikz@textfont=\pgfutil@empty \let\tikz@textopacity=\pgfutil@empty +\let\tikz@node@textfont=\pgfutil@empty -\def\tikz@text@action{\raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax} +\def\tikz@text@action{\pgfutil@raggedright\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax} % Alignment @@ -832,57 +1097,22 @@ % Arrow options \tikzoption{arrows}{\tikz@processarrows{#1}} -\tikzoption{>}{% - \tikz@set@pointed{\csname pgf@arrows@invert#1\endcsname}{#1}% - \expandafter\tikz@processarrows\expandafter{\tikz@current@arrows}% -} + +\tikzoption{>}{\pgfdeclarearrow{name=<->,means={#1}}}% +\pgfdeclarearrow{name=|<->|, means={>[sep=0pt].|}} \tikzoption{shorten <}{\pgfsetshortenstart{#1}} \tikzoption{shorten >}{\pgfsetshortenend{#1}} -\def\tikz@set@pointed#1#2{% - \pgfutil@ifundefined{pgf@arrow@code@tikze@>@#2} - {% - \pgfarrowsdeclarealias{tikzs@<@#2}{tikze@>@#2}{#1}{#2}% - \pgfarrowsdeclarereversed{tikzs@>@#2}{tikze@<@#2}{#1}{#2}% - \pgfarrowsdeclarecombine*{tikz@|<@#2}{tikz@>|@#2}{#1}{#2}{|}{|}% - \pgfarrowsdeclaredouble[\pgflinewidth]{tikzs@<<@#2}{tikze@>>@#2}{#1}{#2}%<< - \pgfarrowsdeclarereversed{tikzs@>>@#2}{tikze@<<@#2}{tikzs@<<@#2}{tikze@>>@#2}%<< - }{}% - \pgfutil@namedef{tikz@special@arrow@start<}{tikzs@<@#2}% - \pgfutil@namedef{tikz@special@arrow@end>}{tikze@>@#2}% - \pgfutil@namedef{tikz@special@arrow@start>}{tikzs@>@#2}% - \pgfutil@namedef{tikz@special@arrow@end<}{tikze@<@#2}% - \pgfutil@namedef{tikz@special@arrow@start|<}{tikz@|<@#2}% - \pgfutil@namedef{tikz@special@arrow@end>|}{tikz@>|@#2}% - \pgfutil@namedef{tikz@special@arrow@start<<}{tikzs@<<@#2}% - \pgfutil@namedef{tikz@special@arrow@end>>}{tikze@>>@#2}%<< - \pgfutil@namedef{tikz@special@arrow@start>>}{tikzs@>>@#2}%<< - \pgfutil@namedef{tikz@special@arrow@end<<}{tikze@<<@#2}%<< -} - \def\tikz@processarrows#1{% \def\tikz@current@arrows{#1}% \def\tikz@temp{#1}% \ifx\tikz@temp\pgfutil@empty% \else% - \tikz@@processarrows#1\@nil - \fi% -} -\def\tikz@@processarrows#1-#2\@nil{% - \expandafter\ifx\csname tikz@special@arrow@start#1\endcsname\relax% - \pgfsetarrowsstart{#1} - \else% - \pgfsetarrowsstart{\csname tikz@special@arrow@start#1\endcsname}% - \fi% - \expandafter\ifx\csname tikz@special@arrow@end#2\endcsname\relax% - \pgfsetarrowsend{#2} - \else% - \pgfsetarrowsend{\csname tikz@special@arrow@end#2\endcsname}% + \pgfsetarrows{#1}% \fi% } -\tikz@set@pointed{\pgf@arrows@invertto}{to} \def\tikz@current@arrows{-} % Parabola options @@ -900,11 +1130,16 @@ % Axis options \tikzoption{domain}{\edef\tikz@plot@domain{#1}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax} \tikzoption{range}{\def\tikz@plot@range{#1}} +\tikzoption{yrange}{\def\tikz@plot@range{#1}} +\let\tikz@plot@range=\pgfutil@empty +\tikzoption{xrange}{\def\tikz@plot@xrange{#1}} +\let\tikz@plot@xrange=\pgfutil@empty % Plot options \tikzoption{smooth}[]{\let\tikz@plot@handler=\pgfplothandlercurveto} \tikzoption{smooth cycle}[]{\let\tikz@plot@handler=\pgfplothandlerclosedcurve} \tikzoption{sharp plot}[]{\let\tikz@plot@handler\pgfplothandlerlineto} +\tikzoption{sharp cycle}[]{\let\tikz@plot@handler\pgfplothandlerpolygon} \tikzoption{tension}{\pgfsetplottension{#1}} @@ -918,14 +1153,16 @@ \tikzoption{const plot}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto} \tikzoption{const plot mark left}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlineto} \tikzoption{const plot mark right}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkright} +\tikzoption{const plot mark mid}[]{\let\tikz@plot@handler=\pgfplothandlerconstantlinetomarkmid} \tikzoption{jump mark right}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkright} +\tikzoption{jump mark mid}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkmid} \tikzoption{jump mark left}[]{\let\tikz@plot@handler=\pgfplothandlerjumpmarkleft} \tikzoption{raw gnuplot}[true]{\csname tikz@plot@raw@gnuplot#1\endcsname} \tikzoption{prefix}{\def\tikz@plot@prefix{#1}} \tikzoption{id}{\def\tikz@plot@id{#1}} -\tikzoption{samples}{\def\tikz@plot@samples{#1}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax} +\tikzoption{samples}{\pgfmathsetmacro\tikz@plot@samples{max(2,#1)}\expandafter\tikz@plot@samples@recalc\tikz@plot@domain\relax} \tikzoption{samples at}{\def\tikz@plot@samplesat{#1}} \tikzoption{parametric}[true]{\csname tikz@plot@parametric#1\endcsname} @@ -963,12 +1200,28 @@ \def\tikz@plot@var{\x} \def\tikz@plot@samplesat{-5,-4.5833333,...,5} \def\tikz@plot@samples@recalc#1:#2\relax{% + \begingroup \pgfmathparse{#1}% \let\tikz@temp@start=\pgfmathresult% \pgfmathparse{#2}% \let\tikz@temp@end=\pgfmathresult% - \pgfmathparse{\tikz@temp@start+(\tikz@temp@end-\tikz@temp@start)/(\tikz@plot@samples-1)}% - \edef\tikz@plot@samplesat{\tikz@temp@start,\pgfmathresult,...,\tikz@temp@end}% + \pgfmathsetmacro\tikz@temp@diff{(\tikz@temp@end-\tikz@temp@start)/(\tikz@plot@samples-1)}% + % + % this particular item is for backwards compatibility. + % Pgfplots <= 1.8 called 'samples' in a context where the 'fpu' was + % active... and I fear there is no simple solution to replace the + % new \ifdim below. Sorry. + \pgfkeys{/pgf/fpu/output format/fixed/.try}% + % + \pgfmathsetmacro\tikz@temp@diff@abs{abs(\tikz@temp@diff)}% + \ifdim\tikz@temp@diff@abs pt<0.0001pt\relax% + \edef\tikz@plot@samplesat{\tikz@temp@start,\tikz@temp@end}% + \else% + \pgfmathparse{\tikz@temp@start+\tikz@temp@diff}% + \edef\tikz@plot@samplesat{\tikz@temp@start,\pgfmathresult,...,\tikz@temp@end}% + \fi% + \pgfmath@smuggleone\tikz@plot@samplesat + \endgroup } @@ -979,11 +1232,24 @@ \newif\iftikz@plot@raw@gnuplot -% To options +% +% To and edge options +% \tikzoption{to path}{\def\tikz@to@path{#1}} \def\tikz@to@path{-- (\tikztotarget) \tikztonodes} +\tikzset{edge macro/.store in=\tikz@edge@macro} +\let\tikz@edge@macro\pgfutil@empty + +\tikzset{ + edge node/.code={ + \expandafter\def\expandafter\tikz@tonodes\expandafter{\tikz@tonodes #1} + }, + edge label/.style={/tikz/edge node={node[auto]{#1}}}, + edge label'/.style={/tikz/edge node={node[auto,swap]{#1}}} +} + % After command options \tikzset{ @@ -1003,6 +1269,10 @@ \newif\iftikz@child@missing \pgfkeys{/tikz/missing/.is if=tikz@child@missing} +\tikzset{edge from parent macro/.initial=\tikz@edge@from@parent@macro} +\def\tikz@edge@from@parent@macro#1#2{ + [style=edge from parent, #1, /utils/exec=\tikz@node@is@a@labeltrue] \tikz@edge@to@parent@path #2} + \tikzoption{edge from parent path}{\def\tikz@edge@to@parent@path{#1}} \tikzoption{parent anchor}{\def\tikzparentanchor{.#1}\ifx\tikzparentanchor\tikz@border@text\let\tikzparentanchor\pgfutil@empty\fi} @@ -1084,10 +1354,10 @@ % Snakes are in a lib: -\tikzset{snake/.code=\PackageError{tikz}{You need to say \string\usetikzlibrary{snakes}}{}} +\tikzset{snake/.code=\tikzerror{You need to say \string\usetikzlibrary{snakes}}} % Decorations -\tikzset{decorate/.code=\PackageError{tikz}{You need to load a decoration library}{}} +\tikzset{decorate/.code=\tikzerror{You need to load a decoration library}} % Matrix options \usepgfmodule{matrix} @@ -1108,6 +1378,15 @@ \let\tikz@ampersand@replacement=\pgfutil@empty +% Automatic shorthand management +\tikzset{% + handle active characters in code/.is if=tikz@handle@active@code, + handle active characters in nodes/.is if=tikz@handle@active@nodes, +} +\newif\iftikz@handle@active@code +\newif\iftikz@handle@active@nodes + + % Execute option \tikzoption{execute at begin picture}{\expandafter\def\expandafter\tikz@atbegin@picture\expandafter{\tikz@atbegin@picture#1}} \tikzoption{execute at end picture}{\expandafter\def\expandafter\tikz@atend@picture\expandafter{\tikz@atend@picture#1}} @@ -1117,6 +1396,8 @@ \tikzoption{execute at end to}{\expandafter\def\expandafter\tikz@atend@to\expandafter{\tikz@atend@to#1}} \tikzoption{execute at begin node}{\expandafter\def\expandafter\tikz@atbegin@node\expandafter{\tikz@atbegin@node#1}} \tikzoption{execute at end node}{\expandafter\def\expandafter\tikz@atend@node\expandafter{\tikz@atend@node#1}} +\tikzoption{execute at begin matrix}{\expandafter\def\expandafter\tikz@atbegin@matrix\expandafter{\tikz@atbegin@matrix#1}} +\tikzoption{execute at end matrix}{\expandafter\def\expandafter\tikz@atend@matrix\expandafter{\tikz@atend@matrix#1}} \tikzoption{execute at begin cell}{\expandafter\def\expandafter\tikz@atbegin@cell\expandafter{\tikz@atbegin@cell#1}} \tikzoption{execute at end cell}{\expandafter\def\expandafter\tikz@atend@cell\expandafter{\tikz@atend@cell#1}} \tikzoption{execute at empty cell}{\expandafter\def\expandafter\tikz@at@emptycell\expandafter{\tikz@at@emptycell#1}} @@ -1132,6 +1413,8 @@ \let\tikz@atbegin@cell=\pgfutil@empty \let\tikz@atend@cell=\pgfutil@empty \let\tikz@at@emptycell=\pgfutil@empty +\let\tikz@atbegin@matrix=\pgfutil@empty +\let\tikz@atend@matrix=\pgfutil@empty % Pre and post actions @@ -1211,11 +1494,17 @@ \tikzstyle{densely dashed}= [dash pattern=on 3pt off 2pt] \tikzstyle{loosely dashed}= [dash pattern=on 3pt off 6pt] \tikzstyle{dashdotted}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt] +\tikzstyle{dash dot}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt] \tikzstyle{densely dashdotted}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt] +\tikzstyle{densely dash dot}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt] \tikzstyle{loosely dashdotted}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt] +\tikzstyle{loosely dash dot}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt] \tikzstyle{dashdotdotted}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt] \tikzstyle{densely dashdotdotted}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt] \tikzstyle{loosely dashdotdotted}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt] +\tikzstyle{dash dot dot}= [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt] +\tikzstyle{densely dash dot dot}= [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt] +\tikzstyle{loosely dash dot dot}= [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt] \tikzstyle{transparent}= [opacity=0] @@ -1258,24 +1547,26 @@ \expandafter\pgfutil@in@\expandafter!\expandafter{\tikz@key}% \ifpgfutil@in@% % this is a color! - \expandafter\tikz@addoption\expandafter{\expandafter\pgfutil@color\expandafter{\tikz@key}}% + \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}% \edef\tikz@textcolor{\tikz@key}% \else% \pgfutil@doifcolorelse{\tikz@key} - { % - \expandafter\tikz@addoption\expandafter{\expandafter\pgfutil@color\expandafter{\tikz@key}}% + {% + \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}% \edef\tikz@textcolor{\tikz@key}% }% {% % Ok, second chance: This might be an arrow specification: - \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key} + \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key}% \ifpgfutil@in@% % Ah, an arrow spec! \expandafter\tikz@processarrows\expandafter{\tikz@key}% \else% % Ok, third chance: A shape! \expandafter\ifx\csname pgf@sh@s@\tikz@key\endcsname\relax% - \pgfkeys{/errors/unknown key={/tikz/\tikz@key}{#1}}% + \pgfkeys{/errors/unknown key/.expand + once=\expandafter{\expandafter/\expandafter t\expandafter + i\expandafter k\expandafter z\expandafter/\tikz@key}{#1}}% \else% \edef\tikz@shape{\tikz@key}% \fi% @@ -1284,35 +1575,60 @@ \fi% \fi% } +\def\tikz@compat@color@set#1{% + \pgfutil@color{#1}\pgfutil@colorlet{pgffillcolor}{#1}% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgffillcolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% + \expandafter\expandafter\expandafter\global% + \expandafter\expandafter\expandafter\let\expandafter\csname\expandafter\string\expandafter\color@pgfstrokecolor\expandafter\endcsname\csname\string\color@pgffillcolor\endcsname% +} +\def\tikz@startup@env{% + \ifnum\the\catcode`\;=\active\relax\expandafter\let\expandafter\tikz@origsemi\expandafter=\tikz@activesemicolon\fi% + \ifnum\the\catcode`\:=\active\relax\expandafter\let\expandafter\tikz@origcolon\expandafter=\tikz@activecolon\fi% + \ifnum\the\catcode`\|=\active\relax\expandafter\let\expandafter\tikz@origbar\expandafter=\tikz@activebar\fi% + \tikz@deactivatthings% + \iftikz@handle@active@code% + \tikz@switchoff@shorthands% + \fi% +} % % Main TikZ Environment % -\def\tikzpicture{\pgfutil@ifnextchar[\tikz@picture{\tikz@picture[]}}%} +\def\tikzpicture{% + \begingroup% + \tikz@startup@env% + \pgfutil@ifnextchar[\tikz@picture{\tikz@picture[]}}%} \def\tikz@picture[#1]{% \pgfpicture% \let\tikz@atbegin@picture=\pgfutil@empty% \let\tikz@atend@picture=\pgfutil@empty% \let\tikz@transform=\relax% \def\tikz@time{.5}% - \tikz@installcommands\scope[every picture,#1]% + \tikz@installcommands% + \scope[every picture,#1]% + \iftikz@handle@active@code% + \tikz@switchoff@shorthands% + \fi% \expandafter\tikz@atbegin@picture% \tikz@lib@scope@check% } \def\endtikzpicture{% \tikz@atend@picture% - \global\let\pgf@shift@baseline=\pgf@baseline% - \global\let\pgf@trimleft@final=\pgf@trimleft% - \global\let\pgf@trimright@final=\pgf@trimright% + \global\let\pgf@shift@baseline@smuggle=\pgf@baseline% + \global\let\pgf@trimleft@final@smuggle=\pgf@trimleft% + \global\let\pgf@trimright@final@smuggle=\pgf@trimright% \global\let\pgf@remember@smuggle=\ifpgfrememberpicturepositiononpage% + \pgf@remember@layerlist@globally \endscope% - \let\pgf@baseline=\pgf@shift@baseline% - \let\pgf@trimleft=\pgf@trimleft@final% - \let\pgf@trimright=\pgf@trimright@final% + \let\pgf@baseline=\pgf@shift@baseline@smuggle% + \let\pgf@trimleft=\pgf@trimleft@final@smuggle% + \let\pgf@trimright=\pgf@trimright@final@smuggle% \let\ifpgfrememberpicturepositiononpage=\pgf@remember@smuggle% - \endpgfpicture} + \pgf@restore@layerlist@from@global + \endpgfpicture\endgroup} % Inlined picture @@ -1327,29 +1643,52 @@ % The rectangle \tikz{\draw (0,0) rectangle (1em,1ex)} has width 1em and % height 1ex. -% This code does not work for some inline \tikz. For example -% \tikz\foreach \x in {1,...,10} \draw (\x,0) circle (0.4cm); -% makes tikz crash. -% Begin suspected code -% \def\tikz{\pgfutil@ifnextchar[{\tikz@opt}{\tikz@opt[]}} -% \def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@}} -% \def\tikz@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endtikzpicture\let\pgf@temp=} -% \def\tikz@@{\begingroup\def\tikz@path@do@at@end{\endgroup\endtikzpicture}} -% End suspected code -% Begin old code -\def\tikz{\pgfutil@ifnextchar[{\tikz@opt}{\tikz@opt[]}} -\def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@}} -\def\tikz@#1{#1\endtikzpicture} + +\def\tikz{% + \begingroup% + \tikz@startup@env% + \pgfutil@ifnextchar[{\tikz@opt}{\tikz@opt[]}} +\def\tikz@opt[#1]{\tikzpicture[#1]\pgfutil@ifnextchar\bgroup{\tikz@}{\tikz@@single}} +\def\tikz@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endtikzpicture\aftergroup\endgroup\let\pgf@temp=} +\def\tikz@@single#1{% + \expandafter\ifx\csname tikz@protected@command\string#1\endcsname\relax% + \expandafter\tikz@@% + \else% + \begingroup\def\tikz@path@do@at@end{\endgroup\endtikzpicture\endgroup}% + \fi% + #1% +} + +\expandafter\let\csname tikz@protected@command\string\draw\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\pattern\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\fill\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\filldraw\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\shade\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\shadedraw\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\clip\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\graph\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\useasboundingbox\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\node\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\coordinate\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\matrix\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\datavisualization\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\path\endcsname\pgfutil@empty +\expandafter\let\csname tikz@protected@command\string\pic\endcsname\pgfutil@empty + +% Comment by TT: I hope I fixed the \tikz \foreach problem. The new +% version will take a conservative approach and will only do fancy +% stuff when the next keyword after \tikz is one of the following: +% \draw, \fill, \filldraw, \graph, \matrix, \def\tikz@@{% \let\tikz@next=\tikz@collectnormalsemicolon% \ifnum\the\catcode`\;=\active\relax% \let\tikz@next=\tikz@collectactivesemicolon% \fi% \tikz@next} -\def\tikz@collectnormalsemicolon#1;{#1;\endtikzpicture} +\def\tikz@collectnormalsemicolon#1;{#1;\endtikzpicture\endgroup} { \catcode`\;=\active - \gdef\tikz@collectactivesemicolon#1;{#1;\endtikzpicture} + \gdef\tikz@collectactivesemicolon#1;{#1;\endtikzpicture\endgroup} } % End old code @@ -1374,7 +1713,7 @@ \tikz@transparency@groupfalse% \tikzset{every scope/.try,#1}% \tikz@options% - \iftikz@transparency@group\pgftransparencygroup\fi% + \iftikz@transparency@group\expandafter\pgftransparencygroup\expandafter[\tikz@transparency@group@options]\tikz@blend@group\fi% \expandafter\tikz@atbegin@scope% \tikz@lib@scope@check% } @@ -1386,6 +1725,31 @@ \tikz@lib@scope@check% } + +\def\tikz@scoped{\pgfutil@ifnextchar[{\tikz@scoped@opt}{\tikz@scoped@opt[]}} +\def\tikz@scoped@opt[#1]{\scope[#1]\pgfutil@ifnextchar\bgroup{\tikz@scoped@}{\tikz@scoped@@single}} +\def\tikz@scoped@{\bgroup\tikz@auto@end@pathtrue\aftergroup\endscope\let\pgf@temp=} +\def\tikz@scoped@@single#1{% + \expandafter\ifx\csname tikz@scoped@protected@command\string#1\endcsname\relax% + \expandafter\tikz@scoped@@% + \else% + \begingroup\def\tikz@scoped@path@do@at@end{\endgroup\endscope}% + \fi% + #1% +} +\def\tikz@scoped@@{% + \let\tikz@scoped@next=\tikz@scoped@collectnormalsemicolon% + \ifnum\the\catcode`\;=\active\relax% + \let\tikz@scoped@next=\tikz@scoped@collectactivesemicolon% + \fi% + \tikz@scoped@next} +\def\tikz@scoped@collectnormalsemicolon#1;{#1;\endscope} +{ + \catcode`\;=\active + \gdef\tikz@scoped@collectactivesemicolon#1;{#1;\endscope} +} + + % Install a shortcut command which is only valid inside of a % tikzpicture. % @@ -1396,7 +1760,7 @@ % #2: real command name \def\tikzaddtikzonlycommandshortcutlet#1#2{% \expandafter\def\expandafter\tikz@installcommands\expandafter{\tikz@installcommands - \let#1=#2 + \let#1=#2% }% }% @@ -1412,10 +1776,8 @@ % Install the abbreviated commands % \def\tikz@installcommands{% - \ifnum\the\catcode`\;=\active\relax\expandafter\let\expandafter\tikz@origsemi\expandafter=\tikz@activesemicolon\fi% - \ifnum\the\catcode`\:=\active\relax\expandafter\let\expandafter\tikz@origcolon\expandafter=\tikz@activecolon\fi% - \ifnum\the\catcode`\|=\active\relax\expandafter\let\expandafter\tikz@origbar\expandafter=\tikz@activebar\fi% \let\tikz@origscope=\scope% + \let\tikz@origscoped=\scoped% \let\tikz@origendscope=\endscope% \let\tikz@origstartscope=\startscope% \let\tikz@origstopscope=\stopscope% @@ -1430,15 +1792,15 @@ \let\tikz@origclip=\clip% \let\tikz@origuseasboundingbox=\useasboundingbox% \let\tikz@orignode=\node% + \let\tikz@origpic=\pic% \let\tikz@origcoordinate=\coordinate% \let\tikz@origmatrix=\matrix% \let\tikz@origcalendar=\calendar% \let\tikz@origdv=\datavisualization% \let\tikz@origgraph=\graph% % - \tikz@deactivatthings% - % \let\scope=\tikz@scope@env% + \let\scoped=\tikz@scoped% \let\endscope=\endtikz@scope@env% \let\startscope=\scope% \let\stopscope=\endscope% @@ -1455,16 +1817,17 @@ \def\graph{\path graph} \def\useasboundingbox{\path[use as bounding box]} \def\node{\tikz@path@overlay{node}} + \def\pic{\tikz@path@overlay{pic}} \def\coordinate{\tikz@path@overlay{coordinate}} \def\matrix{\tikz@path@overlay{node[matrix]}} \def\calendar{\tikz@lib@cal@calendar}% \def\datavisualization{\tikz@lib@datavisualization}% } \ifx\tikz@lib@cal@calendar\@undefined -\def\tikz@lib@cal@calendar{\PackageError{tikz}{You need to say \string\usetikzlibrary{calendar} to use the \string\calendar{} command}{}} +\def\tikz@lib@cal@calendar{\tikzerror{You need to say \string\usetikzlibrary{calendar} to use the \string\calendar{} command}} \fi \ifx\tikz@lib@datavisualization\@undefined -\def\tikz@lib@datavisualization{\PackageError{tikz}{You need to say \string\usetikzlibrary{datavisualization} to use the \string\datavisualization{} command}{}} +\def\tikz@lib@datavisualization{\tikzerror{You need to say \string\usetikzlibrary{datavisualization} to use the \string\datavisualization{} command}} \fi \def\tikz@path@overlay#1{% @@ -1473,10 +1836,8 @@ \def\tikz@path@overlayed#1<#2>{\path<#2> #1} \def\tikz@uninstallcommands{% - \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi% - \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi% - \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi% \let\scope=\tikz@origscope% + \let\scoped=\tikz@origscoped% \let\endscope=\tikz@origendscope% \let\startscope=\tikz@origstartscope% \let\stopscope=\tikz@origstopscope% @@ -1491,6 +1852,7 @@ \let\clip=\tikz@origclip% \let\useasboundingbox=\tikz@origuseasboundingbox% \let\node=\tikz@orignode% + \let\pic=\tikz@origpic% \let\coordinate=\tikz@origcoordinate% \let\matrix=\tikz@origmatrix% \let\calendar=\tikz@origcalendar% @@ -1517,16 +1879,49 @@ \gdef\tikz@activecolon{:}% \gdef\tikz@activebar{|}% \gdef\tikz@activequotes{"}% + \global\let\tikz@active@quotes@token="% \gdef\tikz@activeexlmark{!}% \gdef\tikz@deactivatthings{% \def;{\tikz@nonactivesemicolon}% \def:{\tikz@nonactivecolon}% \def|{\tikz@nonactivebar}% - \def!{\tikz@nonactiveexlmark}% + \def!{\tikz@nonactiveexlmark}% } } - +\let\tikz@orig@shorthands\pgfutil@empty +\def\tikz@switchoff@shorthands{% + \ifx\tikz@orig@shorthands\pgfutil@empty% + \edef\tikz@orig@shorthands{% + \catcode\noexpand`\noexpand\;\the\catcode`\;\relax% + \catcode\noexpand`\noexpand\:\the\catcode`\:\relax% + \catcode\noexpand`\noexpand\|\the\catcode`\|\relax% + \catcode\noexpand`\noexpand\!\the\catcode`\!\relax% + \catcode\noexpand`\noexpand\,\the\catcode`\,\relax% + \catcode\noexpand`\noexpand\<\the\catcode`\<\relax% + \catcode\noexpand`\noexpand\>\the\catcode`\>\relax% + \catcode\noexpand`\noexpand\"\the\catcode`\"\relax% + \catcode\noexpand`\noexpand\'\the\catcode`\'\relax% + \catcode\noexpand`\noexpand\-\the\catcode`\-\relax% + \catcode\noexpand`\noexpand\=\the\catcode`\=\relax% + \catcode\noexpand`\noexpand\.\the\catcode`\.\relax% + \catcode\noexpand`\noexpand\$\the\catcode`\$\relax% + }% + \catcode`\;12\relax% + \catcode`\:12\relax% + \catcode`\|12\relax% + \catcode`\!12\relax% + \catcode`\,12\relax% + \catcode`\<12\relax% + \catcode`\>12\relax% + \catcode`\"12\relax% + \catcode`\'12\relax% + \catcode`\-12\relax% + \catcode`\=12\relax% + \catcode`\.12\relax% + \catcode`\$3\relax% + \fi% +} @@ -1557,11 +1952,14 @@ \def\tikz@@command@path{% \edef\tikzscope@linewidth{\the\pgflinewidth}% \begingroup% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \let\tikz@path@do@at@end=\tikz@lib@scope@check% \let\tikz@options=\pgfutil@empty% \let\tikz@mode=\pgfutil@empty% \let\tikz@moveto@waiting=\relax% \let\tikz@timer=\relax% + \let\tikz@tangent=\relax% \let\tikz@collected@onpath=\pgfutil@empty% \let\tikz@preactions=\pgfutil@empty% \let\tikz@postactions=\pgfutil@empty% @@ -1569,6 +1967,8 @@ \tikz@decoratepathfalse% \tikz@node@is@a@labelfalse% \tikz@expandcount=100\relax% + \pgf@path@lastx=0pt% + \pgf@path@lasty=0pt% \tikz@lastx=0pt% \tikz@lasty=0pt% \tikz@lastxsaved=0pt% @@ -1581,44 +1981,44 @@ \else% \tikz@invoke@collected@onpath% \fi% - \afterassignment\tikz@handle\let\@let@token=% + \afterassignment\tikz@handle\let\pgf@let@token=% } \newcount\tikz@expandcount % Central dispatcher for commands \def\tikz@handle{% \let\@next=\tikz@expand% - \ifx\@let@token(%) + \ifx\pgf@let@token(%) \let\@next=\tikz@movetoabs% \else% - \ifx\@let@token+% + \ifx\pgf@let@token+% \let\@next=\tikz@movetorel% \else% - \ifx\@let@token-% + \ifx\pgf@let@token-% \let\@next=\tikz@lineto% \else% - \ifx\@let@token.% + \ifx\pgf@let@token.% \let\@next=\tikz@dot% \else% - \ifx\@let@token r% + \ifx\pgf@let@token r% \let\@next=\tikz@rect% \else% - \ifx\@let@token n% + \ifx\pgf@let@token n% \let\@next=\tikz@fig% \else% - \ifx\@let@token[%] + \ifx\pgf@let@token[%] \let\@next=\tikz@parse@options% \else% - \ifx\@let@token c% + \ifx\pgf@let@token c% \let\@next=\tikz@cchar% \else% - \ifx\@let@token\bgroup% + \ifx\pgf@let@token\bgroup% \let\@next=\tikz@beginscope% \else% - \ifx\@let@token\egroup% + \ifx\pgf@let@token\egroup% \let\@next=\tikz@endscope% \else% - \ifx\@let@token;% + \ifx\pgf@let@token;% \let\@next=\tikz@finish% \else% \let\@next=\tikz@handle@more% @@ -1638,47 +2038,51 @@ % Continued... \def\tikz@handle@more{% - \ifx\@let@token a% + \ifx\pgf@let@token a% \let\@next=\tikz@arcA% \else% - \ifx\@let@token e% + \ifx\pgf@let@token e% \let\@next=\tikz@e@char% \else% - \ifx\@let@token g% + \ifx\pgf@let@token g% \let\@next=\tikz@g@char% \else% - \ifx\@let@token s% + \ifx\pgf@let@token s% \let\@next=\tikz@schar% \else% - \ifx\@let@token |% + \ifx\pgf@let@token |% \let\@next=\tikz@vh@lineto% \else% - \ifx\@let@token p% + \ifx\pgf@let@token p% \let\@next=\tikz@pchar% \pgfsetmovetofirstplotpoint% \else% - \ifx\@let@token t% + \ifx\pgf@let@token t% \let\@next=\tikz@to% \else% - \ifx\@let@token\pgfextra% + \ifx\pgf@let@token\pgfextra% \let\@next=\tikz@extra% \else% - \ifx\@let@token\foreach% + \ifx\pgf@let@token\foreach% \let\@next=\tikz@foreach% \else% - \ifx\@let@token\pgf@stop% - \let\@next=\relax% + \ifx\pgf@let@token f% + \let\@next=\tikz@fchar% \else% - \ifx\@let@token\par% - \let\@next=\tikz@scan@next@command% + \ifx\pgf@let@token\pgf@stop% + \let\@next=\relax% \else% - \ifx\@let@token d% - \let\@next=\tikz@decoration% + \ifx\pgf@let@token\par% + \let\@next=\tikz@scan@next@command% \else% - \ifx\@let@token l% - \let\@next=\tikz@l@char%\tikz@let@command% + \ifx\pgf@let@token d% + \let\@next=\tikz@decoration% \else% - \let\@next=\tikz@expand% + \ifx\pgf@let@token l% + \let\@next=\tikz@l@char%\tikz@let@command% + \else% + \let\@next=\tikz@expand% + \fi% \fi% \fi% \fi% @@ -1692,6 +2096,7 @@ \fi% \fi% \fi% + \ifx\@next\tikz@expand\else\tikz@expandcount=100\relax\fi% \@next% } @@ -1704,16 +2109,14 @@ } \def\tikz@lsystem{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{lindenmayersystems} to - draw Lindenmayer systems}{} + \tikzerror{You need to say \string\usetikzlibrary{lindenmayersystems} to draw Lindenmayer systems} } \def\tikz@@lsystem{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{lindenmayersystems} to - draw L-systems}{} + \tikzerror{You need to say \string\usetikzlibrary{lindenmayersystems} to draw L-systems} } -\def\tikz@pchar{\pgfutil@ifnextchar l{\tikz@plot}{\tikz@parabola}} +\def\tikz@pchar{\pgfutil@ifnextchar l{\tikz@plot}{\pgfutil@ifnextchar i{\tikz@subpicture}{\tikz@parabola}}} \def\tikz@cchar{% \pgfutil@ifnextchar i{\tikz@circle}% {\pgfutil@ifnextchar h{\tikz@children}{\tikz@cochar}}}% @@ -1729,24 +2132,27 @@ \def\tikz@g@char r{\pgfutil@ifnextchar i{\tikz@grid}{\tikz@graph}} % svg syntax -% svg[options] "..." +% svg[options] {...} \def\tikz@svg@path{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{svg.path} to - use the svg path command}{} + \tikzerror{You need to say \string\usetikzlibrary{svg.path} to use the svg path command} } \def\tikz@finish{% % Rendering pipeline % - % Step 1: Decorate path + % Step 1: The path background box + % + \box\tikz@figbox@bg% + % + % Step 2: Decorate path % \iftikz@decoratepath% \tikz@lib@dec@decorate@path% \fi% % - % Step 1: Preactions + % Step 3: Preactions % \pgfsyssoftpath@getcurrentpath\tikz@actions@path% \edef\tikz@restorepathsize{% @@ -1757,7 +2163,7 @@ }% \tikz@preactions% % - % Reset modes + % Step 4: Reset modes % \let\tikz@path@picture=\pgfutil@empty% \tikz@mode@fillfalse% @@ -1776,20 +2182,27 @@ \iftikz@mode@fade@path% \tikz@addoption{% \iftikz@fade@adjust% - \pgfsetfadingforcurrentpath{\tikz@path@fading}{\tikz@do@fade@transform}% + \iftikz@mode@draw% + \pgfsetfadingforcurrentpathstroked{\tikz@path@fading}{\tikz@do@fade@transform}% + \else% + \pgfsetfadingforcurrentpath{\tikz@path@fading}{\tikz@do@fade@transform}% + \fi% \else% \pgfsetfading{\tikz@path@fading}{\tikz@do@fade@transform}% \fi% \tikz@mode@fade@pathfalse% no more fading... }% \fi% - % Rendering pipeline % - % Step 2: Install scope fading + % Step 5: Install scope fading % \iftikz@mode@fade@scope% \iftikz@fade@adjust% - \pgfsetfadingforcurrentpath{\tikz@scope@fading}{\tikz@do@fade@transform}% + \iftikz@mode@draw% + \pgfsetfadingforcurrentpathstroked{\tikz@scope@fading}{\tikz@do@fade@transform}% + \else% + \pgfsetfadingforcurrentpath{\tikz@scope@fading}{\tikz@do@fade@transform}% + \fi% \else% \pgfsetfading{\tikz@scope@fading}{\tikz@do@fade@transform}% \fi% @@ -1805,7 +2218,7 @@ \tikz@options% \fi% % - % Step 4: Do a fill if shade or a path picture follows. + % Step 6: Do a fill if shade or a path picture follows. % \iftikz@mode@fill% \iftikz@mode@shade% @@ -1828,7 +2241,7 @@ \fi% \fi% % - % Step 5: Do a shade if necessary. + % Step 7: Do a shade if necessary. % \iftikz@mode@shade% \pgfsyssoftpath@getcurrentpath\tikz@temppath @@ -1838,7 +2251,7 @@ \tikz@mode@shadefalse% no more shading... \fi% % - % Step 5a: Do a path picture if necessary. + % Step 8: Do a path picture if necessary. % \ifx\tikz@path@picture\pgfutil@empty% \else% @@ -1866,7 +2279,7 @@ \let\tikz@path@picture=\pgfutil@empty% \fi% % - % Step 6: Double stroke, if necessary + % Step 9: Double stroke, if necessary % \iftikz@mode@draw% \iftikz@mode@double% @@ -1877,17 +2290,17 @@ \fi% \fi% % - % Step 7: Do stroke/fill/clip as needed + % Step 10: Do stroke/fill/clip as needed % \edef\tikz@temp{\noexpand\pgfusepath{% \iftikz@mode@fill fill,\fi% \iftikz@mode@draw draw,\fi% - \iftikz@mode@clip clip,\fi% + \iftikz@mode@clip clip\fi% }}% \tikz@temp% \tikz@mode@fillfalse% no more filling % - % Step 8: Double stroke, if necessary + % Step 11: Double stroke, if necessary % \iftikz@mode@draw% \iftikz@mode@double% @@ -1897,22 +2310,22 @@ \fi% \tikz@mode@drawfalse% no more stroking % - % Step 9: Postactions + % Step 12: Postactions % \tikz@postactions% % - % Step 10: Add labels and nodes + % Step 13: Add labels and nodes % \box\tikz@figbox% % - % Step 11: Close option brace + % Step 14: Close option brace % \ifx\tikz@options\pgfutil@empty% \else% \endgroup% \pgfsys@endscope% \iftikz@mode@clip% - \PackageError{tikz}{Extra options not allowed for clipping path command.}{}% + \tikzerror{Extra options not allowed for clipping path command.}% \fi% \fi% \iftikz@mode@clip% @@ -1934,6 +2347,7 @@ {% \pgfsys@beginscope% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \path[#1];% do extra path \pgfsyssoftpath@setcurrentpath\tikz@actions@path% restore \tikz@restorepathsize% @@ -1945,6 +2359,7 @@ {% \pgfsys@beginscope% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \tikz@restorepathsize% \path[#1]\pgfextra{\pgfsyssoftpath@setcurrentpath\tikz@actions@path};% do extra path \pgf@resetpathsizes% @@ -1958,7 +2373,7 @@ \def\tikz@expand{% \advance\tikz@expandcount by -1% \ifnum\tikz@expandcount<0\relax% - \PackageError{tikz}{Giving up on this path. Did you forget a semicolon?}{}% + \tikzerror{Giving up on this path. Did you forget a semicolon?}% \let\@next=\tikz@finish% \else% \let\@next=\tikz@@expand @@ -1966,7 +2381,7 @@ \@next} \def\tikz@@expand{% - \expandafter\tikz@scan@next@command\@let@token} + \expandafter\tikz@scan@next@command\pgf@let@token} @@ -1981,6 +2396,8 @@ } \def\tikz@@endscope{% \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + \global\let\tikz@tangent@temp\tikz@tangent% \edef\tikz@marshal{% \tikz@lastx=\the\tikz@lastx% \tikz@lasty=\the\tikz@lasty% @@ -2004,6 +2421,8 @@ \expandafter% \endgroup\tikz@marshal% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \let\tikz@tangent\tikz@tangent@temp% \tikz@scan@next@command} @@ -2018,33 +2437,50 @@ \def\pgfextra{pgfextra} -% Syntax for \foreach: +% Syntax for foreach: +% +% foreach \var in {list} {path text} +% +% or +% % \foreach \var in {list} {path text} % % Example: % % \draw (0,0) \foreach \x in {1,2,3} {-- (\x,0) circle (1cm)} -- (5,5); +\def\tikz@fchar oreach{\tikz@foreach} + \def\tikz@foreach{% \def\pgffor@beginhook{% \tikz@lastx=\tikz@foreach@save@lastx% \tikz@lasty=\tikz@foreach@save@lasty% \tikz@lastxsaved=\tikz@foreach@save@lastxsaved% \tikz@lastysaved=\tikz@foreach@save@lastysaved% - \setbox\tikz@figbox=\box\tikz@tempbox\expandafter\tikz@scan@next@command\pgfutil@firstofone}% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \expandafter\tikz@scan@next@command\pgfutil@firstofone}% \def\pgffor@endhook{\pgfextra{% \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}% \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}% \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}% \xdef\tikz@foreach@save@lastysaved{\the\tikz@lastysaved}% - \global\setbox\tikz@tempbox=\copy\tikz@figbox\pgfutil@gobble}}% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + \pgfutil@gobble}}% \def\pgffor@afterhook{% \tikz@lastx=\tikz@foreach@save@lastx% \tikz@lasty=\tikz@foreach@save@lasty% \tikz@lastxsaved=\tikz@foreach@save@lastxsaved% \tikz@lastysaved=\tikz@foreach@save@lastysaved% - \setbox\tikz@figbox=\box\tikz@tempbox\tikz@scan@next@command}% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \let\pgffor@beginhook\relax% + \let\pgffor@endhook\relax% + \let\pgffor@afterhook\relax% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \tikz@scan@next@command}% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \xdef\tikz@foreach@save@lastx{\the\tikz@lastx}% \xdef\tikz@foreach@save@lasty{\the\tikz@lasty}% \xdef\tikz@foreach@save@lastxsaved{\the\tikz@lastxsaved}% @@ -2085,7 +2521,7 @@ \tikz@make@last@position{#1}% \iftikz@shapeborder% % ok, the moveto will have to wait. flag that we have a moveto in - % wainting: + % waiting: \edef\tikz@moveto@waiting{\tikz@shapeborder@name}% \else% \pgfpathmoveto{\tikz@last@position}% @@ -2126,7 +2562,9 @@ % Collecting labels on the path % -\def\tikz@collect@coordinate@onpath#1coordinate{% +\def\tikz@collect@coordinate@onpath#1c{% + \pgfutil@ifnextchar y{\tikz@cycle@expander@add#1}{\tikz@collect@coordinate@onpath@{#1}}} +\def\tikz@collect@coordinate@onpath@#1oordinate{% \pgfutil@ifnextchar[{\tikz@@collect@coordinate@opt#1}{\tikz@@collect@coordinate@opt#1[]}}%} \def\tikz@@collect@coordinate@opt#1[#2]{% \pgfutil@ifnextchar({\tikz@@collect@coordinate#1[#2]}{% @@ -2134,30 +2572,61 @@ \def\tikz@@collect@coordinate#1[#2](#3){% \tikz@collect@label@onpath#1node[shape=coordinate,#2](#3){}} +\newif\iftikz@collect@pic + \def\tikz@collect@label@onpath#1node{% \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath node}% - \tikz@collect@label@scan#1} - -\def\tikz@collect@label@scan#1{% - \pgfutil@ifnextchar({\tikz@collect@paran#1}% - {\pgfutil@ifnextchar[{\tikz@collect@options#1}% - {\pgfutil@ifnextchar\bgroup{\tikz@collect@arg#1}% - {#1}}}% + \let\tikz@collect@cont#1% + \tikz@collect@picfalse% + \tikz@collect@label@scan} + +\def\tikz@collect@pic@onpath#1pic{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath pic}% + \let\tikz@collect@cont#1 + \tikz@collect@pictrue% + \tikz@collect@label@scan} + +\def\tikz@collect@label@scan{% + \pgfutil@ifnextchar f{\tikz@collect@nodes}{% + \pgfutil@ifnextchar({\tikz@collect@paran}% + {\pgfutil@ifnextchar[{\tikz@collect@options}% + {\pgfutil@ifnextchar\bgroup{\tikz@collect@arg}% + {\tikz@collect@cont}}}}% }%}} -\def\tikz@collect@paran#1(#2){% - \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath(#2)}% - \tikz@collect@label@scan#1% +\def\tikz@collect@nodes foreach#1in{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath foreach#1in}% + \pgfutil@ifnextchar\bgroup\tikz@collect@nodes@group\tikz@collect@nodes@one% } -\def\tikz@collect@options#1[#2]{% - \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath[#2]}% - \tikz@collect@label@scan#1% +\def\tikz@collect@nodes@one#1{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath #1}% + \tikz@collect@label@scan% } -\def\tikz@collect@arg#1#2{% - \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#2}}% - #1% +\def\tikz@collect@nodes@group#1{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}% + \tikz@collect@label@scan% } +\def\tikz@collect@paran#1){% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1)}% + \tikz@collect@label@scan% +} +\def\tikz@collect@options#1]{% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath#1]}% + \tikz@collect@label@scan% +} +\def\tikz@collect@arg#1{% + \iftikz@handle@active@nodes% + \iftikz@collect@pic% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}% + \else% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{\scantokens{#1}}}% + \fi% + \else% + \expandafter\def\expandafter\tikz@collected@onpath\expandafter{\tikz@collected@onpath{#1}}% + \fi% + \tikz@collect@cont% +} \def\tikz@invoke@collected@onpath{% \tikz@node@is@a@labeltrue% @@ -2168,6 +2637,15 @@ } +% +% Macros for the cycle command +% + +\def\tikz@cycle@expander#1{\pgfutil@ifnextchar c{\tikz@cycle@expander@{#1}}{#1}} +\def\tikz@cycle@expander@#1c{\pgfutil@ifnextchar y{\tikz@cycle@expander@add{#1}}{#1c}} +\def\tikz@cycle@expander@add#1ycle{#1(current subpath start)--cycle} + + % Syntax for lineto: @@ -2182,8 +2660,11 @@ \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@lineto@mid}% {% \pgfutil@ifnextchar c{\tikz@close}{% - \pgfutil@ifnextchar p{\pgfsetlinetofirstplotpoint\expandafter\tikz@plot\pgfutil@gobble}% - {\tikz@scan@one@point{\tikz@@lineto}}}}} + \pgfutil@ifnextchar p{\tikz@lineto@plot@or@pic}{\tikz@scan@one@point{\tikz@@lineto}}}}} +\def\tikz@lineto@plot@or@pic p{% + \pgfutil@ifnextchar i{\tikz@collect@pic@onpath\tikz@lineto@mid p}{% + \pgfsetlinetofirstplotpoint\tikz@plot}% +} \def\tikz@@lineto#1{% % Record the starting point for later labels on the path: \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}} @@ -2205,6 +2686,7 @@ \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \fi% \let\tikz@timer=\tikz@timer@line% + \let\tikz@tangent\tikz@timer@start% \tikz@scan@next@command% } @@ -2236,14 +2718,15 @@ % -| \def\tikz@hv@lineto{% - \pgfutil@ifnextchar n - {\tikz@collect@label@onpath\tikz@hv@lineto} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@hv@lineto}{ + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@hv@lineto}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@hv@lineto}% - {\tikz@scan@one@point{\tikz@@hv@lineto}}}} + {\tikz@scan@one@point{\tikz@@hv@lineto}}}}} \def\tikz@@hv@lineto#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \pgf@yc=\tikz@lasty% \tikz@make@last@position{#1}% + \edef\tikz@tangent{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\pgf@yc}}% \tikz@flush@moveto@toward{\pgfqpoint{\tikz@lastx}{\pgf@yc}}\pgf@x\pgf@yc% \iftikz@shapeborder% % ok, target is a shape. have to work now: @@ -2270,14 +2753,15 @@ \def\tikz@vh@lineto-{\tikz@vh@lineto@next} \def\tikz@vh@lineto@next{% - \pgfutil@ifnextchar n - {\tikz@collect@label@onpath\tikz@vh@lineto@next} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@vh@lineto@next}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@vh@lineto@next}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@vh@lineto@next}% - {\tikz@scan@one@point\tikz@@vh@lineto}}} + {\tikz@scan@one@point\tikz@@vh@lineto}}}} \def\tikz@@vh@lineto#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \pgf@xc=\tikz@lastx% \tikz@make@last@position{#1}% + \edef\tikz@tangent{\noexpand\pgfqpoint{\the\pgf@xc}{\the\tikz@lasty}}% \tikz@flush@moveto@toward{\pgfqpoint{\pgf@xc}{\tikz@lasty}}\pgf@xc\pgf@y% \iftikz@shapeborder% % ok, target is a shape. have to work now: @@ -2306,9 +2790,13 @@ {\tikz@@close c}}% \def\tikz@@close cycle{% \tikz@flush@moveto% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}} + \tikz@make@last@position{\expandafter\pgfpoint\pgfsyssoftpath@lastmoveto}% \tikz@path@close{\expandafter\pgfpoint\pgfsyssoftpath@lastmoveto}% \def\pgfstrokehook{}% - \let\tikz@timer=\@undefined% + \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \let\tikz@timer=\tikz@timer@line% + \let\tikz@tangent\tikz@timer@start% \tikz@scan@next@command% } @@ -2339,17 +2827,18 @@ \def\tikz@to@or@edge{\pgfutil@ifnextchar[\tikz@@to@or@edge{\tikz@@to@or@edge[]}}%} \def\tikz@@to@or@edge[#1]{% - \def\tikz@@to@local@options{[#1]}% + \def\tikz@@to@local@options{#1}% \let\tikz@collected@onpath=\pgfutil@empty% \tikz@@to@collect% } \def\tikz@@to@collect{% \pgfutil@ifnextchar(\tikz@@to@or@edge@coordinate%) {\pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@to@collect}% - {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}% - {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}% - {\PackageError{tikz}{(, +, coordinate, or node expected}{}%) - \tikz@@to@or@edge@coordinate()}}}}% + {\pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@to@collect}% + {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@to@collect}% + {\pgfutil@ifnextchar +{\tikz@scan@one@point\tikz@@to@or@edge@math}% + {\tikzerror{(, +, coordinate, pic, or node expected}%) + \tikz@@to@or@edge@coordinate()}}}}}% } \def\tikz@@to@or@edge@coordinate({% @@ -2376,34 +2865,43 @@ } \def\tikz@do@edge{% - \setbox\tikz@figbox=\hbox\bgroup% - \unhbox\tikz@figbox% - \hbox\bgroup - \bgroup% - \pgfinterruptpath% - \pgfscope% - \let\tikz@transform=\pgfutil@empty% - \let\tikz@options=\pgfutil@empty% - \let\tikz@tonodes=\tikz@collected@onpath% - \def\tikztonodes{{\pgfextra{\tikz@node@is@a@labeltrue}\tikz@tonodes}}% - \let\tikz@collected@onpath=\pgfutil@empty% - \tikz@options% - \tikz@transform% - % Typeset node: - \let\tikz@after@path\pgfutil@empty% - \tikz@atbegin@to% - \path[style=every edge]\tikz@@to@local@options(\tikztostart)\tikz@to@path - \pgfextra{\global\let\tikz@after@path@smuggle=\tikz@after@path};% - \tikz@atend@to% - \endpgfscope% - \endpgfinterruptpath% - \egroup + \ifx\tikz@edge@macro\pgfutil@empty% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \let\tikz@transform=\pgfutil@empty% + \let\tikz@options=\pgfutil@empty% + \let\tikz@tonodes=\tikz@collected@onpath% + \def\tikztonodes{{\pgfextra{\tikz@node@is@a@labeltrue}\tikz@tonodes}}% + \let\tikz@collected@onpath=\pgfutil@empty% + \tikz@options% + \tikz@transform% + \let\tikz@transform=\relax% + % Typeset node: + \let\tikz@after@path\pgfutil@empty% + \tikz@atbegin@to% + \tikz@enable@edge@quotes% + \path[style=every edge]\expandafter[\tikz@@to@local@options](\tikztostart)\tikz@to@path + \pgfextra{\global\let\tikz@after@path@smuggle=\tikz@after@path};% + \tikz@atend@to% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% \egroup% - \egroup% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% - \endgroup% - \setbox\tikz@figbox=\box\tikz@tempbox% - \expandafter\tikz@scan@next@command\tikz@after@path% + \global\setbox\tikz@tempbox=\box\tikz@whichbox% + \expandafter\endgroup% + \expandafter\setbox\tikz@whichbox=\box\tikz@tempbox% + \else% + \expandafter\expandafter\expandafter\tikz@edge@macro% + \expandafter\expandafter\expandafter{\expandafter\tikz@@to@local@options\expandafter}\expandafter{\tikz@collected@onpath}% + \endgroup% + \let\tikz@after@path@smuggle=\pgfutil@empty% + \fi% + \expandafter\tikz@scan@next@command\tikz@after@path@smuggle% } \def\tikz@do@to{% @@ -2414,7 +2912,8 @@ {% \pgfextra{\let\tikz@after@path\pgfutil@empty}% \pgfextra{\tikz@atbegin@to}% - [style=every to]\tikz@@to@local@options\tikz@to@path% + \pgfextra{\tikz@enable@edge@quotes}% + [style=every to]\expandafter[\tikz@@to@local@options]\tikz@to@path% \pgfextra{\tikz@atend@to}% \pgf@stop% \expandafter\tikz@scan@next@command\expandafter% @@ -2443,8 +2942,7 @@ \def\tikz@lib@graph@parser{\pgfutil@ifnextchar[\tikz@graph@error{\tikz@graph@error[]}}%] \def\tikz@graph@error[#1]#2{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{graph} in - order to use the graph syntax}{}% + \tikzerror{You need to say \string\usetikzlibrary{graphs} in order to use the graph syntax}% \tikz@lib@graph@parser@done% } @@ -2460,8 +2958,23 @@ \def\tikz@edgetoparent from parent{\pgfutil@ifnextchar[\tikz@@edgetoparent{\tikz@@edgetoparent[]}}%} \def\tikz@@edgetoparent[#1]{% \let\tikz@edge@to@parent@needed=\pgfutil@empty% - \tikz@node@is@a@labeltrue% - \tikz@scan@next@command [style=edge from parent,#1] \tikz@edge@to@parent@path% + \def\tikz@edgetoparent@options{#1}% + \begingroup% + \let\tikz@collected@onpath=\pgfutil@empty% + \tikz@edgetoparentcollect% +} +\def\tikz@edgetoparentcollect{ + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@edgetoparentcollect}% + {% + \expandafter% + \endgroup% + \expandafter\tikz@edgetoparent@rollout\expandafter{\tikz@collected@onpath}% + } +} + +\def\tikz@edgetoparent@rollout#1{% + \pgfkeysgetvalue{/tikz/edge from parent macro}\tikz@etop@temp + \expandafter\tikz@scan@next@command\expandafter\tikz@etop@temp\expandafter{\tikz@edgetoparent@options}{#1}% } @@ -2472,9 +2985,10 @@ \def\tikz@dot.{\tikz@@dot}% \def\tikz@@dot{% - \pgfutil@ifnextchar n% - {\tikz@collect@label@onpath\tikz@@dot}% - {\pgfutil@ifnextchar c{\tikz@curveto@double}{\tikz@curveto@auto}}} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@dot}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@dot}% + {\pgfutil@ifnextchar c{\tikz@curveto@double}{\tikz@curveto@auto}}}% +} \def\tikz@curveto@double co{% \pgfutil@ifnextchar o{\tikz@collect@coordinate@onpath\tikz@@dot co} @@ -2485,6 +2999,8 @@ \def\tikz@curveA#1{% \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% {% + \tikz@lastxsaved=\tikz@lastx% + \tikz@lastysaved=\tikz@lasty% \tikz@make@last@position{#1}% \xdef\tikz@curve@first{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% }% @@ -2503,16 +3019,16 @@ \def\tikz@curveCdot.{% \ifx\@next.% \else% - \PackageError{tikz}{Dot expected}{}% + \tikzerror{Dot expected}% \fi% \tikz@updatecurrenttrue% \tikz@curveCcheck% } \def\tikz@curveCcheck{% - \pgfutil@ifnextchar n% - {\tikz@collect@label@onpath\tikz@curveCcheck} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@curveCcheck}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@curveCcheck}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@curveCcheck} - {\tikz@scan@one@point\tikz@curveC}}% + {\tikz@scan@one@point\tikz@curveC}}}% } \def\tikz@curveC#1{% \tikz@make@last@position{#1}% @@ -2552,7 +3068,8 @@ \let\tikz@timer@end=\tikz@curve@third \let\tikz@moveto@waiting=\relax% \fi% - \let\tikz@timer=\tikz@timer@curve% + \let\tikz@timer=\tikz@timer@curve% + \let\tikz@tangent=\tikz@curve@second% \tikz@scan@next@command% } @@ -2564,13 +3081,13 @@ \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% \tikz@@rect}% \def\tikz@@rect{% - \pgfutil@ifnextchar n - {\tikz@collect@label@onpath\tikz@@rect} + \pgfutil@ifnextchar n{\tikz@collect@label@onpath\tikz@@rect}{% + \pgfutil@ifnextchar p{\tikz@collect@pic@onpath\tikz@@rect}% {\pgfutil@ifnextchar c{\tikz@collect@coordinate@onpath\tikz@@rect}% { \pgf@xa=\tikz@lastx\relax% \pgf@ya=\tikz@lasty\relax% - \tikz@scan@one@point\tikz@rectB}}} + \tikz@scan@one@point\tikz@rectB}}}} \def\tikz@rectB#1{% \tikz@make@last@position{#1}% \edef\tikz@timer@end{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% @@ -2585,6 +3102,7 @@ \pgfpathclose% \pgfpathmoveto{\pgfqpoint{\tikz@lastx}{\tikz@lasty}}% \def\pgfstrokehook{}% + \let\tikz@tangent\relax% \tikz@scan@next@command% } @@ -2599,9 +3117,10 @@ \pgfutil@ifnextchar[{\tikz@gridA}{\tikz@gridA[]}}%} \def\tikz@gridA[#1]{% \def\tikz@grid@options{#1}% - \tikz@scan@one@point\tikz@gridB}% + \tikz@cycle@expander{\tikz@scan@one@point\tikz@gridB}}% \def\tikz@gridB#1{% \tikz@make@last@position{#1}% + \let\tikz@tangent\relax% {% \let\tikz@after@path\pgfutil@empty% \expandafter\tikzset\expandafter{\tikz@grid@options} @@ -2636,6 +3155,7 @@ \tikz@flush@moveto% \pgfutil@ifnextchar[{\tikz@@plot}{\tikz@@plot[]}}%} \def\tikz@@plot[#1]{% + \let\tikz@tangent\tikz@tangent@lookup% \begingroup% \let\tikz@after@path\pgfutil@empty% \let\tikz@options=\pgfutil@empty% @@ -2644,7 +3164,7 @@ \pgfutil@ifnextchar f{\tikz@plot@f}% {\pgfutil@ifnextchar c{\tikz@plot@scan@points}% {\pgfutil@ifnextchar ({\tikz@plot@expression}{% - \PackageError{tikz}{Cannot parse this plotting data}{}% + \tikzerror{Cannot parse this plotting data}% \endgroup}}}} \def\tikz@plot@f f{\pgfutil@ifnextchar i{\tikz@plot@file}{\tikz@plot@function}} @@ -2670,11 +3190,16 @@ \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{% set samples \tikz@plot@samples; set parametric; - plot [t=\tikz@plot@domain] #1}}% + plot [t=\tikz@plot@domain] + [\tikz@plot@xrange] + [\tikz@plot@range] + #1}}% \else% \def\tikz@plot@data{\pgfplotgnuplot[\tikz@plot@filename]{% set samples \tikz@plot@samples; - plot [x=\tikz@plot@domain] #1}}% + plot [x=\tikz@plot@domain] + \ifx\tikz@plot@range\pgfutil@empty\else[\tikz@plot@range]\fi + #1}}% \fi% \fi% \tikz@@@plot% @@ -2700,8 +3225,8 @@ \ifx\tikz@plot@mark\pgfutil@empty% \else% % Marks are drawn after the path. - \setbox\tikz@figbox=\hbox{% - \unhbox\tikz@figbox% + \setbox\tikz@whichbox=\hbox{% + \unhbox\tikz@whichbox% \hbox{{% \pgfinterruptpath% \pgfscope% @@ -2720,10 +3245,10 @@ }}% }% \fi% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \global\setbox\tikz@tempbox=\box\tikz@whichbox% \global\let\tikz@after@path@smuggle=\tikz@after@path - \endgroup% - \setbox\tikz@figbox=\box\tikz@tempbox% + \expandafter\endgroup% + \expandafter\setbox\tikz@whichbox=\box\tikz@tempbox% \tikz@make@last@position{\tikz@@@temp}% \expandafter\tikz@scan@next@command\tikz@after@path@smuggle% } @@ -2740,8 +3265,9 @@ % Syntax for cosine curves: % cos -\def\tikz@cosine s{\tikz@scan@one@point\tikz@@cosine} +\def\tikz@cosine s{\tikz@cycle@expander{\tikz@scan@one@point\tikz@@cosine}} \def\tikz@@cosine#1{% + \let\tikz@tangent\tikz@tangent@lookup% \tikz@flush@moveto% \pgf@process{#1}% \pgf@xc=\pgf@x% @@ -2759,8 +3285,9 @@ % Syntax for sine curves: % sin -\def\tikz@sine in{\tikz@scan@one@point\tikz@@sine} +\def\tikz@sine in{\tikz@cycle@expander{\tikz@scan@one@point\tikz@@sine}} \def\tikz@@sine#1{% + \let\tikz@tangent\tikz@tangent@lookup% \tikz@flush@moveto% \pgf@process{#1}% \pgf@xc=\pgf@x% @@ -2779,15 +3306,16 @@ % Syntax for parabolas: % parabola[options] bend \def\tikz@parabola arabola{% + \let\tikz@tangent\tikz@tangent@lookup% \pgfutil@ifnextchar[{\tikz@parabola@options}{\tikz@parabola@options[]}}%} \def\tikz@parabola@options[#1]{% \def\tikz@parabola@option{#1}% - \pgfutil@ifnextchar b{\tikz@parabola@scan@bend}{\tikz@scan@one@point\tikz@parabola@semifinal}} + \pgfutil@ifnextchar b{\tikz@parabola@scan@bend}{\tikz@cycle@expander{\tikz@scan@one@point\tikz@parabola@semifinal}}} \def\tikz@parabola@scan@bend bend{\tikz@scan@one@point\tikz@parabola@scan@bendB} \def\tikz@parabola@scan@bendB#1{% \def\tikz@parabola@bend{#1}% - \tikz@scan@one@point\tikz@parabola@semifinal% + \tikz@cycle@expander{\tikz@scan@one@point\tikz@parabola@semifinal}% } \def\tikz@parabola@semifinal#1{% \tikz@flush@moveto% @@ -2832,6 +3360,7 @@ \def\tikz@circle ircle{\tikz@flush@moveto\tikz@@circle} \def\tikz@ellipse llipse{\tikz@flush@moveto\tikz@@circle} \def\tikz@@circle{% + \let\tikz@tangent\relax% \pgfutil@ifnextchar(\tikz@@@circle {\pgfutil@ifnextchar[\tikz@circle@opt{%]) \advance\tikz@expandcount by -10\relax% go down quickly @@ -2883,13 +3412,13 @@ \pgfpathellipse{\pgfpointorigin}{% \pgfqpoint{\tikz@ellipse@x pt}{0pt}}{\pgfpoint{0pt}{\tikz@ellipse@y pt}}% \else% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an ellipse}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an ellipse}% \fi% \else% \pgfmathparse{#2}% \let\tikz@ellipse@y=\pgfmathresult% \ifpgfmathunitsdeclared% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an ellipse}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an ellipse}% \else% \pgfpathellipse{\pgfpointorigin}{% \pgfpointxy{\tikz@ellipse@x}{0}}{\pgfpointxy{0}{\tikz@ellipse@y}}% @@ -2937,11 +3466,13 @@ \ifx\tikz@e\pgfutil@empty% \pgfmathsetmacro\tikz@e{\tikz@s+\tikz@d} \fi% - \fi + \fi% + \xdef\pgf@marshal{\noexpand% \tikz@do@arc{\tikz@s}{\tikz@e} {\pgfkeysvalueof{/tikz/x radius}} - {\pgfkeysvalueof{/tikz/y radius}} + {\pgfkeysvalueof{/tikz/y radius}}}% }% + \pgf@marshal% \tikz@arcfinal% } @@ -2964,6 +3495,10 @@ \tikz@do@arc{#1}{#2}{#3}{#4}% } \def\tikz@do@arc#1#2#3#4{% + \let\tikz@tangent\tikz@tangent@lookup% + \edef\tikz@timer@start{\noexpand\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \edef\tikz@timer@start@angle{#1}% + \edef\tikz@timer@end@angle{#2}% \pgfmathparse{#3}% \let\tikz@arc@x=\pgfmathresult% \ifpgfmathunitsdeclared% @@ -2973,17 +3508,23 @@ \tikz@@@arcfinal{\pgfpatharc{#1}{#2}{\tikz@arc@x pt and \tikz@arc@y pt}} {\pgfpointpolar{#1}{\tikz@arc@x pt and \tikz@arc@y pt}} {\pgfpointpolar{#2}{\tikz@arc@x pt and \tikz@arc@y pt}}% + \edef\tikz@timer@zero@axis{\noexpand\pgfqpoint{\tikz@arc@x pt}{0pt}} + \edef\tikz@timer@ninety@axis{\noexpand\pgfqpoint{0pt}{\tikz@arc@y pt}} \else% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an arc}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an arc}% \fi% \else% \pgfmathparse{#4}% \let\tikz@arc@y=\pgfmathresult% \ifpgfmathunitsdeclared% - \PackageError{tikz}{You cannot mix dimensions and dimensionless values in an arc}{}% + \tikzerror{You cannot mix dimensions and dimensionless values in an arc}% \else% \tikz@@@arcfinal{\pgfpatharcaxes{#1}{#2}{\pgfpointxy{\tikz@arc@x}{0}}{\pgfpointxy{0}{\tikz@arc@y}}} {\pgfpointpolarxy{#1}{\tikz@arc@x and \tikz@arc@y}}{\pgfpointpolarxy{#2}{\tikz@arc@x and \tikz@arc@y}}% + \pgf@process{\pgfpointxy{\tikz@arc@x}{0}} + \edef\tikz@timer@zero@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} + \pgf@process{\pgfpointxy{0}{\tikz@arc@y}} + \edef\tikz@timer@ninety@axis{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} \fi% \fi% } @@ -3005,6 +3546,7 @@ \advance\tikz@lasty by\pgf@y% \tikz@lastxsaved=\tikz@lastx% \tikz@lastysaved=\tikz@lasty% + \let\tikz@timer=\tikz@timer@arc% \tikz@scan@next@command% } @@ -3037,20 +3579,28 @@ % Syntax for nodes: -% node[options] (node name) {label text} +% node foreach \var in {list} ... [options] (node name) at (pos) {label text} % -% all of [options], (node name) and {label text} are optional. There -% can be multiple options before the label text as in -% node[draw] (a) [rotate=10] {text} +% all of [options], (node name), at(pos), and foreach are +% optional. There can be multiple options and the ordering is not +% important as in node[draw] (a) [rotate=10] {text}, *except* that all +% foreach statements must come first. % % A label text always ``ends'' the node. +% \def\tikz@fig ode{% + \pgfutil@ifnextchar a\tikz@test@also{ + \pgfutil@ifnextchar f{\tikz@nodes@start}\tikz@normal@fig}} +\def\tikz@test@also a{\pgfutil@ifnextchar l\tikz@node@also{\tikz@normal@fig a}}% +\def\tikz@normal@fig{% \edef\tikz@save@line@width{\the\pgflinewidth}% \begingroup% \let\tikz@fig@name=\pgfutil@empty% \begingroup% \tikz@is@matrixfalse% \let\nodepart=\tikz@nodepart% + \let\tikz@atbegin@scope=\pgfutil@empty% + \let\tikz@atend@scope=\pgfutil@empty% \let\tikz@do@after@node=\tikz@scan@next@command% \let\tikz@options=\pgfutil@empty% \let\tikz@after@path=\pgfutil@empty% @@ -3061,9 +3611,12 @@ \let\tikz@postactions=\pgfutil@empty% \let\tikz@alias=\pgfutil@empty% \def\tikz@node@at{\pgfqpoint{\the\tikz@lastx}{\the\tikz@lasty}}% + \let\tikz@time@for@matrix\tikz@time% + \let\tikz@node@content\relax% + \pgfgetpath\tikzpathuptonow% \iftikz@node@is@a@label% \else% - \let\tikz@time=\pgfutil@empty% + \let\tikz@time\pgfutil@empty% \fi% \tikz@node@reset@hook% \tikzset{every node/.try}% @@ -3073,7 +3626,7 @@ {\pgfutil@ifnextchar({\tikz@fig@scan@name} {\pgfutil@ifnextchar[{\tikz@fig@scan@options}% {\pgfutil@ifnextchar\bgroup{\tikz@fig@main}% - {\PackageError{tikz}{A node must have a (possibly empty) label text}{}% + {\tikzerror{A node must have a (possibly empty) label text}% \tikz@fig@main{}}}}}}%}} \def\tikz@fig@scan@at at{% \tikz@scan@one@point\tikz@@fig@scan@at} @@ -3083,17 +3636,26 @@ \pgfkeysvalueof{/tikz/name/.@cmd}#1\pgfeov% CF : this is now ALWAYS consistent with 'name=' option; allows overrides. \tikz@@scan@fig}% % make it \long to allow \par in "pin" options etc: -\long\def\tikz@fig@scan@options[#1]{\tikzset{#1}\tikz@@scan@fig}% +\long\def\tikz@fig@scan@options[#1]{\iftikz@node@is@pic\tikz@enable@pic@quotes\else\tikz@enable@node@quotes\fi\tikzset{#1}\ifx\tikz@node@content\relax\expandafter\tikz@@scan@fig\else\tikz@expand@node@contents\fi}% +\def\tikz@expand@node@contents{% + \expandafter\tikz@@scan@fig\expandafter{\tikz@node@content}% +} \let\tikz@node@reset@hook=\pgfutil@empty% \let\tikz@node@begin@hook=\pgfutil@empty% -\def\tikz@fig@main{\afterassignment\tikz@@fig@main\let\next=} +\def\tikz@fig@main{% + \iftikz@node@is@pic% + \tikz@node@is@picfalse% + \expandafter\tikz@subpicture@handle% + \else% + \afterassignment\tikz@@fig@main\expandafter\let\expandafter\next\expandafter=% + \fi} \def\tikz@@fig@main{% \pgfutil@ifundefined{pgf@sh@s@\tikz@shape}% - {\PackageError{tikz}% - {Unknown shape ``\tikz@shape.'' Using ``rectangle'' instead}{}% + {\tikzerror{Unknown shape ``\tikz@shape.'' Using ``rectangle'' instead}% \def\tikz@shape{rectangle}}% {}% \tikzset{every \tikz@shape\space node/.try}% + \tikz@node@textfont% \tikz@node@begin@hook% \iftikz@is@matrix% \let\tikz@next=\tikz@do@matrix% @@ -3102,7 +3664,12 @@ \fi% \tikz@next% } +\let\tikz@nodepart@list\pgfutil@empty \def\tikz@do@fig{% + % Ok, reset all node part boxes + \pgfutil@for\tikz@temp:=\tikz@nodepart@list\do{% + \expandafter\setbox\csname pgfnodepart\tikz@temp box\endcsname=\box\pgfutil@voidb@x% + }% \setbox\pgfnodeparttextbox=\hbox% \bgroup% \tikzset{every text node part/.try}% @@ -3112,12 +3679,13 @@ \pgfsetstrokeopacity{\tikz@textopacity}% \fi% \pgfinterruptpicture% - \tikz@textfont% \ifx\tikz@text@width\pgfutil@empty% + \tikz@textfont% \else% \begingroup% \pgfmathsetlength{\pgf@x}{\tikz@text@width}% \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@textfont% \tikz@text@action% \fi% \tikz@atbegin@node% @@ -3129,15 +3697,23 @@ \fi% \pgfsetcolor{.}% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \tikz@uninstallcommands% + \iftikz@handle@active@code% + \tikz@orig@shorthands% + \let\tikz@orig@shorthands\pgfutil@empty% + \fi% + \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi% + \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi% + \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi% \aftergroup\tikz@fig@collectresetcolor% \tikz@halign@check% \ignorespaces% } \def\tikz@fig@collectresetcolor{% - \pgfutil@ifnextchar\reset@color% - {\reset@color\afterassignment\tikz@fig@collectresetcolor\let\tikz@temp=}% - {\tikz@fig@boxdone}% + % Hacks for special packages that mess with \aftergroup + \pgfutil@ifnextchar\reset@color% hack for color package + {\reset@color\afterassignment\tikz@fig@collectresetcolor\let\tikz@temp=}\tikz@fig@boxdone% } \def\tikz@fig@boxdone{% \tikz@atend@node% @@ -3158,14 +3734,15 @@ \tikzset{every matrix/.try}% \tikz@node@transformations% \tikz@fig@mustbenamed% - \setbox\tikz@figbox=\hbox\bgroup% - \setbox\pgfutil@tempboxa=\copy\tikz@figbox% - \unhbox\pgfutil@tempboxa% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% \hbox\bgroup\bgroup% \pgfinterruptpath% \pgfscope% + \ifx\tikz@time\pgfutil@empty\let\tikz@time\tikz@time@for@matrix\fi% \tikz@options% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \let\tikzmatrixname=\tikz@fig@name% \edef\tikz@m@anchor{\ifx\tikz@matrix@anchor\pgfutil@empty\tikz@anchor\else\tikz@matrix@anchor\fi}% \expandafter\pgfutil@in@\expandafter{\expandafter.\expandafter}\expandafter{\tikz@m@anchor}% @@ -3221,10 +3798,12 @@ \tikz@at@emptycell% \pgfsys@endscope% }% + \tikz@atbegin@matrix% \aftergroup\tikz@do@matrix@cont}% \bgroup% } -\def\tikz@do@matrix@cont{% +\def\tikz@do@matrix@cont{% + \tikz@atend@matrix% \endpgfscope \endpgfinterruptpath% \egroup\egroup% @@ -3270,16 +3849,17 @@ % % Node transformation % - \tikz@node@transformations - % - \setbox\tikz@figbox=\hbox{% - \setbox\pgfutil@tempboxa=\copy\tikz@figbox% - \unhbox\pgfutil@tempboxa% + \tikz@node@transformations% + \tikz@nlt% + % + \setbox\tikz@whichbox=\hbox{% + \unhbox\tikz@whichbox% \hbox{{% \pgfinterruptpath% \pgfscope% \tikz@options% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{% \pgfutil@tempdima=\pgflinewidth% {\begingroup\tikz@finish}% @@ -3303,7 +3883,7 @@ \fi% } -\def\tikz@node@transformations{ +\def\tikz@node@transformations{% % % Possibly, we are ``online'' % @@ -3325,22 +3905,35 @@ \global\let\tikz@last@fig@name=\tikz@fig@name% \global\let\tikz@after@path@smuggle=\tikz@after@path% % shift box outside group - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \endgroup\endgroup% \setbox\tikz@figbox=\box\tikz@tempbox% - \pgflinewidth=\tikz@save@line@width% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \global\pgflinewidth=\tikz@save@line@width% + \tikz@do@after@path@smuggle% + \tikz@do@after@node% +} +\let\tikz@fig@continue@orig=\tikz@fig@continue + +\def\tikz@do@after@node{\tikz@scan@next@command} + +\def\tikz@do@after@path@smuggle{% \let\tikz@to@last@fig@name=\tikz@last@fig@name% \let\tikz@to@use@whom=\tikz@to@use@last@fig@name% \let\tikzlastnode=\tikz@last@fig@name% \ifx\tikz@after@path@smuggle\pgfutil@empty% \else% - \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop% + \ifpgflatenodepositioning% + \expandafter\expandafter\expandafter\tikz@call@late% + \expandafter\expandafter\expandafter{\expandafter\tikz@last@fig@name\expandafter}\expandafter{\tikz@after@path@smuggle}% + \else% + \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop% + \fi% \fi% - \tikz@do@after@node% } -\let\tikz@fig@continue@orig=\tikz@fig@continue -\def\tikz@do@after@node{\tikz@scan@next@command} +\def\tikz@call@late#1#2{\pgfnodepostsetupcode{#1}{\path[late options={name={#1},append after command={#2}}];}} \newif\iftikz@do@align @@ -3361,7 +3954,8 @@ \expandafter\tikz@start@align% \fi% } -\def\tikz@align@newline{\unskip\pgfutil@ifnextchar[\tikz@@align@newline{\tikz@@align@newline[0pt]}}%} +\def\tikz@align@newline{\pgfutil@protect\tikz@align@newline@} +\def\tikz@align@newline@{\unskip\pgfutil@ifnextchar[\tikz@@align@newline{\tikz@@align@newline[0pt]}}%} \def\tikz@@align@newline[#1]{\egroup\tikz@align@continue\pgfmathparse{#1}\let\tikz@align@temp=\pgfmathresult\tikz@start@align}% % Two safe boxes for alignment: \let\tikz@align@aligned@box=\pgfnodeparttextbox @@ -3399,6 +3993,16 @@ \let\tikz@@align@continue=\pgfutil@empty +\def\tikz@node@also lso{\pgfutil@ifnextchar[\tikz@node@also@opt{\tikz@node@also@opt[]}} +\def\tikz@node@also@opt[#1]{ + \pgfutil@ifnextchar(%) + {\tikz@node@also@opt@cont[#1]}% + {\tikzerror{Syntax error in node also: ``('' expected.}% + \tikz@scan@next@command}% +} +\def\tikz@node@also@opt@cont[#1](#2){\tikzset{late options={name=#2,#1}}\tikz@scan@next@command} + + % Syntax for parts of nodes: % node ... {... \nodepart[options]{name} ... \nodepart{name} ...} @@ -3414,18 +4018,29 @@ } \def\tikz@nodepart@continue{% \global\let\tikz@fig@continue=\tikz@fig@continue@orig% + \ifx\tikz@nodepart@list\pgfutil@empty% + \let\tikz@nodepart@list\tikz@nodepart@name% + \else% + \edef\tikz@nodepart@list{\tikz@nodepart@list,\tikz@nodepart@name}% + \fi% % Now start new box: \expandafter\setbox\csname pgfnodepart\tikz@nodepart@name box\endcsname=\hbox% \bgroup% \tikzset{every \tikz@nodepart@name\space node part/.try}% \expandafter\tikzset\expandafter{\tikz@nodepart@options}% + \ifx\tikz@textopacity\pgfutil@empty% + \else% + \pgfsetfillopacity{\tikz@textopacity}% + \pgfsetstrokeopacity{\tikz@textopacity}% + \fi% \pgfinterruptpicture% - \tikz@textfont% \ifx\tikz@text@width\pgfutil@empty% + \tikz@textfont% \else% \begingroup% - \pgfmathsetlength{\pgf@x}{\tikz@text@width}% + \pgfmathsetlength{\pgf@x}{\tikz@text@width}% \pgfutil@minipage[t]{\pgf@x}\leavevmode\hbox{}% + \tikz@textfont% \tikz@text@action% \fi% \bgroup% @@ -3436,13 +4051,92 @@ \fi% \pgfsetcolor{.}% \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% \tikz@uninstallcommands% + \iftikz@handle@active@code% + \tikz@orig@shorthands% + \let\tikz@orig@shorthands\pgfutil@empty% + \fi% + \ifnum\the\catcode`\;=\active\relax\expandafter\let\tikz@activesemicolon=\tikz@origsemi\fi% + \ifnum\the\catcode`\:=\active\relax\expandafter\let\tikz@activecolon=\tikz@origcolon\fi% + \ifnum\the\catcode`\|=\active\relax\expandafter\let\tikz@activebar=\tikz@origbar\fi% \tikz@atbegin@node% \aftergroup\tikz@fig@collectresetcolor% \tikz@halign@check% \ignorespaces% } + +% +% Node foreach +% + +\def\tikz@nodes@start{% + \let\tikz@nodes@list\pgfutil@empty% + \iftikz@node@is@pic% + \def\tikz@nodes@collect{pic }% + \else% + \def\tikz@nodes@collect{node }% + \fi% + \tikz@nodes% +} +\def\tikz@nodes foreach{\pgfutil@ifnextchar x\tikz@nodes@\tikz@nodes@}% get rid of spaces +\def\tikz@nodes@#1in{% + \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list\foreach#1in}% + \pgfutil@ifnextchar\bgroup\tikz@nodes@group\tikz@nodes@one% +} +\def\tikz@nodes@one#1{% + \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list#1}% + \pgfutil@ifnextchar f\tikz@nodes\tikz@nodes@scan% +} +\def\tikz@nodes@group#1{% + \expandafter\def\expandafter\tikz@nodes@list\expandafter{\tikz@nodes@list{#1}}% + \pgfutil@ifnextchar f\tikz@nodes\tikz@nodes@scan% +} +\def\tikz@nodes@scan{% + \pgfutil@ifnextchar a{\tikz@nodes@at}% + {\pgfutil@ifnextchar({\tikz@nodes@name}% + {\pgfutil@ifnextchar[{\tikz@nodes@opt}% + {\pgfutil@ifnextchar\bgroup{\tikz@nodes@main}% + {\tikzerror{Nodes must have a (possibly empty) label text}% + \tikz@fig@main{}}}}}}%}} +\def\tikz@nodes@at at#1){% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect at#1)}% + \tikz@nodes@scan}% +\def\tikz@nodes@name#1){% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect#1)}% + \tikz@nodes@scan}% +\def\tikz@nodes@opt#1]{% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect#1]}% + \tikz@nodes@scan}% +\def\tikz@nodes@main#1{% + \iftikz@handle@active@nodes% + \iftikz@node@is@pic% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{#1}}% + \else% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{\scantokens{#1}}}% + \fi% + \else% + \expandafter\def\expandafter\tikz@nodes@collect\expandafter{\tikz@nodes@collect{#1}}% + \fi% + % Ok, got everything. + % Now, start building parse text. + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + \tikz@nodes@list{% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \expandafter\tikz@scan@next@command\tikz@nodes@collect\pgfextra\relax% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% + }% + \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% + \tikz@scan@next@command% +} + + + % % "late" options can be used to "redo" a node % @@ -3463,23 +4157,18 @@ \let\tikz@transform=\pgfutil@empty% \tikz@decoratepathfalse% \tikz@node@reset@hook% - \tikzset{every node/.try,#1}% + \tikz@enable@node@quotes% + \tikzset{every node/.try,#1}% \ifx\tikz@fig@name\pgfutil@empty% - \PackageError{tikz}{Late options must reference some existing - node}{}% + \tikzerror{Late options must reference some existing node}% \fi% \tikz@node@begin@hook% \tikz@alias% + \tikzgdlatenodeoptionacallback{\tikz@fig@name}% \global\let\tikz@last@fig@name=\tikz@fig@name% \global\let\tikz@after@path@smuggle=\tikz@after@path% \endgroup% - \let\tikz@to@last@fig@name=\tikz@last@fig@name% - \let\tikz@to@use@whom=\tikz@to@use@last@fig@name% - \let\tikzlastnode=\tikz@last@fig@name% - \ifx\tikz@after@path@smuggle\pgfutil@empty% - \else% - \tikz@scan@next@command{\tikz@after@path@smuggle}\pgf@stop% - \fi% + \tikz@do@after@path@smuggle% } @@ -3555,7 +4244,13 @@ } - +% +% Callbacks: Please see the documentation of the graph drawing +% lib for info on these callbacks +% +\def\tikzgdeventcallback#1#2{} +\def\tikzgdeventgroupcallback#1{} +\def\tikzgdlatenodeoptionacallback#1{} % Syntax for trees: % node {...} child [options] {...} child [options] {...} ... @@ -3595,39 +4290,48 @@ \long\def\tikz@children@collected{% \begingroup% \advance\tikztreelevel by 1\relax% + \tikzgdeventgroupcallback{descendants}% \let\tikz@options=\pgfutil@empty% \let\tikz@transform=\pgfutil@empty% \tikzset{level/.try=\the\tikztreelevel,level \the\tikztreelevel/.try}% \tikz@transform% + \let\tikz@transform=\relax% \let\tikzparentnode=\tikz@last@fig@name% - % Transform to center of node - \pgftransformshift{\pgfpointanchor{\tikzparentnode}{\tikz@growth@anchor}}% + \ifx\tikz@grow\relax\else% + % Transform to center of node + \pgftransformshift{\pgfpointanchor{\tikzparentnode}{\tikz@growth@anchor}}% + \fi% \tikznumberofcurrentchild=0\relax% \tikz@children@list% - \global\setbox\tikz@tempbox=\copy\tikz@figbox% + \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \endgroup% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% \tikz@scan@next@command% } - % Syntax for children: % % child [all children options] foreach \var in {values} [child options] {...} \def\tikz@childrennodes[#1]#2#3#4{% \c@pgf@counta=\tikznumberofcurrentchild\relax% \setbox\tikz@tempbox=\box\tikz@figbox% + \setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% \foreach#2in{#3}{% \tikznumberofcurrentchild=\c@pgf@counta\relax% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% \tikz@childnode[#1]{#4}% % we must now make the current child number and the figbox survive % the group \global\c@pgf@counta=\tikznumberofcurrentchild\relax% \global\setbox\tikz@tempbox=\box\tikz@figbox% + \global\setbox\tikz@tempbox@bg=\box\tikz@figbox@bg% }% \tikznumberofcurrentchild=\c@pgf@counta\relax% \setbox\tikz@figbox=\box\tikz@tempbox% + \setbox\tikz@figbox@bg=\box\tikz@tempbox@bg% } @@ -3644,9 +4348,10 @@ \advance\tikznumberofcurrentchild by1\relax% {\tikzset{every child/.try,#1}\expandafter}% \iftikz@child@missing% + \tikzgdeventcallback{node}{}% \else% - \setbox\tikz@figbox=\hbox\bgroup% - \unhbox\tikz@figbox% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% \hbox\bgroup\bgroup% \pgfinterruptpath% \pgfscope% @@ -3654,6 +4359,7 @@ \tikzset{every child/.try,#1}% \tikz@options% \tikz@transform% + \let\tikz@transform=\relax% \tikz@grow% % Typeset node: \edef\tikz@parent@node@name{[name=\tikzparentnode-\the\tikznumberofcurrentchild,style=every child node]}% @@ -3669,7 +4375,7 @@ \ifx\tikz@child@node@rest\pgfutil@empty% \path edge from parent;% \else% - \path (0,0) \tikz@child@node@rest \tikz@edge@to@parent@needed;% + \path \tikz@child@node@rest \tikz@edge@to@parent@needed;% \fi% }% \endpgfscope% @@ -3682,9 +4388,17 @@ \def\tikz@parse@child@node{% \pgfutil@ifnextchar n{\tikz@parse@child@node@n}% {\pgfutil@ifnextchar c{\tikz@parse@child@node@c}% - {\tikz@parse@child@node@rest}}} -\def\tikz@parse@child@node@rest#1\pgf@stop{\def\tikz@child@node@rest{#1}} -\def\tikz@parse@child@node@c c{\pgfutil@ifnextchar o{\tikz@parse@child@node@co}{\tikz@parse@child@node@rest c}} + {\pgfutil@ifnextchar\pgf@stop\tikz@parse@child@node@rest\tikz@parse@child@node@expand}}} +\def\tikz@parse@child@node@expand{% + \advance\tikz@expandcount by-1\relax% + \ifnum\tikz@expandcount<0\relax% + \expandafter\tikz@parse@child@node@rest% + \else% + \expandafter\expandafter\expandafter\tikz@parse@child@node% + \fi% +} +\def\tikz@parse@child@node@rest#1\pgf@stop{\tikz@expandcount=100\relax\def\tikz@child@node@rest{#1}} +\def\tikz@parse@child@node@c c{\tikz@expandcount=100\pgfutil@ifnextchar o{\tikz@parse@child@node@co}{\tikz@parse@child@node@rest c}} \def\tikz@parse@child@node@co o{\pgfutil@ifnextchar o{\tikz@parse@child@node@coordinate}{\tikz@parse@child@node@rest co}} \def\tikz@parse@child@node@coordinate ordinate{% \pgfutil@ifnextchar ({\tikz@@parse@child@node@coordinate}{% @@ -3706,7 +4420,7 @@ \expandafter\expandafter\expandafter{\expandafter\tikz@child@node@text@pre\tikz@marshal}% \tikz@parse@child@node@rest% } -\def\tikz@parse@child@node@n node{% +\def\tikz@parse@child@node@n node{\tikz@expandcount=100% \let\tikz@child@node@text=\pgfutil@empty% \tikz@p@c@s}% \def\tikz@p@c@s{% @@ -3714,7 +4428,7 @@ {\pgfutil@ifnextchar ({\tikz@p@c@s@paran} {\pgfutil@ifnextchar [{\tikz@p@c@s@bra} {\pgfutil@ifnextchar \bgroup{\tikz@p@c@s@group} - {\PackageError{tikz}{Cannot parse this node}{}}}}}}%}} + {\tikzerror{Cannot parse this node}}}}}}%}} \def\tikz@p@c@s@at at#1({% \tikz@scan@one@point\tikz@p@c@s@at@math(% } @@ -3732,8 +4446,13 @@ \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text[#1]} \tikz@p@c@s} \def\tikz@p@c@s@group#1{% - \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{#1}} - \tikz@parse@child@node@rest} + \iftikz@handle@active@nodes% + \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{\scantokens{#1}}}% + \else% + \expandafter\def\expandafter\tikz@child@node@text\expandafter{\tikz@child@node@text{#1}} + \fi% + \tikz@parse@child@node@rest% +} @@ -3746,10 +4465,10 @@ \pgfutil@ifnextchar[{\tikz@lib@decoration}{\tikz@lib@decoration[]}%] } -\def\tikz@lib@decoration[#1]#2{\PackageError{tikz}{You need to load a decoration library}{}} +\def\tikz@lib@decoration[#1]#2{\tikzerror{You need to load a decoration library}} % The decorate path command: -\def\tikz@lib@dec@decorate@path{\PackageError{tikz}{You need to load a decoration library}{}} +\def\tikz@lib@dec@decorate@path{\tikzerror{You need to load a decoration library}} @@ -3759,10 +4478,121 @@ % let \p1 = (coordinate), \p2 = (coordinate),... in % \def\tikz@let@command et#1in{% - \PackageError{tikz}{You need to say \string\usetikzlibrary{calc} to use the let command}{}% + \tikzerror{You need to say \string\usetikzlibrary{calc} to use the let command}% } +% +% Syntax for pictures: +% +% as for nodes, but with "pic" instead of "node" +% +\newif\iftikz@node@is@pic +\def\tikz@subpicture ic{\tikz@node@is@pictrue\tikz@scan@next@command node} +\def\tikz@subpicture@handle#1{% + \pgfkeys@spdef\tikz@temp{#1}% + \expandafter\tikz@subpicture@handle@\expandafter{\tikz@temp}% +} +\def\tikz@subpicture@handle@#1{ + \pgfkeys{/tikz/pics/.cd,#1} + \tikz@node@transformations% + \let\tikz@transform=\relax% + \let\tikz@picmode\tikz@mode% + \tikzset{name prefix ../.style/.expanded={/tikz/name prefix=\pgfkeysvalueof{/tikz/name prefix}}}% + \ifx\tikz@fig@name\pgfutil@empty\else% + \tikzset{name prefix/.prefix/.expanded=\tikz@fig@name}% + \fi% + \pgfkeysvalueof{/tikz/pics/setup code}% + \pgfkeysgetvalue{/tikz/pics/code}{\tikz@pic@code} + \ifx\tikz@pic@code\pgfutil@empty\else% + \setbox\tikz@whichbox=\hbox\bgroup% + \unhbox\tikz@whichbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \tikz@options% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% + \tikz@atbegin@scope% + \scope[every pic/.try]% + \tikz@pic@code% + \endscope% + \tikz@atend@scope% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% + \fi% + \pgfkeysgetvalue{/tikz/pics/foreground code}{\tikz@pic@code} + \ifx\tikz@pic@code\pgfutil@empty\else% + \setbox\tikz@figbox=\hbox\bgroup% + \unhbox\tikz@figbox% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \tikz@options% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% + \tikz@atbegin@scope% + \scope[every front pic/.try]% + \tikz@pic@code% + \endscope% + \tikz@atend@scope% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% + \fi% + \pgfkeysgetvalue{/tikz/pics/background code}{\tikz@pic@code} + \ifx\tikz@pic@code\pgfutil@empty\else% + \setbox\tikz@figbox@bg=\hbox\bgroup% + \unhbox\tikz@figbox@bg% + \hbox\bgroup + \bgroup% + \pgfinterruptpath% + \pgfscope% + \tikz@options% + \setbox\tikz@figbox=\box\pgfutil@voidb@x% + \setbox\tikz@figbox@bg=\box\pgfutil@voidb@x% + \tikz@atbegin@scope% + \scope[every behind pic/.try]% + \tikz@pic@code% + \endscope% + \tikz@atend@scope% + \endpgfscope% + \endpgfinterruptpath% + \egroup + \egroup% + \egroup% + \fi% + \tikz@node@finish% +} +\tikzset{ + pic actions/.code=\tikz@addmode{\tikz@picmode} +} + +% Setting up the picture codes: +\tikzset{ + pics/setup code/.initial=, + pics/code/.initial=, + pics/background code/.initial=, + pics/foreground code/.initial= +} + +% Defining pictures: + +\def\tikzdeclarepic#1#2{\pgfkeys{/tikz/#1/.cd,#2}} + +\pgfkeysdef{/handlers/.pic}{% + \edef\pgf@temp{\pgfkeyscurrentpath}% + \edef\pgf@temp{\expandafter\tikz@smuggle@pics@in\pgf@temp\pgf@stop}% + \expandafter\pgfkeys\expandafter{\pgf@temp/.style={code={#1}}} +} +\def\tikz@smuggle@pics@in/tikz/#1\pgf@stop{/tikz/pics/#1} % % Timers @@ -3827,6 +4657,27 @@ } +\def\tikz@timer@arc{% + \pgfmathcos@{\tikz@timer@start@angle}% + \let\tikz@angle@cos\pgfmathresult% + \pgfmathsin@{\tikz@timer@start@angle}% + \let\tikz@angle@sin\pgfmathresult% + \pgftransformarcaxesattime{\tikz@time}{% + \pgfpointdiff{% + \pgfpointadd{% + \pgfpointscale{\tikz@angle@cos}{\tikz@timer@zero@axis}% + }{% + \pgfpointscale{\tikz@angle@sin}{\tikz@timer@ninety@axis}% + }% + }% + {\tikz@timer@start}% + }% + {\tikz@timer@zero@axis}% + {\tikz@timer@ninety@axis}% + {\tikz@timer@start@angle}{\tikz@timer@end@angle}% +} + + % % Coordinate systems @@ -3885,14 +4736,14 @@ \expandafter\ifx\csname pgf@sh@ns@\tikz@cs@node\endcsname\tikz@coordinate@text% \else \aftergroup\tikz@shapebordertrue% - \edef\tikz@shapeborder@name{\tikz@cs@node}% + \edef\tikz@shapeborder@name{\tikz@pp@name{\tikz@cs@node}}% \fi% - \pgfpointanchor{\tikz@cs@node}{center}% + \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{center}% \else% - \pgfpointanchor{\tikz@cs@node}{\tikz@cs@angle}% + \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{\tikz@cs@angle}% \fi% \else% - \pgfpointanchor{\tikz@cs@node}{\tikz@cs@anchor}% + \pgfpointanchor{\tikz@pp@name{\tikz@cs@node}}{\tikz@cs@anchor}% \fi% } @@ -3905,7 +4756,7 @@ \def\tikz@cs@unpack#1#2#3{% \expandafter\ifx\csname pgf@sh@ns@#3\endcsname\relax% - \PackageError{tikz}{Undefined node ``#3''}{}% + \tikzerror{Undefined node ``#3''}% \else% \def#1{#3}% \edef#2{\csname pgf@sh@ns@#3\endcsname}% @@ -3921,9 +4772,9 @@ {% \tikzset{cs/.cd,#1}% \expandafter\ifx\csname tikz@intersect@\tikz@cs@type@a @and@\tikz@cs@type@b\endcsname\relax% - \PackageError{tikz}{I do not know how to compute the intersection + \tikzerror{I do not know how to compute the intersection of a \tikz@cs@type@a and a \tikz@cs@type@b. Try saying - \string\usetikzlibrary{calc}}{}% + \string\usetikzlibrary{calc}}% \pgfpointorigin% \else% \csname tikz@intersect@\tikz@cs@type@a @and@\tikz@cs@type@b\endcsname% @@ -4047,7 +4898,7 @@ }% } \def\tikz@@scanexpand#1{\expandafter\tikz@scan@one@point\expandafter#1} -\def\tikz@@scangiveup#1{\PackageError{tikz}{Cannot parse this coordinate}{}#1{\pgfpointorigin}} +\def\tikz@@scangiveup#1{\tikzerror{Cannot parse this coordinate}#1{\pgfpointorigin}} \def\tikz@scan@@absolute#1({% \pgfutil@ifnextchar[% uhoh... options! {\def\tikz@scan@point@recall{#1}\tikz@scan@options}% @@ -4073,7 +4924,19 @@ \tikz@marshal% } +\def\tikz@ensure@dollar@catcode{% + \ifnum\catcode`\$=3 % + \else + \tikzerror{Sorry, some package has redefined the meaning of the + math-mode dollar sign. This is incompatible with tikz and its calc + library and might cause unrecoverable errors}% + % only show error once: + \global\let\tikz@ensure@dollar@catcode=\relax + \fi +}% + \def\tikz@@@scan@@absolute#1({% + \tikz@ensure@dollar@catcode \pgfutil@ifnextchar{$}%$ {\tikz@parse@calculator#1(} {\tikz@scan@no@calculator#1(}% @@ -4118,15 +4981,14 @@ } \def\tikz@parse@calculator#1($#2$){% - \PackageError{tikz}{You need to say \string\usetikzlibrary{calc} for - coordinate calculation}{}% + \tikzerror{You need to say \string\usetikzlibrary{calc} for coordinate calculation}% #1{\pgfpointorigin}% } \def\tikz@parse@coordinatesystem#1(#2 cs:#3){% \let\tikz@return@coordinate=\pgfpointorigin% \pgfutil@ifundefined{tikz@parse@cs@#2} - {\PackageError{tikz}{Unknown coordinate system '#2'}{}} + {\tikzerror{Unknown coordinate system '#2'}} {\csname tikz@parse@cs@#2\endcsname(#3)}% \expandafter#1\expandafter{\tikz@return@coordinate}% } @@ -4140,15 +5002,15 @@ \def\tikz@parse@polar#1(#2:#3){% \pgfutil@ifundefined{tikz@polar@dir@#2} - {\tikz@@parse@polar#1(#2:#3)} - {\tikz@@parse@polar#1(\csname tikz@polar@dir@#2\endcsname:#3)}% + {\tikz@@parse@polar#1({#2}:{#3})} + {\tikz@@parse@polar#1(\csname tikz@polar@dir@#2\endcsname:{#3})}% } \def\tikz@@parse@polar#1(#2:#3){% \pgfutil@in@{ and }{#3}% \ifpgfutil@in@% - \edef\tikz@args{(#2:#3)}% + \edef\tikz@args{({#2}:#3)}% \else% - \edef\tikz@args{(#2:#3 and #3)}% + \edef\tikz@args{({#2}:{#3} and {#3})}% \fi% \expandafter\tikz@@@parse@polar\expandafter#1\tikz@args% } @@ -4159,13 +5021,13 @@ \iftikz@isdimension% \def\tikz@next{#1{\pgfpointpolar{#2}{#3 and #4}}}% \else% - \PackageError{tikz}{You cannot mix dimension and dimensionless values for polar coordinates}{} + \tikzerror{You cannot mix dimension and dimensionless values for polar coordinates} \def\tikz@next{#1{\pgfpointorigin}}% \fi% \else% \tikz@checkunit{#4}% \iftikz@isdimension% - \PackageError{tikz}{You cannot mix dimension and dimensionless values for polar coordinates}{} + \tikzerror{You cannot mix dimension and dimensionless values for polar coordinates} \def\tikz@next{#1{\pgfpointorigin}}% \else% \def\tikz@next{#1{\pgfpointpolarxy{#2}{#3 and #4}}}% @@ -4246,7 +5108,7 @@ \expandafter\ifx\csname pgf@sh@ns@#2\endcsname\tikz@coordinate@text% \else \tikz@shapebordertrue% - \def\tikz@shapeborder@name{#2}% + \def\tikz@shapeborder@name{\tikz@pp@name{#2}}% \fi% \fi% \edef\tikz@marshal{\noexpand#1{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}}% @@ -4254,7 +5116,7 @@ } \def\tikz@calc@anchor#1.#2\tikz@stop{% - \pgfpointanchor{#1}{#2}% + \pgfpointanchor{\tikz@pp@name{#1}}{#2}% } @@ -4276,10 +5138,10 @@ \fi% \fi% \tikz@next#1(#2)} -\def\tikz@parse@hvboth#1(#2 -| #3){\tikz@parse@vhdone#1(#3|-#2)} -\def\tikz@parse@hvleft#1(#2 -|#3){\tikz@parse@vhdone#1(#3|-#2)} -\def\tikz@parse@hvright#1(#2-| #3){\tikz@parse@vhdone#1(#3|-#2)} -\def\tikz@parse@hvdone#1(#2-|#3){\tikz@parse@vhdone#1(#3|-#2)} +\def\tikz@parse@hvboth#1(#2 -| #3){\tikz@parse@vhdone#1({#3}|-{#2})} +\def\tikz@parse@hvleft#1(#2 -|#3){\tikz@parse@vhdone#1({#3}|-{#2})} +\def\tikz@parse@hvright#1(#2-| #3){\tikz@parse@vhdone#1({#3}|-{#2})} +\def\tikz@parse@hvdone#1(#2-|#3){\tikz@parse@vhdone#1({#3}|-{#2})} \def\tikz@parse@vh#1(#2){% \pgfutil@in@{ |- }{#2}% @@ -4299,9 +5161,9 @@ \fi% \fi% \tikz@next#1(#2)} -\def\tikz@parse@vhboth#1(#2 |- #3){\tikz@parse@vhdone#1(#2|-#3)} -\def\tikz@parse@vhleft#1(#2 |-#3){\tikz@parse@vhdone#1(#2|-#3)} -\def\tikz@parse@vhright#1(#2|- #3){\tikz@parse@vhdone#1(#2|-#3)} +\def\tikz@parse@vhboth#1(#2 |- #3){\tikz@parse@vhdone#1({#2}|-{#3})} +\def\tikz@parse@vhleft#1(#2 |-#3){\tikz@parse@vhdone#1({#2}|-{#3})} +\def\tikz@parse@vhright#1(#2|- #3){\tikz@parse@vhdone#1({#2}|-{#3})} \def\tikz@parse@vhdone#1(#2|-#3){% {% \tikz@@@scan@@absolute\tikz@parse@vh@mid(#2)% @@ -4363,6 +5225,17 @@ } + +% +% Quote handling +% + +\let\tikz@enable@node@quotes\relax +\let\tikz@enable@edge@quotes\relax +\let\tikz@enable@pic@quotes\relax + + + % Loading further libraries % Include a library file. @@ -4377,6 +5250,10 @@ % % For the convenience of Context users, both round and square brackets % are possible for the argument. +% +% If no file tikzlibraryX.code.tex exists, the file +% pgflibraryX.code.tex is tried instead. If this file, also, does not +% exist, an error message is printed. % % Example: % @@ -4388,20 +5265,32 @@ \def\use@@tikzlibrary#1{% \edef\pgf@list{#1}% \pgfutil@for\pgf@temp:=\pgf@list\do{% - \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% - \ifx\pgf@temp\pgfutil@empty - \else - \expandafter\ifx\csname tikz@library@\pgf@temp @loaded\endcsname\relax% - \expandafter\global\expandafter\let\csname tikz@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% - \expandafter\edef\csname tikz@library@#1@atcode\endcsname{\the\catcode`\@} - \expandafter\edef\csname tikz@library@#1@barcode\endcsname{\the\catcode`\|} - \catcode`\@=11 - \catcode`\|=12 - \input tikzlibrary\pgf@temp.code.tex - \catcode`\@=\csname tikz@library@#1@atcode\endcsname - \catcode`\|=\csname tikz@library@#1@barcode\endcsname - \fi% - \fi + \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% + \ifx\pgf@temp\pgfutil@empty + \else + \expandafter\ifx\csname tikz@library@\pgf@temp @loaded\endcsname\relax% + \expandafter\global\expandafter\let\csname tikz@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% + \expandafter\edef\csname tikz@library@#1@atcode\endcsname{\the\catcode`\@} + \expandafter\edef\csname tikz@library@#1@barcode\endcsname{\the\catcode`\|} + \expandafter\edef\csname tikz@library@#1@dollarcode\endcsname{\the\catcode`\$} + \catcode`\@=11 + \catcode`\|=12 + \catcode`\$=3 + \pgfutil@InputIfFileExists{tikzlibrary\pgf@temp.code.tex}{}{ + \pgfutil@IfFileExists{pgflibrary\pgf@temp.code.tex}{% + \expandafter\usepgflibrary\expandafter{\pgf@temp}% + }{% + \tikzerror{I did not find the tikz library + '\pgf@temp'. I looked for files named + tikzlibrary\pgf@temp.code.tex and + pgflibrary\pgf@temp.code.tex, but neither + could be found in the current texmf trees.} + }}% + \catcode`\@=\csname tikz@library@#1@atcode\endcsname + \catcode`\|=\csname tikz@library@#1@barcode\endcsname + \catcode`\$=\csname tikz@library@#1@dollarcode\endcsname + \fi% + \fi }% } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE new file mode 100644 index 00000000000..295a8b2ed11 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/LUA_CODING_STYLE @@ -0,0 +1,27 @@ +Lua coding style for the graphdrawing library +============================================= + +General naming rules and indentation: + + * 2 spaces indentation + * variable_names_with_underscores + * namespaced.low_level_functions_with_underscores(foo, bar) + * CamelCaseClassNames + * CamelCaseClassNames.nameOfStaticFunctionLikeNewOrClone(foo, bar) + * CamelCaseClass:functionNamesLikeThis(foo, bar) + * never use global variables + * Use . for static functions and : for member functions + +LuaDoc comments: + + --- + -- A function to do this and that. + -- + -- @param first Description of the first parameter. + -- @param second Description of the second parameter. + -- + -- @return This function returns something. + -- + function myClass:myFunction(first, second) + ... + end diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua new file mode 100644 index 00000000000..0ffbaf53c13 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf.lua @@ -0,0 +1,72 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf.lua,v 1.3 2013/04/04 20:43:44 tantau Exp $ + + +--- +-- The |pgf| namespace lies in the global namespace. It is the only +-- global table defined by \pgfname. The whole graph drawing system, +-- in turn, lies in the table |pgf.gd|. + +pgf = {} + + + +-- Forward +local tostring_table + +--- +-- Writes debug info on the \TeX\ output, separating the parameters +-- by spaces. The debug information will include a complete traceback +-- of the stack, allowing you to see ``where you are'' inside the Lua +-- program. +-- +-- Note that this function resides directly in the |pgf| table. The +-- reason for this is that you can ``always use it'' since |pgf| is +-- always available in the global name space. +-- +-- @param ... List of parameters to write to the \TeX\ output. + +function pgf.debug(...) + local stacktrace = debug.traceback("",2) + texio.write_nl(" ") + texio.write_nl("Debug called for: ") + -- this is to even print out nil arguments in between + local args = {...} + for i = 1, #args do + if i ~= 1 then texio.write(", ") end + texio.write(tostring_table(args[i], "", 5)) + end + texio.write_nl('') + for w in string.gmatch(stacktrace, "/.-:.-:.-%c") do + texio.write('by ', string.match(w,".*/(.*)")) + end +end + + +-- Helper function + +function tostring_table(t, prefix, depth) + if type(t) ~= "table" or (getmetatable(t) and getmetatable(t).__tostring) or depth <= 0 then + return type(t) == "string" and ('"' .. t .. '"') or tostring(t) + else + local r = "{\n" + for k,v in pairs(t) do + r = r .. prefix .. " " .. tostring(k) .. "=" .. + (v==t and "self" or tostring_table(v, prefix .. " ", depth-1)) .. ",\n" + end + return r .. prefix .. "}" + end +end + + + + +return pgf \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua new file mode 100644 index 00000000000..b813ccab603 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd.lua @@ -0,0 +1,72 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + + +-- Declare the gd namespace + +local gd = {} +require("pgf").gd = gd + + + + + + + +-- Deprecated: +-- +-- +-- Helping function for creating new algorithm classes +-- +-- This function creates a new algorithm class. This class will have a +-- new method, that takes a graph and, optionally, a parent algorithm +-- as inputs. They will be stored in the "graph" and "parent_algorithm" +-- fields, respectively. +-- +-- @param info This table is used to configure the new class. It has +-- the following fields: First, there is the "properties" table. If +-- this table is present, it will be used as the default table. Second, +-- it can have a graph_parameters table. This table will be used in the +-- constructor to preload graph parameters from the pgf layer. For +-- this, each entry of the table should be of the form +-- +-- key = 'string' +-- +-- What happens is that upon the creation of a new algorithm object, +-- for each key we lookup the graph option 'string' and +-- store its value in the key of the new algorithm object. +-- +-- @return A table that is a class with a new function setup. + +function gd.new_algorithm_class (class) + class.__index = class + class.new = + function (initial) + + -- Create new object + local obj = {} + for k,v in pairs(initial) do + obj[k] = v + end + setmetatable(obj, class) + + return obj + end + class.preconditions = {} + class.postconditions = {} + + return class +end + + +return gd \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua new file mode 100644 index 00000000000..8f72092e4e9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/bindings.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.bindings = {} + + +-- Done + +return pgf.gd.bindings \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua new file mode 100644 index 00000000000..f062c7a54c5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua @@ -0,0 +1,264 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/bindings/Binding.lua,v 1.6 2013/04/04 20:43:45 tantau Exp $ + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- This class provides a (non-functional) default implementation of a +-- binding between a display layer and the algorithm layer. Subclasses +-- must implement most of the member functions declared in this class. +-- +-- A instance of a subclass of this class encapsulates the complete +-- implementation of all specific code needed for the communication +-- between the display layer and the graph drawing engine. +-- +-- Note that you never call the methods of a |Binding| object +-- directly, neither from the display layer nor from the algorithm +-- layer. Instead, you use the more powerful and more easy to use +-- functions from |InterfaceToDisplay| and +-- |InterfaceToAlgorithms|. They call the appropriate |Binding| +-- methods internally. +-- +-- Because of the above, in order to use the graph drawing system +-- inside a new display layer, you need to subclass |Binding| and +-- implement all the functions. Then you need to write the display +-- layer in such a way that it calls the appropriate functions from +-- |InterfaceToDisplay|. +-- +-- @field storage A |Storage| storing the information passed from the +-- display layer. The interpretation of this left to the actual +-- binding. + +local Binding = { + storage = Storage.newTableStorage () +} +Binding.__index = Binding + +-- Namespace +require("pgf.gd.bindings").Binding = Binding + + + + + +-- +-- This method gets called whenever the graph drawing coroutine should +-- be resumed. First, the binding layer should ask the display layer +-- to execute the |code|, then, after this is done, the function +-- |InterfaceToDisplay.resumeGraphDrawingCoroutine| should be called +-- by this function. +-- +-- @param code Some code to be executed by the display layer. + +function Binding:resumeGraphDrawingCoroutine(code) + -- Does nothing by default +end + + +--- +-- Declare a new key. This callback is called by |declare|. It is the job +-- of the display layer to make the parameter |t.key| available to the +-- parsing process. Furthermore, if |t.initial| is not |nil|, the +-- display layer must convert it into a value that is stored as the +-- initial value and call |InterfaceToDisplay.setOptionInitial|. +-- +-- @param t See |InterfaceToAlgorithms.declare| for details. + +function Binding:declareCallback(t) + -- Does nothing by default +end + + + + +-- Rendering + +--- +-- This function and, later on, |renderStop| are called whenever the +-- rendering of a laid-out graph starts or stops. See +-- |InterfaceToDisplay.render| for details. + +function Binding:renderStart() + -- Does nothing by default +end + +--- +-- See |renderStart|. + +function Binding:renderStop() + -- Does nothing by default +end + + + + + +--- +-- This function and the correspoding |...Stop...| functions are +-- called whenever a collection kind should be rendered. See +-- |InterfaceToDisplay.render_collections| for details. +-- +-- @param kind The kind (a string). +-- @param layer The kind's layer (a number). + +function Binding:renderCollectionStartKind(kind, layer) + -- Does nothing by default +end + + +--- +-- The counterpart to |renderCollectionStartKind|. +-- +-- @param kind The kind. +-- @param layer The kind's layer. + +function Binding:renderCollectionStopKind(kind, layer) + -- Does nothing by default +end + + +--- +-- Renders a single collection, see |renderCollectionStartKind| for +-- details. +-- +-- @param collection The collection object. + +function Binding:renderCollection(collection) + -- Does nothing by default +end + + + +--- +-- This function and the correspoding |...Stop...| functions are +-- called whenever a vertex should be rendered. See +-- |InterfaceToDisplay.render_vertices| for details. +-- + +function Binding:renderVerticesStart() + -- Does nothing by default +end + + +--- +-- The counterpart to |renderVerticesStop|. +-- + +function Binding:renderVerticesStop() + -- Does nothing by default +end + + +--- +-- Renders a single vertex, see |renderVertexStartKind| for +-- details. +-- +-- @param vertex The |Vertex| object. + +function Binding:renderVertex(vertex) + -- Does nothing by default +end + + + +--- +-- This method is called by the interface to the display layer after +-- the display layer has called |createVertex| to create a new +-- vertex. After having done its internal bookkeeping, the interface +-- calls this function to allow the binding to perform further +-- bookkeeping on the node. Typically, this will be done using the +-- information stored in |Binding.infos|. +-- +-- @param v The vertex. + +function Binding:everyVertexCreation(v) + -- Does nothing by default +end + + + + + +--- +-- This function and the correspoding |...Stop...| functions are +-- called whenever an edge should be rendered. See +-- |InterfaceToDisplay.render_edges| for details. +-- + +function Binding:renderEdgesStart() + -- Does nothing by default +end + + +--- +-- The counterpart to |renderEdgesStop|. +-- + +function Binding:renderEdgesStop() + -- Does nothing by default +end + + +--- +-- Renders a single vertex, see |renderEdgeStartKind| for +-- details. +-- +-- @param edge The |Edge| object. + +function Binding:renderEdge(edge) + -- Does nothing by default +end + + +--- +-- Like |everyVertexCreation|, only for edges. +-- +-- @param e The edge. + +function Binding:everyEdgeCreation(e) + -- Does nothing by default +end + + +--- +-- Generate a new vertex. This method will be called when the +-- \emph{algorithm} layer wishes to trigger the creation of a new +-- vertex. This call will be made while an algorithm is running. It is +-- now the job of the binding to cause the display layer to create the +-- node. This is done by calling the |yield| method of the scope's +-- coroutine. +-- +-- @param init A table of initial values for the node. The following +-- fields will be used: +-- \begin{itemize} +-- \item |name| If present, this name will be given to the +-- node. If not present, an iternal name is generated. Note that, +-- unless the node is a subgraph node, this name may not be the name +-- of an already present node of the graph; in this case an error +-- results. +-- \item |shape| If present, a shape of the node. +-- \item |generated_options| A table that is passed back to the +-- display layer as a list of key-value pairs. +-- \item |text| The text of the node, to be passed back to the +-- higher layer. This is what should be displayed as the node's text. +-- \end{itemize} + +function Binding:createVertex(init) + -- Does nothing by default +end + + + + +return Binding \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua new file mode 100644 index 00000000000..5a1337a1327 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua @@ -0,0 +1,280 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/bindings/BindingToPGF.lua,v 1.10 2013/12/20 14:44:46 tantau Exp $ + + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- This class, which is a subclass of |Binding|, binds the graph +-- drawing system to the \pgfname\ display system by overriding (that +-- is, implementing) the methods of the |Binding| class. As a typical +-- example, consider the implementation of the function |renderVertex|: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--function BindingToPGF:renderVertex(v) +-- local info = assert(self.infos[v], "thou shalt not modify the syntactic digraph") +-- tex.print( +-- string.format( +-- "\\pgfgdcallbackrendernode{%s}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%fpt}{%s}", +-- 'not yet positionedPGFINTERNAL' .. v.name, +-- info.x_min, +-- info.x_max, +-- info.y_min, +-- info.y_max, +-- v.pos.x, +-- v.pos.y, +-- info.box_count)) +--end +--\end{codeexample} +-- +-- As can be seen, the main job of this function is to call a function +-- on the \TeX\ layer that is called |\pgfgdcallbackrendernode|, which gets +-- several parameters like the name of the to-be-rendered node or the +-- (new) position for the node. For almost all methods of the +-- |Binding| class there is a corresponding ``callback'' macro on the +-- \TeX\ layer, all of which are implemented in the \pgfname\ library +-- |graphdrawing|. For details on these callbacks, +-- please consult the code of that file and of the class +-- |BindingToPGF| (they are not documented here since they are local +-- to the binding and should not be called by anyone other than the +-- binding class). + +local BindingToPGF = { + storage = Storage.newTableStorage () -- overwrite default storage +} +BindingToPGF.__index = BindingToPGF +setmetatable(BindingToPGF, require "pgf.gd.bindings.Binding") -- subclass of Binding + + +-- Namespace +require("pgf.gd.bindings").BindingToPGF = BindingToPGF + +-- Imports +local lib = require "pgf.gd.lib" + +-- The implementation + +-- Forward +local table_in_pgf_syntax + + + + +-- Scope handling + +function BindingToPGF:resumeGraphDrawingCoroutine(text) + tex.print(text) + tex.print("\\directlua{pgf.gd.interface.InterfaceToDisplay.resumeGraphDrawingCoroutine()}") +end + + +-- Declarations + +function BindingToPGF:declareCallback(t) + tex.print("\\pgfgdcallbackdeclareparameter{" .. t.key .. "}{" .. (t.type or "nil") .. "}") +end + + + +-- Rendering + +function BindingToPGF:renderStart() + tex.print("\\pgfgdcallbackbeginshipout") +end + +function BindingToPGF:renderStop() + tex.print("\\pgfgdcallbackendshipout") +end + + +-- Rendering collections + +function BindingToPGF:renderCollection(collection) + tex.print("\\pgfgdcallbackrendercollection{".. collection.kind .. "}{" + .. table_in_pgf_syntax(collection.generated_options) .. "}") +end + +function BindingToPGF:renderCollectionStartKind(kind, layer) + tex.print("\\pgfgdcallbackrendercollectionkindstart{" .. kind .. "}{" .. tostring(layer) .. "}") +end + +function BindingToPGF:renderCollectionStopKind(kind, layer) + tex.print("\\pgfgdcallbackrendercollectionkindstop{" .. kind .. "}{" .. tostring(layer) .. "}") +end + +-- Printing points + +local function to_pt(x) + return string.format("%.12fpt", x) +end + + +-- Managing vertices (pgf nodes) + +local boxes = {} +local box_count = 0 + +function BindingToPGF:everyVertexCreation(v) + local info = self.storage[v] + + -- Save the box! + box_count = box_count + 1 + boxes[box_count] = node.copy_list(tex.box[info.tex_box_number]) + + -- Special tex stuff, should not be considered by gd algorithm + info.box_count = box_count +end + +function BindingToPGF:renderVertex(v) + local info = assert(self.storage[v], "thou shalt not modify the syntactic digraph") + tex.print( + string.format( + "\\pgfgdcallbackrendernode{%s}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%.12fpt}{%s}", + 'not yet positionedPGFINTERNAL' .. v.name, + info.x_min, + info.x_max, + info.y_min, + info.y_max, + v.pos.x, + v.pos.y, + info.box_count)) +end + +function BindingToPGF:retrieveBox(index, box_num) + tex.box[box_num] = assert(boxes[index], "no box stored at given index") + boxes[index] = nil -- remove from memory +end + +function BindingToPGF:renderVerticesStart() + tex.print("\\pgfgdcallbackbeginnodeshipout") +end + +function BindingToPGF:renderVerticesStop() + tex.print("\\pgfgdcallbackendnodeshipout") +end + + +local function rigid(x) + if type(x) == "function" then + return x() + else + return x + end +end + + +-- Managing edges + +function BindingToPGF:renderEdge(e) + local info = assert(self.storage[e], "thou shalt not modify the syntactic digraph") + + local function get_anchor(e, anchor) + local a = e.options[anchor] + if a and a ~= "" then + return "." .. a + else + return "" + end + end + + local callback = { + '\\pgfgdcallbackedge', + '{', e.tail.name .. get_anchor(e, "tail anchor"), '}', + '{', e.head.name .. get_anchor(e, "head anchor"), '}', + '{', e.direction, '}', + '{', info.pgf_options or "", '}', + '{', info.pgf_edge_nodes or "", '}', + '{', table_in_pgf_syntax(e.generated_options), '}', + '{' + } + + local i = 1 + while i <= #e.path do + local c = e.path[i] + assert (type(c) == "string", "illegal path operand") + + if c == "lineto" then + i = i + 1 + local d = rigid(e.path[i]) + callback [#callback + 1] = '--(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')' + i = i + 1 + elseif c == "moveto" then + i = i + 1 + local d = rigid(e.path[i]) + callback [#callback + 1] = '(' .. to_pt(d.x) .. ',' .. to_pt(d.y) .. ')' + i = i + 1 + elseif c == "closepath" then + callback [#callback + 1] = '--cycle' + i = i + 1 + elseif c == "curveto" then + local d1, d2, d3 = rigid(e.path[i+1]), rigid(e.path[i+2]), rigid(e.path[i+3]) + i = i + 3 + callback [#callback + 1] = '..controls(' .. to_pt(d1.x) .. ',' .. to_pt(d1.y) .. ')and(' + .. to_pt(d2.x) .. ',' .. to_pt(d2.y) .. ')..' + callback [#callback + 1] = '(' .. to_pt(d3.x) .. ',' .. to_pt(d3.y) .. ')' + i = i + 1 + else + error("illegal operation in edge path") + end + end + + callback [#callback + 1] = '}' + + -- hand TikZ code over to TeX + tex.print(table.concat(callback)) +end + + +function BindingToPGF:renderEdgesStart() + tex.print("\\pgfgdcallbackbeginedgeshipout") +end + +function BindingToPGF:renderEdgesStop() + tex.print("\\pgfgdcallbackendedgeshipout") +end + + +-- Vertex creation + +function BindingToPGF:createVertex(init) + -- Now, go back to TeX... + coroutine.yield( + table.concat({ + "\\pgfgdcallbackcreatevertex{", init.name, "}", + "{", init.shape, "}", + "{", table_in_pgf_syntax(init.generated_options), ",", init.pgf_options or "", "}", + "{", (init.text or ""), "}" + })) + -- ... and come back with a new node! +end + + + +-- Local helpers + +function table_in_pgf_syntax (t) + local prefix = "/graph drawing/" + local suffix = "/.try" + return table.concat( lib.imap( t, function(table) + if table.value then + return prefix .. table.key .. suffix .. "={" .. tostring(table.value) .. "}" + else + return prefix .. table.key .. suffix + end + end), ",") +end + + + +return BindingToPGF \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua new file mode 100644 index 00000000000..0249c9130af --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua @@ -0,0 +1,22 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/circular.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +local circular = {} + +-- Declare namespace +require("pgf.gd").circular = circular + + +-- Done + +return circular \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua new file mode 100644 index 00000000000..774bdc907be --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua @@ -0,0 +1,144 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/circular/Tantau2012.lua,v 1.7 2013/05/23 20:01:25 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + +-- The algorithm class +local Tantau2012 = {} + +--- +declare { + key = "simple necklace layout", + algorithm = Tantau2012, + + postconditions = { + upward_oriented = true + }, + + documentation_in = "pgf.gd.doc.circular.Tantau2012" +} + + + +-- Imports + +local Coordinate = require "pgf.gd.model.Coordinate" + +local lib = require "pgf.gd.lib" + + +-- The implementation + +function Tantau2012:run() + local g = self.digraph + local vertices = g.vertices + local n = #vertices + + local sib_dists = self:computeNodeDistances () + local radii = self:computeNodeRadii() + local diam, adjusted_radii = self:adjustNodeRadii(sib_dists, radii) + + -- Compute total necessary length. For this, iterate over all + -- consecutive pairs and keep track of the necessary space for + -- this node. We imagine the nodes to be aligned from left to + -- right in a line. + local carry = 0 + local positions = {} + local function wrap(i) return (i-1)%n + 1 end + local ideal_pos = 0 + for i = 1,n do + positions[i] = ideal_pos + carry + ideal_pos = ideal_pos + sib_dists[i] + local node_sep = + lib.lookup_option('node post sep', vertices[i], g) + + lib.lookup_option('node pre sep', vertices[wrap(i+1)], g) + local arc = node_sep + adjusted_radii[i] + adjusted_radii[wrap(i+1)] + local needed = carry + arc + local dist = math.sin( arc/diam ) * diam + needed = needed + math.max ((radii[i] + radii[wrap(i+1)]+node_sep)-dist, 0) + carry = math.max(needed-sib_dists[i],0) + end + local length = ideal_pos + carry + + local radius = length / (2 * math.pi) + for i,vertex in ipairs(vertices) do + vertex.pos.x = radius * math.cos(2 * math.pi * (positions[i] / length + 1/4)) + vertex.pos.y = -radius * math.sin(2 * math.pi * (positions[i] / length + 1/4)) + end +end + + +function Tantau2012:computeNodeDistances() + local sib_dists = {} + local sum_length = 0 + local vertices = self.digraph.vertices + for i=1,#vertices do + sib_dists[i] = lib.lookup_option('node distance', vertices[i], self.digraph) + sum_length = sum_length + sib_dists[i] + end + + local missing_length = self.digraph.options['radius'] * 2 * math.pi - sum_length + if missing_length > 0 then + -- Ok, the sib_dists to not add up to the desired minimum value. + -- What should we do? Hmm... We increase all by the missing amount: + for i=1,#vertices do + sib_dists[i] = sib_dists[i] + missing_length/#vertices + end + end + + sib_dists.total = math.max(self.digraph.options['radius'] * 2 * math.pi, sum_length) + + return sib_dists +end + + +function Tantau2012:computeNodeRadii() + local radii = {} + for i,v in ipairs(self.digraph.vertices) do + local min_x, min_y, max_x, max_y = v:boundingBox() + local w, h = max_x-min_x, max_y-min_y + if v.shape == "circle" or v.shape == "ellipse" then + radii[i] = math.max(w,h)/2 + else + radii[i] = math.sqrt(w*w + h*h)/2 + end + end + return radii +end + + +function Tantau2012:adjustNodeRadii(sib_dists,radii) + local total = 0 + local max_rad = 0 + for i=1,#radii do + total = total + 2*radii[i] + + lib.lookup_option('node post sep', self.digraph.vertices[i], self.digraph) + + lib.lookup_option('node pre sep', self.digraph.vertices[i], self.digraph) + max_rad = math.max(max_rad, radii[i]) + end + total = math.max(total, sib_dists.total, max_rad*math.pi) + local diam = total/(math.pi) + + -- Now, adjust the radii: + local adjusted_radii = {} + for i=1,#radii do + adjusted_radii[i] = (math.pi - 2*math.acos(radii[i]/diam))*diam/2 + end + + return diam, adjusted_radii +end + + +-- done + +return Tantau2012 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua new file mode 100644 index 00000000000..ac229a8e0d0 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua @@ -0,0 +1,30 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/circular/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + +-- Imports +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +--- +-- ``Circular'' graph drawing algorithms arrange the nodes of a graph +-- on one of more circles. +-- +-- @library + +local circular -- Library name + +-- Load declarations from: + +-- Load algorithms from: +require "pgf.gd.circular.Tantau2012" + + +-- General declarations diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua new file mode 100644 index 00000000000..3492510d242 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.control = {} + + +-- Done + +return pgf.gd.control \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua new file mode 100644 index 00000000000..e4364d695cd --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua @@ -0,0 +1,104 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/Anchoring.lua,v 1.6 2013/05/23 20:01:25 tantau Exp $ + + + +--- +-- @section subsection {Anchoring a Graph} +-- +-- \label{subsection-library-graphdrawing-anchoring} +-- +-- A graph drawing algorithm must compute positions of the nodes of a +-- graph, but the computed positions are only \emph{relative} (``this +-- node is left of this node, but above that other node''). It is not +-- immediately obvious where the ``the whole graph'' should be placed +-- \emph{absolutely} once all relative positions have been computed. In +-- case that the graph consists of several unconnected components, the +-- situation is even more complicated. +-- +-- The order in which the algorithm layer determines the node at which +-- the graph should be anchored: +-- +-- \begin{enumerate} +-- \item If the |anchor node=|\meta{node name} option given to the graph +-- as a whole, the graph is anchored at \meta{node name}, provided +-- there is a node of this name in the graph. (If there is no node of +-- this name or if it is misspelled, the effect is the same as if this +-- option had not been given at all.) +-- \item Otherwise, if there is a node where the |anchor here| option is +-- specified, the first node with this option set is used. +-- \item Otherwise, if there is a node where the |desired at| option is +-- set (perhaps implicitly through keys like |x|), the first such node +-- is used. +-- \item Finally, in all other cases, the first node is used. +-- \end{enumerate} +-- +-- In the above description, the ``first'' node refers to the node first +-- encountered in the specification of the graph. +-- +-- Once the node has been determined, the graph is shifted so that +-- this node lies at the poistion specified by |anchor at|. +-- +-- @end + + + +local Anchoring = {} + + +-- Namespace +require("pgf.gd.control").Anchoring = Anchoring + + +-- Imports +local Coordinate = require("pgf.gd.model.Coordinate") +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + + +--- +declare { + key = "desired at", + type = "coordinate", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + +--- +declare { + key = "anchor node", + type = "string", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + + +--- +declare { + key = "anchor at", + type = "canvas coordinate", + initial = "(0pt,0pt)", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + + +--- +declare { + key = "anchor here", + type = "boolean", + documentation_in = "pgf.gd.doc.control.Anchoring" +} + + + + + +-- Done + +return Anchoring \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua new file mode 100644 index 00000000000..f5475227245 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua @@ -0,0 +1,521 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentAlign.lua,v 1.4 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsubsection {Aligning Components} +-- +-- When components are placed next to each from left to right, it +-- is not immediately clear how the components should be aligned +-- vertically. What happens is that in each component a horizontal line is +-- determined and then all components are shifted vertically so that the +-- lines are aligned. There are different strategies for choosing these +-- ``lines'', see the description of the options described later on. +-- When the |component direction| option is used to change the direction +-- in which components are placed, it certainly make no longer sense to +-- talk about ``horizontal'' and ``vertical'' lines. Instead, what +-- actually happens is that the alignment does not consider +-- ``horizontal'' lines, but lines that go in the direction specified by +-- |component direction| and aligns them by moving components along a +-- line that is perpendicular to the line. For these reasons, let us call +-- the line in the component direction the \emph{alignment line} and a +-- line that is perpendicular to it the \emph{shift line}. +-- +-- The first way of specifying through which point of a component the +-- alignment line should get is to use the option |align here|. +-- In many cases, however, you will not wish to specify an alignment node +-- manually in each component. Instead, you will use the +-- |component align| key to specify a \emph{strategy} that should be used to +-- automatically determine such a node. +-- +-- Using a combination of |component direction| and |component align|, +-- numerous different packing strategies can be configured. However, +-- since names like |counterclockwise| are a bit hard to remember and to +-- apply in practice, a number of easier-to-remember keys are predefined +-- that combine an alignment and a direction. +-- +-- @end + + +--- + +declare { + key = "align here", + type = "boolean", + + summary = [[" + When this option is given to a node, this alignment line will go + through the origin of this node. If this option is passed to more + than one node of a component, the node encountered first in the + component is used. + "]], + examples = [[" + \tikz \graph [binary tree layout, nodes={draw}] + { a, b -- c[align here], d -- e[second, align here] -- f }; + "]] +} + +--- + +declare { + key = "component align", + type = "string", + initial = "first node", + + summary = [[" + Specifies a ``strategy'' for the alignment of components. + "]], + documentation = [[" + The following values are permissible: + \begin{itemize} + \item \declare{|first node|} + In each component, the alignment line goes through the center of + the first node of the component encountered during specification + of the component. +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=first node] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + \item \declare{|center|} + + The nodes of the component are projected onto the shift line. The + alignment line is now chosen so that it is exactly in the middle + between the maximum and minimum value that the projected nodes + have on the shift line. +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=center] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component direction=90, + component align=center] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + \item \declare{|counterclockwise|} + + As for |center|, we project the nodes of the component onto the + shift line. The alignment line is now chosen so that it goes + through the center of the node whose center has the highest + projected value. +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=counterclockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component direction=90, + component align=counterclockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + The name |counterclockwise| is intended to indicate that the align + line goes through the node that comes last if we go from the + alignment direction in a counter-clockwise direction. + \item \declare{|clockwise|} + + Works like |counterclockwise|, only in the other direction: +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component align=clockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [binary tree layout, nodes={draw}, + component direction=90, + component align=clockwise] + { a, b -- c, d -- e[second] -- f }; +\end{codeexample} + \item \declare{|counterclockwise bounding box|} + + This method is quite similar to |counterclockwise|, only the + alignment line does not go through the center of the node with a + maximum projected value on the shift line, but through the maximum + value of the projected bounding boxes. For a left-to-right + packing, this means that the components are aligned so that the + bounding boxes of the components are aligned at the top. +\begin{codeexample}[] +\tikz \graph [tree layout, nodes={draw, align=center}, + component sep=0pt, + component align=counterclockwise] + { a, "high\\node" -- b};\quad +\tikz \graph [tree layout, nodes={draw, align=center}, + component sep=0pt, + component align=counterclockwise bounding box] + { a, "high\\node" -- b}; +\end{codeexample} + \item \declare{|clockwise bounding box|} + + Works like |counterclockwise bounding box|. + \end{itemize} + "]] +} + +--- + +declare { + key = "components go right top aligned", + use = { + { key = "component direction", value = 0}, + { key = "component align", value = "counterclockwise"}, + }, + + summary = [[" + Shorthand for |component direction=right| and + |component align=counterclockwise|. This means that, as the name + suggest, the components will be placed left-to-right and they are + aligned such that their top nodes are in a line. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go right top aligned] + { a, "high\\node" -- b}; + "]] +} + +--- + +declare { + key = "components go right absolute top aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + + summary = [[" + Like |components go right top aligned|, but with + |component align| set to |counterclockwise| |bounding box|. This means that the + components will be aligned with their bounding boxed being + top-aligned. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go right absolute top aligned] + { a, "high\\node" -- b}; + "]] +} + +--- + +declare { + key = "components go right bottom aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "clockwise"}, + }, + + summary = "See the other |components go ...| keys." +} + +--- +-- + +declare { + key = "components go right absolute bottom aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "clockwise bounding box"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- + +declare { + key = "components go right center aligned", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "center"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- + +declare { + key = "components go right", + use = { + { key = "component direction", value=0}, + { key = "component align", value = "first node"}, + }, + + summary = [[" + Shorthand for |component direction=right| and + |component align=first node|. + "]] + } + + +--- + +declare { + key = "components go left top aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "clockwise"}, + }, + + summary = "See the other |components go ...| keys.", + + examples = [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go left top aligned] + { a, "high\\node" -- b}; + "]] +} + +--- +-- + +declare { + key = "components go left absolute top aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "clockwise bounding box"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left bottom aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "counterclockwise"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left absolute bottom aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left center aligned", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "center"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go left", + use = { + { key = "component direction", value=180}, + { key = "component align", value = "first node"}, + }, + summary = "See the other |components go ...| keys." +} + + + +--- + +declare { + key = "components go down right aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "counterclockwise"}, + }, + summary = "See the other |components go ...| keys.", + + examples = { + [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go down left aligned] + { a, hello -- {world,s} }; + "]], + [[" + \tikz \graph [tree layout, nodes={draw, align=center}, + components go up absolute left aligned] + { a, hello -- {world,s}}; + "]] + } +} + +--- +-- + +declare { + key = "components go down absolute right aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down left aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "clockwise"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down absolute left aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "clockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down center aligned", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "center"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go down", + use = { + { key = "component direction", value=270}, + { key = "component align", value = "first node"}, + }, + summary = "See the other |components go ...| keys." +} + +--- +-- + +declare { + key = "components go up right aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "clockwise"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up absolute right aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "clockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up left aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "counterclockwise"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up absolute left aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "counterclockwise bounding box"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up center aligned", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "center"}, + }, + summary = "See the other |components go ...| keys." +} + + +--- +-- + +declare { + key = "components go up", + use = { + { key = "component direction", value=90}, + { key = "component align", value = "first node"}, + }, + summary = "See the other |components go ...| keys." +} + + + + +return Components \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua new file mode 100644 index 00000000000..39df30ab248 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua @@ -0,0 +1,61 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDirection.lua,v 1.2 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsubsection {Arranging Components in a Certain Direction} +-- +-- @end + +--- + +declare { + key = "component direction", + type = "direction", + initial = "0", + + summary = [[" + The \meta{angle} is used to determine the relative position of each + component relative to the previous one. The direction need not be a + multiple of |90|. As usual, you can use texts like |up| or + |right| instead of a number. + "]], + documentation = [[" + As the examples show, the direction only has an influence on the + relative positions of the components, not on the direction of growth + inside the components. In particular, the components are not rotated + by this option in any way. You can use the |grow| option or |orient| + options to orient individual components. + "]], + examples = { + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component direction=left] + { a, b, c -- d -- e, f -- g }; + "]], + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component direction=10] + { a, b, c -- d -- e, f -- g }; + "]], + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component direction=up] + { a, b, c [grow=right] -- d -- e, f[grow=45] -- g }; + "]] + } +} + + +return Components \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua new file mode 100644 index 00000000000..30f5630ce52 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua @@ -0,0 +1,102 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentDistance.lua,v 1.2 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsubsection {The Distance Between Components} +-- +-- Once the components of a graph have been oriented, sorted, aligned, +-- and a direction has been chosen, it remains to determine the distance +-- between adjacent components. Two methods are available for computing +-- this distance, as specified by the following option: +-- +-- @end + + +--- + +declare { + key = "component packing", + type = "string", + initial = "skyline", + + documentation = [[" + Given two components, their distance is computed as follows in + depencende of \meta{method}: + \begin{itemize} + \item \declare{|rectangular|} + + Imagine a bounding box to be drawn around both components. They + are then shifted such that the padding (separating distance) + between the two boxes is the current value of |component sep|. + \begin{codeexample}[] + \tikz \graph [tree layout, nodes={draw}, component sep=0pt, + component packing=rectangular] + { a -- long text, longer text -- b}; + \end{codeexample} + \item \declare{|skyline|} + + The ``skyline method'' is used to compute the distance. It works + as follows: For simplicity, assume that the component direction is + right (other case work similary, only everything is + rotated). Imaging the second component to be placed far right + beyond the first component. Now start moving the second component + back to the left until one of the nodes of the second component + touches a node of the first component, and stop. Again, the + padding |component sep| can be used to avoid the nodes actually + touching each other. + + \begin{codeexample}[] + \tikz \graph [tree layout, nodes={draw}, component sep=0pt, + level distance=1.5cm, + component packing=skyline] + { a -- long text, longer text -- b}; + \end{codeexample} + + In order to avoid nodes of the second component ``passing through + a hole in the first component,'' the actual algorithm is a bit + more complicated: For both components, a ``skyline'' is + computed. For the first component, consider an arbitrary + horizontal line. If there are one or more nodes on this line, the + rightmost point on any of the bounding boxes of these nodes will + be the point on the skyline of the first component for this + line. Similarly, for the second component, for each horizontal + level the skyline is given by the leftmost point on any of the + bounding boxes intersecting the line. + + Now, the interesting case are horizontal lines that do not + intersect any of the nodes of the first and/or second + component. Such lines represent ``holes'' in the skyline. For + them, the following rule is used: Move the horizontal line upward + and downward as little as possible until a height is reached where + there is a skyline defined. Then the skyline position on the + original horizontal line is the skyline position at the reached + line, minus (or, for the second component, plus) the distance by + which the line was moved. This means that the holes are ``filled + up by slanted roofs.'' + \begin{codeexample}[] + \begin{tikzpicture} + \graph [tree layout, nodes={draw}, component sep=0pt, + component packing=skyline] + { a -- long text, longer text -- b}; + \draw[red] (long text.north east) -- ++(north west:1cm); + \end{tikzpicture} + \end{codeexample} + + \end{itemize} + "]] +} + + +return Components \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua new file mode 100644 index 00000000000..63a8896e8a4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua @@ -0,0 +1,107 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/ComponentOrder.lua,v 1.3 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + + + +--- +-- @section subsubsection {Ordering the Components} +-- +-- The different connected components of the graph are collected in a +-- list. The ordering of the nodes in this list can be configured using +-- the following key. +-- +-- @end + + +--- + +declare { + key = "component order", + type = "string", + initial = "by first specified node", + + summary = [[" + Selects a ``strategy'' for ordering the components. By default, + they are ordered in the way they appear in the input. + "]], + documentation = [[" + The following values are permissible for \meta{strategy} + \begin{itemize} + \item \declare{|by first specified node|} + + The components are ordered ``in the way they appear in the input + specification of the graph''. More precisely, for each component + consider the node that is first encountered in the description + of the graph. Order the components in the same way as these nodes + appear in the graph description. + + \item \declare{|increasing node number|} + + The components are ordered by increasing number of nodes. For + components with the same number of nodes, the first node in each + component is considered and they are ordered according to the + sequence in which these nodes appear in the input. + + \item \declare{|decreasing node number|} + As above, but in decreasing order. + \end{itemize} + "]], + examples = { + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component order=by first specified node] + { a, b, c, f -- g, c -- d -- e }; + "]], + [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + component order=increasing node number] + { a, b, c -- d -- e, f -- g }; + "]] + } +} + + +--- + +declare { + key = "small components first", + use = { + { key = "component order", value = "increasing node number" } + }, + + summary = [[" + A shorthand for |component order=increasing node number|. + "]] + } + +--- + +declare { + key = "large components first", + use = { + { key = "component order", value = "decreasing node number" }, + }, + summary = [[" + A shorthand for |component order=decreasing node number|. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={inner sep=1pt,draw,circle}, + large components first] + { a, b, c -- d -- e, f -- g }; + "]] +} + + +return Components \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua new file mode 100644 index 00000000000..0d1d2b1bf48 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua @@ -0,0 +1,129 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/Components.lua,v 1.3 2013/05/23 20:01:25 tantau Exp $ + + +-- Imports + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- +-- @section subsection {Packing of Connected Components} +-- +-- \label{subsection-gd-component-packing} +-- \label{section-gd-packing} +-- +-- Graphs may be composed of subgraphs or \emph{components} that are not +-- connected to each other. In order to draw these nicely, most graph +-- drawing algorithms split them into separate graphs, compute +-- their layouts with the same graph drawing algorithm independently and, +-- in a postprocessing step, arrange them next to each other. Note, +-- however, that some graph drawing algorithms can also arrange the nodes +-- of the graph in a uniform way even for unconnected components (the +-- |simple necklace layout| is a case in point); for such algorithms you can +-- choose whether they should be applied to each component individually +-- or not (if not, the following options do not apply). To configure +-- which is the case, use the |componentwise| key. +-- +-- The default method for placing the different components works as +-- follows: +-- +-- \begin{enumerate} +-- \item For each component, a layout is determined and the component is +-- oriented as described +-- Section~\ref{subsection-library-graphdrawing-standard-orientation} +-- on the orientation of graphs. +-- \item The components are sorted as prescribed by the +-- |component order| key. +-- \item The first component is now placed (conceptually) at the +-- origin. (The final position of this and all other components will be +-- determined later, namely in the anchoring phase, but let us imagine +-- that the first component lies at the origin at this point.) +-- \item The second component is now positioned relative to the first +-- component. The ``direction'' in which the next component is placed +-- relative to the first one is determined by the |component direction| +-- key, so components can be placed from left to right or up to down or +-- in any other direction (even something like $30^\circ$). However, +-- both internally and in the following description, we assume that the +-- components are placed from left to right; other directions are +-- achieved by doing some (clever) rotating of the arrangement achieved +-- in this way. +-- +-- So, we now wish to place the second component to the right of the +-- first component. The component is first shifted vertically according +-- to some alignment strategy. For instance, it can be shifted so that +-- the topmost node of the first component and the topmost node of the +-- second component have the same vertical position. Alternatively, we +-- might require that certain ``alignment nodes'' in both components +-- have the same vertical position. There are several other strategies, +-- which can be configured using the |component align| key. +-- +-- One the vertical position has been fixed, the horizontal position is +-- computed. Here, two different strategies are available: First, image +-- rectangular bounding boxed to be drawn around both components. Then +-- we shift the second component such that the right border of the +-- bounding box of the first component touches the left border of the +-- bounding box of the second component. Instead of having the bounding +-- boxes ``touch,'' we can also have a padding of |component sep| +-- between them. The second strategy is more involved and also known as +-- a ``skyline'' strategy, where (roughly) the components are +-- ``moved together as near as possible so that nodes do not touch''. +-- \item +-- After the second component has been placed, the third component is +-- considered and positioned relative to the second one, and so on. +-- \item +-- At the end, as hinted at earlier, the whole arrangement is rotate so +-- that instead of ``going right'' the component go in the direction of +-- |component direction|. Note, however, that this rotation applies only +-- to the ``shift'' of the components; the components themselves are +-- not rotated. Fortunately, this whole rotation process happens in the +-- background and the result is normally exactly what you would expect. +-- \end{enumerate} +-- +-- In the following, we go over the different keys that can be used to +-- configure the component packing. +-- +-- @end + + +--- + +declare { + key = "componentwise", + type = "boolean", + + summary = [[" + For algorithms that also support drawing unconnected graphs, use + this key to enforce that the components of the graph are, + nevertheless, laid out individually. For algorithms that do not + support laying out unconnected graphs, this option has no effect; + rather it works as if this option were always set. + "]], + examples = { + [[" + \tikz \graph [simple necklace layout] + { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 + }; + "]], + [[", + \tikz \graph [simple necklace layout, componentwise] + { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 + }; + "]] + } +} + + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua new file mode 100644 index 00000000000..046940d84f3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua @@ -0,0 +1,461 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/Distances.lua,v 1.5 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +local lib = require "pgf.gd.lib" + +--- +-- @section subsection {Padding and Node Distances} +-- +-- \label{subsection-gd-dist-pad} +-- +-- In many drawings, you may wish to specify how ``near'' two nodes should +-- be placed by a graph drawing algorithm. Naturally, this depends +-- strongly on the specifics of the algorithm, but there are a number of +-- general keys that will be used by many algorithms. +-- +-- There are different kinds of objects for which you can specify +-- distances and paddings: +-- +-- \begin{itemize} +-- \item You specify the ``natural'' distance between nodes +-- connected by an edge using |node distance|, which is also available in +-- normal \tikzname\ albeit for a slightly different purpose. However, +-- not every algorithm will (or can) honour the key; see the description +-- of each algorithm what it will ``make of this option''. +-- \item A number of graph drawing algorithms arrange nodes in layers +-- (or levels); we refer +-- to the nodes on the same layer as siblings (although, in a tree, +-- siblings are only nodes with the same parent; nevertheless we use +-- ``sibling'' loosely also for nodes that are more like ``cousins''). +-- \item When a graph consists of several connected component, many graph +-- drawing algorithms will layout these components individually. The +-- different components will then be arranged next to each other, see +-- Section~\ref{section-gd-packing} for the details, such that between +-- the nodes of any two components a padding is avaiable. +-- \end{itemize} +-- +-- @end + + + + +--- + +declare { + key = "node distance", + type = "length", + initial = "1cm", + + summary = [[" + This is minimum distance that the centers of nodes connected by an + edge should have. It will not always be possible to satisfy this + desired distance, for instance in case the nodes are too big. In + this case, the \meta{length} is just considered as a lower bound. + "]], + examples = [[" + \begin{tikzpicture} + \graph [simple necklace layout, node distance=1cm, node sep=0pt, + nodes={draw,circle,as=.}] + { + 1 -- 2 [minimum size=2cm] -- 3 -- + 4 -- 5 -- 6 -- 7 --[orient=up] 8 + }; + \draw [red,|-|] (1.center) -- ++(0:1cm); + \draw [red,|-|] (5.center) -- ++(180:1cm); + \end{tikzpicture} + "]] +} + + +--- + +declare { + key = "node pre sep", + type = "length", + initial = ".333em", + + summary = [[" + This is a minimum ``padding'' or ``separation'' between the border + of nodes connected by an edge. Thus, if nodes are so big that nodes + with a distance of |node distance| would overlap (or + just come with \meta{dimension} distance of one another), their + distance is enlarged so that this distance is still satisfied. + The |pre| means that the padding is added to the node ``at the + front.'' This make sense only for some algorithms, like for a + simple necklace layout. + "]], + examples = { + [[" + \tikz \graph [simple necklace layout, node distance=0cm, nodes={circle,draw}] + { 1--2--3--4--5--1 }; + "]], + [[" + \tikz \graph [simple necklace layout, node distance=0cm, node sep=0mm, + nodes={circle,draw}] + { 1--2--3[node pre sep=5mm]--4--5[node pre sep=1mm]--1 }; + "]] + } +} + +--- + +declare { + key = "node post sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |node pre sep|. + "]] +} + + + +--- +-- @param length A length. + +declare { + key = "node sep", + type = "length", + use = { + { key = "node pre sep", value = function(v) return v/2 end }, + { key = "node post sep", value = function(v) return v/2 end }, + }, + summary = [[" + A shorthand for setting both |node pre sep| and |node post sep| to + $\meta{length}/2$. + "]] +} + + +--- + +declare { + key = "level distance", + type = "length", + initial = "1cm", + + summary = [[" + This is minimum distance that the centers of nodes on one + level should have from the centers of nodes on the next level. It + will not always be possible to satisfy this desired distance, for + instance in case the nodes are too big. In this case, the + \meta{length} is just considered as a lower bound. + "]], + examples = [[" + \begin{tikzpicture}[inner sep=2pt] + \draw [help lines] (0,0) grid (3.5,2); + \graph [layered layout, level distance=1cm, level sep=0] + { 1 [x=1,y=2] -- 2 -- 3 -- 1 }; + \graph [layered layout, level distance=5mm, level sep=0] + { 1 [x=3,y=2] -- 2 -- 3 -- 1, 3 -- {4,5} -- 6 -- 3 }; + \end{tikzpicture} + "]] +} + +--- +declare { + key = "layer distance", + type = "length", + use = { + { key = "level distance", value = lib.id }, + }, + summary = "An alias for |level distance|" +} + +--- +declare { + key = "level pre sep", + type = "length", + initial = ".333em", + + summary = [[" + This is a minimum ``padding'' or ``separation'' between the border + of the nodes on a level to any nodes on the previous level. Thus, if + nodes are so big that nodes on consecutive levels would overlap (or + just come with \meta{lrngth} distance of one another), their + distance is enlarged so that this distance is still satisfied. + If a node on the previous level also has a |level post sep|, this + post padding and the \meta{dimension} add up. Thus, these keys + behave like the ``padding'' keys rather + than the ``margin'' key of cascading style sheets. + "]], + examples = [[" + \begin{tikzpicture}[inner sep=2pt, level sep=0pt, sibling distance=0pt] + \draw [help lines] (0,0) grid (3.5,2); + \graph [layered layout, level distance=0cm, nodes=draw] + { 1 [x=1,y=2] -- {2,3[level pre sep=1mm],4[level pre sep=5mm]} -- 5 }; + \graph [layered layout, level distance=0cm, nodes=draw] + { 1 [x=3,y=2] -- {2,3,4} -- 5[level pre sep=5mm] }; + \end{tikzpicture} + "]] +} + +--- + +declare { + key = "level post sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |level pre sep|. + "]] +} + +--- +declare { + key = "layer pre sep", + type = "length", + use = { + { key = "level pre sep", value = lib.id }, + }, + summary = "An alias for |level pre sep|." +} + +--- +declare { + key = "layer post sep", + type = "length", + use = { + { key = "level post sep", value = lib.id }, + }, + summary = "An alias for |level post sep|." +} + + + + +--- +-- @param length A length + +declare { + key = "level sep", + type = "length", + use = { + { key = "level pre sep", value = function (v) return v/2 end }, + { key = "level post sep", value = function (v) return v/2 end }, + }, + + summary = [[" + A shorthand for setting both |level pre sep| and |level post sep| to + $\meta{length}/2$. Note that if you set |level distance=0| and + |level sep=1em|, you get a layout where any two consecutive layers + are ``spaced apart'' by |1em|. + "]] +} + + +--- +declare { + key = "layer sep", + type = "number", + use = { + { key = "level sep", value = lib.id }, + }, + summary = "An alias for |level sep|." +} + + +--- +declare { + key = "sibling distance", + type = "length", + initial = "1cm", + + summary = [[" + This is minimum distance that the centers of node should have to the + center of the next node on the same level. As for levels, this is + just a lower bound. + For some layouts, like a simple necklace layout, the \meta{length} is + measured as the distance on the circle. + "]], + examples = { + [[" + \tikz \graph [tree layout, sibling distance=1cm, nodes={circle,draw}] + { 1--{2,3,4,5} }; + "]], + [[" + \tikz \graph [tree layout, sibling distance=0cm, sibling sep=0pt, + nodes={circle,draw}] + { 1--{2,3,4,5} }; + "]], + [[" + \tikz \graph [tree layout, sibling distance=0cm, sibling sep=0pt, + nodes={circle,draw}] + { 1--{2,3[sibling distance=1cm],4,5} }; + "]] + } +} + + +--- + +declare { + key = "sibling pre sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |level pre sep|, only for siblings. + "]], + examples = [[" + \tikz \graph [tree layout, sibling distance=0cm, nodes={circle,draw}, + sibling sep=0pt] + { 1--{2,3[sibling pre sep=1cm],4,5} }; + "]] +} + +--- + +declare { + key = "sibling post sep", + type = "length", + initial = ".333em", + + summary = [[" + Works like |sibling pre sep|. + "]] + } + + + +--- +-- @param length A length + +declare { + key = "sibling sep", + type = "length", + use = { + { key = "sibling pre sep", value = function(v) return v/2 end }, + { key = "sibling post sep", value = function(v) return v/2 end }, + }, + + summary = [[" + A shorthand for setting both |sibling pre sep| and |sibling post sep| to + $\meta{length}/2$. + "]] +} + + + + + + +--- +declare { + key = "part distance", + type = "length", + initial = "1.5cm", + + summary = [[" + This is minimum distance between the centers of ``parts'' of a + graph. What a ``part'' is depends on the algorithm. + "]] +} + + +--- + +declare { + key = "part pre sep", + type = "length", + initial = "1em", + summary = "A pre-padding for parts." +} + +--- + +declare { + key = "part post sep", + type = "length", + initial = "1em", + summary = "A post-padding for pars." + } + + + +--- +-- @param length A length + +declare { + key = "part sep", + type = "length", + use = { + { key = "part pre sep", value = function(v) return v/2 end }, + { key = "part post sep", value = function(v) return v/2 end }, + }, + + summary = [[" + A shorthand for setting both |part pre sep| and |part post sep| to + $\meta{length}/2$. + "]] +} + + + + +--- + +declare { + key = "component sep", + type = "length", + initial = "1.5em", + + summary = [[" + This is pading between the bounding boxes that nodes of different + connected components will have when they are placed next to each + other. + "]], + examples = { + [[" + \tikz \graph [binary tree layout, sibling distance=4mm, level distance=8mm, + components go right top aligned, + component sep=1pt, nodes=draw] + { + 1 -> 2 -> {3->4[second]->5,6,7}; + a -> b[second] -> c[second] -> d -> e; + x -> y[second] -> z -> u[second] -> v; + }; + "]], + [[" + \tikz \graph [binary tree layout, sibling distance=4mm, level distance=8mm, + components go right top aligned, + component sep=1em, nodes=draw] + { + 1 -> 2 -> {3->4[second]->5,6,7}; + a -> b[second] -> c[second] -> d -> e; + x -> y[second] -> z -> u[second] -> v; + }; + "]] + } +} + + + +--- + +declare { + key = "component distance", + type = "length", + initial = "2cm", + + summary = [[" + This is the minimum distance between the centers of bounding + boxes of connected components when they are placed next to each + other. (Not used, currently.) + "]] +} + + +return Distances \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua new file mode 100644 index 00000000000..bb2fd065b24 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua @@ -0,0 +1,164 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/FineTune.lua,v 1.3 2013/05/23 20:01:25 tantau Exp $ + + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +local Coordinate = require "pgf.gd.model.Coordinate" +local lib = require "pgf.gd.lib" + +--- +-- @section subsection {Fine-Tuning Positions of Nodes} +-- +-- @end + + + +--- +declare { + key = "nudge", + type = "canvas coordinate", + + summary = [[" + This option allows you to slightly ``nudge'' (move) nodes after + they have been positioned by the given offset. The idea is that + this nudging is done after the position of the node has been + computed, so nudging has no influence on the actual graph + drawing algorithms. This, in turn, means that you can use + nudging to ``correct'' or ``optimize'' the positioning of nodes + after the algorithm has computed something. + "]], + + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b, c, d[nudge=(up:2mm)]} -- e -- a; + }; + "]] +} + + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge up", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(0,v) end } + }, + + summary = "A shorthand for nudging a node upwards.", + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b, c, d[nudge up=2mm]} -- e -- a; + }; + "]] +} + + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge down", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(0,-v) end } + }, + + summary = "Like |nudge up|, but downwards." +} + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge left", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(-v,0) end } + }, + + summary = "Like |nudge up|, but left.", + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b, c, d[nudge left=2mm]} -- e -- a; + }; + "]] +} + +--- +-- @param distance A distance by which the node is nudges. + +declare { + key = "nudge right", + type = "length", + use = { + { key = "nudge", value = function (v) return Coordinate.new(v,0) end } + }, + + summary = "Like |nudge left|, but right." +} + + +--- +declare { + key = "regardless at", + type = "canvas coordinate", + + summary = [[" + Using this option you can provide a position for a node to wish + it will be forced after the graph algorithms have run. So, the node + is positioned normally and the graph drawing algorithm does not know + about the position specified using |regardless at|. However, + afterwards, the node is placed there, regardless of what the + algorithm has computed (all other nodes are unaffected). + "]], + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b,c,d[regardless at={(1,0)}]} -- e -- a; + }; + "]] +} + + + + +--- +-- @param pos A canvas position (a coordinate). + +declare { + key = "nail at", + type = "canvas coordinate", + use = { + { key = "desired at", value = lib.id }, + { key = "regardless at", value = lib.id }, + }, + + summary = [[" + This option combines |desired at| and |regardless at|. Thus, the + algorithm is ``told'' about the desired position. If it fails to place + the node at the desired position, it will be put there + regardless. The name of the key is intended to remind one of a node + being ``nailed'' to the canvas. + "]], + examples = [[" + \tikz \graph [edges=rounded corners, nodes=draw, + layered layout, sibling distance=0] { + a -- {b,c,d[nail at={(1,0)}]} -- e[nail at={(1.5,-1)}] -- a; + }; + "]] +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua new file mode 100644 index 00000000000..c32f9d084f6 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua @@ -0,0 +1,1282 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/LayoutPipeline.lua,v 1.11 2013/10/09 19:46:59 tantau Exp $ + + +--- +-- This class controls the running of graph drawing algorithms on +-- graphs. In particular, it performs pre- and posttransformations and +-- also invokes the collapsing of sublayouts. +-- +-- You do not call any of the methods of this class directly, the +-- whole class is included only for documentation purposes. +-- +-- Before an algorithm is applied, a number of transformations will +-- have been applied, depending on the algorithm's |preconditions| +-- field: +-- +-- \begin{itemize} +-- \item |connected| +-- +-- If this property is set for an algorithm (that is, in the +-- |declare| statement for the algorithm the |predconditions| field +-- has the entry |connected=true| set), then the graph will be +-- decomposed into connected components. The algorithm is run on each +-- component individually. +-- \item |tree| +-- +-- When set, the field |spanning_tree| of the algorithm will be set +-- to a spanning tree of the graph. This option implies |connected|. +-- \item |loop_free| +-- +-- When set, all loops (arcs from a vertex to itself) will have been +-- removed when the algorithm runs. +-- +-- \item |at_least_two_nodes| +-- +-- When explicitly set to |false| (this precondition is |true| by +-- default), the algorithm will even be run if there is only a +-- single vertex in the graph. +-- \end{itemize} +-- +-- Once the algorithm has run, the algorithm's |postconditions| will +-- be processed: +-- +-- \begin{itemize} +-- \item |upward_oriented| +-- +-- When set, the algorithm tells the layout pipeline that the graph +-- has been laid out in a layered manner with each layer going from +-- left to right and layers at a whole going upwards (positive +-- $y$-coordinates). The graph will then be rotated and possibly +-- swapped in accordance with the |grow| key set by the user. +-- \item |fixed| +-- +-- When set, no rotational postprocessing will be done after the +-- algorithm has run. Usually, a graph is rotated to meet a user's +-- |orient| settings. However, when the algorithm has already +-- ``ideally'' rotated the graph, set this postcondition. +-- \end{itemize} +-- + +local LayoutPipeline = {} + + +-- Namespace +require("pgf.gd.control").LayoutPipeline = LayoutPipeline + + +-- Imports +local Direct = require "pgf.gd.lib.Direct" +local Storage = require "pgf.gd.lib.Storage" +local Simplifiers = require "pgf.gd.lib.Simplifiers" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Transform = require "pgf.gd.lib.Transform" + +local Arc = require "pgf.gd.model.Arc" +local Vertex = require "pgf.gd.model.Vertex" +local Digraph = require "pgf.gd.model.Digraph" +local Coordinate = require "pgf.gd.model.Coordinate" +local Path = require "pgf.gd.model.Path" + +local Sublayouts = require "pgf.gd.control.Sublayouts" + +local lib = require "pgf.gd.lib" + +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" + + + + +-- Forward definitions + +local prepare_events + + + +-- The main ``graph drawing pipeline'' that handles the pre- and +-- postprocessing for a graph. This method is called by the diplay +-- interface. +-- +-- @param scope A graph drawing scope. + +function LayoutPipeline.run(scope) + + -- The pipeline... + + -- Step 1: Preparations + + -- Prepare events + prepare_events(scope.events) + + -- Step 2: Recursively layout the graph, starting with the root layout + local root_layout = assert(scope.collections[InterfaceCore.sublayout_kind][1], "no layout in scope") + + scope.syntactic_digraph = + Sublayouts.layoutRecursively (scope, + root_layout, + LayoutPipeline.runOnLayout, + { root_layout }) + + -- Step 3: Anchor the graph + LayoutPipeline.anchor(scope.syntactic_digraph, scope) + + -- Step 4: Apply regardless transforms + Sublayouts.regardless(scope.syntactic_digraph) + + -- Step 5: Cut edges + LayoutPipeline.cutEdges(scope.syntactic_digraph) + +end + + + +-- +-- This method is called by the sublayout rendering pipeline when the +-- algorithm should be invoked for an individual graph. At this point, +-- the sublayouts will already have been collapsed. +-- +-- @param scope The graph drawing scope. +-- @param algorithm_class The to-be-applied algorithm class. +-- @param layout_graph A subgraph of the syntactic digraph which is +-- restricted to the current layout and in which sublayouts have +-- been contracted to single nodes. +-- @param layout The layout to which the graph belongs. +-- +function LayoutPipeline.runOnLayout(scope, algorithm_class, layout_graph, layout) + + if #layout_graph.vertices < 1 then + return + end + + -- The involved main graphs: + local layout_copy = Digraph.new (layout_graph) --Direct.digraphFromSyntacticDigraph(layout_graph) + for _,a in ipairs(layout_graph.arcs) do + local new_a = layout_copy:connect(a.tail,a.head) + new_a.syntactic_edges = a.syntactic_edges + end + + -- Step 1: Decompose the graph into connected components, if necessary: + local syntactic_components + if algorithm_class.preconditions.tree or algorithm_class.preconditions.connected or layout_graph.options.componentwise then + syntactic_components = LayoutPipeline.decompose(layout_copy) + LayoutPipeline.sortComponents(layout_graph.options['component order'], syntactic_components) + else + -- Only one component: The graph itself... + syntactic_components = { layout_copy } + end + + -- Step 2: For all components do: + for i,syntactic_component in ipairs(syntactic_components) do + + -- Step 2.1: Reset random number generator to make sure that the + -- same graph is always typeset in the same way. + math.randomseed(layout_graph.options['random seed']) + + local digraph = Direct.digraphFromSyntacticDigraph(syntactic_component) + + -- Step 2.3: If requested, remove loops + if algorithm_class.preconditions.loop_free then + for _,v in ipairs(digraph.vertices) do + digraph:disconnect(v,v) + end + end + + -- Step 2.4: Precompute the underlying undirected graph + local ugraph = Direct.ugraphFromDigraph(digraph) + + -- Step 2.5: Create an algorithm object + local algorithm = algorithm_class.new{ + digraph = digraph, + ugraph = ugraph, + scope = scope, + layout = layout, + layout_graph = layout_graph, + syntactic_component = syntactic_component, + } + + -- Step 2.7: Compute a spanning tree, if necessary + if algorithm_class.preconditions.tree then + local spanning_algorithm_class = syntactic_component.options.algorithm_phases["spanning tree computation"] + algorithm.spanning_tree = + spanning_algorithm_class.new{ + ugraph = ugraph, + events = scope.events + }:run() + end + + -- Step 2.8: Compute growth-adjusted sizes + algorithm.rotation_info = LayoutPipeline.prepareRotateAround(algorithm.postconditions, syntactic_component) + algorithm.adjusted_bb = Storage.newTableStorage() + LayoutPipeline.prepareBoundingBoxes(algorithm.rotation_info, algorithm.adjusted_bb, syntactic_component, syntactic_component.vertices) + + -- Step 2.9: Finally, run algorithm on this component! + if #digraph.vertices > 1 or algorithm_class.run_also_for_single_node + or algorithm_class.preconditions.at_least_two_nodes == false then + -- Main run of the algorithm: + if algorithm_class.old_graph_model then + LayoutPipeline.runOldGraphModel(scope, digraph, algorithm_class, algorithm) + else + algorithm:run () + end + end + + -- Step 2.10: Sync the graphs + digraph:sync() + ugraph:sync() + if algorithm.spanning_tree then + algorithm.spanning_tree:sync() + end + + -- Step 2.11: Orient the graph + LayoutPipeline.orient(algorithm.rotation_info, algorithm.postconditions, syntactic_component, scope) + end + + -- Step 3: Packing: + LayoutPipeline.packComponents(layout_graph, syntactic_components) +end + + + + + + +--- +-- This function is called internally to perform the graph anchoring +-- procedure described in +-- Section~\ref{subsection-library-graphdrawing-anchoring}. These +-- transformations are always performed. +-- +-- @param graph A graph +-- @param scope The scope + +function LayoutPipeline.anchor(graph, scope) + + -- Step 1: Find anchor node: + local anchor_node + + local anchor_node_name = graph.options['anchor node'] + if anchor_node_name then + anchor_node = scope.node_names[anchor_node_name] + end + + if not graph:contains(anchor_node) then + anchor_node = + lib.find (graph.vertices, function (v) return v.options['anchor here'] end) or + lib.find (graph.vertices, function (v) return v.options['desired at'] end) or + graph.vertices[1] + end + + -- Sanity check + assert(graph:contains(anchor_node), "anchor node is not in graph!") + + local desired = anchor_node.options['desired at'] or graph.options['anchor at'] + local delta = desired - anchor_node.pos + + -- Step 3: Shift nodes + for _,v in ipairs(graph.vertices) do + v.pos:shiftByCoordinate(delta) + end + for _,a in ipairs(graph.arcs) do + if a.path then a.path:shiftByCoordinate(delta) end + for _,e in ipairs(a.syntactic_edges) do + e.path:shiftByCoordinate(delta) + end + end +end + + + +--- +-- This method tries to determine in which direction the graph is supposed to +-- grow and in which direction the algorithm will grow the graph. These two +-- pieces of information togehter produce a necessary rotation around some node. +-- This rotation is returned in a table. +-- +-- Note that this method does not actually cause a rotation to happen; this is +-- left to other method. +-- +-- @param postconditions The algorithm's postconditions. +-- @param graph An undirected graph +-- @return A table containing the computed information. + +function LayoutPipeline.prepareRotateAround(postconditions, graph) + + -- Find the vertex from which we orient + local swap = true + + local v,_,grow = lib.find (graph.vertices, function (v) return v.options["grow"] end) + + if not v and graph.options["grow"] then + v,grow,swap = graph.vertices[1], graph.options["grow"], true + end + + if not v then + v,_,grow = lib.find (graph.vertices, function (v) return v.options["grow'"] end) + swap = false + end + + if not v and graph.options["grow'"] then + v,grow,swap = graph.vertices[1], graph.options["grow'"], false + end + + if not v then + v, grow, swap = graph.vertices[1], -90, true + end + + -- Now compute the rotation + local info = {} + local growth_direction = (postconditions.upward_oriented and 90) or (postconditions.upward_oriented_swapped and 90) + + if postconditions.upward_oriented_swapped then + swap = not swap + end + + if growth_direction == "fixed" then + info.angle = 0 -- no rotation + elseif growth_direction then + info.from_node = v + info.from_angle = growth_direction/360*2*math.pi + info.to_angle = grow/360*2*math.pi + info.swap = swap + info.angle = info.to_angle - info.from_angle + else + info.from_node = v + local other = lib.find_min( + graph:outgoing(v), + function (a) + if a.head ~= v and a:eventIndex() then + return a, a:eventIndex() + end + end) + info.to_node = (other and other.head) or + (graph.vertices[1] == v and graph.vertices[2] or graph.vertices[1]) + info.to_angle = grow/360*2*math.pi + info.swap = swap + info.angle = info.to_angle - math.atan2(info.to_node.pos.y - v.pos.y, info.to_node.pos.x - v.pos.x) + end + + return info +end + + + +--- +-- Compute growth-adjusted node sizes. +-- +-- For each node of the graph, compute bounding box of the node that +-- results when the node is rotated so that it is in the correct +-- orientation for what the algorithm assumes. +-- +-- The ``bounding box'' actually consists of the fields +-- \begin{itemize} +-- \item |sibling_pre|, +-- \item |sibling_post|, +-- \item |layer_pre|, and +-- \item |layer_post|, +-- \end{itemize} +-- which correspond to ``min x'', ``min y'', ``min y'', and ``max y'' +-- for a tree growing up. +-- +-- The computation of the ``bounding box'' treats a centered circle in +-- a special way, all other shapes are currently treated like a +-- rectangle. +-- +-- @param rotation_info The table computed by the function prepareRotateAround +-- @param packing_storage A storage in which the computed distances are stored. +-- @param graph An graph +-- @param vertices An array of to-be-prepared vertices inside graph + +function LayoutPipeline.prepareBoundingBoxes(rotation_info, adjusted_bb, graph, vertices) + + local angle = assert(rotation_info.angle, "angle field missing") + local swap = rotation_info.swap + + for _,v in ipairs(vertices) do + local bb = adjusted_bb[v] + local a = angle + + if v.shape == "circle" then + a = 0 -- no rotation for circles. + end + + -- Fill the bounding box field, + bb.sibling_pre = math.huge + bb.sibling_post = -math.huge + bb.layer_pre = math.huge + bb.layer_post = -math.huge + + local c = math.cos(angle) + local s = math.sin(angle) + for _,p in ipairs(v.path:coordinates()) do + local x = p.x*c + p.y*s + local y = -p.x*s + p.y*c + + bb.sibling_pre = math.min (bb.sibling_pre, x) + bb.sibling_post = math.max (bb.sibling_post, x) + bb.layer_pre = math.min (bb.layer_pre, y) + bb.layer_post = math.max (bb.layer_post, y) + end + + -- Flip sibling per and post if flag: + if swap then + bb.sibling_pre, bb.sibling_post = -bb.sibling_post, -bb.sibling_pre + end + end +end + + + + + +-- +-- Rotate the whole graph around a point +-- +-- Causes the graph to be rotated around \meta{around} so that what +-- used to be the |from_angle| becomes the |to_angle|. If the flag |swap| +-- is set, the graph is additionally swapped along the |to_angle|. +-- +-- @param graph The to-be-rotated (undirected) graph +-- @param around_x The $x$-coordinate of the point around which the graph should be rotated +-- @param around_y The $y$-coordinate +-- @param from An ``old'' angle +-- @param to A ``new'' angle +-- @param swap A boolean that, when true, requests that the graph is +-- swapped (flipped) along the new angle + +function LayoutPipeline.rotateGraphAround(graph, around_x, around_y, from, to, swap) + + -- Translate to origin + local t = Transform.new_shift(-around_x, -around_y) + + -- Rotate to zero degrees: + t = Transform.concat(Transform.new_rotation(-from), t) + + -- Swap + if swap then + t = Transform.concat(Transform.new_scaling(1,-1), t) + end + + -- Rotate to from degrees: + t = Transform.concat(Transform.new_rotation(to), t) + + -- Translate back + t = Transform.concat(Transform.new_shift(around_x, around_y), t) + + for _,v in ipairs(graph.vertices) do + v.pos:apply(t) + end + for _,a in ipairs(graph.arcs) do + for _,p in ipairs(a:pointCloud()) do + p:apply(t) + end + end +end + + + +-- +-- Orient the whole graph using two nodes +-- +-- The whole graph is rotated so that the line from the first node to +-- the second node has the given angle. If swap is set to true, the +-- graph is also flipped along this line. +-- +-- @param graph +-- @param first_node +-- @param seond_node +-- @param target_angle +-- @param swap + +function LayoutPipeline.orientTwoNodes(graph, first_node, second_node, target_angle, swap) + if first_node and second_node then + -- Compute angle between first_node and second_node: + local x = second_node.pos.x - first_node.pos.x + local y = second_node.pos.y - first_node.pos.y + + local angle = math.atan2(y,x) + LayoutPipeline.rotateGraphAround(graph, first_node.pos.x, + first_node.pos.y, angle, target_angle, swap) + end +end + + + +--- +-- Performs a post-layout orientation of the graph by performing the +-- steps documented in Section~\ref{subsection-library-graphdrawing-standard-orientation}. +-- +-- @param rotation_info The info record computed by the function |prepareRotateAround|. +-- @param postconditions The algorithm's postconditions. +-- @param graph A to-be-oriented graph. +-- @param scope The graph drawing scope. + +function LayoutPipeline.orient(rotation_info, postconditions, graph, scope) + + -- Sanity check + if #graph.vertices < 2 then return end + + -- Step 1: Search for global graph orient options: + local function f (orient, tail, head, flag) + if orient and head and tail then + local n1 = scope.node_names[tail] + local n2 = scope.node_names[head] + if graph:contains(n1) and graph:contains(n2) then + LayoutPipeline.orientTwoNodes(graph, n1, n2, orient/360*2*math.pi, flag) + return true + end + end + end + if f(graph.options["orient"], graph.options["orient tail"],graph.options["orient head"], false) then return end + if f(graph.options["orient'"], graph.options["orient tail"],graph.options["orient head"], true) then return end + local tail, head = string.match(graph.options["horizontal"] or "", "^(.*) to (.*)$") + if f(0, tail, head, false) then return end + local tail, head = string.match(graph.options["horizontal'"] or "", "^(.*) to (.*)$") + if f(0, tail, head, true) then return end + local tail, head = string.match(graph.options["vertical"] or "", "^(.*) to (.*)$") + if f(-90, tail, head, false) then return end + local tail, head = string.match(graph.options["vertical'"] or "", "^(.*) to (.*)$") + if f(-90, tail, head, true) then return end + + -- Step 2: Search for a node with the orient option: + for _, v in ipairs(graph.vertices) do + local function f (key, flag) + local orient = v.options[key] + local head = v.options["orient head"] + local tail = v.options["orient tail"] + + if orient and head then + local n2 = scope.node_names[head] + if graph:contains(n2) then + LayoutPipeline.orientTwoNodes(graph, v, n2, orient/360*2*math.pi, flag) + return true + end + elseif orient and tail then + local n1 = scope.node_names[tail] + if graph:contains(n1) then + LayoutPipeline.orientTwoNodes(graph, n1, v, orient/360*2*math.pi, flag) + return true + end + end + end + if f("orient", false) then return end + if f("orient'", true) then return end + end + + -- Step 3: Search for an edge with the orient option: + for _, a in ipairs(graph.arcs) do + if a:options("orient",true) then + return LayoutPipeline.orientTwoNodes(graph, a.tail, a.head, a:options("orient")/360*2*math.pi, false) + end + if a:options("orient'",true) then + return LayoutPipeline.orientTwoNodes(graph, a.tail, a.head, a:options("orient'")/360*2*math.pi, true) + end + end + + -- Step 4: Search two nodes with a desired at option: + local first, second, third + + for _, v in ipairs(graph.vertices) do + if v.options['desired at'] then + if first then + if second then + third = v + break + else + second = v + end + else + first = v + end + end + end + + if second then + local a = first.options['desired at'] + local b = second.options['desired at'] + return LayoutPipeline.orientTwoNodes(graph, first, second, math.atan2(b.y-a.y,b.x-a.x), false) + end + + -- Computed during preprocessing: + if rotation_info.from_node and postconditions.fixed ~= true then + local x = rotation_info.from_node.pos.x + local y = rotation_info.from_node.pos.y + local from_angle = rotation_info.from_angle or math.atan2(rotation_info.to_node.pos.y - y, rotation_info.to_node.pos.x - x) + + LayoutPipeline.rotateGraphAround(graph, x, y, from_angle, rotation_info.to_angle, rotation_info.swap) + end +end + + + + +--- +-- This internal function is called to decompose a graph into its +-- components. Whether or not this function is called depends on +-- whether the precondition |connected| is set for the algorithm class +-- and whether the |componentwise| key is used. +-- +-- @param graph A to-be-decomposed graph +-- +-- @return An array of graph objects that represent the connected components of the graph. + +function LayoutPipeline.decompose (digraph) + + -- The list of connected components (node sets) + local components = {} + + -- Remember, which graphs have already been visited + local visited = {} + + for _,v in ipairs(digraph.vertices) do + if not visited[v] then + -- Start a depth-first-search of the graph, starting at node n: + local stack = { v } + local component = Digraph.new { + syntactic_digraph = digraph.syntactic_digraph, + options = digraph.options + } + + while #stack >= 1 do + local tos = stack[#stack] + stack[#stack] = nil -- pop + + if not visited[tos] then + + -- Visit pos: + component:add { tos } + visited[tos] = true + + -- Push all unvisited neighbors: + for _,a in ipairs(digraph:incoming(tos)) do + local neighbor = a.tail + if not visited[neighbor] then + stack[#stack+1] = neighbor -- push + end + end + for _,a in ipairs(digraph:outgoing(tos)) do + local neighbor = a.head + if not visited[neighbor] then + stack[#stack+1] = neighbor -- push + end + end + end + end + + -- Ok, vertices will now contain all vertices reachable from n. + components[#components+1] = component + end + end + + if #components < 2 then + return { digraph } + end + + for _,c in ipairs(components) do + table.sort (c.vertices, function (u,v) return u.event.index < v.event.index end) + for _,v in ipairs(c.vertices) do + for _,a in ipairs(digraph:outgoing(v)) do + local new_a = c:connect(a.tail, a.head) + new_a.syntactic_edges = a.syntactic_edges + end + for _,a in ipairs(digraph:incoming(v)) do + local new_a = c:connect(a.tail, a.head) + new_a.syntactic_edges = a.syntactic_edges + end + end + end + + return components +end + + + + +-- Handling of component order +-- +-- LayoutPipeline are ordered according to a function that is stored in +-- a key of the |LayoutPipeline.component_ordering_functions| table +-- whose name is the graph option |component order|. +-- +-- @param component_order An ordering method +-- @param subgraphs A list of to-be-sorted subgraphs + +function LayoutPipeline.sortComponents(component_order, subgraphs) + if component_order then + local f = LayoutPipeline.component_ordering_functions[component_order] + if f then + table.sort (subgraphs, f) + end + end +end + + +-- Right now, we hardcode the functions here. Perhaps make this +-- dynamic in the future. Could easily be done on the tikzlayer, +-- acutally. + +LayoutPipeline.component_ordering_functions = { + ["increasing node number"] = + function (g,h) + if #g.vertices == #h.vertices then + return g.vertices[1].event.index < h.vertices[1].event.index + else + return #g.vertices < #h.vertices + end + end, + ["decreasing node number"] = + function (g,h) + if #g.vertices == #h.vertices then + return g.vertices[1].event.index < h.vertices[1].event.index + else + return #g.vertices > #h.vertices + end + end, + ["by first specified node"] = nil, +} + + + + +local function compute_rotated_bb(vertices, angle, sep, bb) + + local r = Transform.new_rotation(-angle) + + for _,v in ipairs(vertices) do + -- Find the rotated bounding box field, + local t = Transform.concat(r,Transform.new_shift(v.pos.x, v.pos.y)) + + local min_x = math.huge + local max_x = -math.huge + local min_y = math.huge + local max_y = -math.huge + + for _,e in ipairs(v.path) do + if type(e) == "table" then + local c = e:clone() + c:apply(t) + + min_x = math.min (min_x, c.x) + max_x = math.max (max_x, c.x) + min_y = math.min (min_y, c.y) + max_y = math.max (max_y, c.y) + end + end + + -- Enlarge by sep: + min_x = min_x - sep + max_x = max_x + sep + min_y = min_y - sep + max_y = max_y + sep + + local _,_,_,_,c_x,c_y = v:boundingBox() + local center = Coordinate.new(c_x,c_y) + + center:apply(t) + + bb[v].min_x = min_x + bb[v].max_x = max_x + bb[v].min_y = min_y + bb[v].max_y = max_y + bb[v].c_y = center.y + end +end + + + +--- +-- This internal function packs the components of a graph. See +-- Section~\ref{subsection-gd-component-packing} for details. +-- +-- @param graph The graph +-- @param components A list of components + +function LayoutPipeline.packComponents(syntactic_digraph, components) + + local vertices = Storage.newTableStorage() + local bb = Storage.newTableStorage() + + -- Step 1: Preparation, rotation to target direction + local sep = syntactic_digraph.options['component sep'] + local angle = syntactic_digraph.options['component direction']/180*math.pi + + local mark = {} + for _,c in ipairs(components) do + + -- Setup the lists of to-be-considered nodes + local vs = {} + for _,v in ipairs(c.vertices) do + vs [#vs + 1] = v + end + + for _,a in ipairs(c.arcs) do + for _,p in ipairs(a:pointCloud()) do + vs [#vs + 1] = Vertex.new { pos = p } + end + end + vertices[c] = vs + + compute_rotated_bb(vs, angle, sep/2, bb) + end + + local x_shifts = { 0 } + local y_shifts = {} + + -- Step 2: Vertical alignment + for i,c in ipairs(components) do + local max_max_y = -math.huge + local max_center_y = -math.huge + local min_min_y = math.huge + local min_center_y = math.huge + + for _,v in ipairs(c.vertices) do + local info = bb[v] + max_max_y = math.max(info.max_y, max_max_y) + max_center_y = math.max(info.c_y, max_center_y) + min_min_y = math.min(info.min_y, min_min_y) + min_center_y = math.min(info.c_y, min_center_y) + end + + -- Compute alignment line + local valign = syntactic_digraph.options['component align'] + local line + if valign == "counterclockwise bounding box" then + line = max_max_y + elseif valign == "counterclockwise" then + line = max_center_y + elseif valign == "center" then + line = (max_max_y + min_min_y) / 2 + elseif valign == "clockwise" then + line = min_center_y + elseif valign == "first node" then + line = bb[c.vertices[1]].c_y + else + line = min_min_y + end + + -- Overruled? + for _,v in ipairs(c.vertices) do + if v.options['align here'] then + line = bb[v].c_y + break + end + end + + -- Ok, go! + y_shifts[i] = -line + + -- Adjust nodes: + for _,v in ipairs(vertices[c]) do + local info = bb[v] + info.min_y = info.min_y - line + info.max_y = info.max_y - line + info.c_y = info.c_y - line + end + end + + -- Step 3: Horizontal alignment + local y_values = {} + + for _,c in ipairs(components) do + for _,v in ipairs(vertices[c]) do + local info = bb[v] + y_values[#y_values+1] = info.min_y + y_values[#y_values+1] = info.max_y + y_values[#y_values+1] = info.c_y + end + end + + table.sort(y_values) + + local y_ranks = {} + local right_face = {} + for i=1,#y_values do + y_ranks[y_values[i]] = i + right_face[i] = -math.huge + end + + + + for i=1,#components-1 do + -- First, update right_face: + local touched = {} + + for _,v in ipairs(vertices[components[i]]) do + local info = bb[v] + local border = info.max_x + + for i=y_ranks[info.min_y],y_ranks[info.max_y] do + touched[i] = true + right_face[i] = math.max(right_face[i], border) + end + end + + -- Fill up the untouched entries: + local right_max = -math.huge + for i=1,#y_values do + if not touched[i] then + -- Search for next and previous touched + local interpolate = -math.huge + for j=i+1,#y_values do + if touched[j] then + interpolate = math.max(interpolate,right_face[j] - (y_values[j] - y_values[i])) + break + end + end + for j=i-1,1,-1 do + if touched[j] then + interpolate = math.max(interpolate,right_face[j] - (y_values[i] - y_values[j])) + break + end + end + right_face[i] = math.max(interpolate,right_face[i]) + end + right_max = math.max(right_max, right_face[i]) + end + + -- Second, compute the left face + local touched = {} + local left_face = {} + for i=1,#y_values do + left_face[i] = math.huge + end + for _,v in ipairs(vertices[components[i+1]]) do + local info = bb[v] + local border = info.min_x + + for i=y_ranks[info.min_y],y_ranks[info.max_y] do + touched[i] = true + left_face[i] = math.min(left_face[i], border) + end + end + + -- Fill up the untouched entries: + local left_min = math.huge + for i=1,#y_values do + if not touched[i] then + -- Search for next and previous touched + local interpolate = math.huge + for j=i+1,#y_values do + if touched[j] then + interpolate = math.min(interpolate,left_face[j] + (y_values[j] - y_values[i])) + break + end + end + for j=i-1,1,-1 do + if touched[j] then + interpolate = math.min(interpolate,left_face[j] + (y_values[i] - y_values[j])) + break + end + end + left_face[i] = interpolate + end + left_min = math.min(left_min, left_face[i]) + end + + -- Now, compute the shift. + local shift = -math.huge + + if syntactic_digraph.options['component packing'] == "rectangular" then + shift = right_max - left_min + else + for i=1,#y_values do + shift = math.max(shift, right_face[i] - left_face[i]) + end + end + + -- Adjust nodes: + x_shifts[i+1] = shift + for _,v in ipairs(vertices[components[i+1]]) do + local info = bb[v] + info.min_x = info.min_x + shift + info.max_x = info.max_x + shift + end + end + + -- Now, rotate shifts + for i,c in ipairs(components) do + local x = x_shifts[i]*math.cos(angle) - y_shifts[i]*math.sin(angle) + local y = x_shifts[i]*math.sin(angle) + y_shifts[i]*math.cos(angle) + + for _,v in ipairs(vertices[c]) do + v.pos.x = v.pos.x + x + v.pos.y = v.pos.y + y + end + end +end + + + + + + + +-- +-- Store for each begin/end event the index of +-- its corresponding end/begin event +-- +-- @param events An event list + +prepare_events = + function (events) + local stack = {} + + for i=1,#events do + if events[i].kind == "begin" then + stack[#stack + 1] = i + elseif events[i].kind == "end" then + local tos = stack[#stack] + stack[#stack] = nil -- pop + + events[tos].end_index = i + events[i].begin_index = tos + end + end + end + + + +--- +-- Cut the edges. This function handles the ``cutting'' of edges. The +-- idea is that every edge is a path going from the center of the from +-- node to the center of the target node. Now, we intersect this path +-- with the path of the start node and cut away everything before this +-- intersection. Likewise, we intersect the path with the head node +-- and, again, cut away everything following the intersection. +-- +-- These cuttings are not done if appropriate options are set. + +function LayoutPipeline.cutEdges(graph) + + for _,a in ipairs(graph.arcs) do + for _,e in ipairs(a.syntactic_edges) do + local p = e.path + p:makeRigid() + local orig = p:clone() + + if e.options['tail cut'] and e.tail.options['cut policy'] == "as edge requests" + or e.tail.options['cut policy'] == "all" then + + local vpath = e.tail.path:clone() + vpath:shiftByCoordinate(e.tail.pos) + + local x = p:intersectionsWith (vpath) + + if #x > 0 then + p:cutAtBeginning(x[1].index, x[1].time) + end + end + + if e.options['head cut'] and e.head.options['cut policy'] == "as edge requests" + or e.head.options['cut policy'] == "all" then + + local vpath = e.head.path:clone() + vpath:shiftByCoordinate(e.head.pos) + x = p:intersectionsWith (vpath) + if #x > 0 then + p:cutAtEnd(x[#x].index, x[#x].time) + else + -- Check whether there was an intersection with the original + --path: + local x2 = orig:intersectionsWith (vpath) + if #x2 > 0 then + -- Ok, after cutting the tail vertex, there is no longer + -- an intersection with the head vertex, but there used to + -- be one. This means that the vertices overlap and the + -- path should be ``inside'' them. Hmm... + if e.options['allow inside edges'] and #p > 1 then + local from = p[2] + local to = x2[1].point + p:clear() + p:appendMoveto(from) + p:appendLineto(to) + else + p:clear() + end + end + end + end + end + end +end + + + + + + +-- Deprecated stuff + +local Node = require "pgf.gd.deprecated.Node" +local Graph = require "pgf.gd.deprecated.Graph" +local Edge = require "pgf.gd.deprecated.Edge" +local Cluster = require "pgf.gd.deprecated.Cluster" + + + + + +local unique_count = 0 + +local function compatibility_digraph_to_graph(scope, g) + local graph = Graph.new() + + -- Graph options + graph.options = g.options + graph.orig_digraph = g + + -- Events + for i,e in ipairs(scope.events) do + graph.events[i] = e + end + + -- Nodes + for _,v in ipairs(g.vertices) do + if not v.name then + -- compat needs unique name + v.name = "auto generated node nameINTERNAL" .. unique_count + unique_count = unique_count + 1 + end + local minX, minY, maxX, maxY = v:boundingBox() + local node = Node.new{ + name = v.name, + tex = { + tex_node = v.tex and v.tex.stored_tex_box_number, + shape = v.shape, + minX = minX, + maxX = maxX, + minY = minY, + maxY = maxY, + }, + options = v.options, + event_index = v.event.index, + index = v.event.index, + orig_vertex = v, + } + graph:addNode(node) + graph.events[v.event.index or (#graph.events+1)] = { kind = 'node', parameters = node } + end + + -- Edges + local mark = Storage.new() + for _,a in ipairs(g.arcs) do + local da = g.syntactic_digraph:arc(a.tail, a.head) + if da then + for _,m in ipairs(da.syntactic_edges) do + if not mark[m] then + mark[m] = true + local from_node = graph:findNode(da.tail.name) + local to_node = graph:findNode(da.head.name) + local edge = graph:createEdge(from_node, to_node, m.direction, nil, m.options, nil) + edge.event_index = m.event.index + edge.orig_m = m + graph.events[m.event.index] = { kind = 'edge', parameters = edge } + end + end + end + local da = g.syntactic_digraph:arc(a.head, a.tail) + if da then + for _,m in ipairs(da.syntactic_edges) do + if not mark[m] then + mark[m] = true + local from_node = graph:findNode(da.tail.name) + local to_node = graph:findNode(da.head.name) + local edge = graph:createEdge(from_node, to_node, m.direction, nil, m.options, nil) + edge.event_index = m.event.index + edge.orig_m = m + graph.events[m.event.index] = { kind = 'edge', parameters = edge } + end + end + end + end + + table.sort(graph.edges, function(e1,e2) return e1.event_index < e2.event_index end) + for _,n in ipairs (graph.nodes) do + table.sort(n.edges, function(e1,e2) return e1.event_index < e2.event_index end) + end + + + -- Clusters + for _, c in ipairs(scope.collections['same layer'] or {}) do + cluster = Cluster.new("cluster" .. unique_count) + unique_count = unique_count+1 + graph:addCluster(cluster) + for _,v in ipairs(c.vertices) do + if g:contains(v) then + cluster:addNode(graph:findNode(v.name)) + end + end + end + + return graph +end + + +local function compatibility_graph_to_digraph(graph) + for _,n in ipairs(graph.nodes) do + n.orig_vertex.pos.x = n.pos.x + n.orig_vertex.pos.y = n.pos.y + end + for _,e in ipairs(graph.edges) do + if #e.bend_points > 0 then + local c = {} + for _,x in ipairs(e.bend_points) do + c[#c+1] = Coordinate.new (x.x, x.y) + end + e.orig_m:setPolylinePath(c) + end + end +end + + + + + +function LayoutPipeline.runOldGraphModel(scope, digraph, algorithm_class, algorithm) + + local graph = compatibility_digraph_to_graph(scope, digraph) + + algorithm.graph = graph + graph:registerAlgorithm(algorithm) + + -- If requested, remove loops + if algorithm_class.preconditions.loop_free then + Simplifiers:removeLoopsOldModel(algorithm) + end + + -- If requested, collapse multiedges + if algorithm_class.preconditions.simple then + Simplifiers:collapseMultiedgesOldModel(algorithm) + end + + if #graph.nodes > 1 then + -- Main run of the algorithm: + algorithm:run () + end + + -- If requested, expand multiedges + if algorithm_class.preconditions.simple then + Simplifiers:expandMultiedgesOldModel(algorithm) + end + + -- If requested, restore loops + if algorithm_class.preconditions.loop_free then + Simplifiers:restoreLoopsOldModel(algorithm) + end + + compatibility_graph_to_digraph(graph) +end + + + + +-- Done + +return LayoutPipeline \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua new file mode 100644 index 00000000000..b159f21eef2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua @@ -0,0 +1,174 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/NodeAnchors.lua,v 1.3 2013/10/08 09:21:17 tantau Exp $ + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + + +--- +-- @section subsection {Anchoring Edges} +-- +-- \label{section-gd-anchors} +-- +-- When a graph has been layed out completely, the edges between the +-- nodes must be drawn. Conceptually, an edge is ``between two +-- nodes,'' but when we actually draw the node, we do not really want +-- the edge's path to start ``in the middle'' of the node; rather, we +-- want it to start ``on the border'' and also end there. +-- +-- Normally, computing such border positions for nodes is something we +-- would leave to the so-called display layer (which is typically +-- \tikzname\ and \tikzname\ is reasonably good at computing border +-- positions). However, different display layers may behave +-- differently here and even \tikzname\ fails when the node shapes are +-- very involved and the paths also. +-- +-- For these reasons, computing the anchor positions where edges start +-- and end is done inside the graph drawing system. As a user, you +-- specify a |tail anchor| and a |head anchor|, which are points +-- inside the tail and head nodes, respectively. The edge path will +-- then start and end at these points, however, they will usually be +-- shortened so that they actually start and end on the intersection +-- of the edge's path with the nodes' paths. + + +--- + +declare { + key = "tail anchor", + type = "string", + initial = "", + + summary = [[" + Specifies where in the tail vertex the edge should start. + "]], + + documentation = [[" + This is either a string or a number, interpreted as an angle + (with 90 meaning ``up''). If it is a string, when the start of + the edge is computed, we try to look up the anchor in the tail + vertex's table of anchors (some anchors get installed in this + table by the display system). If it is not found, we test + whether it is one of the special ``direction anchors'' like + |north| or |south east|. If so, we convert them into points on + the border of the node that lie in the direction of a line + starting at the center to a point on the bounding box of the + node in the designated direction. Finally, if the anchor is a + number, we use a point on the border of the node that is on a + line from the center in the specified direction. + + If the anchor is set to the empty string (which is the default), + the anchor is interpreted as the |center| anchor inside the + graph drawing system. However, a display system may choose to + make a difference between the |center| anchor and an empty + anchor (\tikzname\ does: for options like |bend left| if the + anchor is empty, the bend line starts at the border of the node, + while for the anchor set explicitly to |center| it starts at the + center). + + Note that graph drawing algorithms need not take the + setting of this option into consideration. However, the final + rendering of the edge will always take it into consideration + (only, the setting may not be very sensible if the algorithm + ignored it). + "]] +} + +--- + +declare { + key = "head anchor", + type = "string", + initial = "", + + summary = "See |tail anchor|" +} + + +--- + +declare { + key = "tail cut", + type = "boolean", + initial = true, + + summary = [[" + Decides whether the tail of an edge is ``cut'', meaning + that the edge's path will be shortened at the beginning so that + it starts only of the node's border rather than at the exact + position of the |tail anchor|, which may be inside the node. + "]] +} + + +--- + +declare { + key = "head cut", + type = "boolean", + initial = true, + + summary = "See |tail cut|." +} + + +--- + +declare { + key = "cut policy", + type = "string", + initial = "as edge requests", + + summary = "The policy for cutting edges entering or leaving a node.", + + documentation = [[" + This option is important for nodes only. It can have three + possible values: + \begin{itemize} + \item |as edge requests| Whether or not an edge entering or + leaving the node is cut depends on the setting of the edge's + |tail cut| and |head cut| options. This is the default. + \item |all| All edges entering or leaving the node are cut, + regardless of the edges' cut values. + \item |none| No edge entering or leaving the node is cut, + regardless of the edges' cut values. + \end{itemize} + "]] +} + + +--- +declare { + key = "allow inside edges", + type = "boolean", + initial = "true", + + summary = "Decides whether an edge between overlapping nodes should be drawn.", + + documentation = [[" + If two vertices overlap, it may happen that when you draw an + edge between them, this edges would be completely inside the two + vertices. In this case, one could either not draw them or one + could draw a sort of ``inside edge''. + "]], + + examples = { [[" + \tikz \graph [no layout, nodes={draw, minimum size=20pt}] { + a [x=0, y=0] -- b [x=15pt, y=10pt] -- c[x=40pt] + }; + "]], [[" + \tikz \graph [no layout, nodes={draw, minimum size=20pt}, + allow inside edges=false] { + a [x=0, y=0] -- b [x=15pt, y=10pt] -- c[x=40pt] + }; + "]] + } +} \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua new file mode 100644 index 00000000000..a3205a06dbe --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua @@ -0,0 +1,314 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/Orientation.lua,v 1.2 2013/05/23 20:01:26 tantau Exp $ + + + + +--- +-- @section subsection {Orienting a Graph} +-- +-- \label{subsection-library-graphdrawing-standard-orientation} +-- +-- Just as a graph drawing algorithm cannot know \emph{where} a graph +-- should be placed on a page, it is also often unclear which +-- \emph{orientation} it should have. Some graphs, like trees, have a +-- natural direction in which they ``grow'', but for an ``arbitrary'' +-- graph the ``natural orientation'' is, well, arbitrary. +-- +-- There are two ways in which you can specify an orientation: First, +-- you can specify that the line from a certain vertex to another +-- vertex should have a certain slope. How these vertices and slopes +-- are specified in explained momentarily. Second, you can specify a +-- so-called ``growth direction'' for trees. +-- +-- @end + + +-- Namespace +require("pgf.gd.control").Orientation = Orientation + + + +-- Imports +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- + +declare { + key = "orient", + type = "direction", + default = 0, + + summary = [[" + This key specifies that the straight line from the |orient tail| to + the |orient head| should be at an angle of \meta{direction} relative to + the right-going $x$-axis. Which vertices are used as tail an head + depends on where the |orient| option is encountered: When used with + an edge, the tail is the edge's tail und the head is the edge's + head. When used with a node, the tail or the head must be specified + explicitly and the node is used as the node missing in the + specification. When used with a graph as a whole, both the head and + tail nodes must be specified explicitly. + "]], + documentation = [[" + Note that the \meta{direction} is independent of the actual to-path + of an edge, which might define a bend or more complicated shapes. For + instance, a \meta{angle} of |45| requests that the end node is ``up + and right'' relative to the start node. + + You can also specify the standard direction texts |north| or |south east| + and so forth as \meta{direction} and also |up|, |down|, |left|, and |right|. Also, you + can specify |-| for ``right'' and \verb!|! for ``down.'' + "]], + examples = { + [[" + \tikz \graph [spring layout] + { + a -- { b, c, d, e -- {f, g, h} }; + h -- [orient=30] a; + }; + "]], + [[" + \tikz \graph [spring layout] + { + a -- { b, c, d[> orient=right], e -- {f, g, h} }; + h -- a; + }; + "]] + } +} + + +--- + +declare { + key = "orient'", + type = "direction", + default = 0, + + summary = [[" + Same as |orient|, only the rest of the graph should be + flipped relative to the connection line. + "]], + examples = [[" + \tikz \graph [spring layout] + { + a -- { b, c, d[> orient'=right], e -- {f, g, h} }; + h -- a; + }; + "]] +} + +--- + +declare { + key = "orient tail", + type = "string", + + summary = [[" + Specifies the tail vertex for the orientation of a graph. See + |orient| for details. + "]], + examples = { + [[" + \tikz \graph [spring layout] { + a [orient=|, orient tail=f] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz \graph [spring layout] { + a [orient=down, orient tail=h] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]] + } +} + + + + + +--- + +declare { + key = "orient head", + type = "string", + + summary = [[" + Specifies the head vertex for the orientation of a graph. See + |orient| for details. + "]], + examples = { + [[" + \tikz \graph [spring layout] + { + a [orient=|, orient head=f] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz \graph [spring layout] { a -- b -- c -- a }; + \tikz \graph [spring layout, orient=10, + orient tail=a, orient head=b] { a -- b -- c -- a }; + "]] + } +} + +--- + +declare { + key = "horizontal", + type = "string", + + summary = [[" + A shorthand for specifying |orient tail|, |orient head| and + |orient=0|. The tail will be everything before the part ``| to |'' + and the head will be everything following it. + "]], + examples = [[" + \tikz \graph [spring layout] { a -- b -- c -- a }; + \tikz \graph [spring layout, horizontal=a to b] { a -- b -- c -- a }; + "]] +} + + + + +--- + +declare { + key = "horizontal'", + type = "string", + + summary = [[" + Like |horizontal|, but with a flip. + "]] +} + + + + + + + +--- + +declare { + key = "vertical", + type = "string", + + summary = [[" + A shorthand for specifying |orient tail|, |orient head| and + |orient=-90|. + "]], + examples = [[" + \tikz \graph [spring layout] { a -- b -- c -- a }; + \tikz \graph [spring layout, vertical=a to b] { a -- b -- c -- a }; + "]] +} + + + + + +--- + +declare { + key = "vertical'", + type = "string", + + summary = [[" + Like |vertical|, but with a flip. + "]] +} + + + +--- + +declare { + key = "grow", + type = "direction", + + summary = [[" + This key specifies in which direction the neighbors of a node + ``should grow.'' For some graph drawing algorithms, especially for + those that layout trees, but also for those that produce layered + layouts, there is a natural direction in which the ``children'' of + a node should be placed. For instance, saying |grow=down| will cause + the children of a node in a tree to be placed in a left-to-right + line below the node (as always, you can replace the \meta{angle} + by direction texts). The children are requested to be placed in a + counter-clockwise fashion, the |grow'| key will place them in a + clockwise fashion. + "]], + documentation = [[" + Note that when you say |grow=down|, it is not necessarily the case + that any particular node is actually directly below the current + node; the key just requests that the direction of growth is + downward. + + In principle, you can specify the direction of growth for each node + individually, but do not count on graph drawing algorithms to + honour these wishes. + + When you give the |grow=right| key to the graph as a whole, it will + be applied to all nodes. This happens to be exactly what you want: + "]], + examples = { + [[" + \tikz \graph [layered layout, sibling distance=5mm] + { + a [grow=right] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz \graph [layered layout, grow=right, sibling distance=5mm] + { + a -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]], + [[" + \tikz + \graph [layered layout, grow=-80] + { + {a,b,c} --[complete bipartite] {e,d,f} + --[complete bipartite] {g,h,i}; + }; + "]] + } +} + + +--- + +declare { + key = "grow'", + type = "direction", + + summary = "Same as |grow|, only with the children in clockwise order.", + examples = [[" + \tikz \graph [layered layout, sibling distance=5mm] + { + a [grow'=right] -- { b, c, d, e -- {f, g, h} }; + { h, g } -- a; + }; + "]] +} + + +-- Done + +return Orientation \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua new file mode 100644 index 00000000000..c10df7a0696 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua @@ -0,0 +1,536 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/Sublayouts.lua,v 1.4 2013/09/23 20:04:26 tantau Exp $ + +local function full_print(g, pref) + local s = "" + + for _,v in ipairs(g.vertices) do + s = s .. tostring(v) .. "[" .. tostring(v.pos) .. "]\n " + end + + s = s .. "\n" + + for _,a in ipairs(g.arcs) do + for _,e in ipairs(a.syntactic_edges) do + s = s .. tostring(e) .. "(" .. tostring(e.path) .. ")\n" + end + end + + pgf.debug((pref or "") .. s) +end + + +--- +-- The |Sublayouts| module handles graphs for which multiple layouts are defined. +-- +-- Please see Section~\ref{section-gd-sublayouts} for an overview of +-- sublayouts. +-- + +local Sublayouts = {} + +-- Namespace +require("pgf.gd.control").Sublayouts = Sublayouts + + +-- Includes + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Coordinate = require "pgf.gd.model.Coordinate" +local Path = require "pgf.gd.model.Path" + +local lib = require "pgf.gd.lib" + +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" + +local Storage = require "pgf.gd.lib.Storage" + + + +-- Storages + +local subs = Storage.newTableStorage() +local already_nudged = Storage.new() +local positions = Storage.newTableStorage() + + + + +-- Offset a node by an offset. This will \emph{also} offset all +-- subnodes, which arise from sublayouts. +-- +-- @param vertex A vertex +-- @param pos A offset +-- +local function offset_vertex(v, delta) + v.pos:shiftByCoordinate(delta) + for _,sub in ipairs(subs[v]) do + offset_vertex(sub, delta) + end +end + + +-- Nudge positioning. You can call this function several times on the +-- same graph; nudging will be done only once. +-- +-- @param graph A graph +-- +local function nudge(graph) + for _,v in ipairs(graph.vertices) do + local nudge = v.options['nudge'] + if nudge and not already_nudged[v] then + offset_vertex(v, nudge) + already_nudged[v] = true + end + end +end + + + +-- Create subgraph nodes +-- +-- @param scope A scope +-- @param syntactic_digraph The syntactic digraph. +-- @param test Only for vertices whose subgraph collection passes this test will we create subgraph nodes +local function create_subgraph_node(scope, syntactic_digraph, vertex) + + local subgraph_collection = vertex.subgraph_collection + local binding = InterfaceCore.binding + + local cloud = {} + -- Add all points of n's collection, except for v itself, to the cloud: + for _,v in ipairs(subgraph_collection.vertices) do + if vertex ~= v then + assert(syntactic_digraph:contains(v), "the layout must contain all nodes of the subgraph") + for _,p in ipairs(v.path) do + if type(p) == "table" then + cloud[#cloud+1] = p + v.pos + end + end + end + end + for _,e in ipairs(subgraph_collection.edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + cloud[#cloud+1] = p:clone() + end + end + end + local x_min, y_min, x_max, y_max, c_x, c_y = Coordinate.boundingBox(cloud) + + -- Shift the graph so that it is centered on the origin: + for _,p in ipairs(cloud) do + p:unshift(c_x,c_y) + end + + local o = vertex.subgraph_info.generated_options + + o[#o+1] = { key = "subgraph point cloud", value = table.concat(lib.imap(cloud, tostring)) } + o[#o+1] = { key = "subgraph bounding box height", value = tostring(y_max-y_min) .. "pt" } + o[#o+1] = { key = "subgraph bounding box width", value = tostring(x_max-x_min) .. "pt" } + + -- And now, the "grand call": + binding:createVertex(vertex.subgraph_info) + + -- Shift it were it belongs + vertex.pos:shift(c_x,c_y) + + -- Remember all the subnodes for nudging and regardless + -- positioning + local s = {} + for _,v in ipairs(subgraph_collection.vertices) do + if v ~= vertex then + s[#s+1] = v + end + end + + subs[vertex] = s +end + + +-- Tests whether two graphs have a vertex in common +local function intersection(g1, g2) + for _,v in ipairs(g1.vertices) do + if g2:contains(v) then + return v + end + end +end + +-- Tests whether a graph is a set is a subset of another +local function special_vertex_subset(vertices, graph) + for _,v in ipairs(vertices) do + if not graph:contains(v) and not (v.kind == "subgraph node") then + return false + end + end + return true +end + + + +--- +-- The layout recursion. See \ref{section-gd-sublayouts} for details. +-- +-- @param scope The graph drawing scope +-- @param layout The to-be-laid-out collection +-- @param fun The to-be-called function for laying out the graph. +-- processed. This stack is important when a new syntactic vertex is +-- added by the algorithm: In this case, this vertex is added to all +-- layouts on this stack. +-- +-- @return A laid out graph. + +function Sublayouts.layoutRecursively(scope, layout, fun) + + -- Step 1: Iterate over all sublayouts of the current layout: + local resulting_graphs = {} + local loc = Storage.new() + + -- Now, iterate over all sublayouts + for i,child in ipairs(layout:childrenOfKind(InterfaceCore.sublayout_kind)) do + resulting_graphs[i] = Sublayouts.layoutRecursively(scope, child, fun) + loc[resulting_graphs[i]] = child + end + + -- Step 2: Run the merge process: + local merged_graphs = {} + + while #resulting_graphs > 0 do + + local n = #resulting_graphs + + -- Setup marked array: + local marked = {} + for i=1,n do + marked[i] = false + end + + -- Mark first graph and copy everything from there + marked[1] = true + local touched = Storage.new() + for _,v in ipairs(resulting_graphs[1].vertices) do + v.pos = positions[v][resulting_graphs[1]] + touched[v] = true + end + + -- Repeatedly find a node that is connected to a marked node: + local i = 1 + while i <= n do + if not marked[i] then + for j=1,n do + if marked[j] then + local v = intersection(resulting_graphs[i], resulting_graphs[j]) + if v then + -- Aha, they intersect at vertex v + + -- Mark the i-th graph: + marked[i] = true + connected_some_graph = true + + -- Shift the i-th graph: + local x_offset = v.pos.x - positions[v][resulting_graphs[i]].x + local y_offset = v.pos.y - positions[v][resulting_graphs[i]].y + + for _,u in ipairs(resulting_graphs[i].vertices) do + if not touched[u] then + touched[u] = true + u.pos = positions[u][resulting_graphs[i]]:clone() + u.pos:shift(x_offset, y_offset) + + for _,a in ipairs(resulting_graphs[i]:outgoing(u)) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:shift(x_offset, y_offset) + end + end + end + end + end + end + + -- Restart + i = 0 + break + end + end + end + end + i = i + 1 + end + + -- Now, we can collapse all marked graphs into one graph: + local merge = Digraph.new {} + merge.syntactic_digraph = merge + local remaining = {} + + -- Add all vertices and edges: + for i=1,n do + if marked[i] then + merge:add (resulting_graphs[i].vertices) + for _,a in ipairs(resulting_graphs[i].arcs) do + local ma = merge:connect(a.tail,a.head) + for _,e in ipairs(a.syntactic_edges) do + ma.syntactic_edges[#ma.syntactic_edges+1] = e + end + end + else + remaining[#remaining + 1] = resulting_graphs[i] + end + end + + -- Remember the first layout this came from: + loc[merge] = loc[resulting_graphs[1]] + + -- Restart with rest: + merged_graphs[#merged_graphs+1] = merge + + resulting_graphs = remaining + end + + -- Step 3: Run the algorithm on the layout: + + local class = layout.options.algorithm_phases.main + assert (type(class) == "table", "algorithm selection failed") + + local algorithm = class + local uncollapsed_subgraph_nodes = lib.imap( + scope.collections[InterfaceCore.subgraph_node_kind] or {}, + function (c) + if c.parent_layout == layout then + return c.subgraph_node + end + end) + + + -- Create a new syntactic digraph: + local syntactic_digraph = Digraph.new { + options = layout.options + } + + syntactic_digraph.syntactic_digraph = syntactic_digraph + + -- Copy all vertices and edges from the collection... + syntactic_digraph:add (layout.vertices) + for _,e in ipairs(layout.edges) do + syntactic_digraph:add {e.head, e.tail} + local arc = syntactic_digraph:connect(e.tail, e.head) + arc.syntactic_edges[#arc.syntactic_edges+1] = e + end + + -- Find out which subgraph nodes can be created now and make them part of the merged graphs + for i=#uncollapsed_subgraph_nodes,1,-1 do + local v = uncollapsed_subgraph_nodes[i] + local vertices = v.subgraph_collection.vertices + -- Test, if all vertices of the subgraph are in one of the merged graphs. + for _,g in ipairs(merged_graphs) do + if special_vertex_subset(vertices, g) then + -- Ok, we can create a subgraph now + create_subgraph_node(scope, syntactic_digraph, v) + -- Make it part of the collapse! + g:add{v} + -- Do not consider again + uncollapsed_subgraph_nodes[i] = false + break + end + end + end + + -- Collapse the nodes that are part of a merged_graph + local collapsed_vertices = {} + for _,g in ipairs(merged_graphs) do + + local intersection = {} + for _,v in ipairs(g.vertices) do + if syntactic_digraph:contains(v) then + intersection[#intersection+1] = v + end + end + if #intersection > 0 then + -- Compute bounding box of g (this should actually be the convex + -- hull) Hmm...: + local array = {} + for _,v in ipairs(g.vertices) do + local min_x, min_y, max_x, max_y = v:boundingBox() + array[#array+1] = Coordinate.new(min_x + v.pos.x, min_y + v.pos.y) + array[#array+1] = Coordinate.new(max_x + v.pos.x, max_y + v.pos.y) + end + for _,a in ipairs(g.arcs) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + array[#array+1] = p + end + end + end + end + local x_min, y_min, x_max, y_max, c_x, c_y = Coordinate.boundingBox(array) + + -- Shift the graph so that it is centered on the origin: + for _,v in ipairs(g.vertices) do + v.pos:unshift(c_x,c_y) + end + for _,a in ipairs(g.arcs) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:unshift(c_x,c_y) + end + end + end + end + + x_min = x_min - c_x + x_max = x_max - c_x + y_min = y_min - c_y + y_max = y_max - c_y + + local index = loc[g].event.index + + local v = Vertex.new { + -- Standard stuff + shape = "none", + kind = "node", + path = Path.new { + "moveto", + x_min, y_min, + x_min, y_max, + x_max, y_max, + x_max, y_min, + "closepath" + }, + options = {}, + event = scope.events[index] + } + + -- Update node_event + scope.events[index].parameters = v + + local collapse_vertex = syntactic_digraph:collapse( + intersection, + v, + nil, + function (new_arc, arc) + for _,e in ipairs(arc.syntactic_edges) do + new_arc.syntactic_edges[#new_arc.syntactic_edges+1] = e + end + end) + + syntactic_digraph:remove(intersection) + collapsed_vertices[#collapsed_vertices+1] = collapse_vertex + end + end + + -- Sort the vertices + table.sort(syntactic_digraph.vertices, function(u,v) return u.event.index < v.event.index end) + + -- Should we "hide" the subgraph nodes? + local hidden_node + if not algorithm.include_subgraph_nodes then + local subgraph_nodes = lib.imap (syntactic_digraph.vertices, + function (v) if v.kind == "subgraph node" then return v end end) + + if #subgraph_nodes > 0 then + hidden_node = Vertex.new {} + syntactic_digraph:collapse(subgraph_nodes, hidden_node) + syntactic_digraph:remove (subgraph_nodes) + syntactic_digraph:remove {hidden_node} + end + end + + -- Now, we want to call the actual algorithm. This call may modify + -- the layout's vertices and edges fields, namely when new vertices + -- and edges are created. We then need to add these to our local + -- syntactic digraph. So, we remember the length of these fields + -- prior to the call and then add everything ``behind'' these + -- positions later on. + + -- Ok, everything setup! Run the algorithm... + fun(scope, algorithm, syntactic_digraph, layout) + + if hidden_node then + syntactic_digraph:expand(hidden_node) + end + + -- Now, we need to expand the collapsed vertices once more: + for i=#collapsed_vertices,1,-1 do + syntactic_digraph:expand( + collapsed_vertices[i], + function (c, v) + v.pos:shiftByCoordinate(c.pos) + end, + function (a, v) + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:shiftByCoordinate(v.pos) + end + end + end + end + ) + for _,a in ipairs(syntactic_digraph:outgoing(collapsed_vertices[i])) do + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + p:shiftByCoordinate(a.tail.pos) + p:unshiftByCoordinate(e.tail.pos) + end + end + end + end + end + syntactic_digraph:remove(collapsed_vertices) + + -- Step 4: Create the layout node if necessary + for i=#uncollapsed_subgraph_nodes,1,-1 do + if uncollapsed_subgraph_nodes[i] then + create_subgraph_node(scope, syntactic_digraph, uncollapsed_subgraph_nodes[i]) + end + end + + -- Now seems like a good time to nudge and do regardless positioning + nudge(syntactic_digraph) + + -- Step 5: Cleanup + -- Push the computed position into the storage: + for _,v in ipairs(syntactic_digraph.vertices) do + positions[v][syntactic_digraph] = v.pos:clone() + end + + return syntactic_digraph +end + + + + + +--- +-- Regardless positioning. +-- +-- @param graph A graph +-- +function Sublayouts.regardless(graph) + for _,v in ipairs(graph.vertices) do + local regardless = v.options['regardless at'] + if regardless then + offset_vertex(v, regardless - v.pos) + end + end +end + + + +-- Done + +return Sublayouts \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua new file mode 100644 index 00000000000..fbb3a33857d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua @@ -0,0 +1,199 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/control/library.lua,v 1.9 2013/05/23 20:01:26 tantau Exp $ + + +-- Load declarations from: + +require "pgf.gd.control.FineTune" +require "pgf.gd.control.Anchoring" +require "pgf.gd.control.Sublayouts" +require "pgf.gd.control.Orientation" +require "pgf.gd.control.Distances" +require "pgf.gd.control.Components" +require "pgf.gd.control.ComponentAlign" +require "pgf.gd.control.ComponentDirection" +require "pgf.gd.control.ComponentDistance" +require "pgf.gd.control.ComponentOrder" +require "pgf.gd.control.NodeAnchors" + + +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +local lib = require "pgf.gd.lib" + + + +--- + +declare { + key = "nodes behind edges", + type = "boolean", + + summary = "Specifies, that nodes should be drawn behind the edges", + documentation = [[" + Once a graph drawing algorithm has determined positions for the nodes, + they are drawn \emph{before} the edges are drawn; after + all, it is hard to draw an edge between nodes when their positions + are not yet known. However, we typically want the nodes to be + rendered \emph{after} or rather \emph{on top} of the edges. For + this reason, the default behaviour is that the nodes at their + final positions are collected in a box that is inserted into the + output stream only after the edges have been drawn -- which has + the effect that the nodes will be placed ``on top'' of the + edges. + + This behaviour can be changed using this option. When the key is + invoked, nodes are placed \emph{behind} the edges. + "]], + examples = [[" + \tikz \graph [simple necklace layout, nodes={draw,fill=white}, + nodes behind edges] + { subgraph K_n [n=7], 1 [regardless at={(0,-1)}] }; + "]] +} + + +--- + +declare { + key = "edges behind nodes", + use = { + { key = "nodes behind edges", value = "false" }, + }, + + summary = [[" + This is the default placemenet of edges: Behind the nodes. + "]], + examples = [[" + \tikz \graph [simple necklace layout, nodes={draw,fill=white}, + edges behind nodes] + { subgraph K_n [n=7], 1 [regardless at={(0,-1)}] }; + "]] +} + +--- +declare { + key = "random seed", + type = "number", + initial = "42", + + summary = [[" + To ensure that the same is always shown in the same way when the + same algorithm is applied, the random is seed is reset on each call + of the graph drawing engine. To (possibly) get different results on + different runs, change this value. + "]] +} + + +--- +declare { + key = "variation", + type = "number", + use = { + { key = "random seed", value = lib.id }, + }, + summary = "An alias for |random seed|." +} + + +--- +declare { + key = "weight", + type = "number", + initial = 1, + + summary = [[" + Sets the ``weight'' of an edge or a node. For many algorithms, this + number tells the algorithm how ``important'' the edge or node is. + For instance, in a |layered layout|, an edge with a large |weight| + will be as short as possible. + "]], + examples = { + [[" + \tikz \graph [layered layout] { + a -- {b,c,d} -- e -- a; + }; + "]], + [[" + \tikz \graph [layered layout] { + a -- {b,c,d} -- e --[weight=3] a; + }; + "]] + } +} + + + +--- +declare { + key = "length", + type = "length", + initial = 1, + + summary = [[" + Sets the ``length'' of an edge. Algorithms may take this value + into account when drawing a graph. + "]], + examples = { + [[" + \tikz \graph [phylogenetic tree layout] { + a --[length=2] b --[length=1] {c,d}; + a --[length=3] e + }; + "]], + } +} + + +--- + +declare { + key = "radius", + type = "number", + initial = "0", + + summary = [[" + The radius of a circular object used in graph drawing. + "]] +} + +--- + +declare { + key = "no layout", + algorithm = { + run = + function (self) + for _,v in ipairs(self.digraph.vertices) do + if v.options['desired at'] then + v.pos.x = v.options['desired at'].x + v.pos.y = v.options['desired at'].y + end + end + end }, + summary = "This layout does nothing.", +} + + + +-- The following collection kinds are internal + +declare { + key = InterfaceCore.sublayout_kind, + layer = 0 +} + +declare { + key = InterfaceCore.subgraph_node_kind, + layer = 0 +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua new file mode 100644 index 00000000000..748eee9429a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua @@ -0,0 +1,65 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Cluster.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +--- The Cluser class defines a model of a cluster inside a graph. +-- +-- + +local Cluster = {} +Cluster.__index = Cluster + + +-- Namespace + + + +--- TODO Jannis: Add documentation for this class. +-- +function Cluster.new(name) + local cluster = { + name = name, + nodes = {}, + contains_node = {}, + } + setmetatable(cluster, Cluster) + return cluster +end + + + +function Cluster:getName() + return self.name +end + + + +function Cluster:addNode(node) + if not self:findNode(node) then + self.contains_node[node] = true + self.nodes[#self.nodes + 1] = node + end +end + + + +function Cluster:findNode(node) + return self.contains_node[node] +end + + + + +-- Done + +return Cluster \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua new file mode 100644 index 00000000000..22ba62e04af --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua @@ -0,0 +1,358 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Edge.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + + +--- The Edge class +-- +-- + +local Edge = {} +Edge.__index = Edge + + +-- Namespace + +local lib = require "pgf.gd.lib" + + +-- Definitions + +Edge.UNDIRECTED = "--" +Edge.LEFT = "<-" +Edge.RIGHT = "->" +Edge.BOTH = "<->" +Edge.NONE = "-!-" + + +--- Creates an edge between nodes of a graph. +-- +-- @param values Values to override default edge settings. +-- The following parameters can be set:\par +-- |nodes|: TODO \par +-- |edge_nodes|: TODO \par +-- |options|: TODO \par +-- |tikz_options|: TODO \par +-- |direction|: TODO \par +-- |bend_points|: TODO \par +-- |bend_nodes|: TODO \par +-- |reversed|: TODO \par +-- +-- @return A newly-allocated edge. +-- +function Edge.new(values) + local defaults = { + nodes = {}, + edge_nodes = '', + options = {}, + tikz_options = {}, + direction = Edge.DIRECTED, + bend_points = {}, + bend_nodes = {}, + reversed = false, + algorithmically_generated_options = {}, + index = nil, + event_index = nil, + } + setmetatable(defaults, Edge) + if values then + for k,v in pairs(values) do + defaults[k] = v + end + end + return defaults +end + + + +--- Sets the edge option \meta{name} to \meta{value}. +-- +-- @param name Name of the option to be changed. +-- @param value New value for the edge option \meta{name}. +-- +function Edge:setOption(name, value) + self.options[name] = value +end + + + +--- Returns the value of the edge option \meta{name}. +-- +-- @param name Name of the option. +-- @param graph If this optional argument is given, +-- in case the option is not set as a node parameter, +-- we try to look it up as a graph parameter. +-- +-- @return The value of the edge option \meta{name} or |nil|. +-- +function Edge:getOption(name, graph) + return lib.lookup_option(name, self, graph) +end + + + +--- Checks whether or not the edge is a loop edge. +-- +-- An edge is a loop if it one node multiple times and no other node. +-- +-- @return |true| if the edge is a loop, |false| otherwise. +-- +function Edge:isLoop() + local nodes = self.nodes + for i=1,#nodes do + if nodes[i] ~= nodes[1] then + return false + end + end + return true +end + + + +--- Returns whether or not the edge is a hyperedge. +-- +-- A hyperedge is an edge with more than two adjacent nodes. +-- +-- @return |true| if the edge is a hyperedge. |false| otherwise. +-- +function Edge:isHyperedge() + return self:getDegree() > 2 +end + + + +--- Returns all nodes of the edge. +-- +-- Instead of calling |edge:getNodes()| the nodes can alternatively be +-- accessed directly with |edge.nodes|. +-- +-- @return All edges of the node. +-- +function Edge:getNodes() + return self.nodes +end + + + +--- Returns whether or not a node is adjacent to the edge. +-- +-- @param node The node to check. +-- +-- @return |true| if the node is adjacent to the edge. |false| otherwise. +-- +function Edge:containsNode(node) + return lib.find(self.nodes, function (other) return other == node end) ~= nil +end + + + +--- If possible, adds a node to the edge. +-- +-- @param node The node to be added to the edge. +-- +function Edge:addNode(node) + table.insert(self.nodes, node) + node:addEdge(self) +end + + + +--- Gets first neighbour of the node (disregarding hyperedges). +-- +-- @param node The node which first neighbour should be returned. +-- +-- @return The first neighbour of the node. +-- +function Edge:getNeighbour(node) + if node == self.nodes[1] then + return self.nodes[#self.nodes] + else + return self.nodes[1] + end +end + + + +--- Counts the nodes on this edge. +-- +-- @return The number of nodes on the edge. +-- +function Edge:getDegree() + return #self.nodes +end + + + +function Edge:getHead() + -- by default, the head of -> edges is the last node and the head + -- of <- edges is the first node + local head_index = (self.direction == Edge.LEFT) and 1 or #self.nodes + + -- if the edge should be assumed reversed, we simply switch head and + -- tail positions + if self.reversed then + head_index = (head_index == 1) and #self.nodes or 1 + end + + return self.nodes[head_index] +end + + + +function Edge:getTail() + -- by default, the tail of -> edges is the first node and the tail + -- of <- edges is the last node + local tail_index = (self.direction == Edge.LEFT) and #self.nodes or 1 + + -- if the edge should be assumed reversed, we simply switch head + -- and tail positions + if self.reversed then + tail_index = (tail_index == 1) and #self.nodes or 1 + end + + return self.nodes[tail_index] +end + + + +--- Checks whether a node is the head of the edge. Does not work for hyperedges. +-- +-- This method only works for edges with two adjacent nodes. +-- +-- Edges may be reversed internally, so their head and tail might be switched. +-- Whether or not this internal reversal is handled by this method +-- can be specified with the optional second \meta{ignore\_reversed} parameter +-- which is |false| by default. +-- +-- @param node The node to check. +-- +-- @return True if the node is the head of the edge. +-- +function Edge:isHead(node) + local result = false + + -- by default, the head of -> edges is the last node and the head + -- of <- edges is the first node + local head_index = (self.direction == Edge.LEFT) and 1 or #self.nodes + + -- if the edge should be assumed reversed, we simply switch head and + -- tail positions + if self.reversed then + head_index = (head_index == 1) and #self.nodes or 1 + end + + -- check if the head node equals the input node + if self.nodes[head_index].name == node.name then + result = true + end + + return result +end + + + +--- Checks whether a node is the tail of the edge. Does not work for hyperedges. +-- +-- This method only works for edges with two adjacent nodes. +-- +-- Edges may be reversed internally, so their head and tail might be switched. +-- Whether or not this internal reversal is handled by this method +-- can be specified with the optional second \meta{ignore\_reversed} parameter +-- which is |false| by default. +-- +-- @param node The node to check. +-- @param ignore_reversed Optional parameter. Set this to true if reversed edges +-- should not be considered reversed for this method call. +-- +-- @return True if the node is the tail of the edge. +-- +function Edge:isTail(node, ignore_reversed) + local result = false + + -- by default, the tail of -> edges is the first node and the tail + -- of <- edges is the last node + local tail_index = (self.direction == Edge.LEFT) and #self.nodes or 1 + + -- if the edge should be assumed reversed, we simply switch head + -- and tail positions + if self.reversed then + tail_index = (tail_index == 1) and #self.nodes or 1 + end + + -- check if the tail node equals the input node + if self.nodes[tail_index].name == node.name then + result = true + end + + return result +end + + + +--- Copies an edge (preventing accidental use). +-- +-- The nodes of the edge are not preserved and have to be added +-- to the copy manually if necessary. +-- +-- @return Shallow copy of the edge. +-- +function Edge:copy() + local result = lib.copy(self, Edge.new()) + result.nodes = {} + return result + end + + + + +local function reverse_values(source) + local copy = {} + for i = 1,#source do + copy[i] = source[#source-i+1] + end + return copy +end + + +--- Returns a readable string representation of the edge. +-- +-- @ignore This should not appear in the documentation. +-- +-- @return String representation of the edge. +-- +function Edge:__tostring() + local result = "Edge(" .. self.direction .. ", reversed = " .. tostring(self.reversed) .. ", " + if #self.nodes > 0 then + local node_strings = lib.imap(self.nodes, function (node) return node.name end) + result = result .. table.concat(node_strings, ', ') + end + --return result .. ")" + + -- Note: the following lines generate a shorter string representation + -- of the edge that is more readable and can be used for debugging. + -- So please don't remove this: + -- + local node_strings = lib.imap(self.nodes, function (node) return node.name end) + if self.reversed then + return table.concat(reverse_values(node_strings), ' ' .. self.direction .. ' ') + else + return table.concat(node_strings, ' ' .. self.direction .. ' ') + end +end + + + +-- Done + +return Edge \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua new file mode 100644 index 00000000000..43b886787c4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua @@ -0,0 +1,396 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Graph.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + + +--- The Graph class +-- +-- + +local Graph = {} +Graph.__index = Graph + + +-- Namespace + +-- Imports +local Edge = require "pgf.gd.deprecated.Edge" + +local lib = require "pgf.gd.lib" + + +--- Creates a new graph. +-- +-- @param values Values to override default graph settings. +-- The following parameters can be set:\par +-- |nodes|: The nodes of the graph.\par +-- |edges|: The edges of the graph.\par +-- |clusters|: The node clusters of the graph.\par +-- |options|: A table of node options passed over from \tikzname. +-- |events|: A sequence of events signaled during the graph specification. +-- +-- @return A newly-allocated graph. +-- +function Graph.new(values) + local defaults = { + nodes = {}, + edges = {}, + clusters = {}, + options = {}, + events = {}, + } + setmetatable(defaults, Graph) + if values then + for k,v in pairs(values) do + defaults[k] = v + end + end + return defaults +end + + + +--- Prepares a graph for an algorithm. +-- +-- This method causes self, all its nodes, and all its edges to get +-- a new empty table for the key algorithm. This allows an algorithm to +-- store stuff with nodes and edges without them interfering with information +-- stored by other algorithms. +-- +-- @param An algorithm object. + +function Graph:registerAlgorithm(algorithm) + self[algorithm] = self[algorithm] or {} + + -- Add an algorithm field to all nodes, all edges, and the graph: + for _,n in pairs(self.nodes) do + n[algorithm] = n[algorithm] or {} + end + for _,e in pairs(self.edges) do + e[algorithm] = e[algorithm] or {} + end +end + + +--- Sets the graph option \meta{name} to \meta{value}. +-- +-- @param name Name of the option to be changed. +-- @param value New value for the graph option \meta{name}. +-- +function Graph:setOption(name, value) + self.options[name] = value +end + + + +--- Returns the value of the graph option \meta{name}. +-- +-- @param name Name of the option. +-- +-- @return The value of the graph option \meta{name} or |nil|. +-- +function Graph:getOption(name) + return self.options[name] +end + + + + +--- Creates a shallow copy of a graph. +-- +-- The nodes and edges of the original graph are not preserved in the copy. +-- +-- @return A shallow copy of the graph. +-- +function Graph:copy () + return Graph.new({options = self.options, events = self.events}) +end + + +--- Adds a node to the graph. +-- +-- @param node The node to be added. +-- +function Graph:addNode(node) + -- only add the node if it's not included in the graph yet + if not self:findNode(node.name) then + -- Does the node have an index, yet? + if not node.index then + node.index = #self.nodes + 1 + end + + table.insert(self.nodes, node) + end +end + + + +--- If possible, removes a node from the graph and returns it. +-- +-- @param node The node to remove. +-- +-- @return The removed node or |nil| if it was not found in the graph. +-- +function Graph:removeNode(node) + local _, index = lib.find(self.nodes, function (other) + return other.name == node.name + end) + if index then + table.remove(self.nodes, index) + return node + else + return nil + end +end + + + +--- If possible, looks up the node with the given name in the graph. +-- +-- @param name Name of the node to look up. +-- +-- @return The node with the given name or |nil| if it was not found in the graph. +-- +function Graph:findNode(name) + return self:findNodeIf(function (node) return node.name == name end) +end + + + +--- Looks up the first node for which the function \meta{test} returns |true|. +-- +-- @param test A function that takes one parameter (a |Node|) and returns +-- |true| or |false|. +-- +-- @return The first node for which \meta{test} returns |true|. +-- +function Graph:findNodeIf(test) + return lib.find(self.nodes, test) +end + + + +--- Like removeNode, but also deletes all adjacent edges of the removed node. +-- +-- This function also removes the deleted adjacent edges from all neighbours +-- of the removed node. +-- +-- @param node The node to be deleted together with its adjacent edges. +-- +-- @return The removed node or |nil| if the node was not found in the graph. +-- +function Graph:deleteNode(node) + local node = self:removeNode(node) + if node then + for _,edge in ipairs(node.edges) do + self:removeEdge(edge) + for _,other_node in ipairs(edge.nodes) do + if other_node.name ~= node.name then + other_node:removeEdge(edge) + end + end + end + node.edges = {} + end + return node +end + + + +-- Checks whether the edge already exists in the graph and returns it if possible. +-- +-- @param edge Edge to search for. +-- +-- @return The edge if it was found in the graph, |nil| otherwise. +-- +function Graph:findEdge(edge) + return lib.find(self.edges, function (other) return other == edge end) +end + + + +--- Adds an edge to the graph. +-- +-- @param edge The edge to be added. +-- +function Graph:addEdge(edge) + if not edge.index then + edge.index = #self.edges + 1 + end + + table.insert(self.edges, edge) +end + + + +--- If possible, removes an edge from the graph and returns it. +-- +-- @param edge The edge to be removed. +-- +-- @return The removed edge or |nil| if it was not found in the graph. +-- +function Graph:removeEdge(edge) + local _, index = lib.find(self.edges, function (other) return other == edge end) + if index then + table.remove(self.edges, index) + return edge + else + return nil + end +end + + + +--- Like removeEdge, but also removes the edge from its adjacent nodes. +-- +-- @param edge The edge to be deleted. +-- +-- @return The removed edge or |nil| if it was not found in the graph. +-- +function Graph:deleteEdge(edge) + local edge = self:removeEdge(edge) + if edge then + for _,node in ipairs(edge.nodes) do + node:removeEdge(edge) + end + end + return edge +end + + + +--- Removes an edge between two nodes and also removes it from these nodes. +-- +-- @param from Start node of the edge. +-- @param to End node of the edge. +-- +-- @return The deleted edge. +-- +function Graph:deleteEdgeBetweenNodes(from, to) + -- try to find the edge + local edge = lib.find(self.edges, function (edge) + return edge.nodes[1] == from and edge.nodes[2] == to + end) + + -- delete and return the edge + if edge then + return self:deleteEdge(edge) + else + return nil + end +end + + + +--- Creates and adds a new edge to the graph. +-- +-- @param first_node The first node of the new edge. +-- @param second_node The second node of the new edge. +-- @param direction The direction of the new edge. Possible values are +-- \begin{itemize} +-- \item |Edge.UNDIRECTED|, +-- \item |Edge.LEFT|, +-- \item |Edge.RIGHT|, +-- \item |Edge.BOTH| and +-- \item |Edge.NONE| (for invisible edges). +-- \end{itemize} +-- @param edge_nodes A string of \tikzname\ edge nodes that needs to be passed +-- back to the \TeX layer unmodified. +-- @param options The options of the new edge. +-- @param tikz_options A table of \tikzname\ options to be used by graph drawing +-- algorithms to treat the edge in special ways. +-- +-- @return The newly created edge. +-- +function Graph:createEdge(first_node, second_node, direction, edge_nodes, options, tikz_options) + local edge = Edge.new{ + direction = direction, + edge_nodes = edge_nodes, + options = options, + tikz_options = tikz_options + } + edge:addNode(first_node) + edge:addNode(second_node) + self:addEdge(edge) + return edge +end + + + +--- Returns the cluster with the given name or |nil| if no such cluster exists. +-- +-- @param name Name of the node cluster to look up. +-- +-- @return The cluster with the given name or |nil| if no such cluster is defined. +-- +function Graph:findClusterByName(name) + return lib.find(self.clusters, function (cluster) + return cluster.name == name + end) +end + + + +--- Tries to add a cluster to the graph. Returns whether or not this was successful. +-- +-- Clusters are supposed to have unique names. This function will add the given +-- cluster only if there is no cluster with this name already. It returns |true| +-- if the cluster was added and |false| otherwise. +-- +-- @param cluster Cluster to add to the graph. +-- +-- @return |true| if the cluster was added successfully, |false| otherwise. +-- +function Graph:addCluster(cluster) + if not self:findClusterByName(cluster.name) then + table.insert(self.clusters, cluster) + end +end + + + + + +--- Returns a string representation of this graph including all nodes and edges. +-- +-- @ignore This should not appear in the documentation. +-- +-- @return Graph as string. +-- +function Graph:__tostring() + local tmp = Graph.__tostring + Graph.__tostring = nil + local result = "Graph<" .. tostring(self) .. ">((" + Graph.__tostring = tmp + + local first = true + for _,node in ipairs(self.nodes) do + if first then first = false else result = result .. ", " end + result = result .. tostring(node) + end + result = result .. "), (" + first = true + for _,edge in ipairs(self.edges) do + if first then first = false else result = result .. ", " end + result = result .. tostring(edge) + end + + return result .. "))" +end + + + +-- Done + +return Graph \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua new file mode 100644 index 00000000000..8e29d78667a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua @@ -0,0 +1,91 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Iterators.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +--- The Iterators class is a singleton object. +-- +-- It provides advanced iterators. + +local Iterators = {} + +-- Namespace + +local lib = require("pgf.gd.lib") + + + +--- Iterator for traversing a \meta{dag} using a topological sorting. +-- +-- A topological sorting of a directed graph is a linear ordering of its +-- nodes such that, for every edge |(u,v)|, |u| comes before |v|. +-- +-- Important note: if performed on a graph with at least one cycle a +-- topological sorting is impossible. Thus, the nodes returned from the +-- iterator are not guaranteed to satisfy the ``|u| comes before |v|'' +-- criterion. The iterator may even terminate early or loop forever. +-- +-- @param graph A directed acyclic graph. +-- +-- @return An iterator for traversing \meta{graph} in a topological order. +-- +function Iterators.topologicallySorted(dag) + -- track visited edges + local deleted_edges = {} + + -- collect all sources (nodes with no incoming edges) of the dag + local sources = lib.imap(dag.nodes, function (node) if node:getInDegree() == 0 then return node end end) + + -- return the iterator function + return function () + while #sources > 0 do + -- fetch the next sink from the queue + local source = table.remove(sources, 1) + + -- get its outgoing edges + local out_edges = source:getOutgoingEdges() + + -- iterate over all outgoing edges we haven't visited yet + for _,edge in ipairs(out_edges) do + if not deleted_edges[edge] then + -- mark the edge as visited + deleted_edges[edge] = true + + -- get the node at the other end of the edge + local neighbour = edge:getNeighbour(source) + + -- get a list of all incoming edges of the neighbour that have + -- not been visited yet + local in_edges = lib.imap(neighbour:getIncomingEdges(), + function (edge) if not deleted_edges[edge] then return edge end end) + + -- if there are no such edges then we have a new source + if #in_edges == 0 then + sources[#sources+1] = neighbour + end + end + end + + -- return the current source + return source + end + + -- the iterator terminates if there are no sources left + return nil + end +end + + + +-- Done + +return Iterators \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua new file mode 100644 index 00000000000..89e8a2e68fa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua @@ -0,0 +1,280 @@ +-- Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Node.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +--- The Node class +-- +-- + +local Node = {} +Node.__index = Node + + +-- Namespace + +local lib = require "pgf.gd.lib" + + +-- Imports + +local Vector = require "pgf.gd.deprecated.Vector" + + + +--- Creates a new node. +-- +-- @param values Values to override default node settings. +-- The following parameters can be set:\par +-- |name|: The name of the node. It is obligatory to define this.\par +-- |tex|: Information about the corresponding \TeX\ node.\par +-- |edges|: Edges adjacent to the node.\par +-- |pos|: Initial position of the node.\par +-- |options|: A table of node options passed over from \tikzname. +-- +-- @return A newly allocated node. +-- +function Node.new(values) + local new = { + class = Node, + name = nil, + tex = { + -- texNode = nil, + -- maxX = nil, + -- minX = nil, + -- maxY = nil, + -- minY = nil + }, + edges = {}, + -- pos = nil, + options = {}, + -- growth_direction = nil, + -- index = nil, + -- event_index = nil, + kind = "node", + } + setmetatable(new, Node) + if values then + for k,v in pairs(values) do + new [k] = v + end + end + if not new.pos then + new.pos = Vector.new(2) + end + return new +end + + + +--- Sets the node option \meta{name} to \meta{value}. +-- +-- @param name Name of the node option to be changed. +-- @param value New value for the node option \meta{name}. +-- +function Node:setOption(name, value) + self.options[name] = value +end + + + +--- Returns the value of the node option \meta{name}. +-- +-- @param name Name of the node option. +-- @param graph If this optional argument is given, +-- in case the option is not set as a node parameter, +-- we try to look it up as a graph parameter. +-- +-- @return The value of the node option \meta{name} or |nil|. +-- +function Node:getOption(name, graph) + return lib.lookup_option(name, self, graph) +end + + + +--- Computes the width of the node. +-- +-- @return Width of the node. +-- +function Node:getTexWidth() + return math.abs(self.tex.maxX - self.tex.minX) +end + + + +--- Computes the heigth of the node. +-- +-- @return Height of the node. +-- +function Node:getTexHeight() + return math.abs(self.tex.maxY - self.tex.minY) +end + + + +--- Adds new edge to the node. +-- +-- @param edge The edge to be added. +-- +function Node:addEdge(edge) + table.insert(self.edges, edge) +end + + + +--- Removes an edge from the node. +-- +-- @param edge The edge to remove. +-- +function Node:removeEdge(edge) + self.edges = lib.imap (self.edges, function(other) if other ~= edge then return other end end) +end + + + +--- Counts the adjacent edges of the node. +-- +-- @return The number of adjacent edges of the node. +-- +function Node:getDegree() + return #self.edges +end + + + +--- Returns all edges of the node. +-- +-- Instead of calling |node:getEdges()| the edges can alternatively be +-- accessed directly with |node.edges|. +-- +-- @return All edges of the node. +-- +function Node:getEdges() + return self.edges +end + + + +--- Returns the incoming edges of the node. Undefined result for hyperedges. +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return Incoming edges of the node. This includes undirected edges +-- and directed edges pointing to the node. +-- +function Node:getIncomingEdges(ignore_reversed) + return lib.imap(self.edges, + function (edge) + if edge:isHead(self, ignore_reversed) then return edge end + end) +end + + + +--- Returns the outgoing edges of the node. Undefined result for hyperedges. +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return Outgoing edges of the node. This includes undirected edges +-- and directed edges leaving the node. +-- +function Node:getOutgoingEdges(ignore_reversed) + return lib.imap(self.edges, + function (edge) + if edge:isTail(self, ignore_reversed) then return edge end + end) +end + + + +--- Returns the number of incoming edges of the node. +-- +-- @see Node:getIncomingEdges(reversed) +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return The number of incoming edges of the node. +-- +function Node:getInDegree(ignore_reversed) + return #self:getIncomingEdges(ignore_reversed) +end + + + +--- Returns the number of edges starting at the node. +-- +-- @see Node:getOutgoingEdges() +-- +-- @param ignore_reversed Optional parameter to consider reversed edges not +-- reversed for this method call. Defaults to |false|. +-- +-- @return The number of outgoing edges of the node. +-- +function Node:getOutDegree(ignore_reversed) + return #self:getOutgoingEdges(ignore_reversed) +end + + + +--- Creates a shallow copy of the node. +-- +-- Most notably, the edges adjacent are not preserved in the copy. +-- +-- @return Copy of the node. +-- +function Node:copy() + local result = lib.copy(self, Node.new()) + result.edges = {} + return result +end + + + +--- Compares two nodes by their name. +-- +-- @ignore This should not appear in the documentation. +-- +-- @param other Another node to compare with. +-- +-- @return |true| if both nodes have the same name. |false| otherwise. +-- +function Node:__eq(object) + return self.name == object.name +end + + + +--- Returns a formated string representation of the node. +-- +-- @ignore This should not appear in the documentation. +-- +-- @return String represenation of the node. +-- +function Node:__tostring() + local tmp = Node.__tostring + Node.__tostring = nil + local result = "Node<" .. tostring(self) .. ">(" .. self.name .. ")" + Node.__tostring = tmp + return result +end + + + + +-- Done + +return Node \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua new file mode 100644 index 00000000000..ab94ebe9686 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua @@ -0,0 +1,256 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/deprecated/Vector.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +--- Vector class +-- +-- This class augments a normal array so that: +-- +-- 1) Several functions like "plus" or "normalize" become available. +-- 2) You can access the ".x" and ".y" fields to get the fields [1] and [2]. + +local Vector = {} + + +-- Namespace: +local lib = require "pgf.gd.lib" +lib.Vector = Vector + + +-- Class setup +Vector.__index = + function (t, k) + if k == "x" then + return rawget(t,1) + elseif k == "y" then + return rawget(t,2) + else + return rawget(Vector,k) + end + end +Vector.__newindex = + function (t, k, v) + if k == "x" then + rawset(t,1,v) + elseif k == "y" then + rawset(t,2,v) + else + rawset(t,k,v) + end + end + + + +--- Creates a new vector with \meta{n} values using an optional \meta{fill\_function}. +-- +-- @param n The number of elements of the vector. (If omitted, then 2.) +-- @param fill_function Optional function that takes a number between 1 and \meta{n} +-- and is expected to return a value for the corresponding element +-- of the vector. If omitted, all elements of the vector will +-- be initialized with 0. +-- +-- @return A newly-allocated vector with \meta{n} elements. +-- +function Vector.new(n, fill_function) + -- create vector + local vector = { } + setmetatable(vector, Vector) + + local n = n or 2 + + if type(n) == 'table' then + for k,v in pairs(n) do + vector[k] = v + end + else + -- fill vector elements with values + if not fill_function then + for i = 1,n do + rawset(vector,i,0) + end + else + for i = 1,n do + rawset(vector,i,fill_function(i)) + end + end + end + + return vector +end + + + +--- Creates a copy of the vector that holds the same elements as the original. +-- +-- @return A newly-allocated copy of the vector holding exactly the same elements. +-- +function Vector:copy() + return Vector.new(#self, function (n) return self[n] end) +end + + + +--- Performs a vector addition and returns the result in a new vector. +-- +-- @param other The vector to add. +-- +-- @return A new vector with the result of the addition. +-- +function Vector:plus(other) + assert(#self == #other) + + return Vector.new(#self, function (n) return self[n] + other[n] end) +end + + + +--- Subtracts two vectors and returns the result in a new vector. +-- +-- @param other Vector to subtract. +-- +-- @return A new vector with the result of the subtraction. +-- +function Vector:minus(other) + assert(#self == #other) + + return Vector.new(#self, function (n) return self[n] - other[n] end) +end + + + +--- Divides a vector by a scalar value and returns the result in a new vector. +-- +-- @param scalar Scalar value to divide the vector by. +-- +-- @return A new vector with the result of the division. +-- +function Vector:dividedByScalar(scalar) + return Vector.new(#self, function (n) return self[n] / scalar end) +end + + + +--- Multiplies a vector by a scalar value and returns the result in a new vector. +-- +-- @param scalar Scalar value to multiply the vector with. +-- +-- @return A new vector with the result of the multiplication. +-- +function Vector:timesScalar(scalar) + return Vector.new(#self, function (n) return self[n] * scalar end) +end + + + +--- Performs the dot product of two vectors and returns the result in a new vector. +-- +-- @param other Vector to perform the dot product with. +-- +-- @return A new vector with the result of the dot product. +-- +function Vector:dotProduct(other) + assert(#self == #other) + + local product = 0 + for n = 1,#self do + product = product + self[n] * other[n] + end + return product +end + + + +--- Computes the Euclidean norm of the vector. +-- +-- @return The Euclidean norm of the vector. +-- +function Vector:norm() + return math.sqrt(self:dotProduct(self)) +end + + + +--- Normalizes the vector and returns the result in a new vector. +-- +-- @return Normalized version of the original vector. +-- +function Vector:normalized() + local norm = self:norm() + if norm == 0 then + return Vector.new(#self) + else + return self:dividedByScalar(self:norm()) + end +end + + + +--- Updates the values of the vector in-place. +-- +-- @param update_function A function that is called for each element of the +-- vector. The elements are replaced by the values +-- returned from this function. +-- +function Vector:update(update_function) + for i=1,#self do + self[i] = update_function(self[i]) + end +end + + + +--- Limits all elements of the vector in-place. +-- +-- @param limit_function A function that is called for each index/element +-- pair. It is supposed to return minimum and maximum +-- values for the element. The element is then clamped +-- to these values. +-- +function Vector:limit(limit_function) + for i=1,#self do + local min, max = limit_function(i, self[i]) + self[i] = math.max(min, math.min(max, value)) + end +end + + +--- Tests whether all elements of two vectors are the same +-- +-- @param other The other vector +-- +-- @return true or false +-- +function Vector:equals(other) + if #self ~= #other then + return false + end + + for n = 1, #self do + if self[n] ~= other[n] then + return false + end + end + + return true +end + + +function Vector:__tostring() + return '(' .. table.concat(self, ', ') .. ')' +end + + + + + +-- Done + +return Vector \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua new file mode 100644 index 00000000000..5d02603943c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua @@ -0,0 +1,122 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc.lua,v 1.2 2013/03/20 17:16:38 tantau Exp $ + + +--- +-- The table doc is used for documentation purposes. It is used to +-- provide lazy documentation for keys, that is, to install +-- documentation for keys only when this information is requested and +-- when the documentation is kept in a separate file. +-- +-- Using the doc facility is easy: +-- +-- \begin{enumerate} +-- \item In the |declare| statement of the key, you do not provide +-- fields like |documentation| or |summary|. Rather, you provide the +-- field |documentation_in|, which gets the name of a Lua file the +-- will be read whenever one of the fields |documentation|, |summary|, +-- or |examples| is requested for the key. +-- \item When the key is requested, |require| will be applied to the +-- filename given in the |documentation_in| field. +-- \item In this file, you start with the following code: +--\begin{codeexample}[code only] +--local doc = require 'pgf.gd.doc' +--local key = doc.key +--local documentation = doc.documentation +--local summary = doc.summary +--local example = doc.example +--\end{codeexample} +-- This will setup nice shortcuts for the commands you are going to +-- use in your file. +-- \item Next, for each to-be-lazily-documented key, add a block to +-- the file like the following: +--\begin{codeexample}[code only] +-- --- +-- key "my radius" +-- summary "This key specifies a radius." +-- documentation +-- [[ +-- This key is used, whenever... +-- ]] +-- example "\tikz \graph [foo layout, my radius=5] { a--b };" +-- example "\tikz \graph [foo layout, my radius=3] { c--d };" +--\end{codeexample} +-- +-- Note that |[[| and |]]| are used in Lua for raw multi-line +-- strings. +-- +-- The effect of the above code will be that for the key |my radius| +-- the different field like |summary| or |documentation| get +-- updated. The |key| function simple ``selects'' a key and subsequent +-- commands like |summary| will update this key until a different key +-- is selected through another use of |key|. +-- \end{enumerate} + +local doc = {} + +local current_key + + +-- Namespace +require "pgf.gd".doc = doc + + +-- Imports +local keys = require "pgf.gd.interface.InterfaceCore".keys + +--- +-- Selects the key which will be subsequently updated by the other +-- functions of this class. +-- +-- @param key A key. + +function doc.key (key) + current_key = assert(keys[key], "trying to document not-yet-declared key") +end + + +--- +-- Updates (replaces) the summary field of the last key selected +-- through the |key| command. +-- +-- @param string A (new) summary string. + +function doc.summary (string) + current_key.summary = string +end + + +--- +-- Updates (replaces) the documentation field of the last key selected +-- through the |key| command. +-- +-- @param string A (new) documentation string. Typically, the |[[| +-- syntax will be used to specify this string. + +function doc.documentation (string) + current_key.documentation = string +end + + +--- +-- Adds an example to the |examples| field of the last key selected +-- through the |key| command. +-- +-- @param string An additional example string. + +function doc.example (string) + local examples = rawget(current_key, "examples") or {} + examples[#examples + 1] = string + current_key.examples = examples +end + + +return doc diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua new file mode 100644 index 00000000000..e40a0bbdb1f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua @@ -0,0 +1,136 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/circular/Tantau2012.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "simple necklace layout" + +summary +[[ This simple layout arranges the nodes in a circle, which is +especially useful for drawing, well, circles of nodes. ]] + +documentation +[[ +The name |simple necklace layout| is reminiscent of the more general +``necklace layout,'' a term coined by Speckmann and Verbeek in +their paper +\begin{itemize} +\item + Bettina Speckmann and Kevin Verbeek, + \newblock Necklace Maps, + \newblock \emph{IEEE Transactions on Visualization and Computer + Graphics,} 16(6):881--889, 2010. +\end{itemize} + +For a |simple necklace layout|, the centers of the nodes +are placed on a counter-clockwise circle, starting with the first +node at the |grow| direction (for |grow'|, the circle is +clockwise). The order of the nodes is the order in which they appear +in the graph, the edges are not taken into consideration, unless the +|componentwise| option is given. + +\begin{codeexample}[] +\tikz[>=spaced stealth'] + \graph [simple necklace layout, grow'=down, node sep=1em, + nodes={draw,circle}, math nodes] + { + x_1 -> x_2 -> x_3 -> x_4 -> + x_5 -> "\dots"[draw=none] -> "x_{n-1}" -> x_n -> x_1 + }; +\end{codeexample} + +When you give the |componentwise| option, the graph will be +decomposed into connected components, which are then laid out +individually and packed using the usual component packing +mechanisms: + +\begin{codeexample}[] +\tikz \graph [simple necklace layout] { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 +}; +\end{codeexample} +\begin{codeexample}[] +\tikz \graph [simple necklace layout, componentwise] { + a -- b -- c -- d -- a, + 1 -- 2 -- 3 -- 1 +}; +\end{codeexample} + +The nodes are placed in such a way that +\begin{enumerate} +\item The (angular) distance between the centers of consecutive + nodes is at least |node distance|, +\item the distance between the borders of consecutive nodes is at + least |node sep|, and +\item the radius is at least |radius|. +\end{enumerate} +The radius of the circle is chosen near-minimal such that the above +properties are satisfied. To be more precise, if all nodes are +circles, the radius is chosen optimally while for, say, rectangular +nodes there may be too much space between the nodes in order to +satisfy the second condition. +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=0pt, node distance=0pt, + nodes={draw,circle}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] + +example +[[ +\begin{tikzpicture}[radius=1.25cm] + \graph [simple necklace layout, + node sep=0pt, node distance=0pt, + nodes={draw,circle}] + { 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; + + \draw [red] (0,-1.25) circle []; +\end{tikzpicture} +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=0pt, node distance=1cm, + nodes={draw,circle}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=2pt, node distance=0pt, + nodes={draw,circle}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] + +example +[[ +\tikz \graph [simple necklace layout, + node sep=0pt, node distance=0pt, + nodes={rectangle,draw}] +{ 1 -- 2 [minimum size=30pt] -- 3 -- + 4 [minimum size=50pt] -- 5 [minimum size=40pt] -- 6 -- 7 }; +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua new file mode 100644 index 00000000000..0a80baf0ca5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua @@ -0,0 +1,224 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/control/Anchoring.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "desired at" + +summary +[[ +When you add this key to a node in a graph, you ``desire'' +that the node should be placed at the \meta{coordinate} by the graph +drawing algorithm. +]] + +documentation +[[ +Now, when you set this key for a single node of a graph, +then, by shifting the graph around, this ``wish'' can obviously +always be fulfill: +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a [desired at={(1,2)}] -- b -- c -- a; + }; +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- b[desired at={(2,1)}] -- c -- a; + }; +\end{tikzpicture} +\end{codeexample} +Since the key's name is a bit long and since the many braces and +parentheses are a bit cumbersome, there is a special support for +this key inside a |graph|: The standard |/tikz/at| key is redefined +inside a |graph| so that it points to |/graph drawing/desired at| +instead. (Which is more logical anyway, since it makes no sense to +specify an |at| position for a node whose position it to be computed +by a graph drawing algorithm.) A nice side effect of this is that +you can use the |x| and |y| keys (see +Section~\ref{section-graphs-xy}) to specify desired positions: +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- b[x=2,y=0] -- c -- a; + }; +\end{tikzpicture} +\end{codeexample} +\begin{codeexample}[] +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [layered layout] + { + a [x=1,y=2] -- { b, c } -- {e, f} -- a + }; +\end{tikzpicture} +\end{codeexample} + +A problem arises when two or more nodes have this key set, because +then your ``desires'' for placement and the positions computed by +the graph drawing algorithm may clash. Graph drawing algorithms are +``told'' about the desired positions. Most algorithms will simply +ignore these desired positions since they will be taken care of in +the so-called post-anchoring phase, see below. However, for some +algorithms it makes a lot of sense to fix the positions of some +nodes and only compute the positions +of the other nodes relative to these nodes. For instance, for a +|spring layout| it makes perfect sense that some nodes are +``nailed to the canvas'' while other nodes can ``move freely''. +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a[x=1] -- { b, c, d, e -- {f,g,h} }; + { h, g } -- a; + }; +\end{tikzpicture} +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- { b, c, d[x=0], e -- {f[x=2], g, h[x=1]} }; + { h, g } -- a; + }; +\end{tikzpicture} +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + \graph [spring layout] + { + a -- { b, c, d[x=0], e -- {f[x=2,y=1], g, h[x=1]} }; + { h, g } -- a; + }; +\end{tikzpicture} +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "anchor node" + +summary +[[ +This option can be used with a graph to specify a node that +should be used for anchoring the whole graph. +]] + +documentation +[[ +When this option is specified, after the layout has been computed, the +whole graph will be shifted in such a way that the \meta{node name} is +either +\begin{itemize} +\item at the current value of |anchor at| or +\item at the position that is specified in the form of a + |desired at| for the \meta{node name}. +\end{itemize} +Note how in the last example |c| is placed at |(1,1)| rather than +|b| as would happen by default. +]] + +example +[[ +\tikz \draw (0,0) + -- (1,0.5) graph [edges=red, layered layout, anchor node=a] { a -> {b,c} } + -- (1.5,0) graph [edges=blue, layered layout, + anchor node=y, anchor at={(2,0)}] { x -> {y,z} }; +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (3,2); + + \graph [layered layout, anchor node=c, edges=rounded corners] + { a -- {b [x=1,y=1], c [x=1,y=1] } -- d -- a}; +\end{tikzpicture} +]] +-------------------------------------------------------------------- + + + + +-------------------------------------------------------------------- +key "anchor at" + +summary +[[ +The coordinate at which the graph should be anchored when no +explicit anchor is given for any node. The initial value is the origin. +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (2,2); + + \graph [layered layout, edges=rounded corners, anchor at={(1,2)}] + { a -- {b, c [anchor here] } -- d -- a}; +\end{tikzpicture} +]] +-------------------------------------------------------------------- + + + + +-------------------------------------------------------------------- +key "anchor here" + +summary +[[ +This option can be passed to a single node (rather than the +graph as a whole) in order to specify that this node should be used +for the anchoring process. +]] + +documentation +[[ +In the example, |c| is placed at the origin since this is the +default |anchor at| position. +]] + +example +[[ +\begin{tikzpicture} + \draw [help lines] (0,0) grid (2,2); + + \graph [layered layout, edges=rounded corners] + { a -- {b, c [anchor here] } -- d -- a}; +\end{tikzpicture} +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua new file mode 100644 index 00000000000..7dfd9179648 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased.lua,v 1.1 2013/03/07 22:28:37 tantau Exp $ + + + +--- +-- @section subsection {Force-Based Algorithms} +-- +-- + +local _ \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua new file mode 100644 index 00000000000..3f2b9bc2e30 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua @@ -0,0 +1,129 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FMMMLayout.lua,v 1.2 2013/10/09 19:46:59 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "FMMMLayout" +summary "The fast multipole multilevel layout algorithm." + +documentation +[[ +|FMMMLayout| implements a force-directed graph drawing +method suited also for very large graphs. It is based on a +combination of an efficient multilevel scheme and a strategy for +approximating the repulsive forces in the system by rapidly +evaluating potential fields. + +The implementation is based on the following publication: + +\begin{itemize} +\item Stefan Hachul, Michael J\"unger: Drawing Large Graphs with + a Potential-Field-Based Multilevel Algorithm. \emph{12th + International Symposium on Graph Drawing 1998 (GD '04)}, New York, LNCS 3383, + pp. 285--295, 2004. +\end{itemize} +]] + +example +[[ +\tikz \graph [FMMMLayout] { a -- {b,c,d} -- e -- a }; +]] + + +example +[[ +\tikz [nodes={text height=.7em, text depth=.2em, + draw=black!20, thick, fill=white, font=\footnotesize}, + >=spaced stealth', rounded corners, semithick] + \graph [FMMMLayout, node sep=1mm, variation=2] { + "5th Edition" -> { "6th Edition", "PWB 1.0" }; + "6th Edition" -> { "LSX", "1 BSD", "Mini Unix", "Wollongong", "Interdata" }; + "Interdata" ->[orient=down] "Unix/TS 3.0", + "Interdata" -> { "PWB 2.0", "7th Edition" }; + "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" }; + "V7M" -> "Ultrix-11"; + "8th Edition" -> "9th Edition"; + "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" }; + "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" }; + "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" }; + "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }}; + "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" }; + { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0"; + { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } -> + "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3"; + }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "FMMMLayout.randSeed" +summary "Sets the random seed for the |FMMMLayout|." +documentation +[[ +By changing this number, you can vary the appearance of the generated +graph drawing. This key is an alias for |random seed|, which in turn +can be set by using the |variation| key. +]] + +example +[[ +\tikz \graph [FMMMLayout, variation=1] { a -- {b,c,d} -- e -- a }; +]] +example +[[ +\tikz \graph [FMMMLayout, variation=2] { a -- {b,c,d} -- e -- a }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "FMMMLayout.unitEdgeLength" +summary "The ``ideal'' padding between two nodes." + +documentation +[[ +The algorithm will try to make the padding between any two vertices +this distance. Naturally, this is not always possible, so, normally, +distance will actually be different. This key is an alias for the more +natural |node sep|. +]] + +example +[[ +\tikz { + \graph [FMMMLayout, node sep=1cm] { subgraph C_n[n=6]; }; + + \draw [red, ultra thick, |-|] (1.south) -- ++(down:1cm); +} +]] +example +[[ +\tikz { + \graph [FMMMLayout, node sep=5mm] { subgraph C_n[n=6]; }; + + \draw [red, ultra thick, |-|] (1.south) -- ++(down:5mm); +} +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua new file mode 100644 index 00000000000..8fe64399c91 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua @@ -0,0 +1,51 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/FastMultipoleEmbedder.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder" +summary "Implementation of a fast multipole embedder by Martin Gronemann." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.numIterations" +summary "sets the maximum number of iterations" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.multipolePrec" +summary "sets the number of coefficients for the expansions. default = 4" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.defaultEdgeLength" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "FastMultipoleEmbedder.defaultNodeSize" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua new file mode 100644 index 00000000000..d564af44dfa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua @@ -0,0 +1,103 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/GEMLayout.lua,v 1.2 2013/10/07 18:43:25 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "GEMLayout" +summary "The energy-based GEM layout algorithm." + +documentation [[ +The implementation used in |GEMLayout| is based on the following publication: +\begin{itemize} +\item Arne Frick, Andreas Ludwig, Heiko Mehldau: \emph{A Fast Adaptive Layout + Algorithm for Undirected Graphs.} Proc. Graph Drawing 1994, + LNCS 894, pp. 388-403, 1995. +\end{itemize} + +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.numberOfRounds" +summary "Sets the maximal number of round per node." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.minimalTemperature" +summary "Sets the minimal temperature." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.initialTemperature" +summary "Sets the initial temperature; must be $\\ge$ |minimalTemperature|." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.gravitationalConstant" +summary "Sets the gravitational constant; must be $\\ge 0$." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.desiredLength" +summary "Sets the desired edge length; must be $\\ge 0$." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.maximalDisturbance" +summary "Sets the maximal disturbance; must be $\\ge 0$." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.rotationAngle" +summary "Sets the opening angle for rotations ($0 \\le x \\le \\pi / 2$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.oscillationAngle" +summary "Sets the opening angle for oscillations ($0 \\le x \\le \\pi / 2$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.rotationSensitivity" +summary "Sets the rotation sensitivity ($0 \\le x \\le 1$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.oscillationSensitivity" +summary "Sets the oscillation sensitivity ($0 \\le x \\le 1$)." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "GEMLayout.attractionFormula" +summary "sets the formula for attraction (1 = Fruchterman / Reingold, 2 = GEM)." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua new file mode 100644 index 00000000000..783ab8b4bff --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/MultilevelLayout.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "MultilevelLayout" +summary "A wrapper for the multilevel layout computation using the modular multi-level mixer." + +example [[ +\tikz \graph [MultilevelLayout] { + a -- b -- c -- a -- d -- e -- f -- a +}; +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua new file mode 100644 index 00000000000..2c5ae1bc293 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua @@ -0,0 +1,54 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFR.lua,v 1.1 2013/11/07 15:43:35 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR" +summary "The spring-embedder layout algorithm by Fruchterman and Reingold." + +documentation [[ +The implementation used in SpringEmbedderFR is based on the following +publication: + +Thomas M. J. Fruchterman, Edward M. Reingold: \emph{Graph Drawing by Force-directed +Placement}. Software - Practice and Experience 21(11), pp. 1129-1164, 1991. + +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR.iterations" +summary "Sets the number of iterations." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR.noise" +summary "Sets the parameter noise." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFR.scaleFunctionFactor" +summary "Sets the scale function factor." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua new file mode 100644 index 00000000000..8d4462d0815 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua @@ -0,0 +1,57 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderFRExact.lua,v 1.1 2013/11/07 15:43:35 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact" +summary "Declaration of Spring-Embedder (Fruchterman,Reingold) algorithm with exact force computations." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.iterations" +summary "Sets the number of iterations." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.noise" +summary "Sets the parameter noise." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.coolingFunction" +summary "Sets the parameter coolingFunction to |factor| or to |logarithmic|." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.idealEdgeLength" +summary "Sets the ideal edge length to a length." +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderFRExact.convTolerance" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua new file mode 100644 index 00000000000..a2882845c98 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua @@ -0,0 +1,64 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/SpringEmbedderKK.lua,v 1.1 2013/11/07 15:43:35 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SpringEmbedderKK" +summary "The spring embedder of Kamada and Kawai" + +documentation [[ + The implementation used in |SpringEmbedderKK| is based on + the following publication: + + Tomihisa Kamada, Satoru Kawai: \emph{An Algorithm for Drawing + General Undirected Graphs.} Information Processing Letters 31, pp. 7--15, 1989. + + There are some parameters that can be tuned to optimize the + algorithm's behavior regarding runtime and layout quality. + First of all note that the algorithm uses all pairs shortest path + to compute the graph theoretic distance. This can be done either + with BFS (ignoring node sizes) in quadratic time or by using + e.g. Floyd's algorithm in cubic time with given edge lengths + that may reflect the node sizes. Also |m_computeMaxIt| decides + if the computation is stopped after a fixed maximum number of + iterations. The desirable edge length can either be set or computed + from the graph and the given layout. + +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderKK.stopTolerance" +summary "Sets the value for the stop tolerance." +documentation +[[ +Below this value, the system is regarded stable (balanced) and the +optimization stopped. +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SpringEmbedderKK.desLength" +summary "Sets desirable edge length directly" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua new file mode 100644 index 00000000000..20ca3ce3d12 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/BarycenterPlacer.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "BarycenterPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "BarycenterPlacer.weightedPositionPriority" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua new file mode 100644 index 00000000000..0cda25ca466 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua @@ -0,0 +1,45 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/CirclePlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "CirclePlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CirclePlacer.circleSize" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CirclePlacer.radiusFixed" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CirclePlacer.nodeSelection" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua new file mode 100644 index 00000000000..9623b70d89e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/EdgeCoverMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "EdgeCoverMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "EdgeCoverMerger.factor" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua new file mode 100644 index 00000000000..15e11ff91c7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/IndependentSetMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "IndependentSetMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "IndependentSetMerger.searchDepthBase" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua new file mode 100644 index 00000000000..352a1f5400a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/LocalBiconnectedMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "LocalBiconnectedMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "LocalBiconnectedMerger.factor" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua new file mode 100644 index 00000000000..eb52badcc55 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MatchingMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "MatchingMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "MatchingMerger.selectByNodeMass" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua new file mode 100644 index 00000000000..50be16489c2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/MedianPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "MedianPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua new file mode 100644 index 00000000000..4d8bfd179de --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "RandomMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "RandomMerger.factor" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua new file mode 100644 index 00000000000..779e992bb83 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/RandomPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "RandomPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "RandomPlacer.circleSize" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua new file mode 100644 index 00000000000..081067143da --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua @@ -0,0 +1,39 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarMerger.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SolarMerger" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SolarMerger.simple" +summary "" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "SolarMerger.massAsNodeRadius" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua new file mode 100644 index 00000000000..21eb1f122ee --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/SolarPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SolarPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua new file mode 100644 index 00000000000..f4dcfc632cc --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua @@ -0,0 +1,33 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/energybased/multilevelmixer/ZeroPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "ZeroPlacer" +summary "?" +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "ZeroPlacer.randomRange" +summary "" +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua new file mode 100644 index 00000000000..6dfa6a46575 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered.lua,v 1.2 2013/03/07 18:17:14 tantau Exp $ + + + +--- +-- @section subsection {Algorithms for Drawing Layered Graphs} +-- +-- + +local _ \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua new file mode 100644 index 00000000000..f0e20321e86 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua @@ -0,0 +1,23 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/BarycenterHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "BarycenterHeuristic" +summary "The barycenter heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua new file mode 100644 index 00000000000..b5fd3ba6669 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua @@ -0,0 +1,35 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/CoffmanGrahamRanking.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "CoffmanGrahamRanking" +summary "The ranking algorithm due to Coffman and Graham." +documentation +[[ +|CoffmanGrahamRanking| implements a node ranking algorithmn based on +the Coffman--Graham scheduling algorithm, which can be used as first +phase in |SugiyamaLayout|. The aim of the algorithm is to ensure that +the height of the ranking (the number of layers) is kept small. +]] +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "CoffmanGrahamRanking.width" +summary "A mysterious width parameter..." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua new file mode 100644 index 00000000000..4a4935e4aea --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/DfsAcyclicSubgraph.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "DfsAcyclicSubgraph" +summary "DFS-based algorithm for computing a maximal acyclic subgraph." +documentation +[[ +The algorithm simply removes all DFS-backedges and works in linear-time. +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua new file mode 100644 index 00000000000..af593f6d972 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua @@ -0,0 +1,99 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastHierarchyLayout.lua,v 1.2 2013/03/07 22:28:37 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "FastHierarchyLayout" +summary "Coordinate assignment phase for the Sugiyama algorithm by Buchheim et al." +documentation +[[ +This class implements a hierarchy layout algorithm, that is, it +layouts hierarchies with a given order of nodes on each +layer. It is used as a third phase of the Sugiyama algorithm. + +All edges of the layout will have at most two +bends. Additionally, for each edge having exactly two bends, the +segment between them is drawn vertically. This applies in +particular to the long edges arising in the first phase of the +Sugiyama algorithm. + +The implementation is based on: + +\begin{itemize} +\item + Christoph Buchheim, Michael Jünger, Sebastian Leipert: A Fast + Layout Algorithm for k-Level Graphs. \emph{Proc. Graph + Drawing 2000}, volumne 1984 of LNCS, pages 229--240, 2001. +\end{itemize} +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastHierarchyLayout] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "FastHierarchyLayout.fixedLayerDistance" +summary "If true, the distance between neighbored layers is fixed, otherwise variable." +-------------------------------------------------------------------- + + + + +-------------------------------------------------------------------- +key "FastHierarchyLayout.layerDistance" +summary "Separation distance (padding) between two consecutive layers." + +documentation +[[ +Sets the (minimum?) padding between nodes on two consecutive +layers. It defaults to the sum of the keys +|level pre sep| and |level post sep|. +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastHierarchyLayout, + level sep=1cm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + +-------------------------------------------------------------------- +key "FastHierarchyLayout.nodeDistance" +summary "Separation distance (padding) between two consecutive nodes on the same layer." + +documentation +[[ +Sets the (minimum?) padding between sibling nodes. It defaults to the +sum of the keys |sibling pre sep| and |sibling post sep|. +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastHierarchyLayout, + sibling sep=5mm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua new file mode 100644 index 00000000000..1798cb7e0df --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua @@ -0,0 +1,97 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/FastSimpleHierarchyLayout.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "FastSimpleHierarchyLayout" +summary "Coordinate assignment phase for the Sugiyama algorithm by Ulrik Brandes and Boris Köpf." + +documentation +[[ +This class implements a hierarchy layout algorithm, that is, it +layouts hierarchies with a given order of nodes on each +layer. It is used as a third phase of the Sugiyama algorithm. + +The algorithm runs in three phases: +\begin{enumerate} +\item Alignment (4x) +\item Horizontal Compactation (4x) +\item Balancing +\end{enumerate} +The alignment and horizontal compactification phases are calculated +downward, upward, left-to-right and right-to-left. The four +resulting layouts are combined in a balancing step. + +Warning: The implementation is known to not always produce a +correct layout. Therefore this Algorithm is for testing purpose +only. + +The implementation is based on: + +\begin{itemize} +\item + Ulrik Brandes, Boris Köpf: Fast and Simple Horizontal + Coordinate Assignment. \emph{LNCS} 2002, Volume 2265/2002, + pp. 33--36 +\end{itemize} +]] + +example +[[ +\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "FastSimpleHierarchyLayout.layerDistance" +summary "Distance between the cetners of nodes of two consecutive layers." + +documentation +[[ +Sets the (minimum?) distance between nodes on two consecutive +layers. It defaults to the key |level distance|. +]] +example +[[ +\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout, + level distance=2cm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- + +-------------------------------------------------------------------- +key "FastSimpleHierarchyLayout.siblingDistance" +summary "Distance between the cetners of nodes of sibling nodes." + +documentation +[[ +Sets the (minimum?) padding between sibling nodes. It defaults to +|sibling distance|. +]] +example +[[ +\tikz \graph [SugiyamaLayout, FastSimpleHierarchyLayout, + sibling distance=5mm] { + a -- {b,c,d} -- e -- a; +}; +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua new file mode 100644 index 00000000000..c0b407bb050 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua @@ -0,0 +1,27 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyCycleRemoval.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "GreedyCycleRemoval" +summary "Greedy algorithm for computing a maximal acyclic subgraph." +documentation +[[ +The algorithm applies a greedy heuristic to compute a maximal +acyclic subgraph and works in linear-time. +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua new file mode 100644 index 00000000000..f6c59ac2125 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua @@ -0,0 +1,23 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/GreedyInsertHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "GreedyInsertHeuristic" +summary "The greedy-insert heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua new file mode 100644 index 00000000000..65dd5176f8b --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua @@ -0,0 +1,57 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/LongestPathRanking.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "LongestPathRanking" +summary "The longest-path ranking algorithm." +documentation +[[ +|LongestPathRanking| implements the well-known longest-path ranking +algorithm, which can be used as first phase in |SugiyamaLayout|. The +implementation contains a special optimization for reducing edge +lengths, as well as special treatment of mixed-upward graphs (for +instance, \textsc{uml} class diagrams). +]] +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "LongestPathRanking.separateDeg0Layer" +summary "If set to true, isolated nodes are placed on a separate layer." +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "LongestPathRanking.separateMultiEdges" +summary "If set to true, multi-edges will span at least two layers." +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "LongestPathRanking.optimizeEdgeLength" +summary +[[ +If set to true the ranking algorithm tries to reduce edge +length even if this might increase the height of the layout. Choose +false, if the longest-path ranking known from the literature should be +used. +]] +-------------------------------------------------------------------- + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua new file mode 100644 index 00000000000..5ad07881fe1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua @@ -0,0 +1,24 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/MedianHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "MedianHeuristic" +summary "The median heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua new file mode 100644 index 00000000000..e694de6e790 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua @@ -0,0 +1,35 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/OptimalRanking.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "OptimalRanking" +summary "The optimal ranking algorithm." +documentation +[[ +The |OptimalRanking| implements the LP-based algorithm for +computing a node ranking with minimal edge lengths, which can +be used as first phase in |SugiyamaLayout|. +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "OptimalRanking.separateMultiEdges" +summary "If set to true, multi-edges will span at least two layers." +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua new file mode 100644 index 00000000000..6231ab49249 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua @@ -0,0 +1,34 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SiftingHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "SiftingHeuristic" +summary "The sifting heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- + + +-------------------------------------------------------------------- +key "SiftingHeuristic.strategy" +summary "Sets a so-called ``sifting strategy.''" +documentation +[[ +The following values are permissible: |left_to_right|, |desc_degree|, +and |random|. +]] +-------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua new file mode 100644 index 00000000000..fc897d71c51 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua @@ -0,0 +1,24 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SplitHeuristic.lua,v 1.1 2013/03/07 18:17:14 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + + +-------------------------------------------------------------------- +key "SplitHeuristic" +summary "The split heuristic for 2-layer crossing minimization." +-------------------------------------------------------------------- + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua new file mode 100644 index 00000000000..d887b6c6bad --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua @@ -0,0 +1,116 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/layered/SugiyamaLayout.lua,v 1.4 2013/10/09 19:47:00 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout" +summary "The OGDF implementation of the Sugiyama algorithm." + +documentation +[[ +This layout represents a customizable implementation of Sugiyama's +layout algorithm. The implementation used in |SugiyamaLayout| is based +on the following publications: + +\begin{itemize} +\item Emden R. Gansner, Eleftherios Koutsofios, Stephen + C. North, Kiem-Phong Vo: A technique for drawing directed + graphs. \emph{IEEE Trans. Software Eng.} 19(3):214--230, 1993. +\item Georg Sander: \emph{Layout of compound directed graphs.} + Technical Report, Universität des Saarlandes, 1996. +\end{itemize} +]] + +example +[[ +\tikz \graph [SugiyamaLayout] { a -- {b,c,d} -- e -- a }; +]] + +example +[[ +\tikz \graph [SugiyamaLayout, grow=right] { + a -- {b,c,d} -- e -- a +}; +]] + +example +[[ +\tikz [nodes={text height=.7em, text depth=.2em, + draw=black!20, thick, fill=white, font=\footnotesize}, + >=spaced stealth', rounded corners, semithick] + \graph [SugiyamaLayout, FastSimpleHierarchyLayout, grow=-80, + level distance=1.5cm, sibling distance=7mm] { + "5th Edition" -> { "6th Edition", "PWB 1.0" }; + "6th Edition" -> { "LSX", "1 BSD", "Mini Unix", "Wollongong", "Interdata" }; + "Interdata" -> { "Unix/TS 3.0", "PWB 2.0", "7th Edition" }; + "7th Edition" -> { "8th Edition", "32V", "V7M", "Ultrix-11", "Xenix", "UniPlus+" }; + "V7M" -> "Ultrix-11"; + "8th Edition" -> "9th Edition"; + "1 BSD" -> "2 BSD" -> "2.8 BSD" -> { "Ultrix-11", "2.9 BSD" }; + "32V" -> "3 BSD" -> "4 BSD" -> "4.1 BSD" -> { "4.2 BSD", "2.8 BSD", "8th Edition" }; + "4.2 BSD" -> { "4.3 BSD", "Ultrix-32" }; + "PWB 1.0" -> { "PWB 1.2" -> "PWB 2.0", "USG 1.0" -> { "CB Unix 1", "USG 2.0" }}; + "CB Unix 1" -> "CB Unix 2" -> "CB Unix 3" -> { "Unix/TS++", "PDP-11 Sys V" }; + { "USG 2.0" -> "USG 3.0", "PWB 2.0", "Unix/TS 1.0" } -> "Unix/TS 3.0"; + { "Unix/TS++", "CB Unix 3", "Unix/TS 3.0" } -> + "TS 4.0" -> "System V.0" -> "System V.2" -> "System V.3"; + }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout.runs" +summary "Determines, how many times the crossing minimization is repeated." +documentation +[[ +Each repetition (except for the first) starts with +randomly permuted nodes on each layer. Deterministic behaviour can +be achieved by setting |SugiyamaLayout.runs| to 1. +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout.transpose" +documentation +[[ +Determines whether the transpose step is performed +after each 2-layer crossing minimization; this step tries to +reduce the number of crossings by switching neighbored nodes on +a layer. +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "SugiyamaLayout.fails" +documentation +[[ +The number of times that the number of crossings may +not decrease after a complete top-down bottom-up traversal, +before a run is terminated. +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua new file mode 100644 index 00000000000..e9c2c427774 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout.lua,v 1.1 2013/03/15 15:04:41 tantau Exp $ + + + +--- +-- @section subsection {Miscellaneous Algorithms for Graph Drawing} +-- +-- + +local _ \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua new file mode 100644 index 00000000000..9a8dd45a641 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua @@ -0,0 +1,48 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/BalloonLayout.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "BalloonLayout" +summary "A ``balloon layout''." + +documentation +[[ +This algorithm computes a radial (balloon) layout based on a +spanning tree. The algorithm is partially based on the paper +\emph{On Balloon Drawings of Rooted Trees} by Lin and Yen and on +\emph{Interacting with Huge Hierarchies: Beyond Cone Trees} by +Carriere and Kazman. +]] + +example +[[ +\tikz \graph [BalloonLayout] { a -- {b,c,d -- {e,f,h,h,i}, j -- k -- {l,m,n}} }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "BalloonLayout.evenAngles" +summary "Subtrees may be assigned even angles or angles depending on their size." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua new file mode 100644 index 00000000000..4cada7886b4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua @@ -0,0 +1,95 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/misclayout/CircularLayout.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "CircularLayout" +summary "The circular layout algorithm." + +documentation +[[ +The implementation used in CircularLayout is based on the following publication: + +\begin{itemize} +\item Ugur Dogrus\"oz, Brendan Madden, Patrick Madden: Circular + Layout in the Graph Layout Toolkit. \emph{Proc. Graph Drawing 1996,} + LNCS 1190, pp. 92--100, 1997. +\end{itemize} +]] + +example +[[ +\tikz \graph [CircularLayout] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "CircularLayout.minDistCircle" +summary "The minimal padding between nodes on a circle." + +documentation "This is an alias for |part sep|." + +example +[[ +\tikz \graph [CircularLayout, part sep=1cm] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CircularLayout.minDistLevel" +summary "The minimal padding between nodes on different levels." + +documentation "This is an alias for |layer sep| and |level sep|." + +example +[[ +\tikz \graph [CircularLayout, layer sep=1cm] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + +-------------------------------------------------------------------------------- +key "CircularLayout.minDistSibling" +summary "The minimal padding between sibling nodes." + +documentation "This is an alias for |sibling sep|." + +example +[[ +\tikz \graph [CircularLayout, sibling sep=1cm] { + a -- b -- c -- a -- d -- e -- f -- g -- d; + b -- {x,y,z}; +}; +]] +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua new file mode 100644 index 00000000000..97d3a7f0191 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua @@ -0,0 +1,18 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/AcyclicSubgraphModule.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +--- +-- @section subsubsection {Computing Acyclic Subgraphs Module} +-- + +local _ + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua new file mode 100644 index 00000000000..9ee6a534eb4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/HierarchyLayoutModule.lua,v 1.1 2013/03/07 22:28:37 tantau Exp $ + + +--- +-- @section subsubsection {The Hierarchy Layout Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua new file mode 100644 index 00000000000..7fc5c535f2d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/InitialPlacer.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +--- +-- @section subsubsection {The Initial Placer Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua new file mode 100644 index 00000000000..d79f1c41fc7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/MultilevelBuilder.lua,v 1.1 2013/03/15 15:04:43 tantau Exp $ + + +--- +-- @section subsubsection {The Multilevel Builder Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua new file mode 100644 index 00000000000..672a3375358 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/RankingModule.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +--- +-- @section subsubsection {The Ranking Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua new file mode 100644 index 00000000000..edc96e7b49f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua @@ -0,0 +1,17 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/module/TwoLayerCrossMin.lua,v 1.1 2013/03/07 22:28:37 tantau Exp $ + + +--- +-- @section subsubsection {The Two Layer Crossing Minimization Module} +-- + +local _ diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua new file mode 100644 index 00000000000..66835b6f012 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua @@ -0,0 +1,19 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity.lua,v 1.1 2013/05/23 20:01:26 tantau Exp $ + + + +--- +-- @section subsection {Algorithms for Drawing Planar Graphs} +-- +-- + +local _ \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua new file mode 100644 index 00000000000..bceba167894 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua @@ -0,0 +1,66 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/ogdf/planarity/PlanarizationLayout.lua,v 1.1 2013/05/23 20:01:26 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------------------- +key "PlanarizationLayout" +summary "The planarization layout algorithm." + +documentation +[[ +A |PlanarizationLayout| represents a customizable implementation +of the planarization approach for drawing graphs. The implementation +used in PlanarizationLayout is based on the following publication: + +\begin{itemize} +\item C. Gutwenger, P. Mutzel: \emph{An Experimental Study of Crossing + Minimization Heuristics.} 11th International Symposium on Graph + Drawing 2003, Perugia (GD '03), LNCS 2912, pp. 13-24, 2004. +\end{itemize} +]] + +example +[[ +\tikz \graph [PlanarizationLayout] { a -- {b,c,d,e,f} -- g -- a }; +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "PlanarizationLayout.preprocessCliques" +summary "Configures, whether cliques are collapsed in a preprocessing step." +documentation +[[ +If set to true, a preprocessing for cliques (complete subgraphs) +is performed and cliques will be laid out in a special form (straight-line, +not orthogonal). The preprocessing may reduce running time and improve +layout quality if the input graphs contains dense subgraphs. +]] +-------------------------------------------------------------------------------- + + + +-------------------------------------------------------------------------------- +key "PlanarizationLayout.minCliqueSize" +summary "The minimum size of cliques collapsed in preprocessing." +-------------------------------------------------------------------------------- + + +-- Local Variables: +-- mode:latex +-- End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua new file mode 100644 index 00000000000..794214c5f74 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua @@ -0,0 +1,309 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/doc/trees/ReingoldTilford1981.lua,v 1.1 2013/03/05 23:44:30 tantau Exp $ + + +local key = require 'pgf.gd.doc'.key +local documentation = require 'pgf.gd.doc'.documentation +local summary = require 'pgf.gd.doc'.summary +local example = require 'pgf.gd.doc'.example + + +-------------------------------------------------------------------- +key "tree layout" + +summary "This layout uses the Reingold--Tilform method for drawing trees." + +documentation +[[ +The Reingold--Tilford method is a standard method for drawing +trees. It is described in: +\begin{itemize} +\item + E.~M.\ Reingold and J.~S.\ Tilford, + \newblock Tidier drawings of trees, + \newblock \emph{IEEE Transactions on Software Engineering,} + 7(2), 223--228, 1981. +\end{itemize} +My implementation in |graphdrawing.trees| follows the following paper, which +introduces some nice extensions of the basic algorithm: +\begin{itemize} +\item + A.\ Br\"uggemann-Klein, D.\ Wood, + \newblock Drawing trees nicely with \TeX, + \emph{Electronic Publishing,} 2(2), 101--115, 1989. +\end{itemize} +As a historical remark, Br\"uggemann-Klein and Wood have implemented +their version of the Reingold--Tilford algorithm directly in \TeX\ +(resulting in the Tree\TeX\ style). With the power of Lua\TeX\ at +our disposal, the 2012 implementation in the |graphdrawing.tree| +library is somewhat more powerful and cleaner, but it really was an +impressive achievement to implement this algorithm back in 1989 +directly in \TeX. + +The basic idea of the Reingold--Tilford algorithm is to use the +following rules to position the nodes of a tree (the following +description assumes that the tree grows downwards, other growth +directions are handled by the automatic orientation mechanisms of +the graph drawing library): +\begin{enumerate} +\item For a node, recursively compute a layout for each of its children. +\item Place the tree rooted at the first child somewhere on the page. +\item Place the tree rooted at the second child to the right of the + first one as near as possible so that no two nodes touch (and such + that the |sibling sep| padding is not violated). +\item Repeat for all subsequent children. +\item Then place the root above the child trees at the middle + position, that is, at the half-way point between the left-most and + the right-most child of the node. +\end{enumerate} +The standard keys |level distance|, |level sep|, |sibling distance|, +and |sibling sep|, as well as the |pre| and |post| versions of these +keys, as taken into consideration when nodes are positioned. See also +Section~\ref{subsection-gd-dist-pad} for details on these keys. + +\noindent\textbf{Handling of Missing Children.} +As described in Section~\ref{section-gd-missing-children}, you can +specify that some child nodes are ``missing'' in the tree, but some +space should be reserved for them. This is exactly what happens: +When the subtrees of the children of a node are arranged, each +position with a missing child is treated as if a zero-width, +zero-height subtree were present at that positions: +\begin{codeexample}[] +\tikz [tree layout, nodes={draw,circle}] + \node {r} + child { node {a} + child [missing] + child { node {b} } + } + child[missing]; +\end{codeexample} +or in |graph| syntax: +\begin{codeexample}[] + \tikz \graph [tree layout, nodes={draw,circle}] + { + r -> { + a -> { + , %missing + b}, + % missing + } + }; +\end{codeexample} +More than one child can go missing: +\begin{codeexample}[] +\tikz \graph [tree layout, nodes={draw,circle}, sibling sep=0pt] + { r -> { a, , ,b -> {c,d}, ,e} }; +\end{codeexample} +Although missing children are taken into consideration for the +computation of the placement of the children of a root node relative +to one another and also for the computation of the position of the +root node, they are usually \emph{not} considered as part of the +``outline'' of a subtree (the \texttt{minimum number of children} +key ensures that |b|, |c|, |e|, and |f| all have a missing right +child): +\begin{codeexample}[] +\tikz \graph [tree layout, minimum number of children=2, + nodes={draw,circle}] + { a -> { b -> c -> d, e -> f -> g } }; +\end{codeexample} +This behaviour of ``ignoring'' missing children in later stages of +the recursion can be changed using the key |missing nodes get space|. + +\noindent\textbf{Significant Pairs of Siblings.} +Br\"uggemann-Klein and Wood have proposed an extension of the +Reingold--Tilford method that is intended to better highlight the +overall structure of a tree. Consider the following two trees: + +\begin{codeexample}[] +\tikz [baseline=(a.base), tree layout, minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + };\quad +\tikz [baseline=(a.base), tree layout, minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- d -- e, i -- j -- { f -- {g,h}, k } } + }; +\end{codeexample} +As observed by Br\"uggemann-Klein and Wood, the two trees are +structurally quite different, but the Reingold--Tilford method +places the nodes at exactly the same positions and only one edge +``switches'' positions. In order to better highlight the differences +between the trees, they propose to add a little extra separation +between siblings that form a \emph{significant pair}. They define +such a pair as follows: Consider the subtrees of two adjacent +siblings. There will be one or more levels where these subtrees have +a minimum distance. For instance, the following two trees the +subtrees of the nodes |a| and |b| have a minimum distance only at +the top level in the left example, and in all levels in the second +example. A \emph{significant pair} is a pair of siblings where the +minimum distance is encountered on any level other than the first +level. Thus, in the first example there is no significant pair, +while in the second example |a| and |b| form such a pair. +\begin{codeexample}[] +\tikz \graph [tree layout, minimum number of children=2, + level distance=5mm, nodes={circle,draw}] + { / -> { a -> / -> /, b -> /[second] -> /[second] }}; + \quad +\tikz \graph [tree layout, minimum number of children=2, + level distance=5mm, nodes={circle,draw}] + { / -> { a -> / -> /, b -> / -> / }}; +\end{codeexample} +Whenever the algorithm encounters a significant pair, it adds extra +space between the siblings as specified by the |significant sep| +key. +]] + + +example +[[ +\tikz [tree layout, sibling distance=8mm] + \graph [nodes={circle, draw, inner sep=1.5pt}]{ + 1 -- { 2 -- 3 -- { 4 -- 5, 6 -- { 7, 8, 9 }}, 10 -- 11 -- { 12, 13 } } + }; +]] + + +example +[[ +\tikz [tree layout, grow=-30, + sibling distance=0mm, level distance=0mm,] + \graph [nodes={circle, draw, inner sep=1.5pt}]{ + 1 -- { 2 -- 3 -- { 4 -- 5, 6 -- { 7, 8, 9 }}, 10 -- 11 -- { 12, 13 } } + }; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "missing nodes get space" + +summary +[[ +When set to true, missing children are treated as if they +where zero-width, zero-height nodes during the whole tree layout +process. +]] + + +example +[[ +\tikz \graph [tree layout, missing nodes get space, + minimum number of children=2, nodes={draw,circle}] +{ a -> { b -> c -> d, e -> f -> g } }; +]] +-------------------------------------------------------------------- + + + + + +-------------------------------------------------------------------- +key "significant sep" + +summary +[[ This space is added to signifcant pairs by the modified +Reingold--Tilford algorithm. ]] + +example +[[ +\tikz [baseline=(a.base), tree layout, significant sep=1em, + minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + };\quad +\tikz [baseline=(a.base), tree layout, significant sep=1em, + minimum number of children=2, + sibling distance=5mm, level distance=5mm] + \graph [nodes={circle, inner sep=0pt, minimum size=2mm, fill, as=}]{ + a -- { b -- c -- d -- e, i -- j -- { f -- {g,h}, k } } + }; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "binary tree layout" + +summary +[[ A layout based on the Reingold--Tilford method for drawing +binary trees. ]] + +documentation +[[ +This key executes: +\begin{enumerate} +\item |tree layout|, thereby selecting the Reingold--Tilford method, +\item |minimum number of children=2|, thereby ensuring the all nodes + have (at least) two children or none at all, and +\item |significant sep=10pt| to highlight significant pairs. +\end{enumerate} +In the examples, the last one is taken from the paper of +Br\"uggemann-Klein and Wood. It demonstrates nicely the +advantages of having the full power of \tikzname's anchoring and the +graph drawing engine's orientation mechanisms at one's disposal. +]] + + +example +[[ +\tikz [grow'=up, binary tree layout, sibling distance=7mm, level distance=7mm] + \graph { + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + }; +]] + +example +[[ +\tikz \graph [binary tree layout] { + Knuth -> { + Beeton -> Kellermann [second] -> Carnes, + Tobin -> Plass -> { Lamport, Spivak } + } +};\qquad +\tikz [>=spaced stealth'] + \graph [binary tree layout, grow'=right, level sep=1.5em, + nodes={right, fill=blue!50, text=white, chamfered rectangle}, + edges={decorate,decoration={snake, post length=5pt}}] + { + Knuth -> { + Beeton -> Kellermann [second] -> Carnes, + Tobin -> Plass -> { Lamport, Spivak } + } + }; +]] +-------------------------------------------------------------------- + + + +-------------------------------------------------------------------- +key "extended binary tree layout" + +summary +[[ This algorithm is similar to |binary tree layout|, only the +option \texttt{missing nodes get space} is executed and the +\texttt{significant sep} is zero. ]] + +example +[[ +\tikz [grow'=up, extended binary tree layout, + sibling distance=7mm, level distance=7mm] + \graph { + a -- { b -- c -- { d -- e, f -- { g, h }}, i -- j -- k[second] } + }; +]] +-------------------------------------------------------------------- + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua new file mode 100644 index 00000000000..bf6907bddb1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/examples.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.examples = {} + + +-- Done + +return pgf.gd.examples \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua new file mode 100644 index 00000000000..ccaa91f9992 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/ASCIIDisplayer.lua @@ -0,0 +1,32 @@ +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" + +InterfaceToDisplay.bind(require "pgf.gd.examples.BindingToASCII") +require "pgf.gd.layered.library" +require "pgf.gd.force.library" + +local algorithm = io.read():match("%s*graph%s*%[(.-)%]") + +InterfaceToDisplay.pushPhase(algorithm, "main", 1) +InterfaceToDisplay.pushOption("level distance", 6, 2) +InterfaceToDisplay.pushOption("sibling distance", 8, 3) +InterfaceToDisplay.beginGraphDrawingScope(3) +InterfaceToDisplay.pushLayout(4) + +for line in io.lines() do + if line:match("}") then + break + elseif line:find("-") then + local n1, dir, n2 = string.match(line, "^%s*(.-)%s*(-.)%s*(.-)%s*;") + InterfaceToDisplay.createEdge(n1, n2, dir, 4) + else + local n1 = string.match(line, "^%s*(.-)%s*;") + InterfaceToDisplay.createVertex(n1, "rectangle", nil, 4) + end +end + +InterfaceToDisplay.runGraphDrawingAlgorithm() +InterfaceToDisplay.renderGraph() +InterfaceToDisplay.endGraphDrawingScope() + + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua new file mode 100644 index 00000000000..9752254907a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/BindingToASCII.lua @@ -0,0 +1,87 @@ +local lib = require "pgf.gd.lib" + +-- Create a binding to ourselves +local BindingToASCII = lib.class { base_class = require "pgf.gd.bindings.Binding" } + +local canvas + +function BindingToASCII:renderStart() + canvas = {} + -- Clear the canvas + for x=-30,30 do + canvas [x] = {} + for y=-30,30 do + canvas[x][y] = ' ' + end + end +end + +function BindingToASCII:renderStop() + for y=10,-30,-1 do + local t = {} + for x=-30,30 do + local s = canvas[x][y] + for i=1,#s do + pos = x+30+i-math.floor(#s/2) + if not t[pos] or t[pos] == " " or t[pos] == "." then + t[pos] = string.sub(s,i,i) + end + end + end + print(table.concat(t)) + end +end + +function BindingToASCII:renderVertex(v) + canvas [math.floor(v.pos.x)][math.floor(v.pos.y)] = v.name +end + +function BindingToASCII:renderEdge(e) + + local function connect (p,q) + + local x1, y1, x2, y2 = math.floor(p.x+0.5), math.floor(p.y+0.5), math.floor(q.x+0.5), math.floor(q.y+0.5) + + -- Go upward with respect to x + if x2 < x1 then + x1, y1, x2, y2 = x2, y2, x1, y1 + end + + local delta_x = x2-x1 + local delta_y = y2-y1 + + if math.abs(delta_x) > math.abs(delta_y) then + local slope = delta_y/delta_x + for i=x1,x2 do + local x,y = i, math.floor(y1 + (i-x1)*slope + 0.5) + + if canvas[x][y] == " " then + canvas[x][y] = '.' + end + end + elseif math.abs(delta_y) > 0 then + local slope = delta_x/delta_y + for i=y1,y2,(y1 [red] f; % normal edge + + % Edges generated by the algorithm: + a[new edge to=b]; + b[new edge to=d]; + c[new edge to=f]; +}; +\end{codeexample} + + And the algorithm: +\begin{codeexample}[code only, tikz syntax=false] + -- File pgf.gd.examples.SimpleEdgeDemo + + -- Imports + local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" + local declare = InterfaceToAlgorithms.declare + + -- The class object + local SimpleEdgeDemo = {} + +declare { + key = "simple edge demo layout", + algorithm = SimpleEdgeDemo, + summary = "This algorithm shows...", +} +\end{codeexample} + + Next comes the declaration of the new option |new edge to|: + +\begin{codeexample}[code only, tikz syntax=false] +declare { + key = "new edge to", + type = "string", + summary = "This option takes the name of a vertex..." +} +\end{codeexample} + + Finally, the algorithm's code: + +\begin{codeexample}[code only, tikz syntax=false] +function SimpleEdgeDemo:run() + -- As in a SimpleDemo: + ... + -- Now add some edges: + for _,tail in ipairs(g.vertices) do + local name = tail.options['new edge to'] + if name then + local node = InterfaceToAlgorithms.findVertexByName(name) + if node and self.digraph:contains(node) then + InterfaceToAlgorithms.createEdge (self, tail, node) + end + end + end +end +\end{codeexample} + "]] +} + +--- +declare { + key = "new edge to", + type = "string", + + summary = [[" + This option takes the name of a vertex. An edge leading to this + vertex is added to the syntactic digraph. + "]] +} + + +function SimpleEdgeDemo:run() + + -- As in a SimpleDemo: + local g = self.digraph + local alpha = (2 * math.pi) / #g.vertices + + for i,vertex in ipairs(g.vertices) do + local radius = vertex.options['radius'] or g.options['radius'] + vertex.pos.x = radius * math.cos(i * alpha) + vertex.pos.y = radius * math.sin(i * alpha) + end + + -- Now add some edges: + for _,tail in ipairs(g.vertices) do + local name = tail.options['new edge to'] + if name then + local node = InterfaceToAlgorithms.findVertexByName(name) + if node and self.digraph:contains(node) then + InterfaceToAlgorithms.createEdge (self, tail, node) + end + end + end +end + +return SimpleEdgeDemo \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua new file mode 100644 index 00000000000..1e3bd381e79 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua @@ -0,0 +1,277 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/examples/SimpleHuffman.lua,v 1.5 2013/12/20 14:44:46 tantau Exp $ + + +--- +-- @section subsubsection {How To Generate Nodes Inside an Algorithm} +-- +-- @end + + + +-- Imports +local layered = require "pgf.gd.layered" +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +-- The class +local SimpleHuffman = {} + + +--- + +declare { + key = "simple Huffman layout", + algorithm = SimpleHuffman, + + postconditions = { + upward_oriented = true + }, + + summary = [[" + This algorithm demonstrates how an algorithm can generate new + nodes. + "]], + documentation = [[" + The input graph should just consist of some nodes (without + edges) and each node should have a |probability| key set. The nodes + will then be arranged in a line (as siblings) and a Huffman tree + will be constructed ``above'' these nodes. For the construction of + the Huffman tree, new nodes are created and connected. + + \pgfgdset{ + HuffmanLabel/.style={/tikz/edge node={node[fill=white,font=\footnotesize,inner sep=1pt]{#1}}}, + HuffmanNode/.style={/tikz/.cd,circle,inner sep=0pt,outer sep=0pt,draw,minimum size=3pt} + } + +\begin{codeexample}[] +\tikz \graph [simple Huffman layout, + level distance=7mm, sibling distance=8mm, grow'=up] +{ + a ["0.5", probability=0.5], + b ["0.12", probability=0.12], + c ["0.2", probability=0.2], + d ["0.1", probability=0.1], + e ["0.11", probability=0.11] +}; +\end{codeexample} + The file starts with some setups and declarations: +\begin{codeexample}[code only, tikz syntax=false] +-- File pgf.gd.examples.SimpleHuffman + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + +-- The class +local SimpleHuffman = {} + +declare { + key = "simple Huffman layout", + algorithm = SimpleHuffman, + postconditions = { upward_oriented = true } + summary = "..." +} + +declare { + key = "probability", + type = "number", + initial = "1", + summary = "..." +} + +-- Import +local layered = require "pgf.gd.layered" +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local Storage = require "pgf.gd.lib.Storage" + +local probability = Storage.new() +local layer = Storage.new() + +function SimpleHuffman:run() + -- Construct a Huffman tree on top of the vertices... +\end{codeexample} + + Next comes a setup, where we create the working list of vertices + that changes as the Huffman coding method proceeds: +\begin{codeexample}[code only, tikz syntax=false] + -- Shorthand + local function prop (v) + return probability[v] or v.options['probability'] + end + + -- Copy the vertex table, since we are going to modify it: + local vertices = {} + for i,v in ipairs(self.ugraph.vertices) do + vertices[i] = v + end +\end{codeexample} + + The initial vertices are arranged in a line on the last layer. The + function |ideal_sibling_distance| takes care of the rather + complicated handling of the (possibly rotated) bounding boxes and + separations. The |props| and |layer| are tables used by + algorithms to ``store stuff'' at a vertex or at an arc. The + table will be accessed by |arrange_layers_by_baselines| to + determine the ideal vertical placements. +\begin{codeexample}[code only, tikz syntax=false] + -- Now, arrange the nodes in a line: + vertices [1].pos.x = 0 + layer[ vertices [1] ] = #vertices + for i=2,#vertices do + local d = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, vertices[i-1], vertices[i]) + vertices [i].pos.x = vertices[i-1].pos.x + d + layer[ vertices [i] ] = #vertices + end +\end{codeexample} + + Now comes the actual Huffman algorithm: Always find the vertices + with a minimal probability\dots +\begin{codeexample}[code only, tikz syntax=false] + -- Now, do the Huffman thing... + while #vertices > 1 do + -- Find two minimum probabilities + local min1, min2 + + for i=1,#vertices do + if not min1 or prop(vertices[i]) < prop(vertices[min1]) then + min2 = min1 + min1 = i + elseif not min2 or prop(vertices[i]) < prop(vertices[min2]) then + min2 = i + end + end +\end{codeexample} + \dots and connect them with a new node. This new node gets the + option |HuffmanNode|. It is now the job of the higher layers to map + this option to something ``nice''. +\begin{codeexample}[code only, tikz syntax=false] + -- Create new node: + local p = prop(vertices[min1]) + prop(vertices[min2]) + local v = InterfaceToAlgorithms.createVertex(self, { generated_options = {{key="HuffmanNode"}}}) + probability[v] = p + layer[v] = #vertices-1 + v.pos.x = (vertices[min1].pos.x + vertices[min2].pos.x)/2 + vertices[#vertices + 1] = v + + InterfaceToAlgorithms.createEdge (self, v, vertices[min1], + {generated_options = {{key="HuffmanLabel", value = "0"}}}) + InterfaceToAlgorithms.createEdge (self, v, vertices[min2], + {generated_options = {{key="HuffmanLabel", value = "1"}}}) + + table.remove(vertices, math.max(min1, min2)) + table.remove(vertices, math.min(min1, min2)) + end +\end{codeexample} + Ok, we are mainly done now. Finish by computing vertical placements + and do formal cleanup. +\begin{codeexample}[code only, tikz syntax=false] + layered.arrange_layers_by_baselines(layers, self.adjusted_bb, self.ugraph) +end +\end{codeexample} + + In order to use the class, we have to make sure that, on the + display layer, the options |HuffmanLabel| and |HuffmanNode| are + defined. This is done by adding, for instance, the following to + \tikzname: +\begin{codeexample}[code only] +\pgfkeys{ + /graph drawing/HuffmanLabel/.style={ + /tikz/edge node={node[fill=white,font=\footnotesize,inner sep=1pt]{#1}} + }, + /graph drawing/HuffmanNode/.style={ + /tikz/.cd,circle,inner sep=0pt,outer sep=0pt,draw,minimum size=3pt + } +} +\end{codeexample} + "]] +} + + +--- + +declare { + key = "probability", + type = "number", + initial = "1", + + summary = [[" + The probability parameter. It is used by the Huffman algorithm to + group nodes. + "]] +} + +-- Imports + +local Storage = require 'pgf.gd.lib.Storage' + +-- Storages + +local probability = Storage.new() +local layer = Storage.new() + + +function SimpleHuffman:run() + -- Construct a Huffman tree on top of the vertices... + + -- Shorthand + local function prop (v) + return probability[v] or v.options['probability'] + end + + -- Copy the vertex table, since we are going to modify it: + local vertices = {} + for i,v in ipairs(self.ugraph.vertices) do + vertices[i] = v + end + + -- Now, arrange the nodes in a line: + vertices [1].pos.x = 0 + layer[vertices [1]] = #vertices + for i=2,#vertices do + local d = layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, vertices[i-1], vertices[i]) + vertices [i].pos.x = vertices[i-1].pos.x + d + layer[vertices [i]] = #vertices + end + + -- Now, do the Huffman thing... + while #vertices > 1 do + -- Find two minimum probabilities + local min1, min2 + + for i=1,#vertices do + if not min1 or prop(vertices[i]) < prop(vertices[min1]) then + min2 = min1 + min1 = i + elseif not min2 or prop(vertices[i]) < prop(vertices[min2]) then + min2 = i + end + end + + -- Create new node: + local p = prop(vertices[min1]) + prop(vertices[min2]) + local v = InterfaceToAlgorithms.createVertex(self, { generated_options = {{key="HuffmanNode"}}}) + probability[v] = p + layer[v] = #vertices-1 + v.pos.x = (vertices[min1].pos.x + vertices[min2].pos.x)/2 + vertices[#vertices + 1] = v + + InterfaceToAlgorithms.createEdge (self, v, vertices[min1], + {generated_options = {{key="HuffmanLabel", value = "0"}}}) + InterfaceToAlgorithms.createEdge (self, v, vertices[min2], + {generated_options = {{key="HuffmanLabel", value = "1"}}}) + + table.remove(vertices, math.max(min1, min2)) + table.remove(vertices, math.min(min1, min2)) + end + + layered.arrange_layers_by_baselines(layer, self.adjusted_bb, self.ugraph) +end + +return SimpleHuffman \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt new file mode 100644 index 00000000000..052ebdcdb81 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/example_graph_for_ascii_displayer.txt @@ -0,0 +1,20 @@ +graph [layered layout] { + Alice; + Bob; + Charly; + Dave; + Eve; + Fritz; + George; + Alice -> Bob; + Alice -> Charly; + Charly -> Dave; + Bob -> Dave; + Dave -> Eve; + Eve -> Fritz; + Fritz -> Alice; + George -> Eve; + George -> Fritz; + Alice -> George; +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua new file mode 100644 index 00000000000..0c8038d3148 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua @@ -0,0 +1,30 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/examples/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- This package presents some examples of how different aspects of the +-- graph drawing engine can be used. In particular, the algorithms of +-- this package are not really meant to be used to layout graphs +-- (although they can be used, in principle); rather you are invited +-- to have a look at their implementation and to adapt them to your needs. +-- +-- @library + +local examples + + +-- Load algorithms from: +require "pgf.gd.examples.SimpleDemo" +require "pgf.gd.examples.SimpleEdgeDemo" +require "pgf.gd.examples.SimpleHuffman" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua new file mode 100644 index 00000000000..cb30ec17914 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force.lua,v 1.1 2012/11/27 17:24:23 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.force = {} + + +-- Done + +return pgf.gd.force \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua new file mode 100644 index 00000000000..c9739dcaf63 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua @@ -0,0 +1,435 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/CoarseGraph.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +--- A class for handling "coarse" versions of a graph. Such versions contain +-- less nodes and edges than the original graph while retaining the overall +-- structure. + +local Graph = require "pgf.gd.deprecated.Graph" -- we subclass from here +local CoarseGraph = Graph.new() +CoarseGraph.__index = CoarseGraph + + + +-- Namespace: +local force = require "pgf.gd.force" +force.CoarseGraph = CoarseGraph + + +-- Imports +local Node = require "pgf.gd.deprecated.Node" +local Edge = require "pgf.gd.deprecated.Edge" + +local lib = require "pgf.gd.lib" + + +-- Class setup + +CoarseGraph.COARSEN_INDEPENDENT_EDGES = 0 -- TT: Remark: These uppercase constants are *ugly*. Why do people do this?! +CoarseGraph.COARSEN_INDEPENDENT_NODES = 1 +CoarseGraph.COARSEN_HYBRID = 2 + + + +--- Creates a new coarse graph derived from an existing graph. +-- +-- Generates a coarse graph for the input |Graph|. +-- +-- Coarsening describes the process of reducing the amount of nodes in a graph +-- by merging nodes into supernodes. There are different strategies, called +-- schemes, that can be applied, like merging nodes that belong to edges in a +-- maximal independent edge set or by creating supernodes based on a maximal +-- independent node set. +-- +-- Coarsening is not performed automatically. The functions |CoarseGraph:coarsen| +-- and |CoarseGraph:interpolate| can be used to further coarsen the graph or +-- to restore the previous state (while interpolating the node positions from +-- the coarser version of the graph). +-- +-- Note, however, that the input \meta{graph} is always modified in-place, so +-- if the original version of \meta{graph} is needed in parallel to its +-- coarse representations, a deep copy of \meta{grpah} needs to be passed over +-- to |CoarseGraph.new|. +-- +-- @param graph An existing graph that needs to be coarsened. +-- @param scheme Coarsening scheme to use. Possible values are:\par +-- |CoarseGraph.COARSEN_INDEPENDENT_EDGES|: +-- Coarsen the input graph by computing a maximal independent edge set +-- and collapsing edges from this set. The resulting coarse graph has +-- at least 50% of the nodes of the input graph. This coarsening scheme +-- gives slightly better results than +-- |CoarseGraph.COARSEN_INDEPENDENT_NODES| because it is less aggressive. +-- However, this comes at higher computational cost.\par +-- |CoarseGraph.COARSEN_INDEPENDENT_NODES|: +-- Coarsen the input graph by computing a maximal independent node set, +-- making nodes from this set supernodes in the coarse graph, merging +-- adjacent nodes into the supernodes and connecting the supernodes +-- if their grpah distance is no greater than three. This scheme gives +-- slightly worse results than |CoarseGraph.COARSEN_INDEPENDENT_EDGES| +-- but is computationally more efficient.\par +-- |CoarseGraph.COARSEN_HYBRID|: Combines the other schemes by starting +-- with |CoarseGraph.COARSEN_INDEPENDENT_EDGES| and switching to +-- |CoarseGraph.COARSEN_INDEPENDENT_NODES| as soon as the first scheme +-- does not reduce the amount of nodes by a factor of 25%. +-- +function CoarseGraph.new(graph, scheme) + local coarse_graph = { + graph = graph, + level = 0, + scheme = scheme or CoarseGraph.COARSEN_INDEPENDENT_EDGES, + ratio = 0, + } + setmetatable(coarse_graph, CoarseGraph) + return coarse_graph +end + + + +local function custom_merge(table1, table2, first_metatable) + local result = table1 and lib.copy(table1) or {} + local first_metatable = first_metatable == true or false + + for key, value in pairs(table2) do + if not result[key] then + result[key] = value + end + end + + if not first_metatable or not getmetatable(result) then + setmetatable(result, getmetatable(table2)) + end + + return result +end + + +local function pairs_by_sorted_keys (t, f) + local a = {} + for n in pairs(t) do a[#a + 1] = n end + table.sort (a, f) + local i = 0 + return function () + i = i + 1 + return a[i], t[a[i]] + end +end + + + +function CoarseGraph:coarsen() + -- update the level + self.level = self.level + 1 + + local old_graph_size = #self.graph.nodes + + if self.scheme == CoarseGraph.COARSEN_INDEPENDENT_EDGES then + local matching, unmatched_nodes = self:findMaximalMatching() + + for _,edge in ipairs(matching) do + -- get the two nodes of the edge that we are about to collapse + local u, v = edge.nodes[1], edge.nodes[2] + + assert(u ~= v, 'the edge ' .. tostring(edge) .. ' is a loop. loops are not supported by this algorithm') + + -- create a supernode + local supernode = Node.new{ + name = '(' .. u.name .. ':' .. v.name .. ')', + weight = u.weight + v.weight, + subnodes = { u, v }, + subnode_edge = edge, + level = self.level, + } + + -- add the supernode to the graph + self.graph:addNode(supernode) + + -- collact all neighbours of the nodes to merge, create a node -> edge mapping + local u_neighbours = lib.map(u.edges, function(edge) return edge, edge:getNeighbour(u) end) + local v_neighbours = lib.map(v.edges, function(edge) return edge, edge:getNeighbour(v) end) + + -- remove the two nodes themselves from the neighbour lists + u_neighbours = lib.map(u_neighbours, function (edge,node) if node ~= v then return edge,node end end) + v_neighbours = lib.map(v_neighbours, function (edge,node) if node ~= u then return edge,node end end) + + -- compute a list of neighbours u and v have in common + local common_neighbours = lib.map(u_neighbours, + function (edge,node) + if v_neighbours[node] ~= nil then return edge,node end + end) + + -- create a node -> edges mapping for common neighbours + common_neighbours = lib.map(common_neighbours, function (edge, node) + return { edge, v_neighbours[node] }, node + end) + + -- drop common edges from the neighbour mappings + u_neighbours = lib.map(u_neighbours, function (val,node) if not common_neighbours[node] then return val,node end end) + v_neighbours = lib.map(v_neighbours, function (val,node) if not common_neighbours[node] then return val,node end end) + + -- merge neighbour lists + local disjoint_neighbours = custom_merge(u_neighbours, v_neighbours) + + -- create edges between the supernode and the neighbours of the merged nodes + for neighbour, edge in pairs_by_sorted_keys(disjoint_neighbours, function (n,m) return n.index < m.index end) do + + -- create a superedge to replace the existing one + local superedge = Edge.new{ + direction = edge.direction, + weight = edge.weight, + subedges = { edge }, + level = self.level, + } + + -- add the supernode and the neighbour to the edge + if u_neighbours[neighbour] then + superedge:addNode(neighbour) + superedge:addNode(supernode) + + else + superedge:addNode(supernode) + superedge:addNode(neighbour) + + end + + -- replace the old edge + self.graph:addEdge(superedge) + self.graph:deleteEdge(edge) + end + + -- do the same for all neighbours that the merged nodes have + -- in common, except that the weights of the new edges are the + -- sums of the of the weights of the edges to the common neighbours + for neighbour, edges in pairs_by_sorted_keys(common_neighbours, function (n,m) return n.index < m.index end) do + local weights = 0 + for _,e in ipairs(edges) do + weights = weights + edge.weight + end + + local superedge = Edge.new{ + direction = Edge.UNDIRECTED, + weight = weights, + subedges = edges, + level = self.level, + } + + -- add the supernode and the neighbour to the edge + superedge:addNode(supernode) + superedge:addNode(neighbour) + + -- replace the old edges + self.graph:addEdge(superedge) + for _,edge in ipairs(edges) do + self.graph:deleteEdge(edge) + end + end + + -- delete the nodes u and v which were replaced by the supernode + assert(#u.edges == 1, 'node ' .. u.name .. ' is part of a multiedge') -- if this fails, then there is a multiedge involving u + assert(#v.edges == 1, 'node ' .. v.name .. ' is part of a multiedge') -- same here + self.graph:deleteNode(u) + self.graph:deleteNode(v) + end + else + assert(false, 'schemes other than CoarseGraph.COARSEN_INDEPENDENT_EDGES are not implemented yet') + end + + -- calculate the number of nodes ratio compared to the previous graph + self.ratio = #self.graph.nodes / old_graph_size +end + + + +function CoarseGraph:revertSuperedge(superedge) + -- TODO we can probably skip adding edges that have one or more + -- subedges with the same level. But that needs more testing. + + -- TODO we might have to pass the corresponding supernode to + -- this method so that we can move subnodes to the same + -- position, right? Interpolating seems to work fine without + -- though... + + if #superedge.subedges == 1 then + local subedge = superedge.subedges[1] + + if not self.graph:findNode(subedge.nodes[1].name) then + self.graph:addNode(subedge.nodes[1]) + end + + if not self.graph:findNode(subedge.nodes[2].name) then + self.graph:addNode(subedge.nodes[2]) + end + + if not self.graph:findEdge(subedge) then + subedge.nodes[1]:addEdge(subedge) + subedge.nodes[2]:addEdge(subedge) + self.graph:addEdge(subedge) + end + + if subedge.level and subedge.level >= self.level then + self:revertSuperedge(subedge) + end + else + for _,subedge in ipairs(superedge.subedges) do + if not self.graph:findNode(subedge.nodes[1].name) then + self.graph:addNode(subedge.nodes[1]) + end + + if not self.graph:findNode(subedge.nodes[2].name) then + self.graph:addNode(subedge.nodes[2]) + end + + if not self.graph:findEdge(subedge) then + subedge.nodes[1]:addEdge(subedge) + subedge.nodes[2]:addEdge(subedge) + self.graph:addEdge(subedge) + end + + if subedge.level and subedge.level >= self.level then + self:revertSuperedge(subedge) + end + end + end +end + + + +function CoarseGraph:interpolate() + -- FIXME TODO Jannis: This does not work now that we allow multi-edges + -- and loops! Reverting generates the same edges multiple times which leads + -- to distorted drawings compared to the awesome results we had before! + + local nodes = lib.copy(self.graph.nodes) + + for _,supernode in ipairs(nodes) do + assert(not supernode.level or supernode.level <= self.level) + + if supernode.level and supernode.level == self.level then + -- move the subnode to the position of the supernode and add it to the graph + supernode.subnodes[1].pos.x = supernode.pos.x + supernode.subnodes[1].pos.y = supernode.pos.y + + if not self.graph:findNode(supernode.subnodes[1].name) then + self.graph:addNode(supernode.subnodes[1]) + end + + -- move the subnode to the position of the supernode and add it to the graph + supernode.subnodes[2].pos.x = supernode.pos.x + supernode.subnodes[2].pos.y = supernode.pos.y + + if not self.graph:findNode(supernode.subnodes[2].name) then + self.graph:addNode(supernode.subnodes[2]) + end + + if not self.graph:findEdge(supernode.subnode_edge) then + supernode.subnodes[1]:addEdge(supernode.subnode_edge) + supernode.subnodes[2]:addEdge(supernode.subnode_edge) + self.graph:addEdge(supernode.subnode_edge) + end + + local superedges = lib.copy(supernode.edges) + + for _,superedge in ipairs(superedges) do + self:revertSuperedge(superedge) + end + + self.graph:deleteNode(supernode) + end + end + + -- Make sure that the nodes and edges are in the correct order: + table.sort (self.graph.nodes, function (a, b) return a.index < b.index end) + table.sort (self.graph.edges, function (a, b) return a.index < b.index end) + for _, n in pairs(self.graph.nodes) do + table.sort (n.edges, function (a, b) return a.index < b.index end) + end + + -- update the level + self.level = self.level - 1 +end + + + +function CoarseGraph:getSize() + return #self.graph.nodes +end + + + +function CoarseGraph:getRatio() + return self.ratio +end + + + +function CoarseGraph:getLevel() + return self.level +end + + + +function CoarseGraph:getGraph() + return self.graph +end + + + +function CoarseGraph:findMaximalMatching() + local matching = {} + local matched_nodes = {} + local unmatched_nodes = {} + + -- iterate over nodes in random order + for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do + local node = self.graph.nodes[j] + -- ignore nodes that have already been matched + if not matched_nodes[node] then + -- mark the node as matched + matched_nodes[node] = true + + -- filter out edges adjacent to neighbours already matched + local edges = lib.imap(node.edges, + function (edge) + if not matched_nodes[edge:getNeighbour(node)] then return edge end + end) + + -- FIXME TODO We use a light-vertex matching here. This is + -- different from the algorithm proposed by Hu which collapses + -- edges based on a heavy-edge matching... + if #edges > 0 then + -- sort edges by the weights of the node's neighbours + table.sort(edges, function (a, b) + return a:getNeighbour(node).weight < b:getNeighbour(node).weight + end) + + -- match the node against the neighbour with minimum weight + matched_nodes[edges[1]:getNeighbour(node)] = true + table.insert(matching, edges[1]) + end + end + end + + -- generate a list of nodes that were not matched at all + for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do + local node = self.graph.nodes[j] + if not matched_nodes[node] then + table.insert(unmatched_nodes, node) + end + end + + return matching, unmatched_nodes +end + + +-- done + +return CoarseGraph \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua new file mode 100644 index 00000000000..113f54b7ace --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua @@ -0,0 +1,28 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/Control.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Controlling and Configuring Force-Based Algorithms} +-- +-- All force-based algorithms are based on +-- a general pattern which we detail in the following. Numerous options +-- can be used to influence the behaviour of this general pattern; more +-- specific options that apply only to individual algorithms are +-- explained along with these algorithms. +-- +-- @end + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua new file mode 100644 index 00000000000..330f401d5b5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua @@ -0,0 +1,148 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlCoarsening.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +--- +-- @section subsubsection {Coarsening} +-- +-- @end + + +--- + +declare { + key = "coarsen", + type = "boolean", + initial = "true", + + summary = [[" + Defines whether or not a multilevel approach is used that + iteratively coarsens the input graph into graphs $G_1,\dots,G_l$ + with a smaller and smaller number of nodes. The coarsening stops as + soon as a minimum number of nodes is reached, as set via the + |minimum coarsening size| option, or if, in the last iteration, the + number of nodes was not reduced by at least the ratio specified via + |downsize ratio|. + "]], + documentation = [[" + A random initial layout is computed for the coarsest graph $G_l$ first. + Afterwards, it is laid out by computing the attractive and repulsive + forces between its nodes. + + In the subsequent steps, the previous coarse graph $G_{l-1}$ is + restored and its node positions are interpolated from the nodes + in~$G_l$. The graph $G_{l-1}$ is again laid out by computing the forces + between its nodes. These steps are repeated with $G_{l-2},\dots,G_1$ until + the original input graph $G_0$ has been restored, interpolated + and laid out. + + The idea behind this approach is that, by arranging recursively + formed supernodes first and then interpolating and arranging their + subnodes step by step, the algorithm is less likely to settle in a + local energy minimum (of which there can be many, particularly for + large graphs). The quality of the drawings with coarsening enabled is + expected to be higher than graphics where this feature is not applied. + + The following example demonstrates how coarsening can improve the + quality of graph drawings generated with Walshaw's algorihtm + |spring electrical layout'|. + "]], + examples = [[" + \tikz \graph [spring electrical layout', coarsen=false, vertical=3 to 4] + { + { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } + }; + + \tikz \graph [spring electrical layout', coarsen, vertical=3 to 4] + { + { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } + }; + "]] +} + +--- + +declare { + key = "minimum coarsening size", + type = "number", + initial = 2, + + summary = [[" + Defines the minimum number of nodes down to which the graph is + coarsened iteratively. The first graph that has a smaller or equal + number of nodes becomes the coarsest graph $G_l$, where $l$ is the + number of coarsening steps. The algorithm proceeds with the steps + described in the documentation of the |coarsen| option. + "]], + documentation = [[" + In the following example the same graph is coarsened down to two + and four nodes, respectively. The layout of the original graph is + interpolated from the random initial layout and is not improved + further because the forces are not computed (0 iterations). Thus, + in the two graphs, the nodes are placed at exactly two and four + coordinates in the final drawing. + "]], + examples = [[" + \tikz \graph [spring layout, iterations=0, + minimum coarsening size=2] + { subgraph C_n [n=8] }; + + \tikz \graph [spring layout, iterations=0, + minimum coarsening size=4] + { subgraph C_n [n=8] }; + "]] +} + +--- + +declare { + key = "downsize ratio", + type = "number", + initial = "0.25", + + summary = [[" + Minimum ratio between 0 and 1 by which the number of nodes between + two coarse graphs $G_i$ and $G_{i+1}$ need to be reduced in order for + the coarsening to stop and for the algorithm to use $G_{i+1}$ as the + coarsest graph $G_l$. Aside from the input graph, the optimal value + of |downsize ratio| mostly depends on the coarsening scheme being + used. Possible schemes are |collapse independent edges| and + |connect independent nodes|. + "]], + documentation = [[" + Increasing this option possibly reduces the number of coarse + graphs computed during the coarsening phase as coarsening will stop as + soon as a coarse graph does not reduce the number of nodes + substantially. This may speed up the algorithm but if the size of the + coarsest graph $G_l$ is much larger than |minimum coarsening size|, the + multilevel approach may not produce drawings as good as with a lower + |downsize ratio|. + "]], + examples = [[" + % 1. ratio too high, coarsening stops early, benefits are lost + \tikz \graph [spring electrical layout', + downsize ratio=1.0, + node distance=7mm, vertical=3 to 4] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + + % 2. ratio set to default, coarsening benefits are visible + \tikz \graph [spring electrical layout', + downsize ratio=0.2, + node distance=7mm, vertical=3 to 4] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + "]] +} + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua new file mode 100644 index 00000000000..d708bd6d7b7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua @@ -0,0 +1,100 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlElectric.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +--- +-- @section subsubsection {Forces and Their Effects: Electrical +-- Repulsion} +-- +-- @end + + +--- + +declare { + key = "electric charge", + type = "number", + initial = 1, + + summary = [[" + Defines the electric charge of the node. The stronger the + |electric charge| of a node the stronger the repulsion between the + node and others in the graph. A negative |electric charge| means that + other nodes are further attracted to the node rather than repulsed, + although in theory this effect strongly depends on how the + |spring electrical layout| algorithm works. + Two typcal effects of increasing the |electric charge| are distortion + of symmetries and an upscaling of the drawings. + "]], + examples = { + [[" + \tikz \graph [spring electrical layout, horizontal=0 to 1] + { 0 [electric charge=1] -- subgraph C_n [n=10] }; + "]], + [[" + \tikz \graph [spring electrical layout, horizontal=0 to 1] + { 0 [electric charge=5] -- subgraph C_n [n=10] }; + "]], + [[" + \tikz \graph [spring electrical layout, horizontal=0 to 1] + { [clique] 1 [electric charge=5], 2, 3, 4 }; + "]] + } +} + + +--- + +declare { + key = "electric force order", + type = "number", + initial = "1", + + summary = [[" + Sometimes, when drawing symmetric and mesh-like graphs, the + peripheral distortion caused by long-range electric forces may be + undesired. Some electric force models allow to reduce long-range + forces and distortion effects by increasing + the order (epxonent) of electric forces. Values between 0 and 1 + increase long-range electric forces and the scaling of the + generated layouts. Value greater than 1 decrease long-range + electric forces and results in shrinking drawings. + "]] + } + + +--- + +declare { + key = "approximate remote forces", + type = "boolean", + + summary = [[" + Force based algorithms often need to compute a force for each pair + of vertices, which, for larger numbers of vertices, can lead to a + significant time overhead. This problem can be addressed by + approximating these forces: For a vertex far removed from a cluster + of vertices, instead of computing the force contribution of each + vertex of the cluster indiviually, we form a sort of + ``supervertex'' at the ``gravitational center'' of the cluster and + then compute only the force between this supervertex and the single + vertex. + + \emph{Remark:} Currently, the implementation seems to be broken, at + least the results are somewhat strange when this key is used. + "]] + } + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua new file mode 100644 index 00000000000..f07f23aeac3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua @@ -0,0 +1,144 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlIteration.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- +-- @section subsubsection {The Iterative Process and Cooling} +-- +-- @end + + + +--- + +declare { + key = "iterations", + type = "number", + initial = "500", + + summary = [[" + Limits the number of iterations of algorithms for force-based + layouts to \meta{number}. + "]], + documentation = [[" + Depending on the characteristics of the input graph and the parameters + chosen for the algorithm, minimizing the system energy may require + many iterations. + + In these situations it may come in handy to limit the number of + iterations. This feature can also be useful to draw the same graph + after different iterations and thereby demonstrate how the spring or + spring-electrical algorithm improves the drawing step by step. + + The examples shows two drawings generated using two + different |iteration| limits. + "]], + examples = { + [[" + \tikz \graph [spring layout, iterations=10] { subgraph K_n [n=4] }; + "]], + [[" + \tikz \graph [spring layout, iterations=500] { subgraph K_n [n=4] }; + "]], + [[" + \tikz \graph [spring electrical layout, iterations=10] + { subgraph K_n [n=4] }; + "]], + [[" + \tikz \graph [spring electrical layout, iterations=500] + { subgraph K_n [n=4] }; + "]] + } +} + +--- + +declare { + key = "initial step length", + type = "length", + initial = "0", + + summary = [[" + This parameter specifies the amount by which nodes will be + displaced in each iteration, initially. If set to |0| (which is the + default), an appropriate value is computed automatically. + "]] + } + +--- + +declare { + key = "cooling factor", + type = "number", + initial = "0.95", + + summary = [[" + This parameter helps in controlling how layouts evolve over + time. It is used to gradually reduce the step size + between one iteration to the next. + "]], + documentation = [[" + A small positive cooling factor + $\ge 0$ means that the movement of nodes is quickly or abruptly + reduced, while a large cooling factor $\le 1$ allows for a smoother + step by step layout refinement at the cost of more iterations. The + following example demonstrates how a smaller cooling factor may + result in a less balanced drawing. By default, Hu2006 spring, + Hu2006 spring electrical, and Walshaw2000 spring electrical use a + cooling factor of |0.95|. + "]], + examples = { + [[" + \tikz \graph [spring layout, cooling factor=0.1] + { a -> b -> c -> a }; + "]], + [[" + \tikz \graph [spring layout, cooling factor=0.5] + { a -> b -> c -> a }; + "]] + } +} + +--- + +declare { + key = "convergence tolerance", + type = "number", + initial = "0.01", + + summary = [[" + All spring and spring-electrical algorithms implemented in the + thesis terminate as soon as the maximum movement of any node drops + below $k \cdot \meta{tolerance}$. This tolerance factor can be changed + with the convergence tolerance option: + "]], + examples = { + [[" + \tikz \graph [spring layout, convergence tolerance=0.001] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + "]], + [[" + \tikz \graph [spring layout, convergence tolerance=1.0] + { { [clique] 1, 2 } -- 3 -- 4 -- { 5, 6, 7 } }; + "]] + } +} + + + + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua new file mode 100644 index 00000000000..2ef55169bca --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua @@ -0,0 +1,58 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlSprings.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsubsection {Forces and Their Effects: Springs} +-- +-- The most important parameter of springs is their ``natural +-- length'', which can be configured using the general-purpose +-- |node distance| parameter. It is the ``equilibrium length'' of a +-- spring between two nodes in the graph. When an edge has this +-- lenght, no forces will ``push'' or ``pull'' along the edge. +-- +-- The following examples shows how a simple graph can be scaled by +-- changing the |node distance|: +-- \begin{codeexample}[] +-- \tikz \graph [spring layout, node distance=7mm] { subgraph C_n[n=3] }; +-- \tikz \graph [spring layout] { subgraph C_n[n=3] }; +-- \tikz \graph [spring layout, node distance=15mm]{ subgraph C_n[n=3] }; +-- \end{codeexample} +-- \begin{codeexample}[] +-- \tikz \graph [spring electrical layout, node distance=0.7cm] { subgraph C_n[n=3] }; +-- \tikz \graph [spring electrical layout] { subgraph C_n[n=3] }; +-- \tikz \graph [spring electrical layout, node distance=1.5cm] { subgraph C_n[n=3] }; +-- \end{codeexample} +-- +-- @end + + + +--- + +declare { + key = "spring constant", + type = "number", + initial = "0.01", + + summary = [[" + The ``spring constant'' is a factor from Hooke's law describing the + ``stiffness'' of a spring. This factor is used inside spring-based + algorithms to determine how strongly edges ``pull'' and ``push'' at + the nodes they connect. + "]] + } + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua new file mode 100644 index 00000000000..6b93f311290 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua @@ -0,0 +1,40 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/ControlStart.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- +-- @section subsubsection {Start Configuration} +-- +-- Currently, the start configuration for force-based algorithms is a +-- random distribution of the vertices. You can influence it by +-- changing the |random seed|: +-- +--\begin{codeexample}[] +--\tikz \graph [random seed=10, spring layout] { +-- a -- {b, c, d} -- e -- f -- {g,h} -- {a,b,e}; +--}; +--\end{codeexample} +--\begin{codeexample}[] +--\tikz \graph [random seed=11, spring layout] { +-- a -- {b, c, d} -- e -- f -- {g,h} -- {a,b,e}; +--}; +--\end{codeexample} +-- +-- Other methods, like a planar preembedding, are not implemented +-- currently. +-- +-- @end \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua new file mode 100644 index 00000000000..1a7d0abf25a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua @@ -0,0 +1,280 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/QuadTree.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +--- An implementation of a quad trees. +-- +-- The class QuadTree provides methods form handling quadtrees. +-- + +local QuadTree = { + -- Subclases + Particle = {}, + Cell = {} +} +QuadTree.__index = QuadTree + +-- Namespace: +require("pgf.gd.force").QuadTree = QuadTree + +-- Imports: +local Vector = require "pgf.gd.deprecated.Vector" +local lib = require "pgf.gd.lib" + + +--- Creates a new quad tree. +-- +-- @return A newly-allocated quad tree. +-- +function QuadTree.new(x, y, width, height, max_particles) + local tree = { + root_cell = QuadTree.Cell.new(x, y, width, height, max_particles) + } + setmetatable(tree, QuadTree) + return tree +end + + + +--- Inserts a particle +-- +-- @param param A particle of type QuadTree.Particle +-- +function QuadTree:insert(particle) + self.root_cell:insert(particle) +end + + + +--- Computes the interactions of a particle with other cells +-- +-- @param particle A particle +-- @param test_func A test function, which on input of a cubical cell and a particle should +-- decide whether the cubical cell should be inserted into the result +-- @param cells An optional array of cells, to which the found cells will be added +-- +-- @return The cells array or a new array, if it was empty. +-- +function QuadTree:findInteractionCells(particle, test_func, cells) + local test_func = test_func or function (cell, particle) return true end + cells = cells or {} + + self.root_cell:findInteractionCells(particle, test_func, cells) + + return cells +end + + + + +--- Partical subclass +QuadTree.Particle.__index = QuadTree.Particle + + + +--- Creates a new particle. +-- +-- @return A newly-allocated particle. +-- +function QuadTree.Particle.new(pos, mass) + local particle = { + pos = pos:copy(), + mass = mass or 1, + subparticles = {}, + } + setmetatable(particle, QuadTree.Particle) + return particle +end + + + +--- A cell of a quadtree +-- +-- TT: Why is it called "cubical", by the way?! + +QuadTree.Cell.__index = QuadTree.Cell + + + +--- Creates a new cubicle cell. +-- +-- @return a newly-allocated cubicle cell. +-- +function QuadTree.Cell.new(x, y, width, height, max_particles) + local cell = { + x = x, + y = y, + width = width, + height = height, + max_particles = max_particles or 1, + subcells = {}, + particles = {}, + center_of_mass = nil, + mass = 0, + } + setmetatable(cell, QuadTree.Cell) + return cell +end + + + +function QuadTree.Cell:containsParticle(particle) + return particle.pos.x >= self.x and particle.pos.x <= self.x + self.width + and particle.pos.y >= self.y and particle.pos.y <= self.y + self.height +end + + + +function QuadTree.Cell:findSubcell(particle) + return lib.find(self.subcells, function (cell) + return cell:containsParticle(particle) + end) +end + + + +function QuadTree.Cell:createSubcells() + assert(type(self.subcells) == 'table' and #self.subcells == 0) + assert(type(self.particles) == 'table' and #self.particles <= self.max_particles) + + if #self.subcells == 0 then + for _,x in ipairs({self.x, self.x + self.width/2}) do + for _,y in ipairs({self.y, self.y + self.height/2}) do + local cell = QuadTree.Cell.new(x, y, self.width/2, self.height/2, self.max_particles) + table.insert(self.subcells, cell) + end + end + end +end + + + +function QuadTree.Cell:insert(particle) + -- check if we have a particle with the exact same position already + local existing = lib.find(self.particles, function (other) + return other.pos:equals(particle.pos) + end) + + if existing then + -- we already have a particle at the same position; splitting the cell + -- up makes no sense; instead we add the new particle as a + -- subparticle of the existing one + table.insert(existing.subparticles, particle) + else + if #self.subcells == 0 and #self.particles < self.max_particles then + table.insert(self.particles, particle) + else + if #self.subcells == 0 then + self:createSubcells() + end + + -- move particles to the new subcells + for _,existing in ipairs(self.particles) do + local cell = self:findSubcell(existing) + assert(cell, 'failed to find a cell for particle ' .. tostring(existing.pos)) + cell:insert(existing) + end + + self.particles = {} + + local cell = self:findSubcell(particle) + assert(cell) + cell:insert(particle) + end + end + + self:updateMass() + self:updateCenterOfMass() + + assert(self.mass) + assert(self.center_of_mass) +end + + + +function QuadTree.Cell:updateMass() + -- reset mass to zero + self.mass = 0 + + if #self.subcells == 0 then + -- the mass is the number of particles of the cell + for _,particle in ipairs(self.particles) do + self.mass = self.mass + particle.mass + for _,subparticle in ipairs(particle.subparticles) do + self.mass = self.mass + subparticle.mass + end + end + else + -- the mass is the sum of the masses of the subcells + for _,subcell in ipairs(self.subcells) do + self.mass = self.mass + subcell.mass + end + end +end + + + +function QuadTree.Cell:updateCenterOfMass() + -- reset center of mass, assuming the cell is empty + self.center_of_mass = nil + + if #self.subcells == 0 then + -- the center of mass is the average position of the particles + -- weighted by their masses + self.center_of_mass = Vector.new (2) + for _,p in ipairs(self.particles) do + for _,sp in ipairs(p.subparticles) do + self.center_of_mass = self.center_of_mass:plus(sp.pos:timesScalar(sp.mass)) + end + self.center_of_mass = self.center_of_mass:plus(p.pos:timesScalar(p.mass)) + end + self.center_of_mass = self.center_of_mass:dividedByScalar(self.mass) + else + -- the center of mass is the average of the weighted centers of mass + -- of the subcells + self.center_of_mass = Vector.new(2) + for _,sc in ipairs(self.subcells) do + if sc.center_of_mass then + self.center_of_mass = self.center_of_mass:plus(sc.center_of_mass:timesScalar(sc.mass)) + else + assert(sc.mass == 0) + end + end + self.center_of_mass = self.center_of_mass:dividedByScalar(self.mass) + end +end + + + +function QuadTree.Cell:findInteractionCells(particle, test_func, cells) + if #self.subcells == 0 or test_func(self, particle) then + table.insert(cells, self) + else + for _,subcell in ipairs(self.subcells) do + subcell:findInteractionCells(particle, test_func, cells) + end + end +end + + +function QuadTree.Cell:__tostring() + return '((' .. self.x .. ', ' .. self.y .. ') ' + .. 'to (' .. self.x + self.width .. ', ' .. self.y + self.height .. '))' + .. (self.particle and ' => ' .. self.particle.name or '') + .. (self.center_of_mass and ' mass ' .. self.mass .. ' at ' .. tostring(self.center_of_mass) or '') +end + + + +-- done + +return QuadTree \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua new file mode 100644 index 00000000000..54ceddcc25a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua @@ -0,0 +1,521 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalHu2006.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + +local SpringElectricalHu2006 = {} + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- + +declare { + key = "spring electrical Hu 2006 layout", + algorithm = SpringElectricalHu2006, + + preconditions = { + connected = true, + loop_free = true, + simple = true, + }, + + old_graph_model = true, + + summary = [[" + Implementation of a spring electrical graph drawing algorithm based on + a paper by Hu. + "]], + documentation = [[" + \begin{itemize} + \item + Y. Hu. + \newblock Efficient, high-quality force-directed graph drawing. + \newblock \emph{The Mathematica Journal}, 2006. + \end{itemize} + + There are some modifications compared to the original algorithm, + see the Diploma thesis of Pohlmann for details. + "]] +} + +-- Imports + +local PathLengths = require "pgf.gd.lib.PathLengths" +local Vector = require "pgf.gd.deprecated.Vector" + +local QuadTree = require "pgf.gd.force.QuadTree" +local CoarseGraph = require "pgf.gd.force.CoarseGraph" + +local lib = require "pgf.gd.lib" + + +function SpringElectricalHu2006:run() + + -- Setup properties + local options = self.digraph.options + + self.iterations = options['iterations'] + self.cooling_factor = options['cooling factor'] + self.initial_step_length = options['initial step length'] + self.convergence_tolerance = options['convergence tolerance'] + + self.natural_spring_length = options['node distance'] + self.spring_constant = options['spring constant'] + + self.approximate_repulsive_forces = options['approximate remote forces'] + self.repulsive_force_order = options['electric force order'] + + self.coarsen = options['coarsen'] + self.downsize_ratio = options['downsize ratio'] + self.minimum_graph_size = options['minimum coarsening size'] + + -- Adjust types + self.downsize_ratio = math.max(0, math.min(1, self.downsize_ratio)) + self.graph_size = #self.graph.nodes + self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1)) + + -- validate input parameters + assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0') + assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1') + assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0') + assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0') + assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0') + assert(self.spring_constant >= 0, 'the spring constant (value: ' .. self.spring_constant .. ') needs to be greater or equal to 0') + assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1') + assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2') + + -- initialize node weights + for _,node in ipairs(self.graph.nodes) do + node.weight = node:getOption('electric charge') + end + + -- initialize edge weights + for _,edge in ipairs(self.graph.edges) do + edge.weight = 1 + end + + -- initialize the coarse graph data structure. note that the algorithm + -- is the same regardless whether coarsening is used, except that the + -- number of coarsening steps without coarsening is 0 + local coarse_graph = CoarseGraph.new(self.graph) + + -- check if the multilevel approach should be used + if self.coarsen then + -- coarsen the graph repeatedly until only minimum_graph_size nodes + -- are left or until the size of the coarse graph was not reduced by + -- at least the downsize ratio configured by the user + while coarse_graph:getSize() > self.minimum_graph_size + and coarse_graph:getRatio() <= (1 - self.downsize_ratio) + do + coarse_graph:coarsen() + end + end + + if self.coarsen then + -- use the natural spring length as the initial natural spring length + local spring_length = self.natural_spring_length + + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,edge in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- additionally improve the layout with the force-based algorithm + -- if there are more than two nodes in the coarsest graph + if coarse_graph:getSize() > 2 then + self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.adaptive_step_update) + end + + -- undo coarsening step by step, applying the force-based sub-algorithm + -- to every intermediate coarse graph as well as the original graph + while coarse_graph:getLevel() > 0 do + + -- compute the diameter of the parent coarse graph + local parent_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- interpolate the previous coarse graph from its parent + coarse_graph:interpolate() + + -- compute the diameter of the current coarse graph + local current_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- scale node positions by the quotient of the pseudo diameters + for _,node in ipairs(coarse_graph.graph) do + node.pos:update(function (n, value) + return value * (current_diameter / parent_diameter) + end) + end + + -- compute forces in the graph + self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.conservative_step_update) + end + else + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, self.natural_spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,e in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- improve the layout with the force-based algorithm + self:computeForceLayout(coarse_graph.graph, spring_length, SpringElectricalHu2006.adaptive_step_update) + end +end + + + +function SpringElectricalHu2006:computeInitialLayout(graph, spring_length) + -- TODO how can supernodes and fixed nodes go hand in hand? + -- maybe fix the supernode if at least one of its subnodes is + -- fixated? + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + if #graph.nodes == 2 then + if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then + local fixed_index = graph.nodes[2].fixed and 2 or 1 + local loose_index = graph.nodes[2].fixed and 1 or 2 + + if not graph.nodes[1].fixed and not graph.nodes[2].fixed then + -- both nodes can be moved, so we assume node 1 is fixed at (0,0) + graph.nodes[1].pos.x = 0 + graph.nodes[1].pos.y = 0 + end + + -- position the loose node relative to the fixed node, with + -- the displacement (random direction) matching the spring length + local direction = Vector.new{x = math.random(1, spring_length), y = math.random(1, spring_length)} + local distance = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + local displacement = direction:normalized():timesScalar(distance) + + graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement) + else + -- both nodes are fixed, initial layout may be far from optimal + end + else + + -- use a random positioning technique + local function positioning_func(n) + local radius = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + return math.random(-radius, radius) + end + + -- compute initial layout based on the random positioning technique + for _,node in ipairs(graph.nodes) do + if not node.fixed then + node.pos.x = positioning_func(1) + node.pos.y = positioning_func(2) + end + end + end +end + + + +function SpringElectricalHu2006:computeForceLayout(graph, spring_length, step_update_func) + -- global (=repulsive) force function + function accurate_repulsive_force(distance, weight) + -- note: the weight is taken into the equation here. unlike in the original + -- algorithm different electric charges are allowed for each node in this + -- implementation + return - weight * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- global (=repulsive, approximated) force function + function approximated_repulsive_force(distance, mass) + return - mass * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- local (spring) force function + function attractive_force(distance) + return (distance * distance) / spring_length + end + + -- define the Barnes-Hut opening criterion + function barnes_hut_criterion(cell, particle) + local distance = particle.pos:minus(cell.center_of_mass):norm() + return cell.width / distance <= 1.2 + end + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + -- adjust the initial step length automatically if desired by the user + local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length + + -- convergence criteria etc. + local converged = false + local energy = math.huge + local iteration = 0 + local progress = 0 + + while not converged and iteration < self.iterations do + -- remember old node positions + local old_positions = lib.map(graph.nodes, function (node) + return node.pos:copy(), node + end) + + -- remember the old system energy and reset it for the current iteration + local old_energy = energy + energy = 0 + + -- build the quadtree for approximating repulsive forces, if desired + local quadtree = nil + if self.approximate_repulsive_forces then + quadtree = self:buildQuadtree(graph) + end + + for _,v in ipairs(graph.nodes) do + if not v.fixed then + -- vector for the displacement of v + local d = Vector.new(2) + + -- compute repulsive forces + if self.approximate_repulsive_forces then + -- determine the cells that have a repulsive influence on v + local cells = quadtree:findInteractionCells(v, barnes_hut_criterion) + + -- compute the repulsive force between these cells and v + for _,cell in ipairs(cells) do + -- check if the cell is a leaf + if #cell.subcells == 0 then + -- compute the forces between the node and all particles in the cell + for _,particle in ipairs(cell.particles) do + local real_particles = lib.copy(particle.subparticles) + table.insert(real_particles, particle) + + for _,real_particle in ipairs(real_particles) do + local delta = real_particle.pos:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- move the node v accordingly + d = d:plus(force) + end + end + else + -- compute the distance between the node and the cell's center of mass + local delta = cell.center_of_mass:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- move the node v accordingly + d = d:plus(force) + end + end + else + for _,u in ipairs(graph.nodes) do + if v ~= u then + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight) + local force = delta:normalized():timesScalar(repulsive_force) + + -- move the node v accordingly + d = d:plus(force) + end + end + end + + -- compute attractive forces between v and its neighbours + for _,edge in ipairs(v.edges) do + local u = edge:getNeighbour(v) + + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the spring force vector between u and v + local attr_force = attractive_force(delta:norm()) + local force = delta:normalized():timesScalar(attr_force) + + -- move the node v accordingly + d = d:plus(force) + end + + -- really move the node now + -- TODO note how all nodes are moved by the same amount (step_length) + -- while Walshaw multiplies the normalized force with min(step_length, + -- d:norm()). could that improve this algorithm even further? + v.pos = v.pos:plus(d:normalized():timesScalar(step_length)) + + -- TODO Hu doesn't mention this but the energy of a particle is + -- typically considered as the product of its mass and the square of + -- its forces. This means we should probably take the weight of + -- the node v into the equation, doesn't it? + -- + -- update the energy function + energy = energy + math.pow(d:norm(), 2) + end + end + + -- update the step length and progress counter + step_length, progress = step_update_func(step_length, self.cooling_factor, energy, old_energy, progress) + + -- compute the maximum node movement in this iteration + local max_movement = 0 + for _,x in ipairs(graph.nodes) do + local delta = x.pos:minus(old_positions[x]) + max_movement = math.max(delta:norm(), max_movement) + end + + -- the algorithm will converge if the maximum movement is below a + -- threshold depending on the spring length and the convergence + -- tolerance + if max_movement < spring_length * self.convergence_tolerance then + converged = true + end + + -- increment the iteration counter + iteration = iteration + 1 + end +end + + + +-- Fixes nodes at their specified positions. +-- +function SpringElectricalHu2006:fixateNodes(graph) + local number_of_fixed_nodes = 0 + + for _,node in ipairs(graph.nodes) do + -- read the 'desired at' option of the node + local coordinate = node:getOption('desired at') + + if coordinate then + -- apply the coordinate + node.pos.x = coordinate.x + node.pos.y = coordinate.y + + -- mark the node as fixed + node.fixed = true + + number_of_fixed_nodes = number_of_fixed_nodes + 1 + end + end + if number_of_fixed_nodes > 1 then + self.growth_direction = "fixed" -- do not grow, orientation is now fixed + end +end + + + +function SpringElectricalHu2006:buildQuadtree(graph) + -- compute the minimum x and y coordinates of all nodes + local min_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + min_pos = Vector.new(2, function (n) return math.min(min_pos[n], node.pos[n]) end) + end + + -- compute maximum x and y coordinates of all nodes + local max_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + max_pos = Vector.new(2, function (n) return math.max(max_pos[n], node.pos[n]) end) + end + + -- make sure the maximum position is at least a tiny bit + -- larger than the minimum position + if min_pos:equals(max_pos) then + max_pos = max_pos:plus(Vector.new(2, function (n) + return 0.1 + math.random() * 0.1 + end)) + end + + -- make sure to make the quadtree area slightly larger than required + -- in theory; for some reason Lua will otherwise think that nodes with + -- min/max x/y coordinates are outside the box... weird? yes. + min_pos = min_pos:minus({1,1}) + max_pos = max_pos:plus({1,1}) + + -- create the quadtree + quadtree = QuadTree.new(min_pos.x, min_pos.y, + max_pos.x - min_pos.x, + max_pos.y - min_pos.y) + + -- insert nodes into the quadtree + for _,node in ipairs(graph.nodes) do + local particle = QuadTree.Particle.new(node.pos, node.weight) + particle.node = node + quadtree:insert(particle) + end + + return quadtree +end + + + +function SpringElectricalHu2006.conservative_step_update(step, cooling_factor) + return cooling_factor * step, nil +end + + + +function SpringElectricalHu2006.adaptive_step_update(step, cooling_factor, energy, old_energy, progress) + if energy < old_energy then + progress = progress + 1 + if progress >= 5 then + progress = 0 + step = step / cooling_factor + end + else + progress = 0 + step = cooling_factor * step + end + return step, progress +end + + +-- done + +return SpringElectricalHu2006 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua new file mode 100644 index 00000000000..f8854e71618 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua @@ -0,0 +1,54 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalLayouts.lua,v 1.4 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Spring Electrical Layouts} +-- +-- @end + + + +--- + +declare { + key = "spring electrical layout", + use = { + { key = "spring electrical Hu 2006 layout" }, + { key = "spring constant", value = "0.2" } + }, + + summary = [[" + This key selects Hu's 2006 spring electrical layout with + appropriate settings for some parameters. + "]] + } + + +--- + +declare { + key = "spring electrical layout'", + use = { + { key = "spring electrical Walshaw 2000 layout" }, + { key = "spring constant", value = "0.01" }, + { key = "convergence tolerance", value = "0.001" }, + }, + + summary = [[" + This key selects Walshaw's 2000 spring electrical layout with + appropriate settings for some parameters. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua new file mode 100644 index 00000000000..25782bc9c3c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua @@ -0,0 +1,516 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringElectricalWalshaw2000.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + + +local SpringElectricalWalshaw2000 = {} + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- + +declare { + key = "spring electrical Walshaw 2000 layout", + algorithm = SpringElectricalWalshaw2000, + + preconditions = { + connected = true, + loop_free = true, + simple = true, + }, + + old_graph_model = true, + + summary = [[" + Implementation of a spring electrical graph drawing algorithm based on + a paper by Walshaw. + "]], + documentation = [[" + \begin{itemize} + \item + C. Walshaw. + \newblock A multilevel algorithm for force-directed graph + drawing. + \newblock In J. Marks, editor, \emph{Graph Drawing}, Lecture Notes in + Computer Science, 1984:31--55, 2001. + \end{itemize} + + The following modifications compared to the original algorithm were applied: + \begin{itemize} + \item An iteration limit was added. + \item The natural spring length for all coarse graphs is computed based + on the formula presented by Walshaw, so that the natural spring + length of the original graph (coarse graph 0) is the same as + the value requested by the user. + \item Users can define custom node and edge weights. + \item Coarsening stops when $|V(G_i+1)|/|V(G_i)| < p$ where $p = 0.75$. + \item Coarsening stops when the maximal matching is empty. + \item Theruntime of the algorithm is improved by use of a quadtree + data structure like Hu does in his algorithm. + \item A limiting the number of levels of the quadtree is not implemented. + \end{itemize} + "]] +} + +-- TODO Implement the following keys (or whatever seems appropriate +-- and doable for this algorithm): +-- - /tikz/desired at +-- - /tikz/influence cutoff distance +-- - /tikz/spring stiffness (could this be the equivalent to the electric +-- charge of nodes? +-- - /tikz/natural spring dimension per edge +-- +-- TODO Implement the following features: +-- - clustering of nodes using color classes +-- - different cluster layouts (vertical line, horizontal line, +-- normal cluster, internally fixed subgraph) + + + +local Vector = require "pgf.gd.deprecated.Vector" + +local QuadTree = require "pgf.gd.force.QuadTree" +local CoarseGraph = require "pgf.gd.force.CoarseGraph" + + +local lib = require "pgf.gd.lib" + + +function SpringElectricalWalshaw2000:run() + + -- Setup parameters + local options = self.digraph.options + + self.iterations = options['iterations'] + self.cooling_factor = options['cooling factor'] + self.initial_step_length = options['initial step length'] + self.convergence_tolerance = options['convergence tolerance'] + + self.natural_spring_length = options['node distance'] + self.spring_constant = options['spring constant'] + + self.approximate_repulsive_forces = options['approximate remote forces'] + self.repulsive_force_order = options['electric force order'] + + self.coarsen = options['coarsen'] + self.downsize_ratio = options['downsize ratio'] + self.minimum_graph_size = options['minimum coarsening size'] + + -- Adjust types + self.downsize_ratio = math.max(0, math.min(1, self.downsize_ratio)) + self.graph_size = #self.graph.nodes + self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1)) + + -- validate input parameters + assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0') + assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1') + assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0') + assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0') + assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0') + assert(self.spring_constant >= 0, 'the spring constant (value: ' .. self.spring_constant .. ') needs to be greater or equal to 0') + assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1') + assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2') + + -- initialize node weights + for _,node in ipairs(self.graph.nodes) do + node.weight = node:getOption('electric charge') + + -- a node is charged if its weight derives from the default setting + -- of 1 (where it has no influence on the forces) + node.charged = node.weight ~= 1 + end + + -- initialize edge weights + for _,edge in ipairs(self.graph.edges) do + edge.weight = 1 + end + + + -- initialize the coarse graph data structure. note that the algorithm + -- is the same regardless whether coarsening is used, except that the + -- number of coarsening steps without coarsening is 0 + local coarse_graph = CoarseGraph.new(self.graph) + + -- check if the multilevel approach should be used + if self.coarsen then + -- coarsen the graph repeatedly until only minimum_graph_size nodes + -- are left or until the size of the coarse graph was not reduced by + -- at least the downsize ratio configured by the user + while coarse_graph:getSize() > self.minimum_graph_size + and coarse_graph:getRatio() < (1 - self.downsize_ratio) + do + coarse_graph:coarsen() + end + end + + -- compute the natural spring length for the coarsest graph in a way + -- that will result in the desired natural spring length in the + -- original graph + local spring_length = self.natural_spring_length / math.pow(math.sqrt(4/7), coarse_graph:getLevel()) + + if self.coarsen then + -- generate a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- undo coarsening step by step, applying the force-based sub-algorithm + -- to every intermediate coarse graph as well as the original graph + while coarse_graph:getLevel() > 0 do + -- interpolate the previous coarse graph + coarse_graph:interpolate() + + -- update the natural spring length so that, for the original graph, + -- it equals the natural spring dimension configured by the user + spring_length = spring_length * math.sqrt(4/7) + + -- apply the force-based algorithm to improve the layout + self:computeForceLayout(coarse_graph.graph, spring_length) + end + else + -- generate a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- apply the force-based algorithm to improve the layout + self:computeForceLayout(coarse_graph.graph, spring_length) + end +end + + + +function SpringElectricalWalshaw2000:computeInitialLayout(graph, spring_length) + -- TODO how can supernodes and fixed nodes go hand in hand? + -- maybe fix the supernode if at least one of its subnodes is + -- fixated? + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + if #graph.nodes == 2 then + if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then + local fixed_index = graph.nodes[2].fixed and 2 or 1 + local loose_index = graph.nodes[2].fixed and 1 or 2 + + if not graph.nodes[1].fixed and not graph.nodes[2].fixed then + -- both nodes can be moved, so we assume node 1 is fixed at (0,0) + graph.nodes[1].pos.x = 0 + graph.nodes[1].pos.y = 0 + end + + -- position the loose node relative to the fixed node, with + -- the displacement (random direction) matching the spring length + local direction = Vector.new{x = math.random(1, 2), y = math.random(1, 2)} + local distance = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + local displacement = direction:normalized():timesScalar(distance) + + graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement) + else + -- both nodes are fixed, initial layout may be far from optimal + end + else + -- function to filter out fixed nodes + local function nodeNotFixed(node) return not node.fixed end + + -- use the random positioning technique + local function positioning_func(n) + local radius = 3 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + return math.random(-radius, radius) + end + + -- compute initial layout based on the random positioning technique + for _,node in ipairs(graph.nodes) do + if not node.fixed then + node.pos.x = positioning_func(1) + node.pos.y = positioning_func(2) + end + end + end +end + + + +function SpringElectricalWalshaw2000:computeForceLayout(graph, spring_length) + -- global (=repulsive) force function + local function accurate_repulsive_force(distance, weight) + return - self.spring_constant * weight * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- global (=repulsive, approximated) force function + local function approximated_repulsive_force(distance, mass) + return - mass * self.spring_constant * math.pow(spring_length, self.repulsive_force_order + 1) / math.pow(distance, self.repulsive_force_order) + end + + -- local (spring) force function + local function attractive_force(distance, d, weight, charged, repulsive_force) + -- for charged nodes, never subtract the repulsive force; we want ALL other + -- nodes to be attracted more / repulsed less (not just non-adjacent ones), + -- depending on the charge of course + if charged then + return (distance - spring_length) / d - accurate_repulsive_force(distance, weight) + else + return (distance - spring_length) / d - (repulsive_force or 0) + end + end + + -- define the Barnes-Hut opening criterion + function barnes_hut_criterion(cell, particle) + local distance = particle.pos:minus(cell.center_of_mass):norm() + return cell.width / distance <= 1.2 + end + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + -- adjust the initial step length automatically if desired by the user + local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length + + -- convergence criteria + local converged = false + local i = 0 + + while not converged and i < self.iterations do + + -- assume that we are converging + converged = true + i = i + 1 + + -- build the quadtree for approximating repulsive forces, if desired + local quadtree = nil + if self.approximate_repulsive_forces then + quadtree = self:buildQuadtree(graph) + end + + local function nodeNotFixed(node) return not node.fixed end + + -- iterate over all nodes + for _,v in ipairs(graph.nodes) do + if not v.fixed then + -- vector for the displacement of v + local d = Vector.new(2) + + -- repulsive force induced by other nodes + local repulsive_forces = {} + + -- compute repulsive forces + if self.approximate_repulsive_forces then + -- determine the cells that have an repulsive influence on v + local cells = quadtree:findInteractionCells(v, barnes_hut_criterion) + + -- compute the repulsive force between these cells and v + for _,cell in ipairs(cells) do + -- check if the cell is a leaf + if #cell.subcells == 0 then + -- compute the forces between the node and all particles in the cell + for _,particle in ipairs(cell.particles) do + -- build a table that contains the particle plus all its subparticles + -- (particles at the same position) + local real_particles = lib.copy(particle.subparticles) + table.insert(real_particles, particle) + + for _,real_particle in ipairs(real_particles) do + local delta = real_particle.pos:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), real_particle.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- remember the repulsive force for the particle so that we can + -- subtract it later when computing the attractive forces with + -- adjacent nodes + repulsive_forces[real_particle.node] = repulsive_force + + -- move the node v accordingly + d = d:plus(force) + end + end + else + -- compute the distance between the node and the cell's center of mass + local delta = cell.center_of_mass:minus(v.pos) + + -- enforce a small virtual distance if the node and the cell's + -- center of mass are located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = approximated_repulsive_force(delta:norm(), cell.mass) + local force = delta:normalized():timesScalar(repulsive_force) + + -- TODO for each neighbour of v, check if it is in this cell. + -- if this is the case, compute the quadtree force for the mass + -- 'node.weight / cell.mass' and remember this as the repulsive + -- force of the neighbour; (it is not necessarily at + -- the center of mass of the cell, so the result is only an + -- approximation of the real repulsive force generated by the + -- neighbour) + + -- move te node v accordingly + d = d:plus(force) + end + end + else + for _,u in ipairs(graph.nodes) do + if u.name ~= v.name then + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the repulsive force vector + local repulsive_force = accurate_repulsive_force(delta:norm(), u.weight) + local force = delta:normalized():timesScalar(repulsive_force) + + -- remember the repulsive force so we can later subtract them + -- when computing the attractive forces + repulsive_forces[u] = repulsive_force + + -- move the node v accordingly + d = d:plus(force) + end + end + end + + -- compute attractive forces between v and its neighbours + for _,edge in ipairs(v.edges) do + local u = edge:getNeighbour(v) + + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + -- compute the spring force between them + local attr_force = attractive_force(delta:norm(), #v.edges, u.weight, u.charged, repulsive_forces[u]) + local force = delta:normalized():timesScalar(attr_force) + + -- move the node v accordingly + d = d:plus(force) + end + + -- remember the previous position of v + old_position = v.pos:copy() + + if d:norm() > 0 then + -- reposition v according to the force vector and the current temperature + v.pos = v.pos:plus(d:normalized():timesScalar(math.min(step_length, d:norm()))) + end + + -- we need to improve the system energy as long as any of + -- the node movements is large enough to assume we're far + -- away from the minimum system energy + if v.pos:minus(old_position):norm() > spring_length * self.convergence_tolerance then + converged = false + end + end + end + + -- update the step length using the conservative cooling scheme + step_length = self.cooling_factor * step_length + end +end + + + +-- Fixes nodes at their specified positions. +-- +function SpringElectricalWalshaw2000:fixateNodes(graph) + local number_of_fixed_nodes = 0 + + for _,node in ipairs(graph.nodes) do + -- read the 'desired at' option of the node + local coordinate = node:getOption('desired at') + + if coordinate then + -- parse the coordinate + node.pos.x = coordinate.x + node.pos.y = coordinate.y + + -- mark the node as fixed + node.fixed = true + + number_of_fixed_nodes = number_of_fixed_nodes + 1 + end + end + if number_of_fixed_nodes > 1 then + self.growth_direction = "fixed" -- do not grow, orientation is now fixed + end +end + + + +function SpringElectricalWalshaw2000:buildQuadtree(graph) + -- compute the minimum x and y coordinates of all nodes + local min_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + min_pos = Vector.new(2, function (n) return math.min(min_pos[n], node.pos[n]) end) + end + + -- compute maximum x and y coordinates of all nodes + local max_pos = graph.nodes[1].pos + for _,node in ipairs(graph.nodes) do + max_pos = Vector.new(2, function (n) return math.max(max_pos[n], node.pos[n]) end) + end + + -- make sure the maximum position is at least a tiny bit + -- larger than the minimum position + if min_pos:equals(max_pos) then + max_pos = max_pos:plus(Vector.new(2, function (n) + return 0.1 + math.random() * 0.1 + end)) + end + + -- make sure to make the quadtree area slightly larger than required + -- in theory; for some reason Lua will otherwise think that nodes with + -- min/max x/y coordinates are outside the box... weird? yes. + min_pos = min_pos:minusScalar(1) + max_pos = max_pos:plusScalar(1) + + -- create the quadtree + quadtree = QuadTree.new(min_pos.x, min_pos.y, + max_pos.x - min_pos.x, + max_pos.y - min_pos.y) + + -- insert nodes into the quadtree + for _,node in ipairs(graph.nodes) do + local particle = QuadTree.Particle.new(node.pos, node.weight) + particle.node = node + quadtree:insert(particle) + end + + return quadtree +end + + + +-- done + +return SpringElectricalWalshaw2000 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua new file mode 100644 index 00000000000..35dc21008fb --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua @@ -0,0 +1,387 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringHu2006.lua,v 1.1 2012/11/27 17:24:25 tantau Exp $ + + + +local SpringHu2006 = {} + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +--- + +declare { + key = "spring Hu 2006 layout", + algorithm = SpringHu2006, + + preconditions = { + connected = true, + loop_free = true, + simple = true, + }, + + old_graph_model = true, + + summary = [[" + Implementation of a spring graph drawing algorithm based on + a paper by Hu. + "]], + documentation = [[" + \begin{itemize} + \item + Y. Hu. + \newblock Efficient, high-quality force-directed graph drawing. + \newblock \emph{The Mathematica Journal}, 2006. + \end{itemize} + + There are some modifications compared to the original algorithm, + see the Diploma thesis of Pohlmann for details. + "]] +} + + +-- Imports + +local PathLengths = require "pgf.gd.lib.PathLengths" +local Vector = require "pgf.gd.deprecated.Vector" + +local CoarseGraph = require "pgf.gd.force.CoarseGraph" + +local lib = require("pgf.gd.lib") + + + + + +function SpringHu2006:run() + + -- Setup some parameters + local options = self.digraph.options + + self.iterations = options['iterations'] + self.cooling_factor = options['cooling factor'] + self.initial_step_length = options['initial step length'] + self.convergence_tolerance = options['convergence tolerance'] + + self.natural_spring_length = options['node distance'] + + self.coarsen = options['coarsen'] + self.downsize_ratio = options['downsize ratio'] + self.minimum_graph_size = options['minimum coarsening size'] + + + -- Setup + + self.downsize_ratio = math.max(0, math.min(1, tonumber(self.downsize_ratio))) + + self.graph_size = #self.graph.nodes + self.graph_density = (2 * #self.graph.edges) / (#self.graph.nodes * (#self.graph.nodes - 1)) + + -- validate input parameters + assert(self.iterations >= 0, 'iterations (value: ' .. self.iterations .. ') need to be greater than 0') + assert(self.cooling_factor >= 0 and self.cooling_factor <= 1, 'the cooling factor (value: ' .. self.cooling_factor .. ') needs to be between 0 and 1') + assert(self.initial_step_length >= 0, 'the initial step length (value: ' .. self.initial_step_length .. ') needs to be greater than or equal to 0') + assert(self.convergence_tolerance >= 0, 'the convergence tolerance (value: ' .. self.convergence_tolerance .. ') needs to be greater than or equal to 0') + assert(self.natural_spring_length >= 0, 'the natural spring dimension (value: ' .. self.natural_spring_length .. ') needs to be greater than or equal to 0') + assert(self.downsize_ratio >= 0 and self.downsize_ratio <= 1, 'the downsize ratio (value: ' .. self.downsize_ratio .. ') needs to be between 0 and 1') + assert(self.minimum_graph_size >= 2, 'the minimum coarsening size of coarse graphs (value: ' .. self.minimum_graph_size .. ') needs to be greater than or equal to 2') + + -- initialize node weights + for _,node in ipairs(self.graph.nodes) do + node.weight = 1 + end + + -- initialize edge weights + for _,edge in ipairs(self.graph.edges) do + edge.weight = 1 + end + + + -- initialize the coarse graph data structure. note that the algorithm + -- is the same regardless whether coarsening is used, except that the + -- number of coarsening steps without coarsening is 0 + local coarse_graph = CoarseGraph.new(self.graph) + + -- check if the multilevel approach should be used + if self.coarsen then + -- coarsen the graph repeatedly until only minimum_graph_size nodes + -- are left or until the size of the coarse graph was not reduced by + -- at least the downsize ratio configured by the user + while coarse_graph:getSize() > self.minimum_graph_size + and coarse_graph:getRatio() <= (1 - self.downsize_ratio) + do + coarse_graph:coarsen() + end + end + + if self.coarsen then + -- use the natural spring length as the initial natural spring length + local spring_length = self.natural_spring_length + + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,edge in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- additionally improve the layout with the force-based algorithm + -- if there are more than two nodes in the coarsest graph + if coarse_graph:getSize() > 2 then + self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.adaptive_step_update) + end + + -- undo coarsening step by step, applying the force-based sub-algorithm + -- to every intermediate coarse graph as well as the original graph + while coarse_graph:getLevel() > 0 do + -- compute the diameter of the parent coarse graph + local parent_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- interpolate the previous coarse graph from its parent + coarse_graph:interpolate() + + -- compute the diameter of the current coarse graph + local current_diameter = PathLengths.pseudoDiameter(coarse_graph.graph) + + -- scale node positions by the quotient of the pseudo diameters + for _,node in ipairs(coarse_graph.graph) do + node.pos:update(function (n, value) + return value * (current_diameter / parent_diameter) + end) + end + + -- compute forces in the graph + self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.conservative_step_update) + end + else + -- compute a random initial layout for the coarsest graph + self:computeInitialLayout(coarse_graph.graph, self.natural_spring_length) + + -- set the spring length to the average edge length of the initial layout + spring_length = 0 + for _,edge in ipairs(coarse_graph.graph.edges) do + spring_length = spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + spring_length = spring_length / #coarse_graph.graph.edges + + -- improve the layout with the force-based algorithm + self:computeForceLayout(coarse_graph.graph, spring_length, SpringHu2006.adaptive_step_update) + end + + local avg_spring_length = 0 + for _,edge in ipairs(self.graph.edges) do + avg_spring_length = avg_spring_length + edge.nodes[1].pos:minus(edge.nodes[2].pos):norm() + end + avg_spring_length = avg_spring_length / #self.graph.edges +end + + + +function SpringHu2006:computeInitialLayout(graph, spring_length) + -- TODO how can supernodes and fixed nodes go hand in hand? + -- maybe fix the supernode if at least one of its subnodes is + -- fixated? + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + if #graph.nodes == 2 then + if not (graph.nodes[1].fixed and graph.nodes[2].fixed) then + local fixed_index = graph.nodes[2].fixed and 2 or 1 + local loose_index = graph.nodes[2].fixed and 1 or 2 + + if not graph.nodes[1].fixed and not graph.nodes[2].fixed then + -- both nodes can be moved, so we assume node 1 is fixed at (0,0) + graph.nodes[1].pos.x = 0 + graph.nodes[1].pos.y = 0 + end + + -- position the loose node relative to the fixed node, with + -- the displacement (random direction) matching the spring length + local direction = Vector.new{x = math.random(1, spring_length), y = math.random(1, spring_length)} + local distance = 1.8 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + local displacement = direction:normalized():timesScalar(distance) + + graph.nodes[loose_index].pos = graph.nodes[fixed_index].pos:plus(displacement) + else + -- both nodes are fixed, initial layout may be far from optimal + end + else + -- use a random positioning technique + local function positioning_func(n) + local radius = 2 * spring_length * self.graph_density * math.sqrt(self.graph_size) / 2 + return math.random(-radius, radius) + end + + -- compute initial layout based on the random positioning technique + for _,node in ipairs(graph.nodes) do + if not node.fixed then + node.pos.x = positioning_func(1) + node.pos.y = positioning_func(2) + end + end + end +end + + + +function SpringHu2006:computeForceLayout(graph, spring_length, step_update_func) + -- global (=repulsive) force function + function repulsive_force(distance, graph_distance, weight) + --return (1/4) * (1/math.pow(graph_distance, 2)) * (distance - (spring_length * graph_distance)) + return (distance - (spring_length * graph_distance)) + end + + -- fixate all nodes that have a 'desired at' option. this will set the + -- node.fixed member to true and also set node.pos.x and node.pos.y + self:fixateNodes(graph) + + -- adjust the initial step length automatically if desired by the user + local step_length = self.initial_step_length == 0 and spring_length or self.initial_step_length + + -- convergence criteria etc. + local converged = false + local energy = math.huge + local iteration = 0 + local progress = 0 + + -- compute graph distance between all pairs of nodes + local distances = PathLengths.floydWarshall(graph) + + while not converged and iteration < self.iterations do + -- remember old node positions + local old_positions = lib.map(graph.nodes, function (node) return node.pos:copy(), node end) + + -- remember the old system energy and reset it for the current iteration + local old_energy = energy + energy = 0 + + for _,v in ipairs(graph.nodes) do + if not v.fixed then + -- vector for the displacement of v + local d = Vector.new(2) + + for _,u in ipairs(graph.nodes) do + if v ~= u then + -- compute the distance between u and v + local delta = u.pos:minus(v.pos) + + -- enforce a small virtual distance if the nodes are + -- located at (almost) the same position + if delta:norm() < 0.1 then + delta:update(function (n, value) return 0.1 + math.random() * 0.1 end) + end + + local graph_distance = (distances[u] and distances[u][v]) and distances[u][v] or #graph.nodes + 1 + + -- compute the repulsive force vector + local force = repulsive_force(delta:norm(), graph_distance, v.weight) + local force = delta:normalized():timesScalar(force) + + -- move the node v accordingly + d = d:plus(force) + end + end + + -- really move the node now + -- TODO note how all nodes are moved by the same amount (step_length) + -- while Walshaw multiplies the normalized force with min(step_length, + -- d:norm()). could that improve this algorithm even further? + v.pos = v.pos:plus(d:normalized():timesScalar(step_length)) + + -- update the energy function + energy = energy + math.pow(d:norm(), 2) + end + end + + -- update the step length and progress counter + step_length, progress = step_update_func(step_length, self.cooling_factor, energy, old_energy, progress) + + -- compute the maximum node movement in this iteration + local max_movement = 0 + for _,x in ipairs(graph.nodes) do + local delta = x.pos:minus(old_positions[x]) + max_movement = math.max(delta:norm(), max_movement) + end + + -- the algorithm will converge if the maximum movement is below a + -- threshold depending on the spring length and the convergence + -- tolerance + if max_movement < spring_length * self.convergence_tolerance then + converged = true + end + + -- increment the iteration counter + iteration = iteration + 1 + end +end + + + +-- Fixes nodes at their specified positions. +-- +function SpringHu2006:fixateNodes(graph) + local number_of_fixed_nodes = 0 + + for _,node in ipairs(graph.nodes) do + -- read the 'desired at' option of the node + local coordinate = node:getOption('desired at') + + if coordinate then + -- apply the coordinate + node.pos.x = coordinate.x + node.pos.y = coordinate.y + + -- mark the node as fixed + node.fixed = true + + number_of_fixed_nodes = number_of_fixed_nodes + 1 + end + end + if number_of_fixed_nodes > 1 then + self.growth_direction = "fixed" -- do not grow, orientation is now fixed + end +end + + + +function SpringHu2006.conservative_step_update(step, cooling_factor) + return cooling_factor * step, nil +end + + + +function SpringHu2006.adaptive_step_update(step, cooling_factor, energy, old_energy, progress) + if energy < old_energy then + progress = progress + 1 + if progress >= 5 then + progress = 0 + step = step / cooling_factor + end + else + progress = 0 + step = cooling_factor * step + end + return step, progress +end + + +-- done + +return SpringHu2006 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua new file mode 100644 index 00000000000..ab0126d7fcd --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua @@ -0,0 +1,36 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/SpringLayouts.lua,v 1.4 2013/05/23 20:01:27 tantau Exp $ + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Spring Layouts} +-- +-- @end + + + +--- + +declare { + key = "spring layout", + use = { + { key = "spring Hu 2006 layout" }, + }, + + summary = [[" + This key selects Hu's 2006 spring layout with appropriate settings + for some parameters. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua new file mode 100644 index 00000000000..af3a1a62c27 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua @@ -0,0 +1,126 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/force/library.lua,v 1.4 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- Nature creates beautiful graph layouts all the time. Consider a +-- spider's web: Nodes are connected by edges in a visually most pleasing +-- manner (if you ignore the spider in the middle). The layout of a +-- spider's web is created just by the physical forces exerted by the +-- threads. The idea behind force-based graph drawing algorithms is to +-- mimic nature: We treat edges as threads that exert forces and simulate +-- into which configuration the whole graph is ``pulled'' by these +-- forces. +-- +-- When you start thinking about for a moment, it turns out that there +-- are endless variations of the force model. All of these models have +-- the following in common, however: +-- \begin{itemize} +-- \item ``Forces'' pull and push at the nodes in different +-- directions. +-- \item The effect of these forces is simulated by iteratively moving +-- all the nodes simultaneously a little in the direction of the forces +-- and by then recalculating the forces. +-- \item The iteration is stopped either after a certain number of +-- iterations or when a \emph{global energy minimum} is reached (a very +-- scientific way of saying that nothing happens anymore). +-- \end{itemize} +-- +-- The main difference between the different force-based approaches is +-- how the forces are determined. Here are some ideas what could cause a +-- force to be exerted between two nodes (and there are more): +-- \begin{itemize} +-- \item If the nodes are connected by an edge, one can treat the edge as +-- a ``spring'' that has a ``natural spring dimension.'' If the nodes +-- are nearer than the spring dimension, they are push apart; if they +-- are farther aways than the spring dimension, they are pulled +-- together. +-- \item If two nodes are connected by a path of a certain length, the +-- nodes may ``wish to be at a distance proportional to the path +-- length''. If they are nearer, they are pushed apart; if they are +-- farther, they are pulled together. (This is obviously a +-- generalization of the previous idea.) +-- \item There may be a general force field that pushes nodes apart (an +-- electrical field), so that nodes do not tend to ``cluster''. +-- \item There may be a general force field that pulls nodes together (a +-- gravitational field), so that nodes are not too loosely scattered. +-- \item There may be highly nonlinear forces depending on the distance of +-- nodes, so that nodes very near to each get pushed apart strongly, +-- but the effect wears of rapidly at a distance. (Such forces are +-- known as strong nuclear forces.) +-- \item There rotational forces caused by the angles between the edges +-- leaving a node. Such forces try to create a \emph{perfect angular +-- resolution} (a very scientific way of saying that all angles +-- at a node are equal). +-- \end{itemize} +-- +-- Force-based algorithms combine one or more of the above ideas into a +-- single algorithm that uses ``good'' formulas for computing the +-- forces. +-- +-- Currently, three algorithms are implemented in this library, two of +-- which are from the first of the following paper, while the third is +-- from the third paper: +-- +-- \begin{itemize} +-- \item +-- Y. Hu. +-- \newblock Efficient, high-quality force-directed graph drawing. +-- \newblock \emph{The Mathematica Journal}, 2006. +-- \item +-- C. Walshaw. +-- \newblock A multilevel algorithm for force-directed graph +-- drawing. +-- \newblock In J. Marks, editor, \emph{Graph Drawing}, Lecture Notes in +-- Computer Science, 1984:31--55, 2001. +-- \end{itemize} +-- +-- Our implementation is described in detail in the following +-- diploma thesis: +-- +-- \begin{itemize} +-- \item +-- Jannis Pohlmann, +-- \newblock \emph{Configurable Graph Drawing Algorithms +-- for the \tikzname\ Graphics Description Language,} +-- \newblock Diploma Thesis, +-- \newblock Institute of Theoretical Computer Science, Univerist\"at +-- zu L\"ubeck, 2011.\\[.5em] +-- \newblock Online at +-- \url{http://www.tcs.uni-luebeck.de/downloads/papers/2011/}\\ \url{2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf} +-- \end{itemize} +-- +-- In the future, I hope that most, if not all, of the force-based +-- algorithms become ``just configuration options'' of a general +-- force-based algorithm similar to the way the modular Sugiyama method +-- is implemented in the |layered| graph drawing library. +-- +-- @library + +local force -- Library name + +-- Load declarations from: +require "pgf.gd.force.Control" +require "pgf.gd.force.ControlStart" +require "pgf.gd.force.ControlIteration" +require "pgf.gd.force.ControlSprings" +require "pgf.gd.force.ControlElectric" +require "pgf.gd.force.ControlCoarsening" + +require "pgf.gd.force.SpringLayouts" +require "pgf.gd.force.SpringElectricalLayouts" + +-- Load algorithms from: +require "pgf.gd.force.SpringHu2006" +require "pgf.gd.force.SpringElectricalHu2006" +require "pgf.gd.force.SpringElectricalWalshaw2000" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua new file mode 100644 index 00000000000..bd53ae4376b --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface.lua,v 1.1 2012/11/27 17:24:24 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.interface = {} + + +-- Done + +return pgf.gd.interface \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua new file mode 100644 index 00000000000..3e5d947c736 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua @@ -0,0 +1,174 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceCore.lua,v 1.5 2013/03/07 18:17:14 tantau Exp $ + + + +--- +-- This class provides the core functionality of the interface between +-- all the different layers (display layer, binding layer, and +-- algorithm layer). The two classes |InterfaceToAlgorithms| and +-- |InterfaceToDisplay| use, in particular, the data structures +-- provided by this class. +-- +-- @field binding This field stores the ``binding.'' The graph drawing +-- system is ``bound'' to the display layer through such a binding (a +-- subclass of |Binding|). Such a binding can be thought of as a +-- ``driver'' in operating systems terminology: It is a small set of +-- functions needed to adapt the functionality to one specific display +-- system. Note that the whole graph drawing scope is bound to exactly +-- one display layer; to use several bindings you need to setup a +-- completely new Lua instance. +-- +-- @field scopes This is a stack of graph drawing scopes. All +-- interface methods refer to the top of this stack. +-- +-- @field collection_kinds This table stores which collection kinds +-- have been defined together with their properties. +-- +-- @field algorithm_classes A table that maps algorithm keys (like +-- |tree layout| to class objects). +-- +-- @field keys A lookup table of all declared keys. Each entry of this +-- table consists of the original entry passed to the |declare| +-- method. Each of these tables is both index at a number (so you can +-- iterate over it using |ipairs|) and also via the key's name. + +local InterfaceCore = { + -- The main binding. Set by |InterfaceToDisplay.bind| method. + binding = nil, + + -- The stack of Scope objects. + scopes = {}, + + -- The collection kinds. + collection_kinds = {}, + + -- The algorithm classes + algorithm_classes = {}, + + -- The declared keys + keys = {}, + + -- Internals for handling the options stack + option_stack = {}, + option_cache_height = nil, + option_initial = { + algorithm_phases = {} + }, + option_aliases = { + [{}] = true -- dummy entry to make sure table is not empty + }, + + -- Constant strings for special collection kinds. + sublayout_kind = "INTERNAL_sublayout_kind", + subgraph_node_kind = "INTERNAL_subgraph_node_kind", +} + +-- Namespace +require("pgf.gd.interface").InterfaceCore = InterfaceCore + + +InterfaceCore.option_initial.__index = InterfaceCore.option_initial +InterfaceCore.option_initial.algorithm_phases.__index = InterfaceCore.option_initial.algorithm_phases + + +-- Imports +local Coordinate = require "pgf.gd.model.Coordinate" + + +--- Returns the top scope +-- +-- @return The current top scope, which is the scope in which +-- everything should happen right now. + +function InterfaceCore.topScope() + return assert(InterfaceCore.scopes[#InterfaceCore.scopes], "no graph drawing scope open") +end + + + +local factors = { + cm=28.45274, + mm=2.84526, + pt=1.0, + bp=1.00374, + sp=0.00002, + pc=12.0, + em=10, + ex=4.30554, + ["in"]=72.27, + dd=1.07, + cc=12.8401, + [""]=1, +} + +local directions = { + down = -90, + up = 90, + left = 180, + right = 0, + south = -90, + north = 90, + west = 180, + east = 0, + ["north east"] = 45, + ["north west"] = 135, + ["south east"] = -45, + ["south west"] = -135, + ["-"] = 0, + ["|"] = -90, +} + +--- +-- Converts parameters types. This method is used by both the +-- algorithm layer as well as the display layer to convert strings +-- into the different types of parameters. When a parameter +-- is pushed onto the option stack, you can either provide a value of +-- the parameter's type; but you can also provide a string. This +-- string can then be converted by this function to a value of the +-- correct type. +-- +-- @param s A parameter value or a string. +-- @param t The type of the parameter +-- +-- @return If |s| is not a string, it is just returned. If it is a +-- string, it is converted to the type |t|. + +function InterfaceCore.convert(s,t) + if type(s) ~= "string" then + return s + elseif t == "number" then + return tonumber(s) + elseif t == "length" then + local num, dim = string.match(s, "([%d.]+)(.*)") + return tonumber(num) * assert(factors[dim], "unknown unit") + elseif t == "string" then + return s + elseif t == "canvas coordinate" or t == "coordinate" then + local x, y = string.match(s,"%(([%d.]+)pt,([%d.]+)pt%)") + return Coordinate.new(tonumber(x),tonumber(y)) + elseif t == "boolean" then + return s == "true" + elseif t == "raw" then + return loadstring(s)() + elseif t == "direction" then + return directions[s] or tonumber(s) + elseif t == "nil" or t == nil then + return nil + else + error ("unknown parameter type") + end +end + + +-- Done + +return InterfaceCore \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua new file mode 100644 index 00000000000..586efa12067 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua @@ -0,0 +1,938 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToAlgorithms.lua,v 1.17 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- This class provides the interface between the graph drawing system +-- and algorithms. Another class, |InterfaceToDisplay|, binds the +-- display layers (like \tikzname\ or a graph drawing editor) to the +-- graph drawing system ``from the other side''. +-- +-- The functions declared here can be used by algorithms to +-- communicate with the graph drawing system, which will usually +-- forward the ``requests'' of the algorithms to the display layers in +-- some way. For instance, when you declare a new parameter, this +-- parameter will become available on the display layer. + +local InterfaceToAlgorithms = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToAlgorithms = InterfaceToAlgorithms + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" +local InterfaceToC = require "pgf.gd.interface.InterfaceToC" + +local LookupTable = require "pgf.gd.lib.LookupTable" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Edge = require "pgf.gd.model.Edge" + +local lib = require "pgf.gd.lib" + +local doc = require "pgf.gd.doc" + +-- Forwards + +local declare_handlers + + + + +--- +-- Adds a handler for the |declare| function. The |declare| +-- command is just a ``dispatcher'' to one of many possible +-- declaration functions. Which function is used, depends on which +-- fields are present in the table passed to |declare|. For each +-- registered handler, we call the |test| function. If it returns +-- neither |nil| nor |false|, the |handler| field of this handler is +-- called. If it returns |true|, the handler immediately +-- finishes. Otherwise, the next handler is tried. + +function InterfaceToAlgorithms.addHandler(test, handler) + table.insert(declare_handlers, 1, { test = test, handler = handler }) +end + + + +-- Local stuff + +local key_metatable = {} + +--- +-- This function is the ``work-horse'' for declaring things. It allows +-- you to specify on the algorithmic layer that a key ``is available'' +-- for use on the display layer. There is just one function for +-- handling all declarations in order to make the declarations +-- easy-to-use since you just need to import a single function: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare +--\end{codeexample} +-- +-- You can now use |declare| it as follows: You pass it a table +-- containing information about the to-be-declared key. The table +-- \emph{must} have a field |key| whose value is unique and must be a +-- string. If the value of |key| is, say, |"foo"|, the +-- parameter can be set on the display layer such as, say, the +-- \tikzname\ layer, using |/graph drawing/foo|. Here is a typical +-- example of how a declaration is done: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "electrical charge", +-- type = "number", +-- initial = "1.0", +-- +-- summary = "The ``electrical charge'' is a property...", +-- documentation = [[...]], +-- examples = [[...]] +-- } +--\end{codeexample} +-- +-- \medskip\noindent\textbf{Inlining Documentation.} +-- The three keys |summary|, |documentation| and |examples| are +-- intended for the display layer to give the users information about +-- what the key does. The |summary| should be a string that succinctly +-- describes the option. This text will typically be displayed for +-- instance as a ``tool tip'' or in an option overview. The +-- |documentation| optionally provides more information and should be +-- typeset using \TeX. The |examples| can either be a single string or +-- an array of strings. Each should be a \tikzname\ example +-- demonstrating how the key is used. +-- +-- Note that you can take advantage of the Lua syntax of enclosing +-- very long multi-line strings in |[[| and |]]|. As a bonus, if the +-- summary, documentation, or an example starts and ends with a quote, +-- these two quotes will be stripped. This allows you to enclose the +-- whole multi-line string (additionally) in quotes, leading to better +-- syntax highlighting in editors. +-- +-- \medskip\noindent\textbf{External Documentation.} +-- It is sometimes more desirable to put the documentation of a key +-- into an external file. First, this makes the code leaner and, thus, +-- faster to read (both for humans and for computers). Second, for C +-- code, it is quite inconvenient to have long strings inside a C +-- file. In such cases, you can use the |documentation_in| field: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "electrical charge", +-- type = "number", +-- initial = "1.0", +-- documentation_in = "some_filename" +-- } +--\end{codeexample} +-- +-- The |some_filename| must be the name of a Lua file that will be +-- read ``on demand,'' that is, whenever someone tries to access the +-- documentation, summary, or examples field of the key, this file +-- will be loaded using |require|. The file should then use +-- |pgf.gd.doc| to install the missing information in the keys. +-- +-- \medskip\noindent\textbf{The Use Field.} +-- When you declare a key, you can provide a |use| field. If present, +-- you must set it to an array of small tables which have two fields: +-- \begin{itemize} +-- \item |key| This is the name of another key or a function. +-- \item |value| This is either a value (like a string or a number) or +-- a function or |nil|. +-- \end{itemize} +-- +-- Here is an example: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "binary tree layout", +-- use = { +-- { key = "minimum number of children", value = 2 }, +-- { key = "significant sep", value = 12 }, +-- { key = "tree layout" } +-- }, +-- summary = "The |binary tree layout| places node...", +-- documentation = ..., +-- examples = ..., +-- } +--\end{codeexample} +-- +-- The effect of a |use| field is the following: Whenever the key is +-- encountered on the option stack, the key is first handled +-- normally. Then, we iterate over all elements of the |use| +-- array. For each element, we perform the action as if the |key| of +-- the array had been set explicitly to the value given by the |value| +-- field. If the |value| is a function, we pass a different value to +-- the key, namely the result of applying the function to the value +-- originally passed to the original key. Here is a typical example: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "level sep", +-- type = "length", +-- use = { +-- { key = "level pre sep", value = function (v) return v/2 end }, +-- { key = "level post sep", value = function (v) return v/2 end } +-- }, +-- summary = "..." +-- } +--\end{codeexample} +-- +-- Just like the value, the key itself can also be a function. In this +-- case, the to-be-used key is also computed by applying the function +-- to the value passed to the original key. +-- +-- As mentioned at the beginning, |declare| is a work-horse that will call +-- different internal functions depending on whether you declare a +-- parameter key or a new algorithm or a collection kind. Which kind +-- of declaration is being done is detected by the presence of certain +-- fields in the table passed to |t|. The different kind of +-- possible declarations are documented in the |declare_...| +-- functions. Note that these functions are internal and cannot be +-- called from outside; you must use the |declare| function. +-- +-- @param t A table contain the field |key| and other fields as +-- described. + +function InterfaceToAlgorithms.declare (t) + local keys = InterfaceCore.keys + + -- Sanity check: + assert (type(t.key) == "string" and t.key ~= "", "parameter key may not be the empty string") + if keys[t.key] or t.keys == "algorithm_phases" then + error("parameter '" .. t.key .. "' already declared") + end + + for _,h in ipairs (declare_handlers) do + if h.test(t) then + if h.handler(t) then + break + end + end + end + + -- Attach metatable: + setmetatable (t, key_metatable) + + -- Set! + keys[t.key] = t + keys[#keys + 1] = t +end + + +function key_metatable.__index (key_table, what) + if what == "documentation" or what == "summary" or what == "examples" then + local doc = rawget(key_table,"documentation_in") + if doc then + require (doc) + return rawget(key_table, what) + end + end +end + + + +--- +-- This function is called by |declare| for ``normal parameter keys,'' +-- which are all keys for which no special field like |algorithm| or +-- |layer| is declared. You write +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "electrical charge", +-- type = "number", +-- initial = "1.0", +-- +-- summary = "The ``electrical charge'' is a property...", +-- documentation = [[...]], +-- examples = [[...]] +-- } +--\end{codeexample} +-- +-- When an author writes |my node[electrical charge=5-3]| in the +-- description of her graph, the object |vertex| corresponding to the +-- node |my node| will have a field |options| attached to it with +--\begin{codeexample}[code only, tikz syntax=false] +--vertex.options["electrical charge"] == 2 +--\end{codeexample} +-- +-- The |type| field does not refer to Lua types. Rather, these types are +-- sensible types for graph drawing and they are mapped by the higher +-- layers to Lua types. In detail, the following types are available: +-- +-- \begin{itemize} +-- \item |number| A dimensionless number. Will be mapped to a normal +-- Lua |number|. So, when the author writes |foo=5*2|, the |foo| key +-- of the |options| field of the corresponding object will be set to +-- |10.0|. +-- \item |length| A ``dimension'' in the sense of \TeX\ (a number with +-- a dimension like |cm| attached to it). It is the job of the display +-- layer to map this to a number in ``\TeX\ points,'' that is, to a +-- multiple of $1/72.27$th of an inch. +-- \item |string| Some text. Will be mapped to a Lua |string|. +-- \item |canvas coordinate| A position on the canvas. Will be mapped +-- to a |model.Coordinate|. +-- \item |boolean| A Boolean value. +-- \item |raw| Some to-be-executed Lua text. +-- \item |direction| Normally, an angle; however, +-- the special values of |down|, |up|, |left|, |right| as well as the +-- directions |north|, |north west|, and so on are also legal on the +-- display layer. All of them will be mapped to a number. Furthermore, +-- a vertical bar (\verb!|!) will be mapped to |-90| and a minus sign +-- (|-|) will be mapped to |0|. +-- \item |hidden| A key of this type ``cannot be set,'' that is, +-- users cannot set this key at all. However algorithms can still read +-- this key and, through the use of |alias|, can use the key as a +-- handle to another key. +-- \item |user value| The key stores a Lua user value (userdata). Such +-- keys can only be set from C since user values cannot be created in +-- Lua (let alone in \tikzname). +-- \end{itemize} +-- +-- If the |type| field is missing, it is automatically set to +-- |"string"|. +-- +-- A parameter can have an |initial| value. This value will be used +-- whenever the parameter has not been set explicitly for an object. +-- +-- A parameter can have a |default| value. This value will be used as +-- the parameter value whenever the parameter is explicitly set, but +-- no value is provided. For a key of type |"boolean"|, if no +-- |default| is provided, |"true"| will be used automatically. +-- +-- A parameter can habe an |alias| field. This field must be set to +-- the name of another key or to a function. Whenever you access the +-- current key and this key is not set, the |alias| key is tried +-- instead. If it is set, its value will be returned (if the |alias| +-- key has itself an alias set, this is tried recursively). If the +-- alias is not set either and neither does it have an initial value, +-- the |initial| value is used. Note that in case the alias has its +-- |initial| field set, the |initial| value of the current key will +-- never be used. +-- +-- The main purpose of the current key is to allow algorithms to +-- introduce their own terminology for keys while still having access +-- to the standard keys. For instance, the |OptimalHierarchyLayout| +-- class uses the name |layerDistance| for what would be called +-- |level distance| in the rest of the graph drawing system. In this +-- case, we can declare the |layerDistance| key as follows: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- declare { +-- key = "layerDistance", +-- type = "length", +-- alias = "level distance" +-- } +--\end{codeexample} +-- +-- Inside the algorithm, we can write |...options.layerDistance| and +-- will get the current value of the |level distance| unless the +-- |layerDistance| has been set explicitly. Indeed, we might set the +-- |type| to |hidden| to ensure that \emph{only} the |level distance| +-- can and must set to set the layerDistance. +-- +-- Note that there is a difference between |alias| and the |use| +-- field: Suppose we write +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- declare { +-- key = "layerDistance", +-- type = "length", +-- use = { +-- { key = "level distance", value = lib.id } +-- } +-- } +--\end{codeexample} +-- +-- Here, when you say |layerDistance=1cm|, the |level distance| itself +-- will be modified. When the |level distance| is set, however, the +-- |layerDistance| will not be modified. +-- +-- If the alias is a function, it will be called with the option table +-- as its parameter. You can thus say things like +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- declare { +-- key = "layerDistance", +-- type = "length", +-- alias = function (option) +-- return option["layer pre dist"] + option["layer post dist"] +-- end +-- } +--\end{codeexample} +-- +-- As a special curtesy to C code, you can also set the key +-- |alias_function_string|, which allows you to put the function into +-- a string that is read using |loadstring|. +-- +-- (You cannot call this function directly, it is included for +-- documentation purposes only.) +-- +-- @param t The table originally passed to |declare|. + +local function declare_parameter (t) + + t.type = t.type or "string" + + if t.type == "boolean" and t.default == nil then + t.default = true + end + + -- Normal key + assert (type(t.type) == "string", "key type must be a string") + + -- Declare via the hub: + if t.type ~= "hidden" then + InterfaceCore.binding:declareCallback(t) + + -- Handle initials: + if t.initial then + InterfaceCore.option_initial[t.key] = InterfaceCore.convert(t.initial, t.type) + end + end + + if t.alias_function_string and not t.alias then + local count = 0 + t.alias = load ( + function () + count = count + 1 + if count == 1 then + return "return " + elseif count == 2 then + return t.alias_function_string + else + return nil + end + end)() + end + + if t.alias then + assert (type(t.alias) == "string" or type(t.alias == "function"), "alias must be a string or a function") + InterfaceCore.option_aliases[t.key] = t.alias + end + + return true +end + + + + +--- +-- This function is called by |declare| for ``algorithm +-- keys.'' They are detected by the presence of the field |algorithm| +-- in the table |t| passed to |declare|. Here is an example of how it +-- is used: +--\begin{codeexample}[code only, tikz syntax=false] +-- local ReingoldTilford1981 = {} +-- +-- --- +-- declare { +-- key = "tree layout", +-- algorithm = ReingoldTilford1981, +-- +-- preconditions = { +-- connected = true, +-- tree = true +-- }, +-- +-- postconditions = { +-- upward_oriented = true +-- }, +-- +-- summary = "The Reingold--Tilford method is...", +-- documentation = ..., +-- examples = ..., +-- } +-- +-- function ReingoldTilford1981:run() +-- ... +-- end +--\end{codeexample} +-- +-- The |algorithm| field expects either a table or a string as +-- value. If you provide a string, then |require| will be applied to +-- this string to obtain the table; however, this will happen only +-- when the key is actually used for the first time. This means that +-- you can declare (numerous) algorithms in a library without these +-- algorithms actually being loaded until they are needed. +-- +-- Independently of how the table is obtained, it will be ``upgraded'' +-- to a class by setting its |__index| field and installing a static +-- |new| function (which takes a table of initial values as +-- argument). Both these settings will only be done if they have not +-- yet been performed. +-- +-- Next, you can specify the fields |preconditions| and +-- |postconditions|. The preconditions are a table that tell the graph +-- drawing engine what kind of graphs your algorithm expects. If the +-- input graph is not of this kind, it will be automatically +-- transformed to meet this condition. Similarly, the postconditions +-- tell the engine about properties of your graph after the algorithm +-- has run. Again, additional transformations may be performed. +-- +-- You can also specify the field |phase|. This tells the graph +-- drawing engine which ``phase'' of the graph drawing process your +-- option applies to. Each time you select an algorithm later on +-- through use of the algorithm's key, the algorithm for this phase +-- will be set; algorithms of other phases will not be changed. So, +-- for instance, when an algorithm is part of the spanning tree +-- computation, its phase will be |"spanning tree computation"| and +-- using its key does not change the main algorithm, but only the +-- algorithm used during the computation of a spanning tree for the +-- current graph (in case this is needed by the main algorithm). In +-- case the |phase| field is missing, the phase |main| is used. Thus, +-- when no phase field is given, the key will change the main +-- algorithm used to draw the graph. +-- +-- Later on, the algorithm set for the current phase can be accessed +-- through the special |algorithm_phases| field of |options| +-- tables. The |algorithm_phases| table will contain a field for each +-- phase for which some algorithm has been set. +-- +-- The following example shows the declaration of an algorithm that is +-- the default for the phase |spanning tree computation|: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- --- +-- declare { +-- key = "breadth first spanning tree", +-- algorithm = { +-- run = +-- function (self) +-- return SpanningTreeComputation.computeSpanningTree(self.ugraph, false, self.events) +-- end +-- }, +-- phase = "spanning tree computation", +-- phase_default = true, +-- summary = ... +-- } +--\end{codeexample} +-- +-- The algorithm is called as follows during a run of the main +-- algorithms: +-- +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local graph = ... -- the graph object +-- local spanning_algorithm_class = graph.options.algorithm_phases["spanning tree computation"] +-- local spanning_algorithm = +-- spanning_algorithm_class.new{ +-- ugraph = ugraph, +-- events = scope.events +-- } +-- local spanning_tree = spanning_algorithm:run() +--\end{codeexample} +-- +-- If you set the |phase_default| field of |t| to |true|, the algorithm will +-- be installed as the default algorithm for the phase. This can be +-- done only once per phase. Furthermore, for such a default algorithm +-- the |algorithm| key must be table, it may not be a string (in other +-- words, all default algorithms are loaded immediately). +-- +-- (You cannot call this function directly, it is included for +-- documentation purposes only.) +-- +-- @param t The table originally passed to |declare|. + +local function declare_algorithm (t) + -- Algorithm declaration! + assert(type(t.algorithm) == "table" or type(t.algorithm) == "string") + + t.phase = t.phase or "main" + + local function make_class () + local class + + if type(t.algorithm) == "table" then + class = lib.class(t.algorithm) + else + class = lib.class(require(t.algorithm)) + end + + -- Now, save pre- and postconditions + class.preconditions = t.preconditions or {} + class.postconditions = t.postconditions or {} + + -- Save phase + class.phase = t.phase + + -- Compatibility + class.old_graph_model = t.old_graph_model + + return class + end + + -- Store this: + local store_me + if type(t.algorithm) == "table" then + store_me = make_class() + else + store_me = make_class + end + + -- Save in the algorithm_classes table: + InterfaceCore.algorithm_classes[t.key] = store_me + + -- Install! + InterfaceCore.binding:declareCallback(t) + + if t.phase_default then + assert (not InterfaceCore.option_initial.algorithm_phases[t.phase], + "default algorithm for phase already set") + assert (type(store_me) == "table", + "default algorithms must be loaded immediately") + InterfaceCore.option_initial.algorithm_phases[t.phase] = store_me + end + + return true +end + + + + +--- +-- This function is called by |declare| for ``collection kinds.'' They +-- are detected by the presence of the field |layer| +-- in the table |t| passed to |declare|. See the class |Collection| +-- for details on what a collection and a collection kind is. +-- +-- The |key| field of the table |t| passed to this function is both +-- the name of the to-be-declared collection kind as well as the key +-- that is used on the display layer to indicate that a node or edge +-- belongs to a collection. +-- +-- \medskip +-- \noindent\textbf{The Display Layer.} +-- Let us first have a look at what happens on the display layer: +-- A key |t.key| is setup on the display layer that, when used inside +-- a graph drawing scope, starts a new collection of the specified +-- kind. ``Starts'' means that all nodes and edges mentioned in the +-- rest of the current option scope will belong to a new collection +-- of kind |t.key|. +-- +--\begin{codeexample}[code only, tikz syntax=false] +--declare { key = "hyper", layer = 1 } +--\end{codeexample} +-- you can say on the \tikzname\ layer +--\begin{codeexample}[code only] +-- \graph { +-- a, b, c, d; +-- { [hyper] a, b, c } +-- { [hyper] b, c, d } +-- }; +--\end{codeexample} +-- +-- In this case, the nodes |a|, |b|, |c| will belong to a collection of +-- kind |hyper|. The nodes |b|, |c|, and |d| will (also) belong to +-- another collection of the same kind |hyper|. You can nest +-- collections; in this case, nodes will belong to several +-- collections. +-- +-- The effect of declaring a collection kind on the algorithm layer +-- it, first of all, that |scope.collections| will have a field named +-- by the collection kind. This field will store an array that +-- contains all collections that were declared as part of the +-- graph. For instance, |collections.hyper| will contain all +-- hyperedges, each of which is a table with the following fields: The +-- |vertices| and |edges| fields each contain arrays of all objects +-- being part of the collection. The |sub| field is an array of +-- ``subcollections,'' that is, all collections that were started +-- inside another collection. (For the collection kinds |hyper| and +-- |same layer| this makes no sense, but subgraphs could, for instance, +-- be nested.) +-- +-- \medskip +-- \noindent\textbf{Rendering of Collections.} +-- For some kinds of collections, it makes sense to \emph{render} them, +-- but only after the graph drawing algorithm has run. For this +-- purpose, the binding layer will use a callback for each collection +-- kind and each collection, see the |Binding| class for details. +-- Suppose, for instance, you would +-- like hyperedges to be rendered. In this case, a graph drawing +-- algorithm should iterate over all collections of type |hyper| and +-- compute some hints on how to render the hyperedge and store this +-- information in the |generated_options| table of the hyperedge. Then, +-- the binding layer will ask the dislay layer to run some some code +-- that is able to read key--value pairs passed to +-- it (which are the key--value pairs of the |generated_options| table) +-- and use this information to nicely draw the hyperedge. +-- +-- The number |t.layer| determines in which order the different +-- collection kinds are rendered. +-- +-- The last parameter, the layer number, is used to specify the order +-- in which the different collection kinds are rendered. The higher the +-- number, the later the collection will be rendered. Thus, if there is +-- a collection kind with layer number 10 and another with layer number +-- 20, all collections of the first kind will be rendered first, +-- followed by all collections of the second kind. +-- +-- Collections whose layer kinds are non-negative get rendered +-- \emph{after} the nodes and edges have already been rendered. In +-- contrast, collections with a negative layer number get shown +-- ``below'' the nodes and edges. +-- +-- (You cannot call this function directly, it is included for +-- documentation purposes only.) +-- +-- @param t The table originally passed to |declare|. + +local function declare_collection_kind (t) + assert (type(t.layer) == "number", "layer must be a number") + + local layer = t.layer + local kind = t.key + local kinds = InterfaceCore.collection_kinds + local new_entry = { kind = kind, layer = layer } + + -- Insert into table part: + kinds[kind] = new_entry + + -- Insert into array part: + local found + for i=1,#kinds do + if kinds[i].layer > layer or (kinds[i].layer == layer and kinds[i].kind > kind) then + table.insert(kinds, i, new_entry) + return + end + end + + kinds[#kinds+1] = new_entry + + -- Bind + InterfaceCore.binding:declareCallback(t) + + return true +end + + + +-- Build in handlers: + +declare_handlers = { + { test = function (t) return t.algorithm_written_in_c end, handler = InterfaceToC.declare_algorithm_written_in_c }, + { test = function (t) return t.algorithm end, handler = declare_algorithm }, + { test = function (t) return t.layer end, handler = declare_collection_kind }, + { test = function (t) return true end, handler = declare_parameter } +} + + + + + + + + +--- +-- Finds a node by its name. This method should be used by algorithms +-- for which a node name is specified in some option and, thus, needs +-- to be converted to a vertex object during a run of the algorithm. +-- +-- @param name A node name +-- +-- @return The vertex of the given name in the syntactic digraph or +-- |nil|. + +function InterfaceToAlgorithms.findVertexByName(name) + return InterfaceCore.topScope().node_names[name] +end + + + + + +-- Helper function +local function add_to_collections(collection,where,what) + if collection then + LookupTable.addOne(collection[where],what) + add_to_collections(collection.parent,where,what) + end +end + +local unique_count = 1 + +--- +-- Generate a new vertex in the syntactic digraph. Calling this method +-- allows algorithms to create vertices that are not present in the +-- original input graph. Using the graph drawing coroutine, this +-- function will pass back control to the display layer in order to +-- render the vertex and, thereby, create precise size information +-- about it. +-- +-- Note that creating new vertices in the syntactic digraph while the +-- algorithm is already running is a bit at odds with the notion of +-- treating graph drawing as a series of graph transformations: For +-- instance, when a new vertex is created, the graph will (at least +-- temporarily) no longer be connected; even though an algorithm may +-- have requested that it should only be fed connected +-- graphs. Likewise, more complicated requirements like insisting on +-- the graph being a tree also cannot be met. +-- +-- For these reasons, the following happens, when a new vertex is +-- created using the function: +-- +-- \begin{enumerate} +-- \item The vertex is added to the syntactic digraph. +-- \item It is added to all layouts on the current layout stack. When +-- a graph drawing algorithm is run, it is not necessarily run on the +-- original syntactic digraph. Rather, a sequence / stack of nested +-- layouts may currently +-- be processed and the vertex is added to all of them. +-- \item The vertex is added to both the |digraph| and the |ugraph| of +-- the current algorithm. +-- \end{enumerate} +-- +-- @param algorithm An algorithm for whose syntactic digraph the node +-- should be added +-- @param init A table of initial values for the node that is passed +-- to |Binding:createVertex|, see that function for details. +-- +-- @return The newly created node +-- +function InterfaceToAlgorithms.createVertex(algorithm, init) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Setup node + if not init.name then + init.name = "internal@gd@node@" .. unique_count + unique_count = unique_count + 1 + end + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + if not init.shape or init.shape == "none" then + init.shape = "rectangle" + end + + -- Call binding + binding:createVertex(init) + + local v = assert(scope.node_names[init.name], "internal node creation failed") + + -- Add vertex to the algorithm's digraph and ugraph + algorithm.syntactic_component:add {v} + algorithm.digraph:add {v} + algorithm.ugraph:add {v} + + -- Compute bounding boxes: + LayoutPipeline.prepareBoundingBoxes(algorithm.rotation_info, algorithm.adjusted_bb, algorithm.digraph, {v}) + + -- Add the node to the layout stack: + add_to_collections(algorithm.layout, "vertices", v) + + algorithm.layout_graph:add { v } + + return v +end + + + +--- +-- Generate a new edge in the syntactic digraph. This method is quite +-- similar to |createVertex| and has the same effects with respect to +-- the edge: The edge is added to the syntactic digraph and also to +-- all layouts on the layout stack. Forthermore, appropriate edges are +-- added to the |digraph| and the |ugraph| of the algorithm currently +-- running. +-- +-- @param algorithm An algorithm for whose syntactic digraph the node should be added +-- @param tail A syntactic tail vertex +-- @param head A syntactic head vertex +-- @param init A table of initial values for the edge. +-- +-- The following fields are useful for |init|: +-- \begin{itemize} +-- \item |init.direction| If present, a direction for the edge. Defaults to "--". +-- \item |init.options| If present, some options for the edge. +-- \item |init.generated_options| A table that is passed back to the +-- display layer as a list of key-value pairs in the syntax of +-- |declare_parameter|. +-- \end{itemize} + +function InterfaceToAlgorithms.createEdge(algorithm, tail, head, init) + + init = init or {} + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + local syntactic_digraph = algorithm.layout_graph + local syntactic_component = algorithm.syntactic_component + + assert (syntactic_digraph:contains(tail) and + syntactic_digraph:contains(head), + "attempting to create edge between nodes that are not in the syntactic digraph") + + local arc = syntactic_digraph:connect(tail, head) + + local edge = Edge.new { + head = head, + tail = tail, + direction = init.direction or "--", + options = init.options or algorithm.layout.options, + path = init.path, + generated_options = init.generated_options + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + local s_arc = syntactic_component:connect(tail, head) + s_arc.syntactic_edges = arc.syntactic_edges + + -- Create Event + local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) + edge.event = e + + -- Make part of collections + for _,c in ipairs(edge.options.collections) do + LookupTable.addOne(c.edges, edge) + end + + -- Call binding + binding.storage[edge] = {} + binding:everyEdgeCreation(edge) + + -- Add edge to digraph and ugraph + local direction = edge.direction + if direction == "->" then + algorithm.digraph:connect(tail, head) + elseif direction == "<-" then + algorithm.digraph:connect(head, tail) + elseif direction == "--" or direction == "<->" then + algorithm.digraph:connect(tail, head) + algorithm.digraph:connect(head, tail) + end + algorithm.ugraph:connect(tail, head) + algorithm.ugraph:connect(head, tail) + + -- Add edge to layouts + add_to_collections(algorithm.layout, "edges", edge) + +end + + + + + +-- Done + +return InterfaceToAlgorithms \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua new file mode 100644 index 00000000000..5b220f318bc --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua @@ -0,0 +1,77 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToC.lua,v 1.6 2013/05/23 20:01:27 tantau Exp $ + + +--- +-- This table contains functions that are used (on the Lua side) to +-- prepare a graph for use in C and, vice versa, to translate back the +-- results of C to Lua. + +local InterfaceToC = {} + +-- Imports + +local lib = require "pgf.gd.lib" + + +--- +-- This function is called by |declare| for ``algorithm +-- keys'' where the algorithm is not written in Lua, but rather in the +-- programming language C. You do not call this function yourself; +-- |InterfaceFromC.h| will do it for you. Nevertheless, if you +-- provide a table to |declare| with the field +-- |algorithm_written_in_c| set, the following happens: The table's +-- |algorithm| field is set to an algorithm class object whose |run| +-- method calls the function passed via the +-- |algorithm_written_in_c| field. It will be called with the +-- following parameters (in that order): +-- \begin{enumerate} +-- \item The to-be-laid out digraph. This will not be the whole layout +-- graph (syntactic digraph) if preprocessing like decomposition into +-- connected components is used. +-- \item An array of the digraph's vertices, but with the table part +-- hashing vertex objects to their indices in the array part. +-- \item An array of the syntactic edges of the digraph. Like the +-- array, the table part will hash back the indices of the edge objects. +-- \item The algorithm object. +-- \end{enumerate} +-- +-- @param t The table originally passed to |declare|. + +function InterfaceToC.declare_algorithm_written_in_c (t) + t.algorithm = { + run = function (self) + local back_table = lib.icopy(self.ugraph.vertices) + for i,v in ipairs(self.ugraph.vertices) do + back_table[v] = i + end + local edges = {} + for _,a in ipairs(self.ugraph.arcs) do + local b = self.layout_graph:arc(a.tail,a.head) + if b then + lib.icopy(b.syntactic_edges, edges) + end + end + for i=1,#edges do + edges[edges[i]] = i + end + collectgarbage("stop") -- BUG! Remove this when everything is linked against a SINGLE Lua lib at runtime + t.algorithm_written_in_c (self.digraph, back_table, edges, self) + collectgarbage("restart") -- Remove also! + end + } +end + + + +-- Done + +return InterfaceToC \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua new file mode 100644 index 00000000000..cc72dc5910a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua @@ -0,0 +1,990 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua,v 1.12 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- This class provides the interface between a display +-- layer (like \tikzname\ or a graph editor) and graph drawing +-- system. Another class, |InterfaceToAlgorithms|, binds the algorithm +-- layer (which are written in Lua) to the graph drawing system. +-- +-- The functions declared here are independent of the actual display +-- layer. Rather, the differences between the layers are encapsulated +-- by subclasses of the |Binding| class, see that class for +-- details. Thus, when a new display layer is written, the present +-- class is \emph{used}, but not \emph{modified}. Instead, only a new +-- binding is created and all display layer specific interaction is +-- put there. +-- +-- The job of this class is to provide convenient methods that can be +-- called by the display layer. For instance, it provides methods for +-- starting a graph drawing scope, managing the stack of such scope, +-- adding a node to a graph and so on. + +local InterfaceToDisplay = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local Scope = require "pgf.gd.interface.Scope" + +local Binding = require "pgf.gd.bindings.Binding" + +local Sublayouts = require "pgf.gd.control.Sublayouts" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Edge = require "pgf.gd.model.Edge" +local Collection = require "pgf.gd.model.Collection" + +local Storage = require "pgf.gd.lib.Storage" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Event = require "pgf.gd.lib.Event" + +local lib = require "pgf.gd.lib" + + +-- Forward declarations +local get_current_options_table +local render_collections +local push_on_option_stack +local vertex_created + +-- Local objects + +local phase_unique = {} -- a unique handle +local collections_unique = {} -- a unique handle +local option_cache = nil -- The option cache + + + + +--- +-- Initiliaze the binding. This function is called once by the display +-- layer at the very beginning. For instance, \tikzname\ does the +-- following call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF") +--\end{codeexample} +-- +-- Inside this call, many standard declarations will be executed, that +-- is, the declared binding will be used immediately. +-- +-- Subsequently, the |binding| field of the |InterfaceCore| can be used. +-- +-- @param class A subclass of |Binding|. + +function InterfaceToDisplay.bind(class) + assert (not InterfaceCore.binding, "binding already initialized") + + -- Create a new object + InterfaceCore.binding = setmetatable({}, class) + + -- Load these libraries, which contain many standard declarations: + require "pgf.gd.model.library" + require "pgf.gd.control.library" +end + + + + +--- +-- Start a graph drawing scope. Note that this is not the same as +-- starting a subgraph / sublayout, which are local to a graph drawing +-- scope: When a new graph drawing scope is started, it is pushed on +-- top of a stack of graph drawing scopes and all other ``open'' +-- scopes are no longer directly accessible. All method calls to an +-- |Interface...| object will refer to this newly created scope until +-- either a new scope is opened or until the current scope is closed +-- once more. +-- +-- Each graph drawing scope comes with a syntactic digraph that is +-- build using methods like |addVertex| or |addEdge|. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. + +function InterfaceToDisplay.beginGraphDrawingScope(height) + + -- Create a new scope table + local scope = Scope.new {} + + -- Setup syntactic digraph: + local g = scope.syntactic_digraph + + g.options = get_current_options_table(height) + g.syntactic_digraph = g + g.scope = scope + + -- Push scope: + InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope +end + + + +--- +-- Arranges the current graph using the specified algorithm and options. +-- +-- This function should be called after the graph drawing scope has +-- been opened and the syntactic digraph has been completely +-- specified. It will now start running the algorithm specified +-- through the |algorithm_phase| options. +-- +-- Internally, this function creates a coroutine that will run the current graph +-- drawing algorithm. Coroutines are needed since a graph drawing +-- algorithm may choose to create a new node. In this case, the +-- algorithm needs to be suspended and control must be returned back +-- to the display layer, so that the node can be typeset in order to +-- determine the precise size information. Once this is done, control +-- must be passed back to the exact point inside the algorithm where +-- the node was created. Clearly, all of these actions are exactly +-- what coroutines are for. +-- +-- @return Time it took to run the algorithm + +function InterfaceToDisplay.runGraphDrawingAlgorithm() + + -- Time things + local start = os.clock() + + -- Setup + local scope = InterfaceCore.topScope() + assert(not scope.coroutine, "coroutine already created for current gd scope") + + -- The actual drawing function + local function run () + if #scope.syntactic_digraph.vertices == 0 then + -- Nothing needs to be done + return + end + + LayoutPipeline.run(scope) + end + + scope.coroutine = coroutine.create(run) + + -- Run it: + InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- End timing: + local stop = os.clock() + + return stop - start +end + + +--- +-- Resume the graph drawing coroutine. +-- +-- This function is the work horse of the coroutine management. It +-- gets called whenever control passes back from the display layer to +-- the algorithm level. We resume the graph drawing coroutine so that the +-- algorithm can start/proceed. The tricky part is when the algorithm +-- yields, but is not done. In this case, the code needed for creating +-- a new node is passed back to the display layer through the binding, +-- which must then execute the code and then resuming the coroutine. +-- +function InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Asserts + assert(scope.coroutine, "coroutine not created for current gd scope") + + -- Run + local ok, text = coroutine.resume(scope.coroutine) + assert(ok, text) + if coroutine.status(scope.coroutine) ~= "dead" then + -- Ok, ask binding to continue + binding:resumeGraphDrawingCoroutine(text) + end +end + + + +--- Ends the current graph drawing scope. +-- +function InterfaceToDisplay.endGraphDrawingScope() + assert(#InterfaceCore.scopes > 0, "no gd scope open") + InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop +end + + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- node of the graph. The |name| must be a unique string identifying +-- the node. The newly created vertex will be added to the syntactic +-- digraph. The binding function |everyVertexCreation| will then be +-- called, allowing the binding to store information regarding the newly +-- created vertex. +-- +-- For each vertex an event will be created in the event +-- sequence. This event will have the kind |"node"| and its +-- |parameter| will be the vertex. +-- +-- @param name Name of the vertex. +-- +-- @param shape The shape of the vertex such as |"circle"| or +-- |"rectangle"|. This shape may help a graph drawing algorithm +-- figuring out how the node should be placed. +-- +-- @param path A |Path| object representing the vertex's path. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. +-- +-- @param binding_infos These options are passed to and are specific +-- to the current |Binding|. +-- +-- @param anchors A table of anchors (mapping anchor positions to +-- |Coordinates|). + + +function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local v = scope.node_names[name] + assert (not v or not v.created_on_display_layer, "node already created") + + -- Create vertex + if not v then + v = Vertex.new { + name = name, + shape = shape, + kind = "node", + path = path, + options = get_current_options_table(height), + anchors = anchors, + } + + vertex_created(v,scope) + else + assert(v.kind == "subgraph node", "subgraph node expected") + v.shape = shape + v.path = path + v.anchors = anchors + end + + v.created_on_display_layer = true + + -- Call binding + binding.storage[v] = binding_infos + binding:everyVertexCreation(v) +end + + +-- This is a helper function +function vertex_created(v,scope) + + -- Create Event + local e = InterfaceToDisplay.createEvent ("node", v) + v.event = e + + -- Create name lookup + scope.node_names[v.name] = v + + -- Add vertex to graph + scope.syntactic_digraph:add {v} + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope that is a subgraph vertex. Such a vertex +-- ``surrounds'' the vertices of a subgraph. The special property of a +-- subgraph node opposed to a normal node is that it is created only +-- after the subgraph has been laid out. However, the difference to a +-- collection like |hyper| is that the node is availble immediately as +-- a normal node in the sense that you can connect edges to it. +-- +-- What happens internally is that subgraph nodes get ``registered'' +-- immediately both on the display level and on the algorithm level, +-- but the actual node is only created inside the layout pipeline +-- using a callback of the binding. The present function is used to +-- perform this registering. The node creation happens when the +-- innermost layout in which the subgraph node is declared has +-- finished. For each subgraph node, a collection is created that +-- contains all vertices (and edges) being part of the subgraph. For +-- this reason, this method is a |push...| method, since it pushes +-- something on the options stack. +-- +-- The |init| parameter will be used during the creation of the node, +-- see |Binding:createVertex| for details on the fields. Note that +-- |init.text| is often not displayed for such ``vast'' nodes as those +-- created for whole subgraphs, but a shape may use it nevertheless +-- (for instance, one might display this text at the top of the node +-- or, in case of a \textsc{uml} package, in a special box above the +-- actual node). +-- +-- The |init.generated_options| will be augmented by additional +-- key--value pairs when the vertex is created: +-- +-- \begin{itemize} +-- \item The key |subgraph point cloud| will have as its value a +-- string that is be a list of points (without +-- separating commas) like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in +-- this syntax. The list will contain all points inside the +-- subgraph. In particular, a bounding box around these points will +-- encompass all nodes and bend points of the subgraph. +-- The bounding box of this point cloud is guaranteed to be centered on +-- the origin. +-- \item The key |subgraph bounding box width| will have as its value +-- the width of a bounding box (in \TeX\ points, as a string with the +-- suffix |"pt"|). +-- \item The key |subgraph bounding box height| stores the height of a +-- bounding box. +-- \end{itemize} +-- +-- @param name The name of the node. +-- @param height Height of the options stack. Note that this method +-- pushes something (namely a collection) on the options stack. +-- @param info A table passed to |Binding:createVertex|, see that function. +-- +function InterfaceToDisplay.pushSubgraphVertex(name, height, info) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + -- Create vertex + local v = Vertex.new { + name = name, + kind = "subgraph node", + options = get_current_options_table(height-1) + } + + vertex_created(v,scope) + + -- Store info + info.generated_options = info.generated_options or {} + info.name = name + v.subgraph_info = info + + -- Create collection and link it to v + local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height) + v.subgraph_collection = entry.value + v.subgraph_collection.subgraph_node = v + + -- Find parent collection in options stack: + local collections = v.options.collections + for i=#collections,1,-1 do + if collections[i].kind == InterfaceCore.sublayout_kind then + v.subgraph_collection.parent_layout = collections[i] + break + end + end +end + + + +--- +-- Add options for an already existing vertex. +-- +-- This function allows you to add options to an already existing +-- vertex. The options that will be added are all options on the +-- current options stack; they will overwrite existing options of the +-- same name. For collections, the vertex stays in all collections it +-- used to, it is only added to all collections that are currently on +-- the options stack. +-- +-- @param name Name of the vertex. +-- @param height The option stack height. + +function InterfaceToDisplay.addToVertexOptions(name, height) + + -- Setup + local scope = InterfaceCore.topScope() + + -- Does vertex already exist? + local v = assert (scope.node_names[name], "node is missing, cannot add options") + + v.options = get_current_options_table(height, v.options) + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + + + +--- +-- Creates a new edge in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- edge that is created. Both the |from| vertex and the |to| vertex +-- must exist (have been created through |createVertex|) prior to your +-- being able to call this function. +-- +-- After the edge has been created, the binding layer's function +-- |everyEdgeCreation| will be called, allowing the binding layer to +-- store information about the edge. +-- +-- For each edge an event is created, whose kind is |"edge"| and whose +-- |parameter| is a two-element array whose first entry is the edge's +-- arc in the syntactic digraph and whose second entry is the position +-- of the edge in the arc's array of syntactic edges. +-- +-- @param tail Name of the node the edge begins at. +-- @param head Name of the node the edge ends at. +-- @param direction Direction of the edge (e.g. |--| for an undirected edge +-- or |->| for a directed edge from the first to the second +-- node). +-- @param height The option stack height, see for instance |createVertex|. +-- +-- @param binding_infos These options will be stored in the |storage| +-- of the vertex at the field index by the binding. + +function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local h = scope.node_names[head] + local t = scope.node_names[tail] + assert (h and t, "attempting to create edge between nodes that are not in the graph") + + -- Create Arc object + local arc = scope.syntactic_digraph:connect(t, h) + + -- Create Edge object + local edge = Edge.new { + head = h, + tail = t, + direction = direction, + options = get_current_options_table(height) + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + -- Create Event + local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) + edge.event = e + + -- Make part of collections + for _,c in ipairs(edge.options.collections) do + LookupTable.addOne(c.edges, edge) + end + + -- Call binding + binding.storage[edge] = binding_infos + binding:everyEdgeCreation(edge) + +end + + + + + +--- +-- Push an option to the stack of options. +-- +-- As a graph is parsed, a stack of ``current options'' +-- is created. To add something to this table, the display layers may +-- call the method |pushOption|. To pop something from this stack, +-- just set the |height| value during the next push to the position to +-- which you actually wish to push something; everything above and +-- including this position will be popped from the stack. +-- +-- When an option is pushed, several additional options may also be +-- pushed, namely whenever the option has a |use| field set. These +-- additional options may, in turn, also push new options. Because of +-- this, this function returns a new stack height, representing the +-- resulting stack height. +-- +-- In addition to this stack height, this function returns a Boolean +-- value indicating whether a ``main algorithm phase was set.'' This +-- happens whenever a key is executed (directly or indirectly through +-- the |use| field) that selects an algorithm for the ``main'' +-- algorithm phase. This information may help the caller to setup the +-- graph drawing scopes correctly. +-- +-- @param key A parameter (must be a string). +-- @param value A value (can be anything). If it is a string, it will +-- be converted to whatever the key expects. +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. +-- +-- @return A new stack height +-- @return A Boolean that is |true| iff the main algorithm phase was +-- set by the option or one option |use|d by it. +-- @return The newly created entry on the stack. If more entries are +-- created through the use of the |use| field, the original entry is +-- returned nevertheless. + + +function InterfaceToDisplay.pushOption(key, value, height) + assert(type(key) == "string", "illegal key") + + local key_record = assert(InterfaceCore.keys[key], "unknown key") + local main_phase_set = false + + if value == nil and key_record.default then + value = key_record.default + end + + -- Find out what kind of key we are pushing: + + if key_record.algorithm then + -- Push a phase + if type(InterfaceCore.algorithm_classes[key]) == "function" then + -- Call the constructor function + InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]() + end + + local algorithm = InterfaceCore.algorithm_classes[key] + + assert (algorithm, "algorithm class not found") + + push_on_option_stack(phase_unique, + { phase = key_record.phase, algorithm = algorithm }, + height) + + if key_record.phase == "main" then + main_phase_set = true + end + + elseif key_record.layer then + -- Push a collection + local stack = InterfaceCore.option_stack + local scope = InterfaceCore.topScope() + + -- Get the stack above "height": + local options = get_current_options_table(height-1) + + -- Create the collection event + local event = InterfaceToDisplay.createEvent ("collection", key) + + -- Create collection object: + local collection = Collection.new { kind = key, options = options, event = event } + + -- Store in collections table of current scope: + local collections = scope.collections[key] or {} + collections[#collections + 1] = collection + scope.collections[key] = collections + + -- Build collection tree + collection:registerAsChildOf(options.collections[#options.collections]) + + -- Push on stack + push_on_option_stack(collections_unique, collection, height) + + else + + -- A normal key + push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height) + + end + + local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack] + + -- Now, push use keys: + local use = key_record.use + if key_record.use then + local flag + for _,u in ipairs(InterfaceCore.keys[key].use) do + local use_k = u.key + local use_v = u.value + if type(use_k) == "function" then + use_k = use_k(value) + end + if type(use_v) == "function" then + use_v = use_v(value) + end + height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1) + main_phase_set = main_phase_set or flag + end + end + + return height, main_phase_set, newly_created +end + + +--- +-- Push a layout on the stack of options. As long as this layout is on +-- the stack, all vertices and edges will be part of this layout. For +-- details on layouts, please see |Sublayouts|. +-- +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. + +function InterfaceToDisplay.pushLayout(height) + InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height) +end + + + +--- +-- Creates an event and adds it to the event string of the current scope. +-- +-- @param kind Name/kind of the event. +-- @param parameters Parameters of the event. +-- +-- @return The newly pushed event +-- +function InterfaceToDisplay.createEvent(kind, param) + local scope = InterfaceCore.topScope() + local n = #scope.events + 1 + local e = Event.new { kind = kind, parameters = param, index = n } + scope.events[n] = e + + return e +end + + + +--- +-- This method allows you to query the table of all declared keys. It +-- contains them both as an array and also as a table index by the +-- keys's names. In particular, you can then iterate over it using +-- |ipairs| and you can check whether a key is defined by accessing +-- the table at the key's name. Each entry of the table is the +-- original table passed to |InterfaceToAlgorithms.declare|. +-- +-- @return A lookup table of all declared keys. + +function InterfaceToDisplay.getDeclaredKeys() + return InterfaceCore.keys +end + + + + +--- +-- Renders the graph. +-- +-- This function is called after the graph has been laid out by the +-- graph drawing algorithms. It will trigger a sequence of calls to +-- the binding layer that will, via callbacks, start rendering the +-- whole graph. +-- +-- In detail, this function calls: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderStart() +--render_vertices() +--render_edges() +--render_collections() +--binding:renderStop() +--\end{codeexample} +-- +-- Here, the |render_...| functions are local, internal functions that are, +-- nevertheless, documented here. +-- +-- @param name Returns the algorithm class that has been declared using +-- |declare| under the given name. + +function InterfaceToDisplay.renderGraph() + local scope = InterfaceCore.topScope() + local syntactic_digraph = scope.syntactic_digraph + + local binding = InterfaceCore.binding + + binding:renderStart() + render_vertices(syntactic_digraph.vertices) + render_edges(syntactic_digraph.arcs) + render_collections(scope.collections) + binding:renderStop() +end + + + + + +--- +-- Render the vertices after the graph drawing algorithm has +-- finished. This function is local and internal and included only for +-- documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will start +-- rendering the vertices by calling appropriate callbacks of the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +--\graph [... layout] { +-- a -- b -- c -- d; +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderVerticesStart() +--binding:renderVertex(vertex_a) +--binding:renderVertex(vertex_b) +--binding:renderVertex(vertex_c) +--binding:renderVertex(vertex_d) +--binding:renderVerticesStop() +--\end{codeexample} +-- +-- @param vertices An array of all vertices in the syntactic digraph. + +function render_vertices(vertices) + InterfaceCore.binding:renderVerticesStart() + for _,vertex in ipairs(vertices) do + InterfaceCore.binding:renderVertex(vertex) + end + InterfaceCore.binding:renderVerticesStop() +end + + +--- +-- Render the collections whose layer is not |0|. This local, internal +-- function is called to render the different collection kinds. +-- +-- Collection kinds rendered in the order provided by the |layer| +-- field passed to |declare| during the declaration of the colleciton +-- kind, see also |declare_collection|. If several collection kinds +-- have the same layer, they are rendered in lexicographical ordering +-- (to ensure that they are always rendered in the same order). +-- +-- Consider the following code: +--\begin{codeexample}[code only, tikz syntax=false] +--declare { key = "hyper", layer = 1 } +--\end{codeexample} +-- you can say on the \tikzname\ layer +--\begin{codeexample}[code only] +--\graph { +-- a, b, c, d; +-- { [hyper] a, b, c } +-- { [hyper] b, c, d } +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderCollectionStartKind("hyper", 1) +--binding:renderCollection(collection_containing_abc) +--binding:renderCollection(collection_containing_bcd) +--binding:renderCollectionStopKind("hyper", 1) +--\end{codeexample} +-- +-- @param collections The |collections| table of the current scope. + +function render_collections(collections) + local kinds = InterfaceCore.collection_kinds + local binding = InterfaceCore.binding + + for i=1,#kinds do + local kind = kinds[i].kind + local layer = kinds[i].layer + + if layer ~= 0 then + binding:renderCollectionStartKind(kind, layer) + for _,c in ipairs(collections[kind] or {}) do + binding:renderCollection(c) + end + binding:renderCollectionStopKind(kind, layer) + end + end +end + + +--- +-- Render the syntactic edges of a graph after the graph drawing +-- algorithm has finished. This function is local and internal and included only +-- for documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will first +-- rendering the vertices using |render_vertices|, followed by calling +-- this function, which in turn calls appropriate callbacks to the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +-- \graph [... layout] { +-- a -- b -- c -- d; +-- }; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local binding = InterfaceCore.binding +-- +-- binding:renderEdgesStart() +-- binding:renderEdge(edge_from_a_to_b) +-- binding:renderEdge(edge_from_b_to_c) +-- binding:renderEdge(edge_from_c_to_d) +-- binding:renderEdgesStop() +--\end{codeexample} +-- +-- @param arcs The array of arcs of the syntactic digraph. + +function render_edges(arcs) + InterfaceCore.binding:renderEdgesStart() + for _,a in ipairs(arcs) do + for _,e in ipairs (a.syntactic_edges) do + InterfaceCore.binding:renderEdge(e) + end + end + InterfaceCore.binding:renderEdgesStop() +end + + +local aliases = InterfaceCore.option_aliases +local option_initial = InterfaceCore.option_initial + +local option_metatable = { + __index = + function (t, key) + local k = aliases[key] + if k then + local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil + if v ~= nil then + return v + end + end + return option_initial[key] + end +} + + +--- +-- Get the current options table. +-- +-- An option table can be accessed like a normal table; however, there +-- is a global fallback for this table. If an index is not defined, +-- the value of this index in the global fallback table is used. (This +-- reduces the overall amount of option keys that need to be stored +-- with object.) +-- +-- (This function is local and internal and included only for documentation +-- purposes.) +-- +-- @param height The stack height for which the option table is +-- required. +-- @param table If non |nil|, the options will be added to this +-- table. +-- +-- @return The option table as described above. + +function get_current_options_table (height, table) + local stack = InterfaceCore.option_stack + assert (height >= 0 and height <= #stack, "height value out of bounds") + + if height == InterfaceCore.option_cache_height and not table then + return option_cache + else + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + -- Build options table + local cache + if not table then + cache = setmetatable( + { + algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases), + collections = {} + }, option_metatable) + else + cache = lib.copy(table) + cache.algorithm_phases = lib.copy(cache.algorithm_phases) + cache.collections = lib.copy(cache.collections) + end + + local algorithm_phases = cache.algorithm_phases + local collections = cache.collections + local keys = InterfaceCore.keys + + local function handle (k, v) + if k == phase_unique then + algorithm_phases[v.phase] = v.algorithm + elseif k == collections_unique then + LookupTable.addOne(collections, v) + else + cache[k] = v + end + end + + for _,s in ipairs(stack) do + handle (s.key, s.value) + end + + -- Cache it, if this was not added: + if not table then + InterfaceCore.option_cache_height = height + option_cache = cache + end + + return cache + end +end + + + +-- A helper function + +function push_on_option_stack(key, value, height) + local stack = InterfaceCore.option_stack + + assert (type(height) == "number" and height > 0 and height <= #stack + 1, + "height value out of bounds") + + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + stack[height] = { key = key, value = value } + InterfaceCore.option_cache_height = nil -- invalidate cache +end + + + +-- Done + +return InterfaceToDisplay \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua new file mode 100644 index 00000000000..7826e77e6ae --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua @@ -0,0 +1,92 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/Scope.lua,v 1.2 2013/02/08 17:14:05 tantau Exp $ + + + +--- +-- In theory, graph drawing algorithms take graphs as input and +-- output graphs embedded into the plane as output. In practice, however, +-- the input to a graph drawing algorithm is not ``just'' the +-- graph. Rather, additional information about the graph, in particular +-- about the way the user specified the graph, is also important to many +-- graph drawing algorithms. +-- +-- The graph drawing system gathers both the original input graph as well +-- as all additional information that is provided in the graph drawing +-- scope inside a scope table. The object has a number of fields that +-- inform an algorithm about the input. +-- +-- For each graph drawing scope, a new |Scope| object is +-- created. Graph drawing scopes are kepts track of using a stack, but +-- only the top of this stack is available to the interface classes. +-- +-- @field syntactic_digraph The syntactic digraph is a digraph that +-- faithfully encodes the way the input graph is represented +-- syntactically. However, this does not mean that the syntactic +-- digraph contains the actual textual representation of the input +-- graph. Rather, when an edge is specified as, say, |a <- b|, the +-- syntactic digraph will contains an arc from |a| to |b| with an edge +-- object attached to it that is labeled as a ``backward'' +-- edge. Similarly, an edge |a -- b| is also stored as a directed arc +-- from |a| to |b| with the label |--| attached to it. Algorithms will +-- often be more interested graphs derived from the syntactic digraph +-- such as its underlying undirected graph. These derived graphs are +-- made accessible by the graph drawing engine during the preprocessing. +-- +-- @field events An array of |Event| objects. These objects, see the +-- |Event| class for details, are created during the parsing of the +-- input graph. +-- +-- @field node_names A table that maps the names of nodes to node +-- objects. Every node must have a unique name. +-- +-- @field coroutine A Lua coroutine that is used internally to allow +-- callbacks to the display layer to be issued deep down during a run +-- of an algorithm. +-- +-- @field collections The collections specified inside the scope, see +-- the |Collection| class. + +local Scope = {} +Scope.__index = Scope + +-- Namespace +require("pgf.gd.interface").Scope = Scope + +-- Imports +local lib = require "pgf.gd.lib" +local Storage = require "pgf.gd.lib.Storage" + +local Digraph = require "pgf.gd.model.Digraph" + +--- +-- Create a new |Scope| object. +-- +-- @param initial A table of initial values for the newly created +-- |Scope| object. +-- +-- @return The new scope object. + +function Scope.new(initial) + return setmetatable(lib.copy(initial, + { + syntactic_digraph = Digraph.new{}, + events = {}, + node_names = {}, + coroutine = nil, + collections = {}, + }), Scope) +end + + +-- Done + +return Scope \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua new file mode 100644 index 00000000000..e5b4b5f1747 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua @@ -0,0 +1,159 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered.lua,v 1.2 2013/02/08 17:14:04 tantau Exp $ + + +local layered = {} + +-- Namespace + +require("pgf.gd").layered = layered + + +local lib = require "pgf.gd.lib" +local Storage = require "pgf.gd.lib.Storage" + +-- +-- This file defines some basic functions to compute and/or set the +-- ideal distances between nodes of any kind of layered drawing of a +-- graph. + + +--- +-- Compute the ideal distance between two siblings +-- +-- @param paddings A |Storage| object in which the computed distances +-- (paddings) are stored. +-- @param graph The graph object +-- @param n1 The first node +-- @param n2 The second node + +function layered.ideal_sibling_distance (paddings, graph, n1, n2) + local ideal_distance + local sep + + local n1_is_node = n1.kind == "node" + local n2_is_node = n2.kind == "node" + + if not n1_is_node and not n2_is_node then + ideal_distance = graph.options['sibling distance'] + sep = graph.options['sibling post sep'] + + graph.options['sibling pre sep'] + else + if n1_is_node then + ideal_distance = lib.lookup_option('sibling distance', n1, graph) + else + ideal_distance = lib.lookup_option('sibling distance', n2, graph) + end + sep = (n1_is_node and lib.lookup_option('sibling post sep', n1, graph) or 0) + + (n2_is_node and lib.lookup_option('sibling pre sep', n2, graph) or 0) + end + + return math.max(ideal_distance, sep + + ((n1_is_node and paddings[n1].sibling_post) or 0) - + ((n2_is_node and paddings[n2].sibling_pre) or 0)) +end + + + +--- +-- Compute the baseline distance between two layers +-- +-- The "baseline" distance is the distance between two layers that +-- corresponds to the distance of the two layers if the nodes where +-- "words" on two adjacent lines. In this case, the distance is +-- normally the layer_distance, but will be increased such that if we +-- draw a horizontal line below the deepest character on the first +-- line and a horizontal line above the highest character on the +-- second line, the lines will have a minimum distance of layer sep. +-- +-- Since each node on the lines might have a different layer sep and +-- layer distance specified, the maximum over all the values is taken. +-- +-- @param paddings A |Storage| object in which the distances +-- (paddings) are stored. +-- @param graph The graph in which the nodes reside +-- @param l1 An array of the nodes of the first layer +-- @param l2 An array of the nodes of the second layer + +function layered.baseline_distance (paddings, graph, l1, l2) + + if #l1 == 0 or #l2 == 0 then + return 0 + end + + local layer_distance = -math.huge + local layer_pre_sep = -math.huge + local layer_post_sep = -math.huge + + local max_post = -math.huge + local min_pre = math.huge + + for _,n in ipairs(l1) do + layer_distance = math.max(layer_distance, lib.lookup_option('level distance', n, graph)) + layer_post_sep = math.max(layer_post_sep, lib.lookup_option('level post sep', n, graph)) + if n.kind == "node" then + max_post = math.max(max_post, paddings[n].layer_post) + end + end + + for _,n in ipairs(l2) do + layer_pre_sep = math.max(layer_pre_sep, lib.lookup_option('level pre sep', n, graph)) + if n.kind == "node" then + min_pre = math.min(min_pre, paddings[n].layer_pre) + end + end + + return math.max(layer_distance, layer_post_sep + layer_pre_sep + max_post - min_pre) +end + + + +--- +-- Position nodes in layers using baselines +-- +-- @param layers A |Storage| object assigning layers to vertices. +-- @param paddings A |Storage| object storing the computed distances +-- (paddings). +-- @param graph The graph in which the nodes reside + +function layered.arrange_layers_by_baselines (layers, paddings, graph) + + local layer_vertices = Storage.newTableStorage() + + -- Decompose into layers: + for _,v in ipairs(graph.vertices) do + table.insert(layer_vertices[layers[v]], v) + end + + if #layer_vertices > 0 then -- sanity check + -- Now compute ideal distances and store + local height = 0 + + for _,v in ipairs(layer_vertices[1]) do + v.pos.y = 0 + end + + for i=2,#layer_vertices do + height = height + layered.baseline_distance(paddings, graph, layer_vertices[i-1], layer_vertices[i]) + + for _,v in ipairs(layer_vertices[i]) do + v.pos.y = height + end + end + end +end + + + + +-- Done + +return layered \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua new file mode 100644 index 00000000000..86baaf14c33 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua @@ -0,0 +1,342 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/CrossingMinimizationGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +local CrossingMinimizationGansnerKNV1993 = {} + + +-- Imports + +local lib = require "pgf.gd.lib" +local DepthFirstSearch = require "pgf.gd.lib.DepthFirstSearch" + + + +function CrossingMinimizationGansnerKNV1993:run() + + self:computeInitialRankOrdering() + + local best_ranking = self.ranking:copy() + local best_crossings = self:countRankCrossings(best_ranking) + + for iteration=1,24 do + local direction = (iteration % 2 == 0) and 'down' or 'up' + + self:orderByWeightedMedian(direction) + self:transpose(direction) + + local current_crossings = self:countRankCrossings(self.ranking) + + if current_crossings < best_crossings then + best_ranking = self.ranking:copy() + best_crossings = current_crossings + end + end + + self.ranking = best_ranking:copy() + + return self.ranking +end + + + +function CrossingMinimizationGansnerKNV1993:computeInitialRankOrdering() + + local best_ranking = self.ranking:copy() + local best_crossings = self:countRankCrossings(best_ranking) + + for _,direction in ipairs({'down', 'up'}) do + + local function init(search) + for i=#self.graph.nodes,1,-1 do + local node = self.graph.nodes[i] + if direction == 'down' then + if node:getInDegree() == 0 then + search:push(node) + search:setDiscovered(node) + end + else + if node:getOutDegree() == 0 then + search:push(node) + search:setDiscovered(node) + end + end + end + end + + local function visit(search, node) + search:setVisited(node, true) + + local rank = self.ranking:getRank(node) + local pos = self.ranking:getRankSize(rank) + self.ranking:setRankPosition(node, pos) + + if direction == 'down' then + local out = node:getOutgoingEdges() + for i=#out,1,-1 do + local neighbour = out[i]:getNeighbour(node) + if not search:getDiscovered(neighbour) then + search:push(neighbour) + search:setDiscovered(neighbour) + end + end + else + local into = node:getIncomingEdges() + for i=#into,1,-1 do + local neighbour = into[i]:getNeighbour(node) + if not search:getDiscovered(neighbour) then + search:push(neighbour) + search:setDiscovered(neighbour) + end + end + end + end + + DepthFirstSearch.new(init, visit):run() + + local crossings = self:countRankCrossings(self.ranking) + + if crossings < best_crossings then + best_ranking = self.ranking:copy() + best_crossings = crossings + end + end + + self.ranking = best_ranking:copy() + +end + + + +function CrossingMinimizationGansnerKNV1993:countRankCrossings(ranking) + + local crossings = 0 + + local ranks = ranking:getRanks() + + for rank_index = 2, #ranks do + local nodes = ranking:getNodes(ranks[rank_index]) + for i = 1, #nodes-1 do + for j = i+1, #nodes do + local v = nodes[i] + local w = nodes[j] + + -- TODO Jannis: We are REQUIRED to only check edges that lead to nodes + -- on the next or previous rank, depending on the sweep direction!!!! + local cn_vw = self:countNodeCrossings(ranking, v, w, 'down') + + crossings = crossings + cn_vw + end + end + end + + return crossings +end + + + +function CrossingMinimizationGansnerKNV1993:countNodeCrossings(ranking, left_node, right_node, sweep_direction) + + local ranks = ranking:getRanks() + local _, rank_index = lib.find(ranks, function (rank) + return rank == ranking:getRank(left_node) + end) + local other_rank_index = (sweep_direction == 'down') and rank_index-1 or rank_index+1 + + assert(ranking:getRank(left_node) == ranking:getRank(right_node)) + assert(rank_index >= 1 and rank_index <= #ranks) + + -- 0 crossings if we're at the top or bottom and are sweeping down or up + if other_rank_index < 1 or other_rank_index > #ranks then + return 0 + end + + local left_edges = {} + local right_edges = {} + + if sweep_direction == 'down' then + left_edges = left_node:getIncomingEdges() + right_edges = right_node:getIncomingEdges() + else + left_edges = left_node:getOutgoingEdges() + right_edges = right_node:getOutgoingEdges() + end + + local crossings = 0 + + local function left_neighbour_on_other_rank(edge) + local neighbour = edge:getNeighbour(left_node) + return ranking:getRank(neighbour) == ranking:getRanks()[other_rank_index] + end + + local function right_neighbour_on_other_rank(edge) + local neighbour = edge:getNeighbour(right_node) + return ranking:getRank(neighbour) == ranking:getRanks()[other_rank_index] + end + + for _,left_edge in ipairs(left_edges) do + if left_neighbour_on_other_rank(left_edge) then + local left_neighbour = left_edge:getNeighbour(left_node) + + for _,right_edge in ipairs(right_edges) do + if right_neighbour_on_other_rank(right_edge) then + local right_neighbour = right_edge:getNeighbour(right_node) + + local left_position = ranking:getRankPosition(left_neighbour) + local right_position = ranking:getRankPosition(right_neighbour) + + local neighbour_diff = right_position - left_position + + if neighbour_diff < 0 then + crossings = crossings + 1 + end + end + end + end + end + + return crossings +end + + + +function CrossingMinimizationGansnerKNV1993:orderByWeightedMedian(direction) + + local median = {} + + local function get_index(n, node) return median[node] end + local function is_fixed(n, node) return median[node] < 0 end + + if direction == 'down' then + local ranks = self.ranking:getRanks() + + for rank_index = 2, #ranks do + median = {} + local nodes = self.ranking:getNodes(ranks[rank_index]) + for _,node in ipairs(nodes) do + median[node] = self:computeMedianPosition(node, ranks[rank_index-1]) + end + + self.ranking:reorderRank(ranks[rank_index], get_index, is_fixed) + end + else + local ranks = self.ranking:getRanks() + + for rank_index = 1, #ranks-1 do + median = {} + local nodes = self.ranking:getNodes(ranks[rank_index]) + for _,node in ipairs(nodes) do + median[node] = self:computeMedianPosition(node, ranks[rank_index+1]) + end + + self.ranking:reorderRank(ranks[rank_index], get_index, is_fixed) + end + end +end + + + +function CrossingMinimizationGansnerKNV1993:computeMedianPosition(node, prev_rank) + + local positions = lib.imap( + node.edges, + function (edge) + local n = edge:getNeighbour(node) + if self.ranking:getRank(n) == prev_rank then + return self.ranking:getRankPosition(n) + end + end) + + table.sort(positions) + + local median = math.ceil(#positions / 2) + local position = -1 + + if #positions > 0 then + if #positions % 2 == 1 then + position = positions[median] + elseif #positions == 2 then + return (positions[1] + positions[2]) / 2 + else + local left = positions[median-1] - positions[1] + local right = positions[#positions] - positions[median] + position = (positions[median-1] * right + positions[median] * left) / (left + right) + end + end + + return position +end + + + +function CrossingMinimizationGansnerKNV1993:transpose(sweep_direction) + + local function transpose_rank(rank) + + local improved = false + + local nodes = self.ranking:getNodes(rank) + + for i = 1, #nodes-1 do + local v = nodes[i] + local w = nodes[i+1] + + local cn_vw = self:countNodeCrossings(self.ranking, v, w, sweep_direction) + local cn_wv = self:countNodeCrossings(self.ranking, w, v, sweep_direction) + + if cn_vw > cn_wv then + improved = true + + self:switchNodePositions(v, w) + end + end + + return improved + end + + local ranks = self.ranking:getRanks() + + local improved = false + repeat + local improved = false + + if sweep_direction == 'down' then + for rank_index = 1, #ranks-1 do + improved = transpose_rank(ranks[rank_index]) or improved + end + else + for rank_index = #ranks-1, 1, -1 do + improved = transpose_rank(ranks[rank_index]) or improved + end + end + until not improved +end + + + +function CrossingMinimizationGansnerKNV1993:switchNodePositions(left_node, right_node) + assert(self.ranking:getRank(left_node) == self.ranking:getRank(right_node)) + assert(self.ranking:getRankPosition(left_node) < self.ranking:getRankPosition(right_node)) + + local left_position = self.ranking:getRankPosition(left_node) + local right_position = self.ranking:getRankPosition(right_node) + + self.ranking:switchPositions(left_node, right_node) + + local nodes = self.ranking:getNodes(self.ranking:getRank(left_node)) +end + + + +-- done + +return CrossingMinimizationGansnerKNV1993 diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua new file mode 100644 index 00000000000..8e5111cfb72 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua @@ -0,0 +1,75 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990a.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +local CycleRemovalBergerS1990a = {} + +local lib = require("pgf.gd.lib") + + +function CycleRemovalBergerS1990a:run() + -- remember edges that were removed + local removed = {} + + -- remember edges that need to be reversed + local reverse = {} + + -- iterate over all nodes of the graph + for _,node in ipairs(self.graph.nodes) do + -- get all outgoing edges that have not been removed yet + local out_edges = lib.imap(node:getOutgoingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + -- get all incoming edges that have not been removed yet + local in_edges = lib.imap(node:getIncomingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + if #out_edges >= #in_edges then + -- we have more outgoing than incoming edges, reverse all incoming + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + reverse[edge] = true + removed[edge] = true + end + else + -- we have more incoming than outgoing edges, reverse all outgoing + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + reverse[edge] = true + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + removed[edge] = true + end + end + end + + -- mark edges as reversed + for edge in pairs(reverse) do + edge.reversed = true + end +end + + + +-- done + +return CycleRemovalBergerS1990a \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua new file mode 100644 index 00000000000..deaae695246 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua @@ -0,0 +1,76 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalBergerS1990b.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local CycleRemovalBergerS1990b = {} + +local lib = require("pgf.gd.lib") + + +function CycleRemovalBergerS1990b:run() + -- remember edges that were removed + local removed = {} + + -- remember edges that need to be reversed + local reverse = {} + + -- iterate over all nodes of the graph + for _,j in ipairs(lib.random_permutation(#self.graph.nodes)) do + local node = self.graph.nodes[j] + -- get all outgoing edges that have not been removed yet + -- get all outgoing edges that have not been removed yet + local out_edges = lib.imap(node:getOutgoingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + -- get all incoming edges that have not been removed yet + local in_edges = lib.imap(node:getIncomingEdges(), + function (edge) + if not removed[edge] then return edge end + end) + + if #out_edges >= #in_edges then + -- we have more outgoing than incoming edges, reverse all incoming + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + reverse[edge] = true + removed[edge] = true + end + else + -- we have more incoming than outgoing edges, reverse all outgoing + -- edges and mark all incident edges as removed + + for _,edge in ipairs(out_edges) do + reverse[edge] = true + removed[edge] = true + end + for _,edge in ipairs(in_edges) do + removed[edge] = true + end + end + end + + -- mark edges as reversed + for edge in pairs(reverse) do + edge.reversed = true + end +end + + + +-- done + +return CycleRemovalBergerS1990b \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua new file mode 100644 index 00000000000..6ff83ceae39 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua @@ -0,0 +1,124 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalEadesLS1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +-- Declare +local CycleRemovalEadesLS1993 = {} + +-- Import +local lib = require "pgf.gd.lib" + + +function CycleRemovalEadesLS1993:run() + local copied_graph = self.graph:copy() + + local copied_node = {} + local origin_node = {} + local copied_edge = {} + local origin_edge = {} + + local preserve = {} + + for _,edge in ipairs(self.graph.edges) do + copied_edge[edge] = edge:copy() + origin_edge[copied_edge[edge]] = edge + + for _,node in ipairs(edge.nodes) do + if copied_node[node] then + copied_edge[edge]:addNode(copied_node[node]) + else + copied_node[node] = node:copy() + origin_node[copied_node[node]] = node + + copied_graph:addNode(copied_node[node]) + copied_edge[edge]:addNode(copied_node[node]) + end + end + end + + local function node_is_sink(node) + return node:getOutDegree() == 0 + end + + local function node_is_source(node) + return node:getInDegree() == 0 + end + + local function node_is_isolated(node) + return node:getDegree() == 0 + end + + while #copied_graph.nodes > 0 do + local sink = lib.find(copied_graph.nodes, node_is_sink) + while sink do + for _,edge in ipairs(sink:getIncomingEdges()) do + preserve[edge] = true + end + copied_graph:deleteNode(sink) + sink = lib.find(copied_graph.nodes, node_is_sink) + end + + local isolated_node = lib.find(copied_graph.nodes, node_is_isolated) + while isolated_node do + copied_graph:deleteNode(isolated_node) + isolated_node = lib.find(copied_graph.nodes, node_is_isolated) + end + + local source = lib.find(copied_graph.nodes, node_is_source) + while source do + for _,edge in ipairs(source:getOutgoingEdges()) do + preserve[edge] = true + end + copied_graph:deleteNode(source) + source = lib.find(copied_graph.nodes, node_is_source) + end + + if #copied_graph.nodes > 0 then + local max_node = nil + local max_out_edges = nil + local max_in_edges = nil + + for _,node in ipairs(copied_graph.nodes) do + local out_edges = node:getOutgoingEdges() + local in_edges = node:getIncomingEdges() + + if max_node == nil or (#out_edges - #in_edges > #max_out_edges - #max_in_edges) then + max_node = node + max_out_edges = out_edges + max_in_edges = in_edges + end + end + + assert(max_node and max_out_edges and max_in_edges) + + for _,edge in ipairs(max_out_edges) do + preserve[edge] = true + copied_graph:deleteEdge(edge) + end + for _,edge in ipairs(max_in_edges) do + copied_graph:deleteEdge(edge) + end + + copied_graph:deleteNode(max_node) + end + end + + for _,edge in ipairs(self.graph.edges) do + if not preserve[copied_edge[edge]] then + edge.reversed = true + end + end +end + +-- done + +return CycleRemovalEadesLS1993 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua new file mode 100644 index 00000000000..a2ee9c01863 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua @@ -0,0 +1,52 @@ +-- Copyright 2011 by Jannis Pohlmann and 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/CycleRemovalGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local CycleRemovalGansnerKNV1993 = {} + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare +local Simplifiers = require "pgf.gd.lib.Simplifiers" + + +function CycleRemovalGansnerKNV1993:run () + -- merge nonempty sets into supernodes + -- + -- ignore self-loops + -- + -- merge multiple edges into one edge each, whose weight is the sum of the + -- individual edge weights + -- + -- ignore leaf nodes that are not part of the user-defined sets (their ranks + -- are trivially determined) + -- + -- ensure that supernodes S_min and S_max are assigned first and last ranks + -- reverse in-edges of S_min + -- reverse out-edges of S_max + -- + -- ensure the supernodes S_min and S_max are are the only nodes in these ranks + -- for all nodes with indegree of 0, insert temporary edge (S_min, v) with delta=0 + -- for all nodes with outdegree of 0, insert temporary edge (v, S_max) with delta=0 + + -- classify edges as tree/forward, cross and back edges using a DFS traversal + local tree_or_forward_edges, cross_edges, back_edges = Simplifiers:classifyEdges(self.graph) + + -- reverse the back edges in order to make the graph acyclic + for _,edge in ipairs(back_edges) do + edge.reversed = true + end +end + + +-- done + +return CycleRemovalGansnerKNV1993 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua new file mode 100644 index 00000000000..649db1e54b6 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua @@ -0,0 +1,22 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/EdgeRoutingGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +local EdgeRoutingGansnerKNV1993 = {} + + +function EdgeRoutingGansnerKNV1993:run() +end + + +-- done +return EdgeRoutingGansnerKNV1993 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua new file mode 100644 index 00000000000..abc17477bac --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua @@ -0,0 +1,898 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/NetworkSimplex.lua,v 1.2 2013/05/23 20:01:27 tantau Exp $ + + + + +--- This file contains an implementation of the network simplex method +--- for node ranking and x coordinate optimization in layered drawing +--- algorithms, as proposed in +--- +--- "A Technique for Drawing Directed Graphs" +-- by Gansner, Koutsofios, North, Vo, 1993. + + +local NetworkSimplex = {} +NetworkSimplex.__index = NetworkSimplex + +-- Namespace +local layered = require "pgf.gd.layered" +layered.NetworkSimplex = NetworkSimplex + + +-- Imports +local DepthFirstSearch = require "pgf.gd.lib.DepthFirstSearch" +local Ranking = require "pgf.gd.layered.Ranking" +local Graph = require "pgf.gd.deprecated.Graph" +local lib = require "pgf.gd.lib" + + + +-- Definitions + +NetworkSimplex.BALANCE_TOP_BOTTOM = 1 +NetworkSimplex.BALANCE_LEFT_RIGHT = 2 + + +function NetworkSimplex.new(graph, balancing) + local simplex = { + graph = graph, + balancing = balancing, + } + setmetatable(simplex, NetworkSimplex) + return simplex +end + + + +function NetworkSimplex:run() + + assert (#self.graph.nodes > 0, "graph must contain at least one node") + + -- initialize the tree edge search index + self.search_index = 1 + + -- initialize internal edge parameters + self.cut_value = {} + for _,edge in ipairs(self.graph.edges) do + self.cut_value[edge] = 0 + end + + -- reset graph information needed for ranking + self.lim = {} + self.low = {} + self.parent_edge = {} + self.ranking = Ranking.new() + + if #self.graph.nodes == 1 then + self.ranking:setRank(self.graph.nodes[1], 1) + else + self:rankNodes() + end +end + + + +function NetworkSimplex:rankNodes() + -- construct feasible tree of tight edges + self:constructFeasibleTree() + + -- iteratively replace edges with negative cut values + -- with non-tree edges (chosen by minimum slack) + local leave_edge = self:findNegativeCutEdge() + while leave_edge do + local enter_edge = self:findReplacementEdge(leave_edge) + + assert(enter_edge, 'no non-tree edge to replace ' .. tostring(leave_edge) .. ' could be found') + + -- exchange leave_edge and enter_edge in the tree, updating + -- the ranks and cut values of all nodes + self:exchangeTreeEdges(leave_edge, enter_edge) + + -- find the next tree edge with a negative cut value, if + -- there are any left + leave_edge = self:findNegativeCutEdge() + end + + if self.balancing == NetworkSimplex.BALANCE_TOP_BOTTOM then + -- normalize by setting the least rank to zero + self.ranking:normalizeRanks() + + -- move nodes to feasible ranks with the least number of nodes + -- in order to avoid crowding and to improve the overall aspect + -- ratio of the drawing + self:balanceRanksTopBottom() + elseif self.balancing == NetworkSimplex.BALANCE_LEFT_RIGHT then + self:balanceRanksLeftRight() + end +end + + + +function NetworkSimplex:constructFeasibleTree() + + self:computeInitialRanking() + + -- find a maximal tree of tight edges in the graph + while self:findTightTree() < #self.graph.nodes do + + local min_slack_edge = nil + + for _,node in ipairs(self.graph.nodes) do + local out_edges = node:getOutgoingEdges() + for _,edge in ipairs(out_edges) do + if not self.tree_edge[edge] and self:isIncidentToTree(edge) then + if not min_slack_edge or self:edgeSlack(edge) < self:edgeSlack(min_slack_edge) then + min_slack_edge = edge + end + end + end + end + + if min_slack_edge then + local delta = self:edgeSlack(min_slack_edge) + + if delta > 0 then + local head = min_slack_edge:getHead() + local tail = min_slack_edge:getTail() + + if self.tree_node[head] then + delta = -delta + end + + + for _,node in ipairs(self.tree.nodes) do + local rank = self.ranking:getRank(self.orig_node[node]) + self.ranking:setRank(self.orig_node[node], rank + delta) + end + end + end + end + + self:initializeCutValues() +end + + + +function NetworkSimplex:findNegativeCutEdge() + local minimum_edge = nil + + for n=1,#self.tree.edges do + local index = self:nextSearchIndex() + + local edge = self.tree.edges[index] + + if self.cut_value[edge] < 0 then + if minimum_edge then + if self.cut_value[minimum_edge] > self.cut_value[edge] then + minimum_edge = edge + end + else + minimum_edge = edge + end + end + end + + return minimum_edge +end + + + +function NetworkSimplex:findReplacementEdge(leave_edge) + local tail = leave_edge:getTail() + local head = leave_edge:getHead() + + local v = nil + local direction = nil + + if self.lim[tail] < self.lim[head] then + v = tail + direction = 'in' + else + v = head + direction = 'out' + end + + local search_root = v + local enter_edge = nil + local slack = math.huge + + -- TODO Janns: Get rid of this recursion: + + local function find_edge(v, direction) + + if direction == 'out' then + local out_edges = self.orig_node[v]:getOutgoingEdges() + for _,edge in ipairs(out_edges) do + local head = edge:getHead() + local tree_head = self.tree_node[head] + + assert(head and tree_head) + + if not self.tree_edge[edge] then + if not self:inTailComponentOf(tree_head, search_root) then + if self:edgeSlack(edge) < slack or not enter_edge then + enter_edge = edge + slack = self:edgeSlack(edge) + end + end + else + if self.lim[tree_head] < self.lim[v] then + find_edge(tree_head, 'out') + end + end + end + + for _,edge in ipairs(v:getIncomingEdges()) do + if slack <= 0 then + break + end + + local tail = edge:getTail() + + if self.lim[tail] < self.lim[v] then + find_edge(tail, 'out') + end + end + else + local in_edges = self.orig_node[v]:getIncomingEdges() + for _,edge in ipairs(in_edges) do + local tail = edge:getTail() + local tree_tail = self.tree_node[tail] + + assert(tail and tree_tail) + + if not self.tree_edge[edge] then + if not self:inTailComponentOf(tree_tail, search_root) then + if self:edgeSlack(edge) < slack or not enter_edge then + enter_edge = edge + slack = self:edgeSlack(edge) + end + end + else + if self.lim[tree_tail] < self.lim[v] then + find_edge(tree_tail, 'in') + end + end + end + + for _,edge in ipairs(v:getOutgoingEdges()) do + if slack <= 0 then + break + end + + local head = edge:getHead() + + if self.lim[head] < self.lim[v] then + find_edge(head, 'in') + end + end + end + end + + find_edge(v, direction) + + return enter_edge +end + + + +function NetworkSimplex:exchangeTreeEdges(leave_edge, enter_edge) + + self:rerankBeforeReplacingEdge(leave_edge, enter_edge) + + local cutval = self.cut_value[leave_edge] + local head = self.tree_node[enter_edge:getHead()] + local tail = self.tree_node[enter_edge:getTail()] + + local ancestor = self:updateCutValuesUpToCommonAncestor(tail, head, cutval, true) + local other_ancestor = self:updateCutValuesUpToCommonAncestor(head, tail, cutval, false) + + assert(ancestor == other_ancestor) + + -- remove the old edge from the tree + self:removeEdgeFromTree(leave_edge) + + -- add the new edge to the tree + local tree_edge = self:addEdgeToTree(enter_edge) + + -- set its cut value + self.cut_value[tree_edge] = -cutval + + -- update DFS search tree traversal information + self:calculateDFSRange(ancestor, self.parent_edge[ancestor], self.low[ancestor]) +end + + + +function NetworkSimplex:balanceRanksTopBottom() + + -- available ranks + local ranks = self.ranking:getRanks() + + -- node to in/out weight mappings + local in_weight = {} + local out_weight = {} + + -- node to lowest/highest possible rank mapping + local min_rank = {} + local max_rank = {} + + -- compute the in and out weights of each node + for _,node in ipairs(self.graph.nodes) do + -- assume there are no restrictions on how to rank the node + min_rank[node], max_rank[node] = ranks[1], ranks[#ranks] + + for _,edge in ipairs(node:getIncomingEdges()) do + -- accumulate the weights of all incoming edges + in_weight[node] = (in_weight[node] or 0) + edge.weight + + -- update the minimum allowed rank (which is the maximum of + -- the ranks of all parent neighbours plus the minimum level + -- separation caused by the connecting edges) + local neighbour = edge:getNeighbour(node) + local neighbour_rank = self.ranking:getRank(neighbour) + min_rank[node] = math.max(min_rank[node], neighbour_rank + edge.minimum_levels) + end + + for _,edge in ipairs(node:getOutgoingEdges()) do + -- accumulate the weights of all outgoing edges + out_weight[node] = (out_weight[node] or 0) + edge.weight + + -- update the maximum allowed rank (which is the minimum of + -- the ranks of all child neighbours minus the minimum level + -- sparation caused by the connecting edges) + local neighbour = edge:getNeighbour(node) + local neighbour_rank = self.ranking:getRank(neighbour) + max_rank[node] = math.min(max_rank[node], neighbour_rank - edge.minimum_levels) + end + + -- check whether the in- and outweight is the same + if in_weight[node] == out_weight[node] then + + -- check which of the allowed ranks has the least number of nodes + local min_nodes_rank = min_rank[node] + for n = min_rank[node] + 1, max_rank[node] do + if #self.ranking:getNodes(n) < #self.ranking:getNodes(min_nodes_rank) then + min_nodes_rank = n + end + end + + -- only move the node to the rank with the least number of nodes + -- if it differs from the current rank of the node + if min_nodes_rank ~= self.ranking:getRank(node) then + self.ranking:setRank(node, min_nodes_rank) + end + + end + end +end + + + +function NetworkSimplex:balanceRanksLeftRight() + for _,edge in ipairs(self.tree.edges) do + if self.cut_value[edge] == 0 then + local other_edge = self:findReplacementEdge(edge) + if other_edge then + local delta = self:edgeSlack(other_edge) + if delta > 1 then + if self.lim[edge:getTail()] < self.lim[edge:getHead()] then + self:rerank(edge:getTail(), delta / 2) + else + self:rerank(edge:getHead(), -delta / 2) + end + end + end + end + end +end + + + +function NetworkSimplex:computeInitialRanking() + + -- queue for nodes to rank next + local queue = {} + + -- convenience functions for managing the queue + local function enqueue(node) table.insert(queue, node) end + local function dequeue() return table.remove(queue, 1) end + + -- reset the two-dimensional mapping from ranks to lists + -- of corresponding nodes + self.ranking:reset() + + -- mapping of nodes to the number of unscanned incoming edges + local remaining_edges = {} + + -- add all sinks to the queue + for _,node in ipairs(self.graph.nodes) do + local edges = node:getIncomingEdges() + + remaining_edges[node] = #edges + + if #edges == 0 then + enqueue(node) + end + end + + -- run long as there are nodes to be ranked + while #queue > 0 do + + -- fetch the next unranked node from the queue + local node = dequeue() + + -- get a list of its incoming edges + local in_edges = node:getIncomingEdges() + + -- determine the minimum possible rank for the node + local rank = 1 + for _,edge in ipairs(in_edges) do + local neighbour = edge:getNeighbour(node) + if self.ranking:getRank(neighbour) then + -- the minimum possible rank is the maximum of all neighbour ranks plus + -- the corresponding edge lengths + rank = math.max(rank, self.ranking:getRank(neighbour) + edge.minimum_levels) + end + end + + -- rank the node + self.ranking:setRank(node, rank) + + -- get a list of the node's outgoing edges + local out_edges = node:getOutgoingEdges() + + -- queue neighbours of nodes for which all incoming edges have been scanned + for _,edge in ipairs(out_edges) do + local head = edge:getHead() + remaining_edges[head] = remaining_edges[head] - 1 + if remaining_edges[head] <= 0 then + enqueue(head) + end + end + end +end + + + +function NetworkSimplex:findTightTree() + + -- TODO: Jannis: Remove the recursion below: + + local marked = {} + + local function build_tight_tree(node) + + local out_edges = node:getOutgoingEdges() + local in_edges = node:getIncomingEdges() + + local edges = lib.copy(out_edges) + for _,v in ipairs(in_edges) do + edges[#edges + 1] = v + end + + for _,edge in ipairs(edges) do + local neighbour = edge:getNeighbour(node) + if (not marked[neighbour]) and math.abs(self:edgeSlack(edge)) < 0.00001 then + self:addEdgeToTree(edge) + + for _,node in ipairs(edge.nodes) do + marked[node] = true + end + + if #self.tree.edges == #self.graph.nodes-1 then + return true + end + + if build_tight_tree(neighbour) then + return true + end + end + end + + return false + end + + for _,node in ipairs(self.graph.nodes) do + self.tree = Graph.new() + self.tree_node = {} + self.orig_node = {} + self.tree_edge = {} + self.orig_edge = {} + + build_tight_tree(node) + + if #self.tree.edges > 0 then + break + end + end + + return #self.tree.nodes +end + + + +function NetworkSimplex:edgeSlack(edge) + -- make sure this is never called with a tree edge + assert(not self.orig_edge[edge]) + + local head_rank = self.ranking:getRank(edge:getHead()) + local tail_rank = self.ranking:getRank(edge:getTail()) + local length = head_rank - tail_rank + return length - edge.minimum_levels +end + + + +function NetworkSimplex:isIncidentToTree(edge) + -- make sure this is never called with a tree edge + assert(not self.orig_edge[edge]) + + local head = edge:getHead() + local tail = edge:getTail() + + if self.tree_node[head] and not self.tree_node[tail] then + return true + elseif self.tree_node[tail] and not self.tree_node[head] then + return true + else + return false + end +end + + + +function NetworkSimplex:initializeCutValues() + self:calculateDFSRange(self.tree.nodes[1], nil, 1) + + local function init(search) + search:push({ node = self.tree.nodes[1], parent_edge = nil }) + end + + local function visit(search, data) + search:setVisited(data, true) + + local into = data.node:getIncomingEdges() + local out = data.node:getOutgoingEdges() + + for i=#into,1,-1 do + local edge = into[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getTail(), parent_edge = edge }) + end + end + + for i=#out,1,-1 do + local edge = out[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getHead(), parent_edge = edge }) + end + end + end + + local function complete(search, data) + if data.parent_edge then + self:updateCutValue(data.parent_edge) + end + end + + DepthFirstSearch.new(init, visit, complete):run() +end + + + +--- DFS algorithm that calculates post-order traversal indices and parent edges. +-- +-- This algorithm performs a depth-first search in a directed or undirected +-- graph. For each node it calculates the node's post-order traversal index, the +-- minimum post-order traversal index of its descendants as well as the edge by +-- which the node was reached in the depth-first traversal. +-- +function NetworkSimplex:calculateDFSRange(root, edge_from_parent, lowest) + + -- global traversal index counter + local lim = lowest + + -- start the traversal at the root node + local function init(search) + search:push({ node = root, parent_edge = edge_from_parent, low = lowest }) + end + + -- visit nodes in depth-first order + local function visit(search, data) + -- mark node as visited so we only visit it once + search:setVisited(data, true) + + -- remember the parent edge + self.parent_edge[data.node] = data.parent_edge + + -- remember the minimum traversal index for this branch of the search tree + self.low[data.node] = lim + + -- next we push all outgoing and incoming edges in reverse order + -- to simulate recursive calls + + local into = data.node:getIncomingEdges() + local out = data.node:getOutgoingEdges() + + for i=#into,1,-1 do + local edge = into[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getTail(), parent_edge = edge }) + end + end + + for i=#out,1,-1 do + local edge = out[i] + if edge ~= data.parent_edge then + search:push({ node = edge:getHead(), parent_edge = edge }) + end + end + end + + -- when completing a node, store its own traversal index + local function complete(search, data) + self.lim[data.node] = lim + lim = lim + 1 + end + + -- kick off the depth-first search + DepthFirstSearch.new(init, visit, complete):run() + + local lim_lookup = {} + local min_lim = math.huge + local max_lim = -math.huge + for _,node in ipairs(self.tree.nodes) do + assert(self.lim[node]) + assert(self.low[node]) + assert(not lim_lookup[self.lim[node]]) + lim_lookup[self.lim[node]] = true + min_lim = math.min(min_lim, self.lim[node]) + max_lim = math.max(max_lim, self.lim[node]) + end + for n = min_lim, max_lim do + assert(lim_lookup[n] == true) + end +end + + + +function NetworkSimplex:updateCutValue(tree_edge) + + local v = nil + if self.parent_edge[tree_edge:getTail()] == tree_edge then + v = tree_edge:getTail() + dir = 1 + else + v = tree_edge:getHead() + dir = -1 + end + + local sum = 0 + + local out_edges = self.orig_node[v]:getOutgoingEdges() + local in_edges = self.orig_node[v]:getIncomingEdges() + local edges = lib.copy(out_edges) + for _,v in ipairs(in_edges) do + edges[#edges + 1] = v + end + + for _,edge in ipairs(edges) do + local other = edge:getNeighbour(self.orig_node[v]) + + local f = 0 + local rv = 0 + + if not self:inTailComponentOf(self.tree_node[other], v) then + f = 1 + rv = edge.weight + else + f = 0 + + if self.tree_edge[edge] then + rv = self.cut_value[self.tree_edge[edge]] + else + rv = 0 + end + + rv = rv - edge.weight + end + + local d = 0 + + if dir > 0 then + if edge:isHead(self.orig_node[v]) then + d = 1 + else + d = -1 + end + else + if edge:isTail(self.orig_node[v]) then + d = 1 + else + d = -1 + end + end + + if f > 0 then + d = -d + end + + if d < 0 then + rv = -rv + end + + sum = sum + rv + end + + self.cut_value[tree_edge] = sum +end + + + +function NetworkSimplex:inTailComponentOf(node, v) + return (self.low[v] <= self.lim[node]) and (self.lim[node] <= self.lim[v]) +end + + + +function NetworkSimplex:nextSearchIndex() + local index = 1 + + -- avoid tree edge index out of bounds by resetting the search index + -- as soon as it leaves the range of edge indices in the tree + if self.search_index > #self.tree.edges then + self.search_index = 1 + index = 1 + else + index = self.search_index + self.search_index = self.search_index + 1 + end + + return index +end + + + +function NetworkSimplex:rerank(node, delta) + local function init(search) + search:push({ node = node, delta = delta }) + end + + local function visit(search, data) + search:setVisited(data, true) + + local orig_node = self.orig_node[data.node] + self.ranking:setRank(orig_node, self.ranking:getRank(orig_node) - data.delta) + + local into = data.node:getIncomingEdges() + local out = data.node:getOutgoingEdges() + + for i=#into,1,-1 do + local edge = into[i] + if edge ~= self.parent_edge[data.node] then + search:push({ node = edge:getTail(), delta = data.delta }) + end + end + + for i=#out,1,-1 do + local edge = out[i] + if edge ~= self.parent_edge[data.node] then + search:push({ node = edge:getHead(), delta = data.delta }) + end + end + end + + DepthFirstSearch.new(init, visit):run() +end + + + +function NetworkSimplex:rerankBeforeReplacingEdge(leave_edge, enter_edge) + local delta = self:edgeSlack(enter_edge) + + if delta > 0 then + local tail = leave_edge:getTail() + + if #tail.edges == 1 then + self:rerank(tail, delta) + else + local head = leave_edge:getHead() + + if #head.edges == 1 then + self:rerank(head, -delta) + else + if self.lim[tail] < self.lim[head] then + self:rerank(tail, delta) + else + self:rerank(head, -delta) + end + end + end + end +end + + + +function NetworkSimplex:updateCutValuesUpToCommonAncestor(v, w, cutval, dir) + + while not self:inTailComponentOf(w, v) do + local edge = self.parent_edge[v] + + if edge:isTail(v) then + d = dir + else + d = not dir + end + + if d then + self.cut_value[edge] = self.cut_value[edge] + cutval + else + self.cut_value[edge] = self.cut_value[edge] - cutval + end + + if self.lim[edge:getTail()] > self.lim[edge:getHead()] then + v = edge:getTail() + else + v = edge:getHead() + end + end + + return v +end + + + +function NetworkSimplex:addEdgeToTree(edge) + assert(not self.tree_edge[edge]) + + -- create the new tree edge + local tree_edge = edge:copy() + self.orig_edge[tree_edge] = edge + self.tree_edge[edge] = tree_edge + + -- create tree nodes if necessary + for _,node in ipairs(edge.nodes) do + local tree_node + + if self.tree_node[node] then + tree_node = self.tree_node[node] + else + tree_node = node:copy() + self.orig_node[tree_node] = node + self.tree_node[node] = tree_node + end + + self.tree:addNode(tree_node) + tree_edge:addNode(tree_node) + end + + self.tree:addEdge(tree_edge) + + return tree_edge +end + + + +function NetworkSimplex:removeEdgeFromTree(edge) + self.tree:deleteEdge(edge) + self.tree_edge[self.orig_edge[edge]] = nil + self.orig_edge[edge] = nil +end + + + + +-- Done + +return NetworkSimplex \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua new file mode 100644 index 00000000000..ce0fab4efe7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua @@ -0,0 +1,154 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodePositioningGansnerKNV1993.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + + +local NodePositioningGansnerKNV1993 = {} + + +-- Imports + +local layered = require "pgf.gd.layered" + +local Graph = require "pgf.gd.deprecated.Graph" +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + +local NetworkSimplex = require "pgf.gd.layered.NetworkSimplex" +local Storage = require "pgf.gd.lib.Storage" + + +function NodePositioningGansnerKNV1993:run() + local auxiliary_graph = self:constructAuxiliaryGraph() + + local simplex = NetworkSimplex.new(auxiliary_graph, NetworkSimplex.BALANCE_LEFT_RIGHT) + simplex:run() + local x_ranking = simplex.ranking + + local layers = Storage.new() + + local ranks = self.ranking:getRanks() + for _,rank in ipairs(ranks) do + local nodes = self.ranking:getNodes(rank) + for _,node in ipairs(nodes) do + node.pos.x = x_ranking:getRank(node.aux_node) + layers[node.orig_vertex] = rank + end + end + + layered.arrange_layers_by_baselines(layers, self.main_algorithm.adjusted_bb, self.main_algorithm.ugraph) + + -- Copy back + for _,rank in ipairs(ranks) do + local nodes = self.ranking:getNodes(rank) + for _,node in ipairs(nodes) do + node.pos.y = node.orig_vertex.pos.y + end + end +end + + + + +function NodePositioningGansnerKNV1993:constructAuxiliaryGraph() + + local aux_graph = Graph.new() + + local edge_node = {} + + for _,node in ipairs(self.graph.nodes) do + local copy = Node.new{ + name = node.name, + orig_node = node, + } + node.aux_node = copy + aux_graph:addNode(copy) + end + + for i=#self.graph.edges,1,-1 do + local edge = self.graph.edges[i] + local node = Node.new{ + name = '{' .. tostring(edge) .. '}', + } + + aux_graph:addNode(node) + + node.orig_edge = edge + edge_node[edge] = node + + local head = edge:getHead() + local tail = edge:getTail() + + local tail_edge = Edge.new{ + direction = Edge.RIGHT, + minimum_levels = 0, + weight = edge.weight * self:getOmega(edge), + } + tail_edge:addNode(node) + tail_edge:addNode(tail.aux_node) + aux_graph:addEdge(tail_edge) + + local head_edge = Edge.new{ + direction = Edge.RIGHT, + minimum_levels = 0, + weight = edge.weight * self:getOmega(edge), + } + head_edge:addNode(node) + head_edge:addNode(head.aux_node) + aux_graph:addEdge(head_edge) + end + + local ranks = self.ranking:getRanks() + for _,rank in ipairs(ranks) do + local nodes = self.ranking:getNodes(rank) + for n = 1, #nodes-1 do + local v = nodes[n] + local w = nodes[n+1] + + local separator_edge = Edge.new{ + direction = Edge.RIGHT, + minimum_levels = self:getDesiredHorizontalDistance(v, w), + weight = 0, + } + separator_edge:addNode(v.aux_node) + separator_edge:addNode(w.aux_node) + aux_graph:addEdge(separator_edge) + end + end + + return aux_graph +end + + + +function NodePositioningGansnerKNV1993:getOmega(edge) + local node1 = edge.nodes[1] + local node2 = edge.nodes[2] + + if (node1.kind == "dummy") and (node2.kind == "dummy") then + return 8 + elseif (node1.kind == "dummy") or (node2.kind == "dummy") then + return 2 + else + return 1 + end +end + + + +function NodePositioningGansnerKNV1993:getDesiredHorizontalDistance(v, w) + return layered.ideal_sibling_distance(self.main_algorithm.adjusted_bb, self.graph.orig_digraph, v.orig_vertex, w.orig_vertex) +end + + +-- done + +return NodePositioningGansnerKNV1993 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua new file mode 100644 index 00000000000..e941029b3d3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua @@ -0,0 +1,159 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingGansnerKNV1993.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local NodeRankingGansnerKNV1993 = {} + + +-- Imports + +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + +local NetworkSimplex = require "pgf.gd.layered.NetworkSimplex" + + + +function NodeRankingGansnerKNV1993:run() + + local simplex = NetworkSimplex.new(self.graph, NetworkSimplex.BALANCE_TOP_BOTTOM) + simplex:run() + self.ranking = simplex.ranking + + return simplex.ranking +end + + + +function NodeRankingGansnerKNV1993:mergeClusters() + + self.cluster_nodes = {} + self.cluster_node = {} + self.cluster_edges = {} + + self.original_nodes = {} + self.original_edges = {} + + for _,cluster in ipairs(self.graph.clusters) do + + local cluster_node = Node.new{ + name = 'cluster@' .. cluster.name, + } + table.insert(self.cluster_nodes, cluster_node) + + for _,node in ipairs(cluster.nodes) do + self.cluster_node[node] = cluster_node + table.insert(self.original_nodes, node) + end + + self.graph:addNode(cluster_node) + end + + for _,edge in ipairs(self.graph.edges) do + local tail = edge:getTail() + local head = edge:getHead() + + if self.cluster_node[tail] or self.cluster_node[head] then + table.insert(self.original_edges, edge) + + local cluster_edge = Edge.new{ + direction = Edge.RIGHT, + weight = edge.weight, + minimum_levels = edge.minimum_levels, + } + table.insert(self.cluster_edges, cluster_edge) + + if self.cluster_node[tail] then + cluster_edge:addNode(self.cluster_node[tail]) + else + cluster_edge:addNode(tail) + end + + if self.cluster_node[head] then + cluster_edge:addNode(self.cluster_node[head]) + else + cluster_edge:addNode(head) + end + + end + end + + for _,edge in ipairs(self.cluster_edges) do + self.graph:addEdge(edge) + end + + for _,edge in ipairs(self.original_edges) do + self.graph:deleteEdge(edge) + end + + for _,node in ipairs(self.original_nodes) do + self.graph:deleteNode(node) + end +end + + + +function NodeRankingGansnerKNV1993:createClusterEdges() + for n = 1, #self.cluster_nodes-1 do + local first_cluster = self.cluster_nodes[n] + local second_cluster = self.cluster_nodes[n+1] + + local edge = Edge.new{ + direction = Edge.RIGHT, + weight = 1, + minimum_levels = 1, + } + + edge:addNode(first_cluster) + edge:addNode(second_cluster) + + self.graph:addEdge(edge) + + table.insert(self.cluster_edges, edge) + end +end + + + +function NodeRankingGansnerKNV1993:removeClusterEdges() +end + + + +function NodeRankingGansnerKNV1993:expandClusters() + + for _,node in ipairs(self.original_nodes) do + assert(self.ranking:getRank(self.cluster_node[node])) + self.ranking:setRank(node, self.ranking:getRank(self.cluster_node[node])) + self.graph:addNode(node) + end + + for _,edge in ipairs(self.original_edges) do + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + self.graph:addEdge(edge) + end + + for _,node in ipairs(self.cluster_nodes) do + self.ranking:setRank(node, nil) + self.graph:deleteNode(node) + end + + for _,edge in ipairs(self.cluster_edges) do + self.graph:deleteEdge(edge) + end +end + + +-- done + +return NodeRankingGansnerKNV1993 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua new file mode 100644 index 00000000000..38f52f6ba7f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua @@ -0,0 +1,47 @@ +-- Copyright 2011 by Jannis Pohlmann +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/NodeRankingMinimumHeight.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +local NodeRankingMinimumHeight = {} + +-- Imports + +local Ranking = require "pgf.gd.layered.Ranking" +local Iterators = require "pgf.gd.deprecated.Iterators" + + +function NodeRankingMinimumHeight:run() + local ranking = Ranking.new() + + for node in Iterators.topologicallySorted(self.graph) do + local edges = node:getIncomingEdges() + + if #edges == 0 then + ranking:setRank(node, 1) + else + local max_rank = -math.huge + for _,edge in ipairs(edge) do + max_rank = math.max(max_rank, ranking:getRank(edge:getNeighbour(node))) + end + + assert(max_rank >= 1) + + ranking:setRank(node, max_rank + 1) + end + end + + return ranking +end + + +-- done + +return NodeRankingMinimumHeight \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua new file mode 100644 index 00000000000..8b2527edd5f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua @@ -0,0 +1,291 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/Ranking.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- The Ranking class is used by the Sugiyama algorithm to compute an ordering on the +-- nodes of a layer + +local Ranking = {} +Ranking.__index = Ranking + +-- Namespace +local layered = require "pgf.gd.layered" +layered.Ranking = Ranking + + +local lib = require "pgf.gd.lib" + + +-- TODO Jannis: document! + + +function Ranking.new() + local ranking = { + rank_to_nodes = {}, + node_to_rank = {}, + position_in_rank = {}, + } + setmetatable(ranking, Ranking) + return ranking +end + + + +function Ranking:copy() + local copied_ranking = Ranking.new() + + -- copy rank to nodes mapping + for rank, nodes in pairs(self.rank_to_nodes) do + copied_ranking.rank_to_nodes[rank] = lib.copy(self.rank_to_nodes[rank]) + end + + -- copy node to rank mapping + copied_ranking.node_to_rank = lib.copy(self.node_to_rank) + + -- copy node to position in rank mapping + copied_ranking.position_in_rank = lib.copy(self.position_in_rank) + + return copied_ranking +end + + + +function Ranking:reset() + self.rank_to_nodes = {} + self.node_to_rank = {} + self.position_in_rank = {} +end + + + +function Ranking:getRanks() + local ranks = {} + for rank, nodes in pairs(self.rank_to_nodes) do + table.insert(ranks, rank) + end + table.sort(ranks) + return ranks +end + + + +function Ranking:getRankSize(rank) + if self.rank_to_nodes[rank] then + return #self.rank_to_nodes[rank] + else + return 0 + end +end + + + +function Ranking:getNodeInfo(node) + return self:getRank(node), self:getRankPosition(node) +end + + + +function Ranking:getNodes(rank) + return self.rank_to_nodes[rank] or {} +end + + + +function Ranking:getRank(node) + return self.node_to_rank[node] +end + + + +function Ranking:setRank(node, new_rank) + local rank, pos = self:getNodeInfo(node) + + if rank == new_rank then + return + end + + if rank then + for n = pos+1, #self.rank_to_nodes[rank] do + local other_node = self.rank_to_nodes[rank][n] + self.position_in_rank[other_node] = self.position_in_rank[other_node]-1 + end + + table.remove(self.rank_to_nodes[rank], pos) + self.node_to_rank[node] = nil + self.position_in_rank[node] = nil + + if #self.rank_to_nodes[rank] == 0 then + self.rank_to_nodes[rank] = nil + end + end + + if new_rank then + self.rank_to_nodes[new_rank] = self.rank_to_nodes[new_rank] or {} + table.insert(self.rank_to_nodes[new_rank], node) + self.node_to_rank[node] = new_rank + self.position_in_rank[node] = #self.rank_to_nodes[new_rank] + end +end + + + +function Ranking:getRankPosition(node) + return self.position_in_rank[node] +end + + + +function Ranking:setRankPosition(node, new_pos) + local rank, pos = self:getNodeInfo(node) + + assert((rank and pos) or ((not rank) and (not pos))) + + if pos == new_pos then + return + end + + if rank and pos then + for n = pos+1, #self.rank_to_nodes[rank] do + local other_node = self.rank_to_nodes[rank][n] + self.position_in_rank[other_node] = self.position_in_rank[other_node]-1 + end + + table.remove(self.rank_to_nodes[rank], pos) + self.node_to_rank[node] = nil + self.position_in_rank[node] = nil + end + + if new_pos then + self.rank_to_nodes[rank] = self.rank_to_nodes[rank] or {} + + for n = new_pos+1, #self.rank_to_nodes[rank] do + local other_node = self.rank_to_nodes[rank][new_pos] + self.position_in_rank[other_node] = self.position_in_rank[other_node]+1 + end + + table.insert(self.rank_to_nodes[rank], node) + self.node_to_rank[node] = rank + self.position_in_rank[node] = new_pos + end +end + + + +function Ranking:normalizeRanks() + + -- get the current ranks + local ranks = self:getRanks() + + local min_rank = ranks[1] + local max_rank = ranks[#ranks] + + -- clear ranks + self.rank_to_nodes = {} + + -- iterate over all nodes and rerank them manually + for node in pairs(self.position_in_rank) do + local rank, pos = self:getNodeInfo(node) + local new_rank = rank - (min_rank - 1) + + self.rank_to_nodes[new_rank] = self.rank_to_nodes[new_rank] or {} + self.rank_to_nodes[new_rank][pos] = node + + self.node_to_rank[node] = new_rank + end +end + + + +function Ranking:switchPositions(left_node, right_node) + local left_rank = self.node_to_rank[left_node] + local right_rank = self.node_to_rank[right_node] + + assert(left_rank == right_rank, 'only positions of nodes in the same rank can be switched') + + local left_pos = self.position_in_rank[left_node] + local right_pos = self.position_in_rank[right_node] + + self.rank_to_nodes[left_rank][left_pos] = right_node + self.rank_to_nodes[left_rank][right_pos] = left_node + + self.position_in_rank[left_node] = right_pos + self.position_in_rank[right_node] = left_pos +end + + + +function Ranking:reorderRank(rank, get_index_func, is_fixed_func) + self:reorderTable(self.rank_to_nodes[rank], get_index_func, is_fixed_func) + + for n = 1, #self.rank_to_nodes[rank] do + self.position_in_rank[self.rank_to_nodes[rank][n]] = n + end +end + + + +function Ranking:reorderTable(input, get_index_func, is_fixed_func) + -- collect all allowed indices + local allowed_indices = {} + for n = 1, #input do + if not is_fixed_func(n, input[n]) then + table.insert(allowed_indices, n) + end + end + + -- collect all desired indices; for each of these desired indices, + -- remember by which element it was requested + local desired_to_real_indices = {} + local sort_indices = {} + for n = 1, #input do + if not is_fixed_func(n, input[n]) then + local index = get_index_func(n, input[n]) + if not desired_to_real_indices[index] then + desired_to_real_indices[index] = {} + table.insert(sort_indices, index) + end + table.insert(desired_to_real_indices[index], n) + end + end + + -- sort the desired indices + table.sort(sort_indices) + + -- compute the final indices by counting the final indices generated + -- prior to the current one and by mapping this number to the allowed + -- index with the same number + local final_indices = {} + local n = 1 + for _,index in ipairs(sort_indices) do + local real_indices = desired_to_real_indices[index] + for _,real_index in ipairs(real_indices) do + final_indices[real_index] = allowed_indices[n] + n = n + 1 + end + end + + -- flat-copy the input table so that we can still access the elements + -- using their real index while overwriting the input table in-place + local input_copy = lib.copy(input) + + -- move flexible elements to their final indices + for old_index, new_index in pairs(final_indices) do + input[new_index] = input_copy[old_index] + end +end + + + +-- Done + +return Ranking \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua new file mode 100644 index 00000000000..4d1e0ae47ed --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua @@ -0,0 +1,478 @@ +-- Copyright 2011 by Jannis Pohlmann, 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/Sugiyama.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- @section subsection {The Modular Sugiyama Method} +-- +-- @end + +local Sugiyama = {} + +-- Namespace +require("pgf.gd.layered").Sugiyama = Sugiyama + +-- Imports +local layered = require "pgf.gd.layered" +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + +local Ranking = require "pgf.gd.layered.Ranking" +local Simplifiers = require "pgf.gd.lib.Simplifiers" + +-- Deprecated stuff. Need to get rid of it! +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + +local Iterators = require "pgf.gd.deprecated.Iterators" +local Vector = require "pgf.gd.deprecated.Vector" + + + +--- + +declare { + key = "layered layout", + algorithm = Sugiyama, + + preconditions = { + connected = true, + loop_free = true, + }, + + postconditions = { + upward_oriented = true + }, + + old_graph_model = true, + + summary = [[" + The |layered layout| is the key used to select the modular Sugiyama + layout algorithm. + "]], + documentation = [[" + This algorithm consists of five consecutive steps, each of which can be + configured independently of the other ones (how this is done is + explained later in this section). Naturally, the ``best'' heuristics + are selected by default, so there is typically no need to change the + settings, but what is the ``best'' method for one graph need not be + the best one for another graph. + + As can be seen in the first example, the algorithm will not only + position the nodes of a graph, but will also perform an edge + routing. This will look visually quite pleasing if you add the + |rounded corners| option: + "]], + examples = { + [[" + \tikz \graph [layered layout, sibling distance=7mm] + { + a -> { + b, + c -> { d, e, f } + } -> + h -> + a + }; + "]], + [[" + \tikz [rounded corners] \graph [layered layout, sibling distance=7mm] + { + a -> { + b, + c -> { d, e, f } + } -> + h -> + a + }; + "]] + } +} + +--- + +declare { + key = "minimum layers", + type = "number", + initial = "1", + + summary = [[" + The minimum number of levels that an edge must span. It is a bit of + the opposite of the |weight| parameter: While a large |weight| + causes an edge to become shorter, a larger |minimum layers| value + causes an edge to be longer. + "]], + examples = [[" + \tikz \graph [layered layout] { + a -- {b [> minimum layers=3], c, d} -- e -- a; + }; + "]] +} + + +--- + +declare { + key = "same layer", + layer = 0, + + summary = [[" + The |same layer| collection allows you to enforce that several nodes + a on the same layer of a layered layout (this option is also known + as |same rank|). You use it like this: + "]], + examples = {[[" + \tikz \graph [layered layout] { + a -- b -- c -- d -- e; + + { [same layer] a, b }; + { [same layer] d, e }; + }; + "]],[[" + \tikz [rounded corners] \graph [layered layout] { + 1972 -> 1976 -> 1978 -> 1980 -> 1982 -> 1984 -> 1986 -> 1988 -> 1990 -> future; + + { [same layer] 1972, Thompson }; + { [same layer] 1976, Mashey, Bourne }, + { [same layer] 1978, Formshell, csh }, + { [same layer] 1980, esh, vsh }, + { [same layer] 1982, ksh, "System-V" }, + { [same layer] 1984, v9sh, tcsh }, + { [same layer] 1986, "ksh-i" }, + { [same layer] 1988, KornShell ,Perl, rc }, + { [same layer] 1990, tcl, Bash }, + { [same layer] "future", POSIX, "ksh-POSIX" }, + + Thompson -> { Mashey, Bourne, csh -> tcsh}, + Bourne -> { ksh, esh, vsh, "System-V", v9sh -> rc, Bash}, + { "ksh-i", KornShell } -> Bash, + { esh, vsh, Formshell, csh } -> ksh, + { KornShell, "System-V" } -> POSIX, + ksh -> "ksh-i" -> KornShell -> "ksh-POSIX", + Bourne -> Formshell, + + { [edge={draw=none}] + Bash -> tcl, + KornShell -> Perl + } + }; + "]] + } +} + + + +-- Implementation + +function Sugiyama:run() + if #self.graph.nodes <= 1 then + return + end + + local options = self.digraph.options + + local cycle_removal_algorithm_class = options.algorithm_phases['cycle removal'] + local node_ranking_algorithm_class = options.algorithm_phases['node ranking'] + local crossing_minimization_algorithm_class = options.algorithm_phases['crossing minimization'] + local node_positioning_algorithm_class = options.algorithm_phases['node positioning'] + local edge_routing_algorithm_class = options.algorithm_phases['layer edge routing'] + + self:preprocess() + + -- Helper function for collapsing multiedges + local function collapse (m,e) + m.weight = (m.weight or 0) + e.weight + m.minimum_levels = math.max((m.minimum_levels or 0), e.minimum_levels) + end + + -- Rank using cluster + + -- Create a subalgorithm object. Needed so that removed loops + -- are not stored on top of removed loops from main call. + local cluster_subalgorithm = { graph = self.graph } + self.graph:registerAlgorithm(cluster_subalgorithm) + + self:mergeClusters() + + Simplifiers:removeLoopsOldModel(cluster_subalgorithm) + Simplifiers:collapseMultiedgesOldModel(cluster_subalgorithm, collapse) + + cycle_removal_algorithm_class.new { main_algorithm = self, graph = self.graph }:run() + self.ranking = node_ranking_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run() + self:restoreCycles() + + Simplifiers:expandMultiedgesOldModel(cluster_subalgorithm) + Simplifiers:restoreLoopsOldModel(cluster_subalgorithm) + + self:expandClusters() + + -- Now do actual computation + Simplifiers:collapseMultiedgesOldModel(cluster_subalgorithm, collapse) + cycle_removal_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run() + self:insertDummyNodes() + + -- Main algorithm + crossing_minimization_algorithm_class.new{ + main_algorithm = self, + graph = self.graph, + ranking = self.ranking + }:run() + node_positioning_algorithm_class.new{ + main_algorithm = self, + graph = self.graph, + ranking = self.ranking + }:run() + + -- Cleanup + self:removeDummyNodes() + Simplifiers:expandMultiedgesOldModel(cluster_subalgorithm) + edge_routing_algorithm_class.new{ main_algorithm = self, graph = self.graph }:run() + self:restoreCycles() + +end + + + +function Sugiyama:preprocess() + -- initialize edge parameters + for _,edge in ipairs(self.graph.edges) do + -- read edge parameters + edge.weight = edge:getOption('weight') + edge.minimum_levels = edge:getOption('minimum layers') + + -- validate edge parameters + assert(edge.minimum_levels >= 0, 'the edge ' .. tostring(edge) .. ' needs to have a minimum layers value greater than or equal to 0') + end +end + + + +function Sugiyama:insertDummyNodes() + -- enumerate dummy nodes using a globally unique numeric ID + local dummy_id = 1 + + -- keep track of the original edges removed + self.original_edges = {} + + -- keep track of dummy nodes introduced + self.dummy_nodes = {} + + for node in Iterators.topologicallySorted(self.graph) do + local in_edges = node:getIncomingEdges() + + for _,edge in ipairs (in_edges) do + local neighbour = edge:getNeighbour(node) + local dist = self.ranking:getRank(node) - self.ranking:getRank(neighbour) + + if dist > 1 then + local dummies = {} + + for i=1,dist-1 do + local rank = self.ranking:getRank(neighbour) + i + + local dummy = Node.new{ + pos = Vector.new(), + name = 'dummy@' .. neighbour.name .. '@to@' .. node.name .. '@at@' .. rank, + kind = "dummy", + orig_vertex = pgf.gd.model.Vertex.new{} + } + + dummy_id = dummy_id + 1 + + self.graph:addNode(dummy) + self.ugraph:add {dummy.orig_vertex} + + self.ranking:setRank(dummy, rank) + + table.insert(self.dummy_nodes, dummy) + table.insert(edge.bend_nodes, dummy) + + table.insert(dummies, dummy) + end + + table.insert(dummies, 1, neighbour) + table.insert(dummies, #dummies+1, node) + + for i = 2, #dummies do + local source = dummies[i-1] + local target = dummies[i] + + local dummy_edge = Edge.new{ + direction = Edge.RIGHT, + reversed = false, + weight = edge.weight, -- TODO or should we divide the weight of the original edge by the number of virtual edges? + } + + dummy_edge:addNode(source) + dummy_edge:addNode(target) + + self.graph:addEdge(dummy_edge) + end + + table.insert(self.original_edges, edge) + end + end + end + + for _,edge in ipairs(self.original_edges) do + self.graph:deleteEdge(edge) + end +end + + + +function Sugiyama:removeDummyNodes() + -- delete dummy nodes + for _,node in ipairs(self.dummy_nodes) do + self.graph:deleteNode(node) + end + + -- add original edge again + for _,edge in ipairs(self.original_edges) do + -- add edge to the graph + self.graph:addEdge(edge) + + -- add edge to the nodes + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + + -- convert bend nodes to bend points for TikZ + for _,bend_node in ipairs(edge.bend_nodes) do + local point = bend_node.pos:copy() + table.insert(edge.bend_points, point) + end + + if edge.reversed then + local bp = edge.bend_points + for i=1,#bp/2 do + local j = #bp + 1 - i + bp[i], bp[j] = bp[j], bp[i] + end + end + + -- clear the list of bend nodes + edge.bend_nodes = {} + end +end + + + +function Sugiyama:mergeClusters() + + self.cluster_nodes = {} + self.cluster_node = {} + self.cluster_edges = {} + self.cluster_original_edges = {} + self.original_nodes = {} + + for _,cluster in ipairs(self.graph.clusters) do + + local cluster_node = cluster.nodes[1] + table.insert(self.cluster_nodes, cluster_node) + + for n = 2, #cluster.nodes do + local other_node = cluster.nodes[n] + self.cluster_node[other_node] = cluster_node + table.insert(self.original_nodes, other_node) + end + end + + for _,edge in ipairs(self.graph.edges) do + local tail = edge:getTail() + local head = edge:getHead() + + if self.cluster_node[tail] or self.cluster_node[head] then + local cluster_edge = Edge.new{ + direction = Edge.RIGHT, + weight = edge.weight, + minimum_levels = edge.minimum_levels, + } + + if self.cluster_node[tail] then + cluster_edge:addNode(self.cluster_node[tail]) + else + cluster_edge:addNode(tail) + end + + if self.cluster_node[head] then + cluster_edge:addNode(self.cluster_node[head]) + else + cluster_edge:addNode(head) + end + + table.insert(self.cluster_edges, cluster_edge) + table.insert(self.cluster_original_edges, edge) + end + end + + for n = 1, #self.cluster_nodes-1 do + local first_node = self.cluster_nodes[n] + local second_node = self.cluster_nodes[n+1] + + local edge = Edge.new{ + direction = Edge.RIGHT, + weight = 1, + minimum_levels = 1, + } + + edge:addNode(first_node) + edge:addNode(second_node) + + table.insert(self.cluster_edges, edge) + end + + for _,node in ipairs(self.original_nodes) do + self.graph:deleteNode(node) + end + for _,edge in ipairs(self.cluster_edges) do + self.graph:addEdge(edge) + end + for _,edge in ipairs(self.cluster_original_edges) do + self.graph:deleteEdge(edge) + end +end + + + +function Sugiyama:expandClusters() + + for _,node in ipairs(self.original_nodes) do + self.ranking:setRank(node, self.ranking:getRank(self.cluster_node[node])) + self.graph:addNode(node) + end + + for _,edge in ipairs(self.cluster_original_edges) do + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + self.graph:addEdge(edge) + end + + for _,edge in ipairs(self.cluster_edges) do + self.graph:deleteEdge(edge) + end +end + + +function Sugiyama:restoreCycles() + for _,edge in ipairs(self.graph.edges) do + edge.reversed = false + end +end + + + + + +-- done + +return Sugiyama \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua new file mode 100644 index 00000000000..16e3b1653de --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua @@ -0,0 +1,81 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/crossing_minimization.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Crossing Minimization (Node Ordering)} +-- +-- The number of edge crossings in a layered drawing is determined by +-- the ordering of nodes at each of its layers. Therefore, crossing +-- minimization is the problem of reordering the nodes at each layer +-- so that the overall number of edge crossings is minimized. The +-- crossing minimization step takes a proper layering where every edge +-- connects nodes in neighbored layers, allowing algorithms to +-- minimize crossings layer by layer rather than all at once. While +-- this does not reduce the complexity of the problem, it does make it +-- considerably easier to understand and implement. Techniques based +-- on such an iterative approach are also known as layer-by-layer +-- sweep methods. They are used in many popular heuristics due to +-- their simplicity and the good results they produce. +-- +-- Sweeping refers to moving up and down from one layer to the next, +-- reducing crossings along the way. In layer-by-layer sweep methods, +-- an initial node ordering for one of the layers is computed +-- first. Depending on the sweep direction this can either be the +-- first layer or the last; in rare occasions the layer in the middle +-- is used instead. Followed by this, the actual layer-by-layer sweep +-- is performed. Given an initial ordering for the first layer $L_1$, a +-- downward sweep first holds the nodes in $L_1$ fixed while reordering +-- the nodes in the second layer $L_2$ to reduce the number of +-- crossings between $L_1$ and $L_2$. It then goes on to reorder the +-- third layer while holding the second layer fixed. This is continued +-- until all layers except for the first one have been +-- examined. Upward sweeping and sweeping from the middle work +-- analogous. +-- +-- Obviously, the central aspect of the layer-by-layer sweep is how +-- the nodes of a specific layer are reordered using a neighbored +-- layer as a fixed reference. This problem is known as one-sided +-- crossing minimization, which unfortunately is NP-hard. In the +-- following various heuristics to solve this problem are +-- presented. +-- +-- For more details, please see Section 4.1.4 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "sweep crossing minimization", + algorithm = require "pgf.gd.layered.CrossingMinimizationGansnerKNV1993", + phase = "crossing minimization", + phase_default = true, + + summary = [[" + Gansner et al. combine an initial ordering based on a depth-first + search with the median and greedy switch heuristics applied in the + form of an alternating layer-by-layer sweep based on a weighted + median. + "]], + documentation = [[" + For more details, please see Section 4.1.4 of Pohlmann's Diploma + thesis. + + This is the default algorithm for crossing minimization. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua new file mode 100644 index 00000000000..e201de6da4a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua @@ -0,0 +1,139 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/cycle_removal.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Cycle Removal} +-- +-- The Sugiyama method works only on directed \emph{acyclic} +-- graphs. For this reason, if the input graph is not (yet) acyclic, a +-- number of edges need to be redirected so that acyclicity arises. In +-- the following, the different options that allow you to fine-tune +-- this process are documented. +-- +-- @end + + + +--- + +declare { + key = "depth first cycle removal", + algorithm = require "pgf.gd.layered.CycleRemovalGansnerKNV1993", + phase = "cycle removal", + phase_default = true, + + summary = [[" + Selects a cycle removal algorithm that is especially + appropriate for graphs specified ``by hand''. + "]], + documentation = [[" + When graphs are created by humans manually, one can + make assumptions about the input graph that would otherwise not + be possible. For instance, it seems reasonable to assume that the + order in which nodes and edges are entered by the user somehow + reflects the natural flow the user has had in mind for the graph. + + In order to preserve the natural flow of the input graph, Gansner + et al.\ propose to remove cycles by performing a series of + depth-first searches starting at individual nodes in the order they + appear in the graph. This algorithm + implicitly constructs a spanning tree of the nodes reached during + the searches. It thereby partitions the edges of the graph into + tree edges and non-tree edges. The non-tree edges are further + subdivided into forward edges, cross edges, and back edges. Forward + edges point from a tree nodes to one of their descendants. Cross + edges connect unrelated branches in + the search tree. Back edges connect descendants to one of their + ancestors. It is not hard to see that reversing back edges will not + only introduce no new cycles but will also make any directed graph + acyclic. Gansner et al.\ argue that this approach is more stable + than others in that fewer inappropriate edges are reversed compared + to other methods, despite the lack of a provable upper bound + for the number of reversed edges. + + See section 4.1.1 of Pohlmann's Diplom thesis for more details. + + This is the default algorithm for cycle removals. + "]] + } + +--- + +declare { + key = "prioritized greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalEadesLS1993", + phase = "cycle removal", + + summary = [[" + This algorithm implements a greedy heuristic of Eades et al.\ for + cycle removal that prioritizes sources and sinks. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] +} + + +--- + +declare { + key = "greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalEadesLS1993", + phase = "cycle removal", + + summary = [[" + This algorithm implements a greedy heuristic of Eades et al.\ for + cycle removal that prioritizes sources and sinks. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] + } + +--- + +declare { + key = "naive greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalBergerS1990a", + phase = "cycle removal", + + summary = [[" + This algorithm implements a greedy heuristic of Berger and Shor for + cycle removal. It + is not really compared to the other heuristics and only included + for demonstration purposes. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] + } + +--- + +declare { + key = "random greedy cycle removal", + algorithm = "pgf.gd.layered.CycleRemovalBergerS1990b", + phase = "cycle removal", + + summary = [[" + This algorithm implements a randomized greedy heuristic of Berger + and Shor for cycle removal. It, too, is not really compared to + the other heuristics and only included for demonstration purposes. + "]], + documentation = [[" + See section 4.1.1 of Pohlmann's Diploma theses for details. + "]] + } + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua new file mode 100644 index 00000000000..e2cb40f68b3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua @@ -0,0 +1,50 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/edge_routing.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Edge Routing} +-- +-- The original layered drawing method described by Eades and Sugiyama +-- in does not include the routing or shaping of edges as a main +-- step. This makes sense if all nodes have the same size and +-- shape. In practical scenarios, however, this assumption often does +-- not hold. In these cases, advanced techniques may have to be +-- applied in order to avoid overlaps of nodes and edges. +-- +-- For more details, please see Section 4.1.5 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "polyline layer edge routing", + algorithm = require "pgf.gd.layered.EdgeRoutingGansnerKNV1993", + phase = "layer edge routing", + phase_default = true, + + summary = [[" + This edge routing algorithm uses polygonal lines to connect nodes. + "]], + documentation = [[" + For more details, please see Section 4.1.5 of Pohlmann's Diploma + thesis. + + This is the default algorithm for edge routing. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua new file mode 100644 index 00000000000..a3c03b7283e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua @@ -0,0 +1,91 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/library.lua,v 1.3 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- A ``layered'' layout of a graph tries to arrange the nodes in +-- consecutive horizontal layers (naturally, by rotating the graph, this +-- can be changed in to vertical layers) such that edges tend to be only +-- between nodes on adjacent layers. Trees, for instance, can always be +-- laid out in this way. This method of laying out a graph is especially +-- useful for hierarchical graphs. +-- +-- The method implemented in this library is often called the +-- \emph{Sugiyama method}, which is a rather advanced method of +-- assigning nodes to layers and positions on these layers. The same +-- method is also used in the popular GraphViz program, indeed, the +-- implementation in \tikzname\ is based on the same pseudo-code from the +-- same paper as the implementation used in GraphViz and both programs +-- will often generate the same layout (but not always, as explained +-- below). The current implementation is due to Jannis Pohlmann, who +-- implemented it as part of his Diploma thesis. Please consult this +-- thesis for a detailed explanation of the Sugiyama method and its +-- history: +-- +-- \begin{itemize} +-- \item +-- Jannis Pohlmann, +-- \newblock \emph{Configurable Graph Drawing Algorithms +-- for the \tikzname\ Graphics Description Language,} +-- \newblock Diploma Thesis, +-- \newblock Institute of Theoretical Computer Science, Univerist\"at +-- zu L\"ubeck, 2011.\\[.5em] +-- \newblock Available online via +-- \url{http://www.tcs.uni-luebeck.de/downloads/papers/2011/}\\ \url{2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf} +-- \\[.5em] +-- (Note that since the publication of this thesis some option names +-- have been changed. Most noticeably, the option name +-- |layered drawing| was changed to |layered layout|, which is somewhat +-- more consistent with other names used in the graph drawing +-- libraries. Furthermore, the keys for choosing individual +-- algorithms for the different algorithm phases, have all changed.) +-- \end{itemize} +-- +-- The Sugiyama methods lays out a graph in five steps: +-- \begin{enumerate} +-- \item Cycle removal. +-- \item Layer assignment (sometimes called node ranking). +-- \item Crossing minimization (also referred to as node ordering). +-- \item Node positioning (or coordinate assignment). +-- \item Edge routing. +-- \end{enumerate} +-- It turns out that behind each of these steps there lurks an +-- NP-complete problem, which means, in practice, that each step is +-- impossible to perform optimally for larger graphs. For this reason, +-- heuristics and approximation algorithms are used to find a ``good'' +-- way of performing the steps. +-- +-- A distinctive feature of Pohlmann's implementation of the Sugiyama +-- method for \tikzname\ is that the algorithms used for each of the +-- steps can easily be exchanged, just specify a different option. For +-- the user, this means that by specifying a different +-- option and thereby using a different heuristic for one of the steps, a +-- better layout can often be found. For the researcher, this means that +-- one can very easily test new approaches and new heuristics without +-- having to implement all of the other steps anew. +-- +-- @library + +local layered + + +-- Load declarations from: +require "pgf.gd.layered" + +-- Load algorithms from: +require "pgf.gd.layered.Sugiyama" +require "pgf.gd.layered.cycle_removal" +require "pgf.gd.layered.node_ranking" +require "pgf.gd.layered.crossing_minimization" +require "pgf.gd.layered.node_positioning" +require "pgf.gd.layered.edge_routing" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua new file mode 100644 index 00000000000..d53b0873a3f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua @@ -0,0 +1,57 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_positioning.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Node Positioning (Coordinate Assignment)} +-- +-- The second last step of the Sugiyama method decides about the final +-- $x$- and $y$-coordinates of the nodes. The main objectives of this +-- step are to position nodes so that the number of edge bends is kept +-- small and edges are drawn as vertically as possible. Another goal +-- is to avoid node and edge overlaps which is crucial in particular +-- if the nodes are allowed to have non-uniform sizes. The +-- y-coordinates of the nodes have no influence on the number of +-- bends. Obviously, nodes need to be separated enough geometrically +-- so that they do not overlap. It feels natural to aim at separating +-- all layers in the drawing by the same amount. Large nodes, however, +-- may force node positioning algorithms to override this uniform +-- level distance in order to avoid overlaps. +-- +-- For more details, please see Section 4.1.2 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "linear optimization node positioning", + algorithm = require "pgf.gd.layered.NodePositioningGansnerKNV1993", + phase = "node positioning", + phase_default = true, + + summary = [[" + This node positioning method, due to Gasner et al., is based on a + linear optimization problem. + "]], + documentation = [[" + For more details, please see Section 4.1.3 of Pohlmann's Diploma + thesis. + + This is the default algorithm for layer assignments. + "]] + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua new file mode 100644 index 00000000000..3a1098d6c03 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua @@ -0,0 +1,74 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/layered/node_ranking.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + +--- +-- @section subsection {Layer Assignment (Node Ranking)} +-- +-- Algorithms for producing layered drawings place nodes on discrete +-- layers from top to bottom. Layer assignment is the problem of +-- finding a partition so that for all edges $e = (u,v) \in E(G)$ the +-- equation $\mathit{layer}(u) < \mathit{layer}(v)$ holds. Such a +-- partition is called a \emph{layering}. This definition can be extended by +-- introducing edge weights or priorities and minimum length +-- constraints which has practical applications and allows users to +-- fine-tune the results. +-- +-- For more details, please see Section 4.1.2 of Pohlmann's Diploma +-- thesis. +-- +-- @end + + + +--- + +declare { + key = "linear optimization layer assignment", + algorithm = require "pgf.gd.layered.NodeRankingGansnerKNV1993", + phase = "node ranking", + phase_default = true, + + summary = [[" + This layer assigment method, due to Gasner et al., is based on a + linear optimization problem. + "]], + documentation = [[" + For more details, please see Section 4.1.2 of Pohlmann's Diploma + thesis. + + This is the default algorithm for layer assignments. + "]] + } + + + +--- + +declare { + key = "minimum height layer assignment", + algorithm = "pgf.gd.layered.NodeRankingMinimumHeight", + phase = "node ranking", + + summary = [[" + This layer assigment method minimizes the height of the resulting + graph. + "]], + documentation = [[" + For more details, please see Section 4.1.3 of Pohlmann's Diploma + thesis. + "]] + } + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua new file mode 100644 index 00000000000..dcfb468d063 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua @@ -0,0 +1,356 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib.lua,v 1.5 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- Basic library functions + +local lib = {} + +-- Declare namespace + +require("pgf.gd").lib = lib + + +-- General lib functions: + + +--- +-- Finds the first value in the |array| for which |test| is true. +-- +-- @param array An array to search in. +-- @param test A function that is applied to each element of the +-- array together with the index of the element and the +-- whole table. +-- +-- @return The value of the first value where the test is true. +-- @return The index of the first value where the test is true. +-- @return The function value of the first value where the test is +-- true (only returned if test is a function). +-- +function lib.find(array, test) + for i=1,#array do + local t = array[i] + local result = test(t,i,array) + if result then + return t,i,result + end + end +end + + +--- +-- Finds the first value in the |array| for which a function +-- returns a minimal value +-- +-- @param array An array to search in. +-- @param f A function that is applied to each element of the +-- array together with the index of the element and the +-- whole table. It should return an integer and, possibly, a value. +-- +-- Among all elements for which a non-nil integer is returned, let |i| +-- by the index of the element where this integer is minimal. +-- +-- @return |array[i]| +-- @return |i| +-- @return The return value(s) of the function at |array[i]|. +-- +function lib.find_min(array, f) + local best = math.huge + local best_result + local best_index + for i=1,#array do + local t = array[i] + local result, p = f(t,i,array) + if result and p < best then + best = p + best_result = result + best_index = i + end + end + if best_index then + return array[best_index],best_index,best_result,best + end +end + + + + +--- +-- Copies a table while preserving its metatable. +-- +-- @param source The table to copy. +-- @param target The table to which values are to be copied or |nil| if a new +-- table is to be allocated. +-- +-- @return The |target| table or a newly allocated table containing all +-- keys and values of the |source| table. +-- +function lib.copy(source, target) + if not target then + target = {} + end + for key, val in pairs(source) do + target[key] = val + end + return setmetatable(target, getmetatable(source)) +end + + +--- +-- Copies an array while preserving its metatable. +-- +-- @param source The array to copy. +-- @param target The array to which values are to be copied or |nil| if a new +-- table is to be allocated. The elements of the +-- |source| array will be added at the end. +-- +-- @return The |target| table or a newly allocated table containing all +-- keys and values of the |source| table. +-- +function lib.icopy(source, target) + target = target or {} + for _, val in ipairs(source) do + target[#target+1] = val + end + return setmetatable(target, getmetatable(source)) +end + + + + +--- +-- Apply a function to all pairs of a table, resulting in a new table. +-- +-- @param source The table. +-- @param fun A function taking two arguments (|val| and |key|, in +-- that order). Should return two values (a |new_val| and a +-- |new_key|). This pair will be inserted into the new table. If, +-- however, |new_key| is |nil|, the |new_value| will be inserted at +-- the position |key|. This means, in particular, that if the |fun| +-- takes only a single argument and returns only a single argument, +-- you have a ``classical'' value mapper. Also note that if +-- |new_value| is |nil|, the value is removed from the table. +-- +-- @return The new table. +-- +function lib.map(source, fun) + local target = {} + for key, val in pairs(source) do + local new_val, new_key = fun(val, key) + if new_key == nil then + new_key = key + end + target[new_key] = new_val + end + return target +end + + + +--- +-- Apply a function to all elements of an array, resulting in a new +-- array. +-- +-- @param source The array. +-- @param fun A function taking two arguments (|val| and |i|, the +-- current index). This function is applied to all elements of the +-- array. The result of this function is placed at the end of a new +-- array, expect when the function returns |nil|, in which case the +-- element is skipped. If this function is not provided (is |nil|), +-- the identity function is used. +-- @param new The target array (if |nil|, a new array is create). +-- +--\begin{codeexample}[code only] +-- local a = lib.imap(array, function(v) if some_test(v) then return v end end) +--\end{codeexample} +-- +-- The above code is a filter that will remove all elements from the +-- array that do not pass |some_test|. +-- +--\begin{codeexample}[code only] +-- lib.imap(a, lib.id, b) +--\end{codeexample} +-- +-- The above code has the same effect as |lib.icopy(a,b)|. +-- +-- @return The new array +-- +function lib.imap(source, fun, new) + if not new then + new = { } + end + for i, v in ipairs(source) do + new[#new+1] = fun(v, i) + end + return new +end + + +--- +-- Generate a random permutation of the numbers $1$ to $n$ in time +-- $O(n)$. Knuth's shuffle is used for this. +-- +-- @param n The desired size of the table +-- @return A random permutation + +function lib.random_permutation(n) + local p = {} + for i=1,n do + p[i] = i + end + for i=1,n-1 do + local j = math.random(i,n) + p[i], p[j] = p[i], p[j] + end + return p +end + + +--- +-- The identity function, so you can write |lib.id| instead of +-- |function (x) return x end|. +-- + +function lib.id(...) + return ... +end + + + +--- +-- Tries to find an option in different objects that have an +-- options field. +-- +-- This function iterates over all objects given as parameters. In +-- each, it tries to find out whether the options field of the object +-- contains the option |name| and, if so, +-- returns the value. The important point is that checking whether the +-- option table of an object contains the name field is done using +-- |rawget| for all but the last parameter. This means that when you +-- write +--\begin{codeexample}[code only] +--lib.lookup_option("foo", vertex, graph) +--\end{codeexample} +-- and if |/graph drawin/foo| has an inital value set, if the +-- parameter is not explicitly set in a vertex, you will get the value +-- set for the graph or, if it is not set there either, the initial +-- value. In contrast, if you write +--\begin{codeexample}[code only] +-- vertex.options["foo"] or graph.options["foo"] +--\end{codeexample} +-- what happens is that the first access to |.options| will +-- \emph{always} return something when an initial parameter has been +-- set for the option |foo|. +-- +-- @param name The name of the options +-- @param ... Any number of objects. Each must have an options +-- field. +-- +-- @return The found option + +function lib.lookup_option(name, ...) + local list = {...} + for i=1,#list-1 do + local o = list[i].options + if o then + local v = rawget(o, name) + if v then + return v + end + end + end + return list[#list].options[name] +end + + + +--- +-- Turns a table |t| into a class in the sense of object oriented +-- programming. In detail, this means that |t| is augmented by +-- a |new| function, which takes an optional table of |initial| values +-- and which outputs a new table whose metatable is the +-- class. The |new| function will call the function |constructor| if +-- it exsist. Furthermore, the class object's |__index| is set to itself +-- and its meta table is set to the |base_class| field of the +-- table. If |t| is |nil|, a new table is created. +-- +-- Here is a typical usage of this function: +-- +--\begin{codeexample}[code only] +--local Point = lib.class {} +-- +--function Point:length() +-- return math.sqrt(self.x*self.x + self.y*self.y) +--end +-- +--local p = Point.new { x = 5, y = 6 } +-- +--print(p:length()) +--\end{codeexample} +-- We can subclass this as follows: +-- +--\begin{codeexample}[code only] +--local Point3D = lib.class { base_class = Point } +-- +--function Point3D:length() +-- local l = Point.length(self) -- Call base class's function +-- return math.sqrt(l*l + self.z*self.zdy) +--end +-- +--local p = Point3D.new { x = 5, y = 6, z = 6 } +-- +--print(p:length()) +--\end{codeexample} +-- +-- @param t A table that gets augmented to a class. If |nil|, a new +-- table is created. +-- @return The augmented table. + +function lib.class(t) + t = t or {} + + -- First, setup indexing, if necessary + if not t.__index then + t.__index = t + end + + -- Second, setup new method, if necessary + t.new = t.new or + function (initial) + + -- Create new object + local obj = {} + for k,v in pairs(initial or {}) do + obj[k] = v + end + setmetatable(obj, t) + + if obj.constructor then + obj:constructor() + end + + return obj + end + + -- Third, setup inheritence, if necessary + if not getmetatable(t) then + setmetatable(t, t.base_class) + end + + return t +end + + +-- Done + +return lib \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua new file mode 100644 index 00000000000..aa149c3e4f9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua @@ -0,0 +1,160 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Bezier.lua,v 1.1 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- This library offers a number of methods for working with Bezi\'er +-- curves. + +local Bezier = {} + +-- Namespace +require("pgf.gd.lib").Bezier = Bezier + + +-- Imports + +local Coordinate = require 'pgf.gd.model.Coordinate' + + +--- +-- Compute a point ``along a curve at a time''. You provide the four +-- coordinates of the curve and a time. You get a point on the curve +-- as return value as well as the two suport vector for curve +-- before this point and two support vectors for the curve after the +-- point. +-- +-- For speed reasons and in order to avoid superfluous creation of +-- lots of tables, all values are provided and returned as pairs of +-- values rather than as |Coordinate| objects. +-- +-- @param ax The coordinate where the curve starts. +-- @param ay +-- @param bx The first support point. +-- @param by +-- @param cx The second support point. +-- @param cy +-- @param dx The coordinate where the curve ends. +-- @param dy +-- @param t A time (a number). +-- +-- @return The point |p| on the curve at time |t| ($x$-part). +-- @return The point |p| on the curve at time |t| ($y$-part). +-- @return The first support point of the curve between |a| and |p| ($x$-part). +-- @return The first support point of the curve between |a| and |p| ($y$-part). +-- @return The second support point of the curve between |a| and |p| ($x$-part). +-- @return The second support point of the curve between |a| and |p| ($y$-part). +-- @return The first support point of the curve between |p| and |d| ($x$-part). +-- @return The first support point of the curve between |p| and |d| ($y$-part). +-- @return The second support point of the curve between |p| and |d| ($x$-part). +-- @return The second support point of the curve between |p| and |d| ($y$-part). + +function Bezier.atTime(ax,ay,bx,by,cx,cy,dx,dy,t) + + local s = 1-t + + local ex, ey = ax*s + bx*t, ay*s + by*t + local fx, fy = bx*s + cx*t, by*s + cy*t + local gx, gy = cx*s + dx*t, cy*s + dy*t + + local hx, hy = ex*s + fx*t, ey*s + fy*t + local ix, iy = fx*s + gx*t, fy*s + gy*t + + local jx, jy = hx*s + ix*t, hy*s + iy*t + + return jx, jy, ex, ey, hx, hy, ix, iy, gx, gy +end + + +--- +-- The ``coordinate version'' of the |atTime| function, where both the +-- parameters and the return values are coordinate objects. + +function Bezier.atTimeCoordinates(a,b,c,d,t) + local jx, jy, ex, ey, hx, hy, ix, iy, gx, gy = + Bezier.atTime(a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y,t) + + return + Coordinate.new(jx, jy), + Coordinate.new(ex, ey), + Coordinate.new(hx, hy), + Coordinate.new(ix, iy), + Coordinate.new(gx, gy) +end + + +--- +-- Computes the support points of a Bezier curve based on two points +-- on the curves at certain times. +-- +-- @param from The start point of the curve +-- @param p1 A first point on the curve +-- @param t1 A time when this point should be reached +-- @param p2 A second point of the curve +-- @param t2 A time when this second point should be reached +-- @param to The end of the curve +-- +-- @return sup1 A first support point of the curve +-- @return sup2 A second support point of the curve + +function Bezier.supportsForPointsAtTime(from, p1, t1, p2, t2, to) + + local s1 = 1 - t1 + local s2 = 1 - t2 + + local f1a = s1^3 + local f1b = t1 * s1^2 * 3 + local f1c = t1^2 * s1 * 3 + local f1d = t1^3 + + local f2a = s2^3 + local f2b = t2 * s2^2 * 3 + local f2c = t2^2 * s2 * 3 + local f2d = t2^3 + + -- The system: + -- p1.x - from.x * f1a - to.x * f1d = sup1.x * f1b + sup2.x * f1c + -- p2.x - from.x * f2a - to.x * f2d = sup1.x * f2b + sup2.x * f2c + -- + -- p1.y - from.y * f1a - to.y * f1d = sup1.y * f1b + sup2.y * f1c + -- p2.y - from.y * f2a - to.y * f2d = sup1.y * f2b + sup2.y * f2c + + local a = f1b + local b = f1c + local c = p1.x - from.x * f1a - to.x * f1d + local d = f2b + local e = f2c + local f = p2.x - from.x * f2a - to.x * f2d + + local det = a*e - b*d + local x1 = -(b*f - e*c)/det + local x2 = -(c*d - a*f)/det + + local c = p1.y - from.y * f1a - to.y * f1d + local f = p2.y - from.y * f2a - to.y * f2d + + local det = a*e - b*d + local y1 = -(b*f - e*c)/det + local y2 = -(c*d - a*f)/det + + return Coordinate.new(x1,y1), Coordinate.new(x2,y2) + +end + + + + + + +-- Done + +return Bezier \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua new file mode 100644 index 00000000000..768a5da0ffe --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua @@ -0,0 +1,125 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/DepthFirstSearch.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- The DepthFirstSearch class implements a generic depth first function. It does not +-- require that it is run on graphs, but can be used for anything where a visit function and +-- a complete function is available. + +local DepthFirstSearch = {} +DepthFirstSearch.__index = DepthFirstSearch + +-- Namespace +require("pgf.gd.lib").DepthFirstSearch = DepthFirstSearch + +-- Imports +local Stack = require "pgf.gd.lib.Stack" + + + +-- TT: TODO Jannis: Please document... + +function DepthFirstSearch.new(init_func, visit_func, complete_func) + local dfs = { + init_func = init_func, + visit_func = visit_func, + complete_func = complete_func, + + stack = Stack.new(), + discovered = {}, + visited = {}, + completed = {}, + } + setmetatable(dfs, DepthFirstSearch) + return dfs +end + + + +function DepthFirstSearch:run() + self:reset() + self.init_func(self) + + while self.stack:getSize() > 0 do + local data = self.stack:peek() + + if not self:getVisited(data) then + if self.visit_func then + self.visit_func(self, data) + end + else + if self.complete_func then + self.complete_func(self, data) + end + self:setCompleted(data, true) + self.stack:pop() + end + end +end + + + +function DepthFirstSearch:reset() + self.discovered = {} + self.visited = {} + self.completed = {} + self.stack = Stack.new() +end + + + +function DepthFirstSearch:setDiscovered(data, discovered) + self.discovered[data] = discovered +end + + + +function DepthFirstSearch:getDiscovered(data) + return self.discovered[data] +end + + + +function DepthFirstSearch:setVisited(data, visited) + self.visited[data] = visited +end + + + +function DepthFirstSearch:getVisited(data) + return self.visited[data] +end + + + +function DepthFirstSearch:setCompleted(data, completed) + self.completed[data] = completed +end + + + +function DepthFirstSearch:getCompleted(data) + return self.completed[data] +end + + + +function DepthFirstSearch:push(data) + self.stack:push(data) +end + + + +-- Done + +return DepthFirstSearch \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua new file mode 100644 index 00000000000..dd5dde22e1c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua @@ -0,0 +1,95 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Direct.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- Direct is a class that collects algorithms for computing new +-- versions of a graph where arcs point in certain directions. + +local Direct = {} + +-- Namespace +require("pgf.gd.lib").Direct = Direct + +-- Imports +local Digraph = require "pgf.gd.model.Digraph" + + +--- Compute a digraph from a syntactic digraph. +-- +-- This function takes a syntactic digraph and compute a new digraph +-- where all arrow point in the "semantic direction" of the syntactic +-- arrows. For instance, while "a <- b" will cause an arc from a to be +-- to be added to the syntactic digraph, calling this function will +-- return a digraph in which there is an arc from b to a rather than +-- the other way round. In detail, "a <- b" is tranlated as just +-- described, "a -> b" yields an arc from a to b as expected, "a <-> b" +-- and "a -- b" yield arcs in both directions and, finally, "a -!- b" +-- yields no arc at all. +-- +-- @param syntactic_digraph A syntacitic digraph, usually the "input" +-- graph as specified syntactically be the user. +-- +-- @return A new "semantic" digraph object. + +function Direct.digraphFromSyntacticDigraph(syntactic_digraph) + local digraph = Digraph.new(syntactic_digraph) -- copy + + -- Now go over all arcs of the syntactic_digraph and turn them into + -- arcs with the correct direction in the digraph: + for _,a in ipairs(syntactic_digraph.arcs) do + for _,m in ipairs(a.syntactic_edges) do + local direction = m.direction + if direction == "->" then + digraph:connect(a.tail, a.head) + elseif direction == "<-" then + digraph:connect(a.head, a.tail) + elseif direction == "--" or direction == "<->" then + digraph:connect(a.tail, a.head) + digraph:connect(a.head, a.tail) + end + -- Case -!-: No edges... + end + end + + return digraph +end + + +--- Turn an arbitrary graph into a directed graph +-- +-- Takes a digraph as input and returns its underlying undirected +-- graph, coded as a digraph. This means that between any two vertices +-- if there is an arc in one direction, there is also one in the other. +-- +-- @param digraph A directed graph +-- +-- @return The underlying undirected graph of digraph. + +function Direct.ugraphFromDigraph(digraph) + local ugraph = Digraph.new(digraph) + + -- Now go over all arcs of the syntactic_digraph and turn them into + -- arcs with the correct direction in the digraph: + for _,a in ipairs(digraph.arcs) do + ugraph:connect(a.head,a.tail) + ugraph:connect(a.tail,a.head) + end + + return ugraph +end + + + + +-- Done + +return Direct \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua new file mode 100644 index 00000000000..918c118f4b2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua @@ -0,0 +1,98 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Event.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- +-- Events are used to communicate ``interesting'' events from the +-- parser to the graph drawing algorithms. +-- +-- As a syntactic description of some graph is being parsed, vertices, +-- arcs, and a digraph object representing this graph get +-- constructed. However, even though syntactic annotations such as +-- options for the vertices and arcs are attached to them and can be +-- accessed through the graph objects, some syntactic inforamtion is +-- neither represented in the digraph object nor in the vertices and +-- the arcs. A typical example is a ``missing'' node in a tree: Since +-- it is missing, there is neither a vertex object nor arc objects +-- representing it. It is also not a global option of the graph. +-- +-- For these reasons, in addition to the digraph object itself, +-- additional information can be passed by a parser to graph drawing +-- algorithms through the means of events. Each |Event| consists of a +-- |kind| field, which is just some string, and a |parameters| field, +-- which stores additional, kind-specific information. As a graph is +-- being parsed, a string of events is accumulated and is later on +-- available through the |events| field of the graph drawing scope. +-- +-- The following events are created during the parsing process by the +-- standard parsers of \tikzname: +-- +-- \begin{itemize} +-- \item[|node|] When a node of the input graph has been parsed and +-- a |Vertex| object has been created for it, an event with kind +-- |node| is created. The |parameter| of this event is the +-- just-created vertex. +-- +-- The same kind of event is used to indicate ``missing'' nodes. In +-- this case, the |parameters| field is |nil|. +-- \item[|edge|] When an edge of the input graph has been parsed, an +-- event is created of kind |edge|. The |parameters| field will store +-- an array with two entries: The first is the |Arc| object whose +-- |syntactic_edges| field stores the |edge|. The second is the index +-- of the edge inside the |syntactic_edges| field. +-- \item[|begin|] +-- Signals the beginning of a group, which will be ended with a +-- corresponding |end| event later on. The |parameters| field will +-- indicate the kind of group. Currently, only the string +-- |"descendants"| is used as |parameters|, indicating the start of +-- several nodes that are descendants of a given node. This +-- information can be used by algorithms for reconstructing the +-- input structure of trees. +-- \item[|end|] Signals the end of a group begun by a |begin| event +-- earlier on. +-- \end{itemize} +-- +-- @field kind A string representing the kind of the events. +-- @field parameters Kind-specific parameters. +-- @field index A number that stores the events logical position in +-- the sequence of events. The number need not be an integer array +-- index. +-- +local Event = {} +Event.__index = Event + + +-- Namespace +require("pgf.gd.lib").Event = Event + + + +--- +-- Create a new event object +-- +-- @param initial Initial fields of the new event. +-- +-- @return The new object + +function Event.new(values) + local new = {} + for k,v in pairs(values) do + new[k] = v + end + return setmetatable(new, Event) +end + + + +-- done + +return Event \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua new file mode 100644 index 00000000000..a3c04ca54df --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua @@ -0,0 +1,111 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/LookupTable.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- This table provides two utility functions for managing ``lookup +-- tables.'' Such a table is a mixture of an array and a hashtable: +-- It stores (only) tables. Each table is stored once in a normal +-- array position. Additionally, the lookup table is also indexed at +-- the position of the table (used as a key) and this position is set +-- to |true|. This means that you can test whether a table |t| is in the +-- lookup table |l| simply by testing whether |l[t]| is true. +-- +local LookupTable = {} + +-- Namespace +require("pgf.gd.lib").LookupTable = LookupTable + + + +--- +-- Add all elements in the |array| to a lookup table. If an element of +-- the array is already present in the table, it will not be added +-- again. +-- +-- This operation takes time $O(|\verb!array!|)$. +-- +-- @param l Lookup table +-- @param array An array of to-be-added tables. + +function LookupTable.add(l, array) + for i=1,#array do + local t = array[i] + if not l[t] then + l[t] = true + l[#l + 1] = t + end + end +end + + +--- +-- Add one element to a lookup table. If it is already present in the +-- table, it will not be added again. +-- +-- This operation takes time $O(1)$. +-- +-- @param l Lookup table +-- @param e The to-be-added element. + +function LookupTable.addOne(l, e) + if not l[e] then + l[e] = true + l[#l + 1] = e + end +end + + +--- +-- Remove tables from a lookup table. +-- +-- Note that this operation is pretty expensive insofar as it will +-- always cost a traversal of the whole lookup table. However, this is +-- also the maximum cost, even when a lot of entries need to be +-- deleted. Thus, it is much better to ``pool'' multiple remove +-- operations in a single one. +-- +-- This operation takes time $O(\max\{|\verb!array!|, |\verb!l!|\})$. +-- +-- @param l Lookup table +-- @param t An array of to-be-removed tables. + +function LookupTable.remove(l, array) + -- Step 1: Mark all to-be-deleted entries + for i=1,#array do + local t = array[i] + if l[t] then + l[t] = false + end + end + + -- Step 2: Collect garbage... + local target = 1 + for i=1,#l do + local t = l[i] + if l[t] == false then + l[t] = nil + else + l[target] = t + target = target + 1 + end + end + for i=#l,target,-1 do + l[i] = nil + end +end + + + +-- Done + +return LookupTable \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua new file mode 100644 index 00000000000..c617cf80d8b --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua @@ -0,0 +1,209 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/PathLengths.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- +-- This table provides algorithms for computing distances between +-- nodes of a graph (in the sense of path lengths). + +local PathLengths = {} + +-- Namespace +require("pgf.gd.lib").PathLengths = PathLengths + +-- Import +local PriorityQueue = require "pgf.gd.lib.PriorityQueue" + + + +--- +-- Performs the Dijkstra algorithm to solve the single-source shortes path problem. +-- +-- The algorithm computes the shortest paths from |source| to all nodes +-- in the graph. It also generates a table with distance level sets, each of +-- which contain all nodes that have the same corresponding distance to +-- |source|. Finally, a mapping of nodes to their parents along the +-- shortest paths is generated to allow the reconstruction of the paths +-- that were chosen by the Dijkstra algorithm. +-- +-- @param graph The graph to compute the shortest paths for. +-- @param source The node to compute the distances to. +-- +-- @return A mapping of nodes to their distance to |source|. +-- @return An array of distance level sets. The set at index |i| contains +-- all nodes that have a distance of |i| to |source|. +-- @return A mapping of nodes to their parents to allow the reconstruction +-- of the shortest paths chosen by the Dijkstra algorithm. +-- +function PathLengths.dijkstra(graph, source) + local distance = {} + local levels = {} + local parent = {} + + local queue = PriorityQueue.new() + + -- reset the distance of all nodes and insert them into the priority queue + for _,node in ipairs(graph.nodes) do + if node == source then + distance[node] = 0 + parent[node] = nil + queue:enqueue(node, distance[node]) + else + distance[node] = #graph.nodes + 1 -- this is about infinity ;) + queue:enqueue(node, distance[node]) + end + end + + while not queue:isEmpty() do + local u = queue:dequeue() + + assert(distance[u] < #graph.nodes + 1, 'the graph is not connected, Dijkstra will not work') + + if distance[u] > 0 then + levels[distance[u]] = levels[distance[u]] or {} + table.insert(levels[distance[u]], u) + end + + for _,edge in ipairs(u.edges) do + local v = edge:getNeighbour(u) + local alternative = distance[u] + 1 + if alternative < distance[v] then + distance[v] = alternative + + parent[v] = u + + -- update the priority of v + queue:updatePriority(v, distance[v]) + end + end + end + + return distance, levels, parent +end + + + + +--- +-- Performs the Floyd-Warshall algorithm to solve the all-source shortes path problem. +-- +-- @param graph The graph to compute the shortest paths for. +-- +-- @return A distance matrix +-- +function PathLengths.floydWarshall(graph) + local distance = {} + local infinity = math.huge + + for _,i in ipairs(graph.nodes) do + distance[i] = {} + for _,j in ipairs(graph.nodes) do + distance[i][j] = infinity + end + end + + for _,i in ipairs(graph.nodes) do + for _,edge in ipairs(i.edges) do + local j = edge:getNeighbour(i) + distance[i][j] = edge.weight or 1 + end + end + + for _,k in ipairs(graph.nodes) do + for _,i in ipairs(graph.nodes) do + for _,j in ipairs(graph.nodes) do + distance[i][j] = math.min(distance[i][j], distance[i][k] + distance[k][j]) + end + end + end + + return distance +end + + + + +--- +-- Computes the pseudo diameter of a graph. +-- +-- The diameter of a graph is the maximum of the shortest paths between +-- any pair of nodes in the graph. A pseudo diameter is an approximation +-- of the diameter that is computed by picking a starting node |u| and +-- finding a node |v| that is farthest away from |u| and has the smallest +-- degree of all nodes that have the same distance to |u|. The algorithm +-- continues with |v| as the new starting node and iteratively tries +-- to find an end node that is generates a larger pseudo diameter. +-- It terminates as soon as no such end node can be found. +-- +-- @param graph The graph. +-- +-- @return The pseudo diameter of the graph. +-- @return The start node of the corresponding approximation of a maximum +-- shortest path. +-- @return The end node of that path. +-- +function PathLengths.pseudoDiameter(graph) + + -- find a node with minimum degree + local start_node = graph.nodes[1] + for _,node in ipairs(graph.nodes) do + if node:getDegree() < start_node:getDegree() then + start_node = node + end + end + + assert(start_node) + + local old_diameter = 0 + local diameter = 0 + local end_node = nil + + while true do + local distance, levels = PathLengths.dijkstra(graph, start_node) + + -- the number of levels is the same as the distance of the nodes + -- in the last level to the start node + old_diameter = diameter + diameter = #levels + + -- abort if the diameter could not be improved + if diameter == old_diameter then + end_node = levels[#levels][1] + break + end + + -- select the node with the smallest degree from the last level as + -- the start node for the next iteration + start_node = levels[#levels][1] + for _,node in ipairs(levels[#levels]) do + if node:getDegree() < start_node:getDegree() then + start_node = node + end + end + + assert(start_node) + end + + assert(start_node) + assert(end_node) + + return diameter, start_node, end_node +end + + + + + +-- Done + +return PathLengths \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua new file mode 100644 index 00000000000..7b93c755c56 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua @@ -0,0 +1,342 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/PriorityQueue.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- +-- A PriorityQueue supports operations for quickly finding the minimum from a set of elements +-- +-- Its implementation is based on (simplified) Fibonacci heaps. +local PriorityQueue = {} +PriorityQueue.__index = PriorityQueue + + +-- Namespace +local lib = require "pgf.gd.lib" +lib.PriorityQueue = PriorityQueue + + + +-- Local declarations +local FibonacciHeap = {} +local FibonacciHeapNode = {} + + + + +--- Creates a new priority queue +-- +-- @return The newly created queue + +function PriorityQueue.new() + local queue = { + heap = FibonacciHeap.new(), + nodes = {}, + values = {}, + } + setmetatable(queue, PriorityQueue) + return queue +end + + + +--- Add an element with a certain priority to the queue +-- +-- @param value An object +-- @param priority Its priority + +function PriorityQueue:enqueue(value, priority) + local node = self.heap:insert(priority) + self.nodes[value] = node + self.values[node] = value +end + + + +--- Removes the element with the minimum priority from the queue +-- +-- @return The element with the minimum priority + +function PriorityQueue:dequeue() + local node = self.heap:extractMinimum() + + if node then + local value = self.values[node] + self.nodes[value] = nil + self.values[node] = nil + return value + else + return nil + end +end + + + +--- Lower the priority of an element of a queue +-- +-- @param value An object +-- @param priority A new priority, which must be lower than the old priority + +function PriorityQueue:updatePriority(value, priority) + local node = self.nodes[value] + assert(node, 'updating the priority of ' .. tostring(value) .. ' failed because it is not in the priority queue') + self.heap:updateValue(node, priority) +end + + + +--- Tests, whether the queue is empty +-- +-- @return True, if the queue is empty + +function PriorityQueue:isEmpty() + return #self.heap.trees == 0 +end + + + + + + +-- Internals: An implementation of fibonacci heaps. +FibonacciHeap.__index = FibonacciHeap + + +function FibonacciHeap.new() + local heap = { + trees = trees or {}, + minimum = nil, + } + setmetatable(heap, FibonacciHeap) + return heap +end + + + +function FibonacciHeap:insert(value) + local node = FibonacciHeapNode.new(value) + local heap = FibonacciHeap.new() + table.insert(heap.trees, node) + self:merge(heap) + return node +end + + + +function FibonacciHeap:merge(other) + for _, tree in ipairs(other.trees) do + table.insert(self.trees, tree) + end + self:updateMinimum() +end + + + +function FibonacciHeap:extractMinimum() + if self.minimum then + local minimum = self:removeTableElement(self.trees, self.minimum) + + for _, child in ipairs(minimum.children) do + child.root = child + table.insert(self.trees, child) + end + + local same_degrees_found = true + while same_degrees_found do + same_degrees_found = false + + local degrees = {} + + for _, root in ipairs(self.trees) do + local degree = root:getDegree() + + if degrees[degree] then + if root.value < degrees[degree].value then + self:linkRoots(root, degrees[degree]) + else + self:linkRoots(degrees[degree], root) + end + + degrees[degree] = nil + same_degrees_found = true + break + else + degrees[degree] = root + end + end + end + + self:updateMinimum() + + return minimum + end +end + + + +function FibonacciHeap:updateValue(node, value) + local old_value = node.value + local new_value = value + + if new_value <= old_value then + self:decreaseValue(node, value) + else + assert(false, 'FibonacciHeap:increaseValue is not implemented yet') + end +end + + + +function FibonacciHeap:decreaseValue(node, value) + assert(value <= node.value) + + node.value = value + + if node.value < node.parent.value then + local parent = node.parent + self:cutFromParent(node) + + if not parent:isRoot() then + if parent.marked then + self:cutFromParent(parent) + else + parent.marked = true + end + end + end + + if node.value < self.minimum.value then + self.minimum = node + end +end + + + +function FibonacciHeap:delete(node) + self:decreaseValue(node, -math.huge) + self:extractMinimum() +end + + + +function FibonacciHeap:linkRoots(root, child) + child.root = root + child.parent = root + + child = self:removeTableElement(self.trees, child) + table.insert(root.children, child) + + return root +end + + + +function FibonacciHeap:cutFromParent(node) + local parent = node.parent + + node.root = node + node.parent = node + node.marked = false + + node = self:removeTableElement(parent.children, node) + table.insert(self.trees, node) +end + + + +function FibonacciHeap:updateMinimum() + self.minimum = self.trees[1] + + for _, root in ipairs(self.trees) do + if root.value < self.minimum.value then + self.minimum = root + end + end +end + + + +function FibonacciHeap:removeTableElement(input_table, element) + for i = 1, #input_table do + if input_table[i] == element then + return table.remove(input_table, i) + end + end +end + + + + +-- Now come the nodes + +FibonacciHeapNode.__index = FibonacciHeapNode + +function FibonacciHeapNode.new(value, root, parent) + local node = { + value = value, + children = {}, + marked = false, + root = nil, + parent = nil, + } + setmetatable(node, FibonacciHeapNode) + + if root then + node.root = root + node.parent = parent + else + node.root = node + node.parent = node + end + + return node +end + +function FibonacciHeapNode:addChild(value) + local child = FibonacciHeapNode.new(value, self.root, self) + table.insert(self.children, child) +end + +function FibonacciHeapNode:getDegree() + return #self.children +end + + + +function FibonacciHeapNode:setRoot(root) + self.root = root + + if root == self then + self.parent = root + end + + if #self.children > 0 then + for _, child in ipairs(self.children) do + child.root = root + end + end +end + + + +function FibonacciHeapNode:isRoot() + return self.root == self +end + + + + + + +-- done + +return PriorityQueue \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua new file mode 100644 index 00000000000..b935305893a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua @@ -0,0 +1,279 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Simplifiers.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + + +--- The Simplifiers class is a singleton object. +-- Its methods allow implement methods for simplifing graphs, for instance +-- for removing loops or multiedges or computing spanning trees. + +local Simplifiers = {} + +-- Namespace +local lib = require "pgf.gd.lib" +lib.Simplifiers = Simplifiers + + + + +-- Imports + +local Edge = require "pgf.gd.deprecated.Edge" +local Node = require "pgf.gd.deprecated.Node" + + + + + +--- Algorithm to classify edges of a DFS search tree. +-- +-- TODO Jannis: document this algorithm as soon as it is completed and bug-free. +-- TT: Replace this algorithm by something else, perhaps? +-- +function Simplifiers:classifyEdges(graph) + local discovered = {} + local visited = {} + local recursed = {} + local completed = {} + + local tree_and_forward_edges = {} + local cross_edges = {} + local back_edges = {} + + local stack = {} + + local function push(node) + table.insert(stack, node) + end + + local function peek() + return stack[#stack] + end + + local function pop() + return table.remove(stack) + end + + local initial_nodes = graph.nodes + + for i=#initial_nodes,1,-1 do + local node = initial_nodes[i] + push(node) + discovered[node] = true + end + + while #stack > 0 do + local node = peek() + local edges_to_traverse = {} + + visited[node] = true + + if not recursed[node] then + recursed[node] = true + + local out_edges = node:getOutgoingEdges() + for _,edge in ipairs(out_edges) do + local neighbour = edge:getNeighbour(node) + + if not discovered[neighbour] then + table.insert(tree_and_forward_edges, edge) + table.insert(edges_to_traverse, edge) + else + if not completed[neighbour] then + if not visited[neighbour] then + table.insert(tree_and_forward_edges, edge) + table.insert(edges_to_traverse, edge) + else + table.insert(back_edges, edge) + end + else + table.insert(cross_edges, edge) + end + end + end + + if #edges_to_traverse == 0 then + completed[node] = true + pop() + else + for i=#edges_to_traverse,1,-1 do + local neighbour = edges_to_traverse[i]:getNeighbour(node) + discovered[neighbour] = true + push(neighbour) + end + end + else + completed[node] = true + pop() + end + end + + return tree_and_forward_edges, cross_edges, back_edges +end + + + + + +-- +-- +-- Loops and Multiedges +-- +-- + + +--- Remove all loops from a graph +-- +-- This method will remove all loops from a graph. +-- +-- @param algorithm An algorithm object + +function Simplifiers:removeLoopsOldModel(algorithm) + local graph = algorithm.graph + local loops = {} + + for _,edge in ipairs(graph.edges) do + if edge:getHead() == edge:getTail() then + loops[#loops+1] = edge + end + end + + for i=1,#loops do + graph:deleteEdge(loops[i]) + end + + graph[algorithm].loops = loops +end + + + +--- Restore loops that were previously removed. +-- +-- @param algorithm An algorithm object + +function Simplifiers:restoreLoopsOldModel(algorithm) + local graph = algorithm.graph + + for _,edge in ipairs(graph[algorithm].loops) do + graph:addEdge(edge) + edge:getTail():addEdge(edge) + end + + graph[algorithm].loops = nil +end + + + + +--- Remove all multiedges. +-- +-- Every multiedge of the graph will be replaced by a single edge. +-- +-- @param algorithm An algorithm object + +function Simplifiers:collapseMultiedgesOldModel(algorithm, collapse_action) + local graph = algorithm.graph + local collapsed_edges = {} + local node_processed = {} + + for _,node in ipairs(graph.nodes) do + node_processed[node] = true + + local multiedge = {} + + local function handle_edge (edge) + + local neighbour = edge:getNeighbour(node) + + if not node_processed[neighbour] then + if not multiedge[neighbour] then + multiedge[neighbour] = Edge.new{ direction = Edge.RIGHT } + collapsed_edges[multiedge[neighbour]] = {} + end + + if collapse_action then + collapse_action(multiedge[neighbour], edge, graph) + end + + table.insert(collapsed_edges[multiedge[neighbour]], edge) + end + end + + for _,edge in ipairs(node:getIncomingEdges()) do + handle_edge(edge) + end + + for _,edge in ipairs(node:getOutgoingEdges()) do + handle_edge(edge) + end + + for neighbour, multiedge in pairs(multiedge) do + + if #collapsed_edges[multiedge] <= 1 then + collapsed_edges[multiedge] = nil + else + for _,subedge in ipairs(collapsed_edges[multiedge]) do + graph:deleteEdge(subedge) + end + + multiedge:addNode(node) + multiedge:addNode(neighbour) + + graph:addEdge(multiedge) + end + end + end + + graph[algorithm].collapsed_edges = collapsed_edges +end + + +--- Expand multiedges that were previously collapsed +-- +-- @param algorithm An algorithm object + +function Simplifiers:expandMultiedgesOldModel(algorithm) + local graph = algorithm.graph + for multiedge, subedges in pairs(graph[algorithm].collapsed_edges) do + assert(#subedges >= 2) + + graph:deleteEdge(multiedge) + + for _,edge in ipairs(subedges) do + + -- Copy bend points + for _,p in ipairs(multiedge.bend_points) do + edge.bend_points[#edge.bend_points+1] = p:copy() + end + + -- Copy options + for k,v in pairs(multiedge.algorithmically_generated_options) do + edge.algorithmically_generated_options[k] = v + end + + for _,node in ipairs(edge.nodes) do + node:addEdge(edge) + end + + graph:addEdge(edge) + end + end + + graph[algorithm].collapsed_edges = nil +end + + + + + +-- Done + +return Simplifiers \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua new file mode 100644 index 00000000000..11466c04961 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua @@ -0,0 +1,61 @@ +-- Copyright 2011 by Jannis Pohlmann +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Stack.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +--- A Stack is a very simple wrapper around an array +-- +-- + +local Stack = {} +Stack.__index = Stack + + +-- Namespace +require("pgf.gd.lib").Stack = Stack + + +--- Create a new stack +function Stack.new() + local stack = {} + setmetatable(stack, Stack) + return stack +end + + +--- Push an element on top of the stack +function Stack:push(data) + self[#self+1] = data +end + + +--- Inspect (but not pop) the top element of a stack +function Stack:peek() + return self[#self] +end + + +--- Pop an element from the top of the stack +function Stack:pop() + return table.remove(self, #self) +end + + +--- Get the height of the stack +function Stack:getSize() + return #self +end + + + +-- done + +return Stack \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua new file mode 100644 index 00000000000..525fcb4f8fc --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua @@ -0,0 +1,110 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Storage.lua,v 1.4 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- A storage is an object that, as the name suggests, allows you to +-- ``store stuff concerning objects.'' Basically, it behaves like +-- table having weak keys, which means that once the objects for which +-- you ``store stuff'' go out of scope, they are also removed from the +-- storage. Also, you can specify that for each object of the storage +-- you store a table. In this case, there is no need to initialize +-- this table for each object; rather, when you write into such a +-- table and it does not yet exist, it is created ``on the fly''. +-- +-- The typical way you use storages is best explained with the +-- following example: Suppose you want to write a depth-first search +-- algorithm for a graph. This algorithm might wish to mark all nodes +-- it has visisted. It could just say |v.marked = true|, but this might +-- clash with someone else also using the |marked| key. The solution is +-- to create a |marked| storage. The algorithm can first say +--\begin{codeexample}[code only, tikz syntax=false] +--local marked = Storage.new() +--\end{codeexample} +-- and then say +--\begin{codeexample}[code only, tikz syntax=false] +--marked[v] = true +--\end{codeexample} +-- to mark its objects. The |marked| storage object does not need to +-- be created locally inside a function, you can declare it as a local +-- variable of the whole file; nevertheless, the entries for vertices +-- no longer in use get removed automatically. You can also make it a +-- member variable of the algorithm class, which allows you make the +-- information about which objects are marked globally +-- accessible. +-- +-- Now suppose the algorithm would like to store even more stuff in +-- the storage. For this, we might use a table and can use the fact +-- that a storage will automatically create a table when necessary: +--\begin{codeexample}[code only, tikz syntax=false] +--local info = Storage.newTableStorage() +-- +--info[v].marked = true -- the "info[v]" table is +-- -- created automatically here +-- +--info[v].foo = "bar" +--\end{codeexample} +-- Again, once |v| goes out of scope, both it and the info table will +-- removed. + +local Storage = {} + +-- Namespace +require("pgf.gd.lib").Storage = Storage + + +-- The simple metatable + +local SimpleStorageMetaTable = { __mode = "k" } + +-- The adcanved metatable for table storages: + +local TableStorageMetaTable = { + __mode = "k", + __index = + function(t, k) + local new = {} + rawset(t, k, new) + return new + end +} + + +--- +-- Create a new storage object. +-- +-- @return A new |Storage| instance. + +function Storage.new() + return setmetatable({}, SimpleStorageMetaTable) +end + + +--- +-- Create a new storage object which will install a table for every +-- entry automatilly. +-- +-- @return A new |Storage| instance. + +function Storage.newTableStorage() + return setmetatable({}, TableStorageMetaTable) +end + + + + + + + +-- Done + +return Storage \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua new file mode 100644 index 00000000000..88ffd6446a4 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua @@ -0,0 +1,104 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/lib/Transform.lua,v 1.1 2012/11/27 17:24:26 tantau Exp $ + + +--- +-- The |Transform| table provides a set of static methods for +-- creating and handling canvas transformation matrices. Such a matrix +-- is actually just an array of six numbers. The idea is that +-- ``applying'' an array { a, b, c, d, e, f } a vector $(x,y)$ will +-- yield the new vector $(ax+by+e,cx+dy+f)$. For details on how such +-- matrices work, see Section~\ref{section-transform-cm} +-- +local Transform = {} + + +-- Namespace + +require("pgf.gd.model").Transform = Transform + + +--- Creates a new transformation array. +-- +-- @param a First component +-- @param b Second component +-- @param c Third component +-- @param d Fourth component +-- @param x The x shift +-- @param y The y shift +-- +-- @return A transformation object. +-- +function Transform.new(a,b,c,d,x,y) + return { a, b, c, d, x, y } +end + + +--- Creates a new transformation object that represents a shift. +-- +-- @param x An x-shift +-- @param y A y-shift +-- +-- @return A transformation object +-- +function Transform.new_shift(x,y) + return { 1, 0, 0, 1, x, y } +end + + +--- Creates a new transformation object that represents a rotation. +-- +-- @param angle An angle +-- +-- @return A transformation object +-- +function Transform.new_rotation(angle) + local c = math.cos(angle) + local s = math.sin(angle) + return { c, -s, s, c, 0, 0 } +end + + +--- Creates a new transformation object that represents a scaling. +-- +-- @param x The horizontal scaling +-- @param y The vertical scaling (if missing, the horizontal scaling is used) +-- +-- @return A transformation object +-- +function Transform.new_scaling(x_scale, y_scale) + return { x_scale, 0, 0, y_scale or x_scale, 0, 0 } +end + + + + +--- +-- Concatenate two transformation matrices, returning the new one. +-- +-- @param a The first transformation +-- @param b The second transformation +-- +-- @return The transformation representing first applying |b| and then +-- applying |a|. +-- +function Transform.concat(a,b) + local a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6 = + a[1], a[2], a[3], a[4], a[5], a[6], b[1], b[2], b[3], b[4], b[5], b[6] + return { a1*b1 + a2*b3, a1*b2 + a2*b4, + a3*b1 + a4*b3, a3*b2 + a4*b4, + a1*b5 + a2*b6 + a5, a3*b5 + a4*b6 + a6 } +end + + +-- Done + +return Transform \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua new file mode 100644 index 00000000000..badde1bbd58 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model.lua,v 1.1 2012/11/27 17:24:24 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.model = {} + + +-- Done + +return pgf.gd.model \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua new file mode 100644 index 00000000000..ff08573cbbd --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua @@ -0,0 +1,592 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Arc.lua,v 1.6 2013/12/20 14:44:46 tantau Exp $ + + +--- +-- An arc is a light-weight object representing an arc from a vertex +-- in a graph to another vertex. You may not create an |Arc| by +-- yourself, which is why there is no |new| method, arc creation is +-- done by the Digraph class. +-- +-- Every arc belongs to exactly one graph. If you want the same arc in +-- another graph, you need to newly connect two vertices in the other graph. +-- +-- You may read the |head| and |tail| fields, but you may not write +-- them. In order to store data for an arc, use |Storage| objects. +-- +-- Between any two vertices of a graph there can be only one arc, so +-- all digraphs are always simple graphs. However, in the +-- specification of a graph (the syntactic digraph), there might +-- be multiple edges between two vertices. This means, in particular, +-- that an arc has no |options| field. Rather, it has several +-- |optionsXxxx| functions, that will search for options in all of the +-- synactic edges that ``belong'' to an edge. +-- +-- Similarly, even though an arc has a |path| field, setting this +-- field does not immediately set the paths of the syntactic +-- edges. Indeed, you will normally want to setup and modify the +-- |path| field of an arc during your algorithm and only at the very +-- end, ``write it back'' to the multiple syntactic edges underlying +-- the graph. For this purpose, the method |sync| is used, which is +-- called automatically for the |ugraph| and |digraph| of a scope as +-- well as for spanning trees. +-- +-- The bottom line concerning the |path| field is the following: If +-- you just want a straight line along an arc, just leave the field as +-- it is (namely, |nil|). If you want to have all edges along a path +-- to follow a certain path, set the |path| field of the arc to the +-- path you desire (typically, using the |setPolylinePath| or a +-- similar method). This will cause all syntactic edges underlying the +-- arc to be set to the specified path. In the event that you want to +-- set different paths for the edges underlying a single arc +-- differently, set the |path| fields of these edges and set the +-- |path| field of the arc to |nil|. This will disable the syncing for +-- the arc and will cause the edge |paths| to remain untouched. +-- +-- @field tail The tail vertex of the arc. +-- @field head The head vertex of the arc. May be the same as the tail +-- in case of a loop. +-- @field path If non-nil, the path of the arc. See the description +-- above. +-- @field syntactic_edges This field is an array containing syntactic +-- edges (``real'' edges in the syntactic digraph) that underly this +-- arc. +-- +local Arc = {} +Arc.__index = Arc + + +-- Namespace + +require("pgf.gd.model").Arc = Arc + + +-- Imports + +local Path = require 'pgf.gd.model.Path' +local lib = require 'pgf.gd.lib' + + +--- +-- Get an array of options of the syntactic edges corresponding to an arc. +-- +-- An arc in a digraph is typically (but not always) present because +-- there are one or more edges in the syntactic digraph between the +-- tail and the head of the arc or between the head and the tail. +-- +-- Since for every arc there can be several edges present in the +-- syntactic digraph, an option like |length| may have +-- been given multiple times for the edges corresponding to the arc. +-- +-- If your algorithm gets confused by multiple edges, try saying +-- |a:options(your_option)|. This will always give the ``most +-- sensible'' choice of the option if there are multiple edges +-- corresponding to the same arc. +-- +-- @param option A string option like |"length"|. +-- +-- @return A table with the following contents: +-- \begin{enumerate} +-- \item It is an array of all values the option has for edges +-- corresponding to |self| in the syntactic digraph. Suppose, for +-- instance, you write the following: +--\begin{codeexample}[code only] +--graph { +-- tail -- [length=1] head, % multi edge 1 +-- tail -- [length=3] head, % mulit edge 2 +-- head -- [length=8] tail, % multi edge 3 +-- tail -- head, % multi edge 4 +-- head -- [length=7] tail, % multi edge 5 +-- tail -- [length=2] head, % multi edge 6 +--} +--\end{codeexample} +-- Suppose, furthermore, that |length| has been setup as an edge +-- option. Now suppose that |a| is the arc from the vertex |tail| to +-- the vertex |head|. Calling |a:optionsArray('length')| will +-- yield the array part |{1,3,2,8,7}|. The reason for the ordering is +-- as follows: First come all values |length| had for syntactic edges +-- going from |self.tail| to |self.head| in the order they appear in the graph +-- description. Then come all values the options has for syntactic +-- edges going from |self.head| to |self.tail|. The reason for this +-- slightly strange behaviour is that many algorithms do not really +-- care whether someone writes |a --[length=1] b| or +-- |b --[length=1] a|; in both cases they would ``just'' like to know +-- that the length is~|1|. +-- +-- \item There is field called |aligned|, which is an array storing +-- the actual syntactic edge objects whose values can be found in the +-- array part of the returned table. However, |aligned| contains only +-- the syntactic edges pointing ``in the same direction'' as the arc, +-- that is, the tail and head of the syntactic edge are the same as +-- those of the arc. In the above example, this array would contain +-- the edges with the comment numbers |1|, |2|, and |6|. +-- +-- Using the length of this array and the fact that the ``aligned'' +-- values come first in the table, you can easily iterate over the +-- |option|'s values of only those edges that are aligned with the arc: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local a = g:arc(tail.head) -- some arc +--local opt = a:optionsArray('length') +--local sum = 0 +--for i=1,#opt.aligned do +-- sum = sum + opt[i] +--end +--\end{codeexample} +-- +--\item There is a field called |anti_aligned|, which is an array +-- containing exactly the edges in the array part of the table not +-- aligned with the arc. The numbering start at |1| as usual, so the +-- $i$th entry of this table corresponds to the entry at position $i + +-- \verb!#opt.aligned!$ of the table. +-- +--\end{enumerate} +-- +function Arc:optionsArray(option) + + local cache = self.option_cache + local t = cache[option] + if t then + return t + end + + -- Accumulate the edges for which the option is set: + local tail = self.tail + local head = self.head + local s_graph = self.syntactic_digraph + + local arc = s_graph:arc(tail, head) + local aligned = {} + if arc then + for _,m in ipairs(arc.syntactic_edges) do + if m.options[option] ~= nil then + aligned[#aligned + 1] = m + end + end + table.sort(aligned, function (a,b) return a.event.index < b.event.index end) + end + + local arc = head ~= tail and s_graph:arc(head, tail) + local anti_aligned = {} + if arc then + for _,m in ipairs(arc.syntactic_edges) do + if m.options[option] ~= nil then + anti_aligned[#anti_aligned + 1] = m + end + end + table.sort(anti_aligned, function (a,b) return a.event.index < b.event.index end) + end + + -- Now merge them together + local t = { aligned = aligned, anti_aligned = anti_aligned } + for i=1,#aligned do + t[i] = aligned[i].options[option] + end + for i=1,#anti_aligned do + t[#t+1] = anti_aligned[i].options[option] + end + cache[option] = t + + return t +end + + + +--- +-- Returns the first option, that is, the first entry of +-- |Arc:optionsArray(option)|. However, if the |only_aligned| +-- parameter is set to true and there is no option with any aligned +-- synactic edge, |nil| is returned. +-- +-- @param option An option +-- @param only_aligned If true, only aligned syntactic edges will be +-- considered. +-- @return The first entry of the |optionsArray| +function Arc:options(option, only_aligned) + if only_aligned then + local opt = self:optionsArray(option) + if #opt.aligned > 0 then + return opt[1] + end + else + return self:optionsArray(option)[1] + end +end + + + + +--- +-- Get an accumulated value of an option of the syntactic edges +-- corresponding to an arc. +-- +-- @param option The option of interest +-- @param accumulator A function taking two values. When there are +-- more than one syntactic edges corresponding to |self| for which the +-- |option| is set, this function will be called repeatedly for the +-- different values. The first time it will be called for the first +-- two values. Next, it will be called for the result of this call and +-- the third value, and so on. +-- @param only_aligned A boolean. If true, only the aligned syntactic +-- edges will be considered. +-- +-- @return If the option is not set for any (aligned) syntactic edges +-- corresponding to |self|, |nil| is returned. If there is exectly one +-- edge, the value of this edge is returned. Otherwise, the result of +-- repeatedly applying the |accumulator| function as described +-- above. +-- +-- The result is cached, repeated calls will not invoke the +-- |accumulator| function again. +-- +-- @usage Here is typical usage: +--\begin{codeexample}[code only, tikz syntax=false] +--local total_length = a:optionsAccumulated('length', function (a,b) return a+b end) or 0 +--\end{codeexample} +-- +function Arc:optionsAccumulated(option, accumulator, only_aligned) + local opt = self:options(option) + if only_aligned then + local aligned = opt.aligned + local v = aligned[accumulator] + if v == nil then + v = opt[1] + for i=2,#aligned do + v = accumulator(v, opt[i]) + end + align[accumulator] = v + end + return v + else + local v = opt[accumulator] + if v == nil then + v = opt[1] + for i=2,#opt do + v = accumulator(v, opt[i]) + end + opt[accumulator] = v + end + return v + end +end + + + +--- +-- Compute the syntactic head and tail of an arc. For this, we have a +-- look at the syntactic digraph underlying the arc. If there is at +-- least once syntactic edge going from the arc's tail to the arc's +-- head, the arc's tail and head are returned. Otherweise, we test +-- whether there is a syntactic edge in the other direction and, if +-- so, return head and tail in reverse order. Finally, if there is no +-- syntactic edge at all corresponding to the arc in either direction, +-- |nil| is returned. +-- +-- @return The syntactic tail +-- @return The syntactic head + +function Arc:syntacticTailAndHead () + local s_graph = self.syntactic_digraph + local tail = self.tail + local head = self.head + if s_graph:arc(tail, head) then + return tail, head + elseif s_graph:arc(head, tail) then + return head, tail + end +end + + +--- +-- Compute the point cloud. +-- +-- @return This method will return the ``point cloud'' of an arc, +-- which is an array of all points that must be rotated and shifted +-- along with the endpoints of an edge. +-- +function Arc:pointCloud () + if self.cached_point_cloud then + return self.cached_point_cloud -- cached + end + local cloud = {} + local a = self.syntactic_digraph:arc(self.tail,self.head) + if a then + for _,e in ipairs(a.syntactic_edges) do + for _,p in ipairs(e.path) do + if type(p) == "table" then + cloud[#cloud + 1] = p + end + end + end + end + self.cached_point_cloud = cloud + return cloud +end + + + +--- +-- Compute an event index for the arc. +-- +-- @return The lowest event index of any edge involved +-- in the arc (or nil, if there is no syntactic edge). +-- +function Arc:eventIndex () + if self.cached_event_index then + return self.cached_event_index + end + local head = self.head + local tail = self.tail + local e = math.huge + local a = self.syntactic_digraph:arc(tail,head) + if a then + for _,m in ipairs(a.syntactic_edges) do + e = math.min(e, m.event.index) + end + end + local a = head ~= tail and self.syntactic_digraph:arc(head,tail) + if a then + for _,m in ipairs(a.syntactic_edges) do + e = math.min(e, m.event.index) + end + end + self.cached_event_index = e + return e +end + + + + +--- +-- The span collector +-- +-- This method returns the top (that is, smallest) priority of any +-- edge involved in the arc. +-- +-- The priority of an edge is computed as follows: +-- +-- \begin{enumerate} +-- \item If the option |"span priority"| is set, this number +-- will be used. +-- +-- \item If the edge has the same head as the arc, we lookup the key\\ +-- |"span priority " .. edge.direction|. If set, we use +-- this value. +-- +-- \item If the edge has a different head from the arc (the arc is +-- ``reversed'' with respect to the syntactic edge), we lookup the key +-- |"span priority reversed " .. edge.direction|. If set, +-- we use this value. +-- +-- \item Otherwise, we use priority 5. +-- \end{enumerate} +-- +-- @return The priority of the arc, as described above. +-- +function Arc:spanPriority() + if self.cached_span_priority then + return self.cached_span_priority + end + + local head = self.head + local tail = self.tail + local min + local g = self.syntactic_digraph + + local a = g:arc(tail,head) + if a then + for _,m in ipairs(a.syntactic_edges) do + local p = + m.options["span priority"] or + lib.lookup_option("span priority " .. m.direction, m, g) + + min = math.min(p or 5, min or math.huge) + end + end + + local a = head ~= tail and g:arc(head,tail) + if a then + for _,m in ipairs(a.syntactic_edges) do + local p = + m.options["span priority"] or + lib.lookup_option("span priority reversed " .. m.direction, m, g) + + min = math.min(p or 5, min or math.huge) + end + end + + self.cached_span_priority = min or 5 + + return min or 5 +end + + + + + + +--- +-- Sync an |Arc| with its syntactic edges. This causes the following: +-- If the |path| field of the arc is |nil|, nothing +-- happens. Otherwise, a copy of the |path| is created. However, for +-- every path element that is a function, this function is invoked +-- with the syntactic edge as its parameter. The result of this call +-- should now be a |Coordinate|, which will replace the function in +-- the |Path|. +-- +-- You use this method like this: +--\begin{codeexample}[code only, tikz syntax=false] +--... +--local arc = g:connect(s,t) +--arc:setPolylinePath { Coordinate.new(x,y), Coordinate.new(x1,y1) } +--... +--arc:sync() +--\end{codeexample} +-- +-- Note that this function will automatically be called for all arcs +-- of the |ugraph|, the |digraph|, and the |spanning_tree| of an +-- algorithm by the rendering pipeline. +-- +function Arc:sync() + if self.path then + local path = self.path + local head = self.head + local tail = self.tail + local a = self.syntactic_digraph:arc(tail,head) + if a and #a.syntactic_edges>0 then + for _,e in ipairs(a.syntactic_edges) do + local clone = path:clone() + for i=1,#clone do + local p = clone[i] + if type(p) == "function" then + clone[i] = p(e) + if type(clone[i]) == "table" then + clone[i] = clone[i]:clone() + end + end + end + e.path = clone + end + end + local a = head ~= tail and self.syntactic_digraph:arc(head,tail) + if a and #a.syntactic_edges>0 then + for _,e in ipairs(a.syntactic_edges) do + local clone = path:reversed() + for i=1,#clone do + local p = clone[i] + if type(p) == "function" then + clone[i] = p(e) + if type(clone[i]) == "table" then + clone[i] = clone[i]:clone() + end + end + end + e.path = clone + end + end + end +end + + +--- +-- This method returns a ``coordinate factory'' that can be used as +-- the coordinate of a |moveto| at the beginning of a path starting at +-- the |tail| of the arc. Suppose you want to create a path starting +-- at the tail vertex, going to the coordinate $(10,10)$ and ending at +-- the head vertex. The trouble is that when you create the path +-- corresponding to this route, you typically do not know where the +-- tail vertex is going to be. Even if that \emph{has} already been +-- settled, you will still have the problem that different edges +-- underlying the arc may wish to start their paths at different +-- anchors inside the tail vertex. In such cases, you use this +-- method to get a function that will, later on, compute the correct +-- position of the anchor as needed. +-- +-- Here is the code you would use to create the abovementioned path: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local a = g:connect(tail,head) +--... +--arc.path = Path.new() +--arc.path:appendMoveto(arc:tailAnchorForArcPath()) +--arc.path:appendLineto(10, 10) +--arc.path:appendLineto(arc:headAnchorForArcPath()) +--\end{codeexample} +-- +-- Normally, however, you will not write code as detailed as the above +-- and you would just write instead of the last three lines: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--arc:setPolylinePath { Coordinate.new (10, 10) } +--\end{codeexample} + +function Arc:tailAnchorForArcPath() + return function (edge) + local a = edge.options['tail anchor'] + if a == "" then + a = "center" + end + return self.tail:anchor(a) + self.tail.pos + end +end + +--- +-- See |Arc:tailAnchorForArcPath|. + +function Arc:headAnchorForArcPath() + return function (edge) + local a = edge.options['head anchor'] + if a == "" then + a = "center" + end + return self.head:anchor(a) + self.head.pos + end +end + + + +--- +-- Setup the |path| field of an arc in such a way that it corresponds +-- to a sequence of straight line segments starting at the tail's +-- anchor and ending at the head's anchor. +-- +-- @param coordinates An array of |Coordinates| through which the line +-- will go through. + +function Arc:setPolylinePath(coordinates) + local p = Path.new () + + p:appendMoveto(self:tailAnchorForArcPath()) + + for _,c in ipairs(coordinates) do + p:appendLineto(c) + end + + p:appendLineto(self:headAnchorForArcPath()) + + self.path = p +end + + + + +-- Returns a string representation of an arc. This is mainly for debugging +-- +-- @return The Arc as string. +-- +function Arc:__tostring() + return tostring(self.tail) .. "->" .. tostring(self.head) +end + + +-- Done + +return Arc diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua new file mode 100644 index 00000000000..a460e83505d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua @@ -0,0 +1,208 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Collection.lua,v 1.2 2013/02/08 17:14:05 tantau Exp $ + + +--- +-- A collection is essentially a subgraph of a graph, that is, a +-- ``collection'' of some nodes and some edges of the graph. The name +-- ``collection'' was chosen over ``subgraph'' since the latter are +-- often thought of as parts of a graph that are rendered in a special +-- way (such as being surrounded by a rectangle), while collections +-- are used to model such diverse things as hyperedges, sets of +-- vertices that should be on the same level in a layered algorithm, +-- or, indeed, subgraphs that are rendered in a special way. +-- +-- Collections are grouped into ``kinds.'' All collections of a given +-- kind can be accessed by algorithms through an array whose elements +-- are the collections. On the displya layer, for each kind a separate +-- key is available to indicate that a node or an edge belongs to a +-- collection. +-- +-- Collections serve two purposes: First, they can be seen as ``hints'' +-- to graph drawing algorithms that certain nodes and/or edges ``belong +-- together''. For instance, collections of kind |same layer| are used +-- by the Sugiyama algorithm to group together nodes that should appear +-- at the same height of the output. Second, since collections are also +-- passed back to the display layer in a postprocessing step, they can be +-- used to render complicated concepts such as hyperedges (which are +-- just collections of nodes, after all) or subgraphs. +-- +-- @field kind The ``kind'' of the collection. +-- +-- @field vertices A lookup table of vertices (that is, both an array +-- with the vertices in the order in which they appear as well as a +-- table such that |vertices[vertex] == true| whenever |vertex| is +-- present in the table. +-- +-- @field edges A lookup table of edges (not arcs!). +-- +-- @field options An options table. This is the table of options that +-- was in force when the collection was created. +-- +-- @field child_collections An array of all collections that are +-- direct children of this collection (that is, +-- they were defined while the current collection was the most +-- recently defined collection on the options stack). However, you +-- should use the methods |children|, |descendants|, and so to access +-- this field. +-- +-- @field parent_collection The parent collection of the current +-- colleciton. This field may be |nil| in case a collection has no parent. +-- +-- @field event An |Event| object that was create for this +-- collection. Its |kind| will be |"collection"| while its |parameter| +-- will be the collection kind. + +local Collection = {} +Collection.__index = Collection + + +-- Namespace + +require("pgf.gd.model").Collection = Collection + + +-- Imports +local Storage = require "pgf.gd.lib.Storage" + + + +--- +-- Creates a new collection. You should not call this function +-- directly, it is called by the interface classes. +-- +-- @param t A table of initial values. The field |t.kind| must be a +-- nonempty string. +-- +-- @return The new collection +-- +function Collection.new(t) + assert (type(t.kind) == "string" and t.kind ~= "", "collection kind not set") + + return setmetatable( + { + vertices = t.vertices or {}, + edges = t.edges or {}, + options = t.options or {}, + generated_options = t.generated_options or {}, + kind = t.kind, + event = t.event, + child_collections = t.child_collections or {}, + }, Collection) +end + + + + +-- +-- An internal function for registering a collection as child of +-- another collection. The collection |self| will be made a child +-- collection of |parent|. +-- +-- @param parent A collection. + +function Collection:registerAsChildOf(parent) + self.parent = parent + if parent then + assert (getmetatable(parent) == Collection, "parent must be a collection") + parent.child_collections[#parent.child_collections+1] = self + end +end + + + +--- +-- A collection can have any number of \emph{child collections}, which +-- are collections nested inside the collection. You can access the +-- array of these children through this method. You may not modify +-- the array returned by this function. +-- +-- @return The array of children of |self|. +-- +function Collection:children() + return self.child_collections +end + + +--- +-- This method works like the |children| method. However, the tree of +-- collections is, conceptually, contracted by considering only these +-- collections that have the |kind| given as parameter. For instance, +-- if |self| has a child collection of a kind different from |kind|, +-- but this child collection has, in turn, a child collection of kind +-- |kind|, this latter child collection will be included in the array +-- -- but not any of its child collections. +-- +-- @param kind The collection kind to which the tree of collections +-- should be restricted. +-- +-- @return The array of children of |self| in this contracted tree. +-- +function Collection:childrenOfKind(kind) + local function rec (c, a) + for _,d in ipairs(c.child_collections) do + if d.kind == kind then + a[#a + 1] = d + else + rec (d, a) + end + end + return a + end + return rec(self, {}) +end + + +--- +-- The descendants of a collection are its children, plus their +-- children, plus their children, and so on. +-- +-- @return An array of all descendants of |self|. It will be in +-- preorder. + +function Collection:descendants() + local function rec (c, a) + for _,d in ipairs(c.child_collections) do + a[#a + 1] = d + rec (d, a) + end + return a + end + return rec(self, {}) +end + + + +--- +-- The descendants of a collection of the given |kind|. +-- +-- @param kind A colleciton kind. +-- +-- @return An array of all descendants of |self| of the given |kind|. + +function Collection:descendantsOfKind(kind) + local function rec (c, a) + for _,d in ipairs(c.child_collections) do + if d.kind == kind then + a[#a + 1] = d + end + rec (d, a) + end + return a + end + return rec(self, {}) +end + + + +-- Done + +return Collection \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua new file mode 100644 index 00000000000..a3b0a7c20bf --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua @@ -0,0 +1,301 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Coordinate.lua,v 1.3 2013/05/23 20:01:27 tantau Exp $ + + +--- +-- A Coordinate models a position on the drawing canvas. +-- +-- It has an |x| field and a |y| field, which are numbers that will be +-- interpreted as \TeX\ points (1/72.27th of an inch). The $x$-axis goes +-- right and the $y$-axis goes up. +-- +-- @field x +-- @field y + +local Coordinate = {} +Coordinate.__index = Coordinate + + +-- Namespace + +require("pgf.gd.model").Coordinate = Coordinate + + + + +--- Creates a new coordinate. +-- +-- @param x The $x$ value +-- @param y The $y$ value +-- +-- @return A coordinate +-- +function Coordinate.new(x,y) + return setmetatable( {x=x, y=y}, Coordinate) +end + + +--- Creates a new coordinate that is a copy of an existing one. +-- +-- @return A new coordinate at the same location as |self| +-- +function Coordinate:clone() + return setmetatable( { x = self.x, y = self.y }, Coordinate) +end + + + +--- Apply a transformation matrix to a coordinate, +-- see |pgf.gd.lib.Transform| for details. +-- +-- @param t A tansformation + +function Coordinate:apply(t) + local x = self.x + local y = self.y + self.x = t[1]*x + t[2]*y + t[5] + self.y = t[3]*x + t[4]*y + t[6] +end + + +--- Shift a coordinate +-- +-- @param a An $x$ offset +-- @param b A $y$ offset + +function Coordinate:shift(a,b) + self.x = self.x + a + self.y = self.y + b +end + + +--- +-- ``Unshift'' a coordinate (which is the same as shifting by the +-- inversed coordinate; only faster). +-- +-- @param a An $x$ offset +-- @param b A $y$ offset + +function Coordinate:unshift(a,b) + self.x = self.x - a + self.y = self.y - b +end + + +--- +-- Like |shift|, only for coordinate parameters. +-- +-- @param c Another coordinate. The $x$- and $y$-values of |self| are +-- increased by the $x$- and $y$-values of this coordinate. + +function Coordinate:shiftByCoordinate(c) + self.x = self.x + c.x + self.y = self.y + c.y +end + + +--- +-- Like |unshift|, only for coordinate parameters. +-- +-- @param c Another coordinate. + +function Coordinate:unshiftByCoordinate(c) + self.x = self.x - c.x + self.y = self.y - c.y +end + + +--- +-- Moves the coordinate a fraction of |f| along a straight line to |c|. +-- +-- @param c Another coordinate +-- @param f A fraction + +function Coordinate:moveTowards(c,f) + self.x = self.x + f*(c.x-self.x) + self.y = self.y + f*(c.y-self.y) +end + + + +--- Scale a coordinate by a factor +-- +-- @param s A factor. + +function Coordinate:scale(s) + self.x = s*self.x + self.y = s*self.y +end + + + + +--- +-- Add two coordinates, yielding a new coordinate. Note that it will +-- be a lot faster to call shift, whenever this is possible. +-- +-- @param a A coordinate +-- @param b A coordinate + +function Coordinate.__add(a,b) + return setmetatable({ x = a.x + b.x, y = a.y + b.y }, Coordinate) +end + + +--- +-- Subtract two coordinates, yielding a new coordinate. Note that it will +-- be a lot faster to call unshift, whenever this is possible. +-- +-- @param a A coordinate +-- @param b A coordinate + +function Coordinate.__sub(a,b) + return setmetatable({ x = a.x - b.x, y = a.y - b.y }, Coordinate) +end + + +--- +-- The unary minus (mirror the coordinate against the origin). +-- +-- @param a A coordinate + +function Coordinate.__unm(a) + return setmetatable({ x = - a.x, y = - a.y }, Coordinate) +end + + +--- +-- The multiplication operator. Its effect depends on the parameters: +-- If both are coordinates, their dot-product is returned. If exactly +-- one of them is a coordinate and the other is a number, the scalar +-- multiple of this coordinate is returned. +-- +-- @param a A coordinate or a scalar +-- @param b A coordinate or a scalar +-- @return The dot product or scalar product. + +function Coordinate.__mul(a,b) + if getmetatable(a) == Coordinate then + if getmetatable(b) == Coordinate then + return a.x * b.x + a.y * b.y + else + return setmetatable({ x = a.x * b, y = a.y *b }, Coordinate) + end + else + return setmetatable({ x = a * b.x, y = a * b.y }, Coordinate) + end +end + +--- +-- The division operator. Returns the scalar division of a coordinate +-- by a scalar. +-- +-- @param a A coordinate +-- @param b A scalar (not equal to zero). +-- @return The scalar product or a * (1/b). + +function Coordinate.__div(a,b) + return setmetatable({ x = a.x / b, y = a.y / b }, Coordinate) +end + + +--- +-- The norm function. Returns the norm of a coordinate. +-- +-- @param a A coordinate +-- @return The norm of the coordinate + +function Coordinate:norm() + return math.sqrt(self.x * self.x + self.y * self.y) +end + + +--- +-- Normalize a vector: Ensure that it has length 1. If the vector used +-- to be the 0-vector, it gets replaced by (1,0). +-- + +function Coordinate:normalize() + local x, y = self.x, self.y + if x == 0 and y == 0 then + self.x = 1 + else + local norm = math.sqrt(x*x+y*y) + self.x = x / norm + self.y = y / norm + end +end + + +--- +-- Normalized version of a vector: Like |normalize|, only the result is +-- returned in a new vector. +-- +-- @return Normalized version of |self| + +function Coordinate:normalized() + local x, y = self.x, self.y + if x == 0 and y == 0 then + return setmetatable({ x = 1, y = 0 }, Coordinate) + else + local norm = math.sqrt(x*x+y*y) + return setmetatable({ x = x/norm, y = y/norm }, Coordinate) + end +end + + + +--- +-- Compute a bounding box around an array of coordinates +-- +-- @param array An array of coordinates +-- +-- @return |min_x| The minimum $x$ value of the bounding box of the array +-- @return |min_y| The minimum $y$ value +-- @return |max_x| +-- @return |max_y| +-- @return |center_x| The center of the bounding box +-- @return |center_y| + +function Coordinate.boundingBox(array) + if #array > 0 then + local min_x, min_y = math.huge, math.huge + local max_x, max_y = -math.huge, -math.huge + + for i=1,#array do + local c = array[i] + local x = c.x + local y = c.y + if x < min_x then min_x = x end + if y < min_y then min_y = y end + if x > max_x then max_x = x end + if y > max_y then max_y = y end + end + + return min_x, min_y, max_x, max_y, (min_x+max_x) / 2, (min_y+max_y) / 2 + end +end + + + + +-- Returns a string representation of an arc. This is mainly for debugging +-- +-- @return The Arc as string. +-- +function Coordinate:__tostring() + return "(" .. self.x .. "pt," .. self.y .. "pt)" +end + + +-- Done + +return Coordinate \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua new file mode 100644 index 00000000000..f0568d13ad9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua @@ -0,0 +1,843 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Digraph.lua,v 1.7 2013/12/20 14:44:47 tantau Exp $ + + + + +--- +-- Each |Digraph| instance models a \emph{directed, simple} +-- graph. ``Directed'' means that all edges ``point'' from a head node +-- to a tail node. ``Simple'' means that between any nodes there can be +-- (at most) one edge. Since these properties are a bit at odds with +-- the normal behaviour of ``nodes'' and ``edges'' in \tikzname, +-- different names are used for them inside the |model| namespace: +-- The class modeling ``edges'' is actually called |Arc| to stress +-- that an arc has a specific ``start'' (the tail) and a specific +-- ``end'' (the head). The class modeling ``nodes'' is actually called +-- |Vertex|, just to stress that this is not a direct model of a +-- \tikzname\ |node|, but can represent a arbitrary vertex of a graph, +-- independently of whether it is an actual |node| in \tikzname. +-- +-- \medskip +-- \noindent\emph{Time Bounds.} +-- Since digraphs are constantly created and modified inside the graph +-- drawing engine, some care was taken to ensure that all operations +-- work as quickly as possible. In particular: +-- \begin{itemize} +-- \item Adding an array of $k$ vertices using the |add| method needs +-- time $O(k)$. +-- \item Adding an arc between two vertices needs time $O(1)$. +-- \item Accessing both the |vertices| and the |arcs| fields takes time +-- $O(1)$, provided only the above operations are used. +-- \end{itemize} +-- Deleting vertices and arcs takes more time: +-- \begin{itemize} +-- \item Deleting the vertices given in an array of $k$ vertices from a +-- graph with $n$ vertices takes time $O(\max\{n,c\})$ where $c$ is the +-- number of arcs between the to-be-deleted nodes and the remaining +-- nodes. Note that this time bound in independent of~$k$. In +-- particular, it will be much faster to delete many vertices by once +-- calling the |remove| function instead of calling it repeatedly. +-- \item Deleting an arc takes time $O(t_o+h_i)$ where $t_o$ is the +-- number of outgoing arcs at the arc's tail and $h_i$ is the number +-- of incoming arcs at the arc's head. After a call to |disconnect|, +-- the next use of the |arcs| field will take time $O(|V| + |E|)$, +-- while subsequent accesses take time $O(1)$ -- till the +-- next use of |disconnect|. This means that once you start deleting +-- arcs using |disconnect|, you should perform as many additional +-- |disconnect|s as possible before accessing |arcs| one more. +-- \end{itemize} +-- +-- \medskip +-- \noindent\emph{Stability.} The |vertices| field and the array +-- returned by |Digraph:incoming| and |Digraph:outgoing| are +-- \emph{stable} in the following sense: The ordering of the elements +-- when you use |ipairs| on the will be the ordering in which the +-- vertices or arcs were added to the graph. Even when you remove a +-- vertex or an arc, the ordering of the remaining elements stays the +-- same. +-- +-- @field vertices This array contains the vertices that are part of +-- the digraph. Internally, this array +-- is an object of type |LookupTable|, but you can mostly treat it as +-- if it were an array. In particular, you can iterate over its +-- elements using |ipairs|, but you may not modify the array; use the +-- |add| and |remove| methods, instead. +-- +-- \begin{codeexample}[code only, tikz syntax=false] +-- local g = Digraph.new {} +-- +-- g:add { v1, v2 } -- Add vertices v1 and v2 +-- g:remove { v2 } -- Get rid of v2. +-- +-- assert (g:contains(v1)) +-- assert (not g:contains(v2)) +-- \end{codeexample} +-- +-- It is important to note that although each digraph stores a +-- |vertices| array, the elements in this array are not exclusive to +-- the digraph: A vertex can be an element of any number of +-- digraphs. Whether or not a vertex is an element of digraph is not +-- stored in the vertex, only in the |vertices| array of the +-- digraph. To test whether a digraph contains a specific node, use the +-- |contains| method, which takes time $O(1)$ to perform the test (this +-- is because, as mentioned earlier, the |vertices| array is actually a +-- |LookupTable| and for each vertex |v| the field |vertices[v]| will +-- be true if, and only if, |v| is an element of the |vertices| array). +-- +-- Do not use |pairs(g.vertices)| because this may cause your graph +-- drawing algorithm to produce different outputs on different runs. +-- +-- A slightly annoying effect of vertices being able to belong to +-- several graphs at the same time is that the set of arcs incident to +-- a vertex is not a property of the vertex, but rather of the +-- graph. In other words, to get a list of all arcs whose tail is a +-- given vertex |v|, you cannot say something like |v.outgoings| or +-- perhaps |v:getOutgoings()|. Rather, you have to say |g:outgoing(v)| +-- to get this list: +--\begin{codeexample}[code only, tikz syntax=false] +--for _,a in ipairs(g:outgoing(v)) do -- g is a Digraph object. +-- pgf.debug ("There is an arc leaving " .. tostring(v) .. +-- " heading to " .. tostring(a.head)) +--end +--\end{codeexample} +-- Naturally, there is also a method |g:incoming()|. +-- +-- To iterate over all arcs of a graph you can say: +--\begin{codeexample}[code only, tikz syntax=false] +--for _,v in ipairs(g.vertices) do +-- for _,a in ipairs(g:outgoing(v)) do +-- ... +-- end +--end +--\end{codeexample} +-- +-- However, it will often be more convenient and, in case the there +-- are far less arcs than vertices, also faster to write +-- +--\begin{codeexample}[code only, tikz syntax=false] +--for _,a in ipairs(g.arcs) do +-- ... +--end +--\end{codeexample} +-- +-- @field arcs For any two vertices |t| and |h| of a graph, there may +-- or may not be +-- an arc from |t| to |h|. If this is the case, there is an |Arc| +-- object that represents this arc. Note that, since |Digraph|s are +-- always simple graphs, there can be at most one such object for every +-- pair of vertices. However, you can store any information you like for +-- an |Arc| through a |Storage|, see the |Storage| class for +-- details. Each |Arc| for an edge of the syntactic digraph stores +-- an array called |syntactic_edges| of all the multiple edges that +-- are present in the user's input. +-- +-- Unlike vertices, the arc objects of a graph are always local to a +-- graph; an |Arc| object can never be part of two digraphs at the same +-- time. For this reason, while for vertices it makes sense to create +-- |Vertex| objects independently of any |Digraph| objects, it is not +-- possible to instantiate an |Arc| directly: only the |Digraph| method +-- |connect| is allowed to create new |Arc| objects and it will return +-- any existing arcs instead of creating new ones, if there is already +-- an arc present between two nodes. +-- +-- The |arcs| field of a digraph contains a |LookupTable| of all arc +-- objects present in the |Digraph|. Although you can access this field +-- normally and use it in |ipairs| to iterate over all arcs of a graph, +-- note that this array is actually ``reconstructed lazily'' whenever +-- an arc is deleted from the graph. What happens is the following: As +-- long as you just add arcs to a graph, the |arcs| array gets updated +-- normally. However, when you remove an arc from a graph, the arc does +-- not get removed from the |arcs| array (which would be an expensive +-- operation). Instead, the |arcs| array is invalidated (internally set +-- to |nil|), allowing us to perform a |disconnect| in time +-- $O(1)$. The |arcs| array is then ignored until the next time it is +-- accessed, for instance when a user says |ipairs(g.arcs)|. At this +-- point, the |arcs| array is reconstructed by adding all arcs of all +-- nodes to it. +-- +-- The bottom line of the behaviour of the |arcs| field is that (a) the +-- ordering of the elements may change abruptly whenever you remove an +-- arc from a graph and (b) performing $k$ |disconnect| operations in +-- sequence takes time $O(k)$, provided you do not access the |arcs| +-- field between calls. +-- +-- @field syntactic_digraph is a reference to the syntactic digraph +-- from which this graph stems ultimately. This may be a cyclic +-- reference to the graph itself. +-- @field options If present, it will be a table storing +-- the options set for the syntactic digraph. +-- +local Digraph = {} + +local function recalc_arcs (digraph) + local arcs = {} + local vertices = digraph.vertices + for i=1,#vertices do + local out = vertices[i].outgoings[digraph] + for j=1,#out do + arcs[#arcs + 1] = out[j] + end + end + digraph.arcs = arcs + return arcs +end + +Digraph.__index = + function (t, k) + if k == "arcs" then + return recalc_arcs(t) + else + return rawget(Digraph,k) + end + end + + + +-- Namespace +require("pgf.gd.model").Digraph = Digraph + +-- Imports +local Arc = require "pgf.gd.model.Arc" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Vertex = require "pgf.gd.model.Vertex" + + + + + +--- +-- Graphs are created using the |new| method, which takes a table of +-- |initial| values as input (like most |new| methods in the graph +-- drawing system). It is permissible that this table of initial values +-- has a |vertices| field, in which case this array will be copied. In +-- contrast, an |arcs| field in the table will be ignored -- newly +-- created graphs always have an empty arcs set. This means that +-- writing |Digraph.new(g)| where |g| is a graph creates a new graph +-- whose vertex set is the same as |g|'s, but where there are no edges: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local g = Digraph.new {} +--g:add { v1, v2, v3 } +--g:connect (v1, v2) +-- +--local h = Digraph.new (g) +--assert (h:contains(v1)) +--assert (not h:arc(v1, v2)) +--\end{codeexample} +-- +-- To completely copy a graph, including all arcs, you have to write: +--\begin{codeexample}[code only, tikz syntax=false] +--local h = Digraph.new (g) +--for _,a in ipairs(g.arcs) do h:connect(a.tail, a.head) end +--\end{codeexample} +-- +-- This operation takes time $O(1)$. +-- +-- @param initial A table of initial values. It is permissible that +-- this array contains a |vertices| field. In this +-- case, this field must be an array and its entries +-- must be nodes, which will be inserted. If initial +-- has an |arcs| field, this field will be ignored. +-- The table must contain a field |syntactic_digraph|, +-- which should normally be the syntactic digraph of +-- the graph, but may also be the string |"self"|, in +-- which case it will be set to the newly created +-- (syntactic) digraph. +-- @return A newly-allocated digraph. +-- +function Digraph.new(initial) + local digraph = {} + setmetatable(digraph, Digraph) + + if initial then + for k,v in pairs(initial or {}) do + digraph [k] = v + end + end + + local vertices = digraph.vertices + digraph.vertices = {} + digraph.arcs = {} + + if vertices then + digraph:add(vertices) + end + return digraph +end + + +--- Add vertices to a digraph. +-- +-- This operation takes time $O(|\verb!array!|)$. +-- +-- @param array An array of to-be-added vertices. +-- +function Digraph:add(array) + local vertices = self.vertices + for i=1,#array do + local v = array[i] + if not vertices[v] then + vertices[v] = true + vertices[#vertices + 1] = v + v.incomings[self] = {} + v.outgoings[self] = {} + end + end +end + + +--- Remove vertices from a digraph. +-- +-- This operation removes an array of vertices from a graph. The +-- operation takes time linear in the number of vertices, regardless of +-- how many vertices are to be removed. Thus, it will be (much) faster +-- to delete many vertices by first compiling them in an array and to +-- then delete them using one call to this method. +-- +-- This operation takes time $O(\max\{|\verb!array!|, |\verb!self.vertices!|\})$. +-- +-- @param array The to-be-removed vertices. +-- +function Digraph:remove(array) + local vertices = self.vertices + + -- Mark all to-be-deleted nodes + for i=1,#array do + local v = array[i] + assert(vertices[v], "to-be-deleted node is not in graph") + vertices[v] = false + end + + -- Disconnect them + for i=1,#array do + self:disconnect(array[i]) + end + + LookupTable.remove(self.vertices, array) +end + + + +--- Test, whether a graph contains a given vertex. +-- +-- This operation takes time $O(1)$. +-- +-- @param v The vertex to be tested. +-- +function Digraph:contains(v) + return v and self.vertices[v] == true +end + + + + +--- +-- Returns the arc between two nodes, provided it exists. Otherwise, +-- |nil| is retured. +-- +-- This operation takes time $O(1)$. +-- +-- @param tail The tail vertex +-- @param head The head vertex +-- +-- @return The arc object connecting them +-- +function Digraph:arc(tail, head) + local out = tail.outgoings[self] + if out then + return out[head] + end +end + + + +--- +-- Returns an array containing the outgoing arcs of a vertex. You may +-- only iterate over his array using ipairs, not using pairs. +-- +-- This operation takes time $O(1)$. +-- +-- @param v The vertex +-- +-- @return An array of all outgoing arcs of this vertex (all arcs +-- whose tail is the vertex) +-- +function Digraph:outgoing(v) + return assert(v.outgoings[self], "vertex not in graph") +end + + + +--- +-- Sorts the array of outgoing arcs of a vertex. This allows you to +-- later iterate over the outgoing arcs in a specific order. +-- +-- This operation takes time $O(|\verb!outgoing!| \log |\verb!outgoings!|)$. +-- +-- @param v The vertex +-- @param f A comparison function that is passed to |table.sort| +-- +function Digraph:sortOutgoing(v, f) + table.sort(assert(v.outgoings[self], "vertex not in graph"), f) +end + + +--- +-- Reorders the array of outgoing arcs of a vertex. The parameter array +-- \emph{must} contain the same set of vertices as the outgoing array, +-- but possibly in a different order. +-- +-- This operation takes time $O(|\verb!outgoing!|)$, where |outgoing| +-- is the array of |v|'s outgoing arcs in |self|. +-- +-- @param v The vertex +-- @param vertices An array containing the outgoing vertices in some order. +-- +function Digraph:orderOutgoing(v, vertices) + local outgoing = assert (v.outgoings[self], "vertex not in graph") + assert (#outgoing == #vertices) + + -- Create back hash + local lookup = {} + for i=1,#vertices do + lookup[vertices[i]] = i + end + + -- Compute ordering of the arcs + local reordered = {} + for _,arc in ipairs(outgoing) do + reordered [lookup[arc.head]] = arc + end + + -- Copy back + for i=1,#outgoing do + outgoing[i] = assert(reordered[i], "illegal vertex order") + end +end + + + +--- See |outgoing|. +-- +function Digraph:incoming(v) + return assert(v.incomings[self], "vertex not in graph") +end + + +--- +-- See |sortOutgoing|. +-- +function Digraph:sortIncoming(v, f) + table.sort(assert(v.incomings[self], "vertex not in graph"), f) +end + + +--- +-- See |orderOutgoing|. +-- +function Digraph:orderIncoming(v, vertices) + local incoming = assert (v.incomings[self], "vertex not in graph") + assert (#incoming == #vertices) + + -- Create back hash + local lookup = {} + for i=1,#vertices do + lookup[vertices[i]] = i + end + + -- Compute ordering of the arcs + local reordered = {} + for _,arc in ipairs(incoming) do + reordered [lookup[arc.head]] = arc + end + + -- Copy back + for i=1,#incoming do + incoming[i] = assert(reordered[i], "illegal vertex order") + end +end + + + + + +--- +-- Connects two nodes by an arc and returns the newly created arc +-- object. If they are already connected, the existing arc is returned. +-- +-- This operation takes time $O(1)$. +-- +-- @param s The tail vertex +-- @param t The head vertex (may be identical to |tail| in case of a +-- loop) +-- +-- @return The arc object connecting them (either newly created or +-- already existing) +-- +function Digraph:connect(s, t) + assert (s and t and self.vertices[s] and self.vertices[t], "trying connect nodes not in graph") + + local s_outgoings = s.outgoings[self] + local arc = s_outgoings[t] + + if not arc then + -- Ok, create and insert new arc object + arc = { + tail = s, + head = t, + option_cache = {}, + syntactic_digraph = self.syntactic_digraph, + syntactic_edges = {} + } + setmetatable(arc, Arc) + + -- Insert into outgoings: + s_outgoings [#s_outgoings + 1] = arc + s_outgoings [t] = arc + + local t_incomings = t.incomings[self] + -- Insert into incomings: + t_incomings [#t_incomings + 1] = arc + t_incomings [s] = arc + + -- Insert into arcs field, if it exists: + local arcs = rawget(self, "arcs") + if arcs then + arcs[#arcs + 1] = arc + end + end + + return arc +end + + + + +--- +-- Disconnect either a single vertex |v| from all its neighbors (remove all +-- incoming and outgoing arcs of this vertex) or, in case two nodes +-- are given as parameter, remove the arc between them, if it exsits. +-- +-- This operation takes time $O(|I_v| + |I_t|)$, where $I_x$ is the set +-- of vertices incident to $x$, to remove the single arc between $v$ and +-- $v$. For a single vertex $v$, it takes time $O(\sum_{y: \text{there is some +-- arc between $v$ and $y$ or $y$ and $v$}} |I_y|)$. +-- +-- @param v The single vertex or the tail vertex +-- @param t The head vertex +-- +function Digraph:disconnect(v, t) + if t then + -- Case 2: Remove a single arc. + local s_outgoings = assert(v.outgoings[self], "tail node not in graph") + local t_incomings = assert(t.incomings[self], "head node not in graph") + + if s_outgoings[t] then + -- Remove: + s_outgoings[t] = nil + for i=1,#s_outgoings do + if s_outgoings[i].head == t then + table.remove (s_outgoings, i) + break + end + end + t_incomings[v] = nil + for i=1,#t_incomings do + if t_incomings[i].tail == v then + table.remove (t_incomings, i) + break + end + end + self.arcs = nil -- invalidate arcs field + end + else + -- Case 1: Remove all arcs incident to v: + + -- Step 1: Delete all incomings arcs: + local incomings = assert(v.incomings[self], "node not in graph") + local vertices = self.vertices + + for i=1,#incomings do + local s = incomings[i].tail + if s ~= v and vertices[s] then -- skip self-loop and to-be-deleted nodes + -- Remove this arc from s: + local s_outgoings = s.outgoings[self] + s_outgoings[v] = nil + for i=1,#s_outgoings do + if s_outgoings[i].head == v then + table.remove (s_outgoings, i) + break + end + end + end + end + + -- Step 2: Delete all outgoings arcs: + local outgoings = v.outgoings[self] + for i=1,#outgoings do + local t = outgoings[i].head + if t ~= v and vertices[t] then + local t_incomings = t.incomings[self] + t_incomings[v] = nil + for i=1,#t_incomings do + if t_incomings[i].tail == v then + table.remove (t_incomings, i) + break + end + end + end + end + + if #incomings > 0 or #outgoings > 0 then + self.arcs = nil -- invalidate arcs field + end + + -- Step 3: Reset incomings and outgoings fields + v.incomings[self] = {} + v.outgoings[self] = {} + end +end + + + + +--- +-- An arc is changed so that instead of connecting |self.tail| +-- and |self.head|, it now connects a new |head| and |tail|. The +-- difference to first disconnecting and then reconnecting is that all +-- fields of the arc (other than |head| and |tail|, of course), will +-- be ``moved along.'' Reconnecting an arc in the same way as before has no +-- effect. +-- +-- If there is already an arc at the new position, fields of the +-- to-be-reconnected arc overwrite fields of the original arc. This is +-- especially dangerous with a syntactic digraph, so do not reconnect +-- arcs of the syntactic digraph (which you should not do anyway). +-- +-- The |arc| object may no longer be valid after a reconnect, but the +-- operation returns the new arc object. +-- +-- This operation needs the time of a disconnect (if necessary). +-- +-- @param arc The original arc object +-- @param tail The new tail vertex +-- @param head The new head vertex +-- +-- @return The new arc object connecting them (either newly created or +-- already existing) +-- +function Digraph:reconnect(arc, tail, head) + assert (arc and tail and head, "connect with nil parameters") + + if arc.head == head and arc.tail == tail then + -- Nothing to be done + return arc + else + local new_arc = self:connect(tail, head) + + for k,v in pairs(arc) do + if k ~= "head" and k ~= "tail" then + new_arc[k] = v + end + end + + -- Remove old arc: + self:disconnect(arc.tail, arc.head) + + return new_arc + end +end + + + +--- +-- Collapse a set of vertices into a single vertex +-- +-- Often, algorithms will wish to treat a whole set of vertices ``as a +-- single vertex''. The idea is that a new vertex is then inserted +-- into the graph, and this vertex is connected to all vertices to +-- which any of the original vertices used to be connected. +-- +-- The |collapse| method takes an array of to-be-collapsed vertices as +-- well as a vertex. First, it will store references to the +-- to-be-collapsed vertices inside the vertex. Second, we iterate over +-- all arcs of the to-be-collapsed vertices. If this arc connects a +-- to-be-collapsed vertex with a not-to-be-collapsed vertex, the +-- not-to-be-collapsed vertex is connected to the collapse +-- vertex. Additionally, the arc is stored at the vertex. +-- +-- Note that the collapse vertex will be added to the graph if it is +-- not already an element. The collapsed vertices will not be removed +-- from the graph, so you must remove them yourself, if necessary. +-- +-- A collapse vertex will store the collapsed vertices so that you can +-- call |expand| later on to ``restore'' the vertices and arcs that +-- were saved during a collapse. This storage is \emph{not} local to +-- the graph in which the collapse occured. +-- +-- @param collapse_vertices An array of to-be-collapsed vertices +-- @param collapse_vertex The vertex that represents the collapse. If +-- missing, a vertex will be created automatically and added to the graph. +-- @param vertex_fun This function is called for each to-be-collapsed +-- vertex. The parameters are the collapse vertex and the +-- to-be-collapsed vertex. May be |nil|. +-- @param arc_fun This function is called whenever a new arc is added +-- between |rep| and some other vertex. The arguments are the new arc +-- and the original arc. May be |nil|. +-- +-- @return The new vertex that represents the collapsed vertices. + +function Digraph:collapse(collapse_vertices, collapse_vertex, vertex_fun, arc_fun) + + + -- Create and add node, if necessary. + if not collapse_vertex then + collapse_vertex = Vertex.new {} + end + self:add {collapse_vertex} + + -- Copy the collapse_vertices and create lookup + local cvs = {} + for i=1,#collapse_vertices do + local v = collapse_vertices[i] + cvs[i] = v + cvs[v] = true + end + assert (cvs[collapse_vertex] ~= true, "collapse_vertex is in collapse_vertices") + + -- Connected collapse_vertex appropriately + local collapsed_arcs = {} + + if not arc_fun then + arc_fun = function () end + end + + for _,v in ipairs(cvs) do + if vertex_fun then + vertex_fun (collapse_vertex, v) + end + for _,a in ipairs(v.outgoings[self]) do + if cvs[a.head] ~= true then + arc_fun (self:connect(collapse_vertex, a.head), a) + collapsed_arcs[#collapsed_arcs + 1] = a + end + end + for _,a in ipairs(v.incomings[self]) do + if cvs[a.tail] ~= true then + arc_fun (self:connect(a.tail, collapse_vertex), a) + end + collapsed_arcs[#collapsed_arcs + 1] = a + end + end + + -- Remember the old vertices. + collapse_vertex.collapsed_vertices = cvs + collapse_vertex.collapsed_arcs = collapsed_arcs + + return collapse_vertex +end + + + +--- +-- Expand a previously collapsed vertex. +-- +-- If you have collapsed a set of vertices in a graph using +-- |collapse|, you can expand this set once more using this method. It +-- will add all vertices that were previously removed from the graph +-- and will also reinstall the deleted arcs. The collapse vertex is +-- not removed. +-- +-- @param vertex A to-be-expanded vertex that was previously returned +-- by |collapse|. +-- @param vertex_fun A function that is called once for each +-- reinserted vertex. The parameters are the collapse vertex and the +-- reinstalled vertex. May be |nil|. +-- @param arc_fun A function that is called once for each +-- reinserted arc. The parameter is the arc and the |vertex|. May be |nil|. +-- +function Digraph:expand(vertex, vertex_fun, arc_fun) + local cvs = assert(vertex.collapsed_vertices, "no expand information stored") + + -- Add all vertices: + self:add(cvs) + if vertex_fun then + for _,v in ipairs(cvs) do + vertex_fun(vertex, v) + end + end + + -- Add all arcs: + for _,arc in ipairs(vertex.collapsed_arcs) do + local new_arc = self:connect(arc.tail, arc.head) + + for k,v in pairs(arc) do + if k ~= "head" and k ~= "tail" then + new_arc[k] = v + end + end + + if arc_fun then + arc_fun(new_arc, vertex) + end + end +end + + + + + +--- +-- Invokes the |sync| method for all arcs of the graph. +-- +-- @see Arc:sync() +-- +function Digraph:sync() + for _,a in ipairs(self.arcs) do + a:sync() + end +end + + + +--- +-- Computes a string representation of this graph including all nodes +-- and edges. The syntax of this representation is such that it can be +-- used directly in \tikzname's |graph| syntax. +-- +-- @return |self| as string. +-- +function Digraph:__tostring() + local vstrings = {} + local astrings = {} + for i,v in ipairs(self.vertices) do + vstrings[i] = " " .. tostring(v) .. "[x=" .. math.floor(v.pos.x) .. "pt,y=" .. math.floor(v.pos.y) .. "pt]" + local out_arcs = v.outgoings[self] + if #out_arcs > 0 then + local t = {} + for j,a in ipairs(out_arcs) do + t[j] = tostring(a.head) + end + astrings[#astrings + 1] = " " .. tostring(v) .. " -> { " .. table.concat(t,", ") .. " }" + end + end + return "graph [id=" .. tostring(self.vertices) .. "] {\n {\n" .. + table.concat(vstrings, ",\n") .. "\n }; \n" .. + table.concat(astrings, ";\n") .. "\n}"; +end + + + + +-- Done + +return Digraph \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua new file mode 100644 index 00000000000..a91979d0ad5 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua @@ -0,0 +1,205 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Edge.lua,v 1.6 2013/12/20 14:44:47 tantau Exp $ + + +--- +-- An |Edge| is a ``syntactic'' connection between two +-- vertices that represents a connection present in the syntactic +-- digraph. Unlike an |Arc|, |Edge| objects are not controlled by the +-- |Digraph| class. Also unlike |Arc| objects, there can be several +-- edges betwen the same vertices, namely whenever several such edges +-- are present in the syntactic digraph. +-- +-- In detail, the relationship between arcs and edges is as follows: +-- If there is an |Edge| between two vertices $u$ and $v$ in the +-- syntactic digraph, there will be an |Arc| from $u$ to $v$ and the +-- array |syntactic_edges| of this |Arc| object will contain the +-- |Edge| object. In particular, if there are several edges between +-- the same vertices, all of these edges will be part of the array in +-- a single |Arc| object. +-- +-- Edges, like arcs, are always directed from a |tail| vertex to a +-- |head| vertex; this is true even for undirected vertices. The +-- |tail| vertex will always be the vertex that came first in the +-- syntactic specification of the edge, the |head| vertex is the +-- second one. Whether +-- an edge is directed or not depends on the |direction| of the edge, which +-- may be one of the following: +-- +-- \begin{enumerate} +-- \item |"->"| +-- \item |"--"| +-- \item |"<-"| +-- \item |"<->"| +-- \item |"-!-"| +-- \end{enumerate} +-- +-- +-- @field head The head vertex of this edge. +-- +-- @field tail The tail vertex of this edge. +-- +-- @field event The creation |Event| of this edge. +-- +-- @field options A table of options that contains user-defined options. +-- +-- @field direction One of the directions named above. +-- +-- @field path A |Path| object that describes the path of the +-- edge. The path's coordinates are interpreted \emph{absolutely}. +-- +-- @field generated_options This is an options array that is generated +-- by the algorithm. When the edge is rendered later on, this array +-- will be passed back to the display layer. The syntax is the same as +-- for the |declare_parameter_sequence| function, see +-- |InterfaceToAlgorithms|. + +local Edge = {} +Edge.__index = Edge + + +-- Namespace + +require("pgf.gd.model").Edge = Edge + + +-- Imports + +local Path = require "pgf.gd.model.Path" + + +--- +-- Create a new edge. The |initial| parameter allows you to setup +-- some initial values. +-- +-- @usage +--\begin{codeexample}[code only, tikz syntax=false] +--local v = Edge.new { tail = v1, head = v2 } +--\end{codeexample} +-- +-- @param initial Values to override defaults. -- +-- @return A new edge object. +-- +function Edge.new(values) + local new = {} + for k,v in pairs(values) do + new[k] = v + end + new.generated_options = new.generated_options or {} + if not new.path then + local p = Path.new () + p:appendMoveto(Edge.tailAnchorForEdgePath(new)) + p:appendLineto(Edge.headAnchorForEdgePath(new)) + new.path = p + end + + return setmetatable(new, Edge) +end + + + + +--- +-- This method returns a ``coordinate factory'' that can be used as +-- the coordinate of a |moveto| at the beginning of a path starting at +-- the |tail| of the arc. Suppose you want to create a path starting +-- at the tail vertex, going to the coordinate $(10,10)$ and ending at +-- the head vertex. The trouble is that when you create the path +-- corresponding to this route, you typically do not know where the +-- tail vertex is going to be. In this case, you use this +-- method to get a function that will, later on, compute the correct +-- position of the anchor as needed. +-- +-- Note that you typically do not use this function, but use the +-- corresponding function of the |Arc| class. Use this function only +-- if there are multiple edges between two vertices that need to be +-- routed differently. +-- +-- Here is the code you would use to create the abovementioned path: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local a = g:connect(tail,head) +--local e = a.syntactic_edges[1] +--... +--e.path = Path.new() +--e.path:appendMoveto(e:tailAnchorForEdgePath()) +--e.path:appendLineto(10, 10) +--e.path:appendLineto(e:headAnchorForEdgePath()) +--\end{codeexample} +-- +-- As for the |Arc| class, you can also setup a polyline more easily: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--e:setPolylinePath { Coordinate.new (10, 10) } +--\end{codeexample} + +function Edge:tailAnchorForEdgePath() + return function () + local a = self.options['tail anchor'] + if a == "" then + a = "center" + end + return self.tail:anchor(a) + self.tail.pos + end +end + +--- +-- See |Arc:tailAnchorForArcPath|. + +function Edge:headAnchorForEdgePath() + return function () + local a = self.options['head anchor'] + if a == "" then + a = "center" + end + return self.head:anchor(a) + self.head.pos + end +end + + + +--- +-- Setup the |path| field of an edge in such a way that it corresponds +-- to a sequence of straight line segments starting at the tail's +-- anchor and ending at the head's anchor. +-- +-- @param coordinates An array of |Coordinates| through which the line +-- will go through. + +function Edge:setPolylinePath(coordinates) + local p = Path.new () + + p:appendMoveto(self:tailAnchorForEdgePath()) + + for _,c in ipairs(coordinates) do + p:appendLineto(c) + end + + p:appendLineto(self:headAnchorForEdgePath()) + + self.path = p +end + + + +-- +-- Returns a string representation of an edge. This is mainly for debugging. +-- +-- @return The Edge as a string. +-- +function Edge:__tostring() + return tostring(self.tail) .. self.direction .. tostring(self.head) +end + + +-- Done + +return Edge \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua new file mode 100644 index 00000000000..54a373bf83f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua @@ -0,0 +1,56 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Hyperedge.lua,v 1.2 2013/05/23 20:01:27 tantau Exp $ + + + +--- +-- @section subsection {Hyperedges} +-- +-- @end + + +-- Includes + +local declare = require "pgf.gd.interface.InterfaceToAlgorithms".declare + + +--- + +declare { + key = "hyper", + layer = -10, + + summary = [[" + A \emph{hyperedge} of a graph does not connect just two nodes, but + is any subset of the node set (although a normal edge is also a + hyperedge that happens to contain just two nodes). Internally, a + collection of kind |hyper| is created. Currently, there is + no default renderer for hyper edges. + "]], + documentation = [[" +\begin{codeexample}[code only] +\graph { + % The nodes: + a, b, c, d; + + % The edges: + {[hyper] a,b,c}; + {[hyper] b,c,d}; + {[hyper] a,c}; + {[hyper] d} +}; +\end{codeexample} + "]] +} + +-- Done + +return Hyperedge \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua new file mode 100644 index 00000000000..03a7e7c695c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua @@ -0,0 +1,1220 @@ +-- Copyright 2014 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Path.lua,v 1.2 2013/09/23 20:04:26 tantau Exp $ + + +--- +-- A Path models a path in the plane. +-- +-- Following the PostScript/\textsc{pdf}/\textsc{svg} convention, a +-- path consists of a series of path segments, each of which can be +-- closed or not. Each path segement, in turn, consists of a series of +-- Bézier curvers and straight line segments; see +-- Section~\ref{section-paths} for an introduction to paths in +-- general. +-- +-- A |Path| object is a table whose array part stores +-- |Coordinate| objects, |strings|, and |function|s that +-- describe the path of the edge. The following strings are allowed in +-- this array: +-- +-- \begin{itemize} +-- \item |"moveto"| The line's path should stop at the current +-- position and then start anew at the next coordinate in the array. +-- \item |"lineto"| The line should continue from the current position +-- to the next coordinate in the array. +-- \item |"curveto"| The line should continue form the current +-- position with a Bézier curve that is specified bz the next three +-- |Coordinate| objects (in the usual manner). +-- \item |"closepath"| The line's path should be ``closed'' in the sense +-- that the current subpath that was started with the most recent +-- moveto operation should now form a closed curve. +-- \end{itemize} +-- +-- Instead of a |Coordinate|, a |Path| may also contain a function. In +-- this case, the function, when called, must return the |Coordinate| +-- that is ``meant'' by the position. This allows algorithms to +-- add coordinates to a path that are still not fixed at the moment +-- they are added to the path. + +local Path = {} +Path.__index = Path + + +-- Namespace + +require("pgf.gd.model").Path = Path + + +-- Imports + +local Coordinate = require "pgf.gd.model.Coordinate" +local Bezier = require "pgf.gd.lib.Bezier" + + + + +local function rigid (x) + if type(x) == "function" then + return x() + else + return x + end +end + + + +--- +-- Creates an empty path. +-- +-- @param initial A table containing an array of strings and +-- coordinates that constitute the path. Coordinates may be given as +-- tables or as a pair of numbers. In this case, each pair of numbers +-- is converted into one coordinate. If omitted, a new empty path +-- is created. +-- +-- @return A empty Path +-- +function Path.new(initial) + if initial then + local new = {} + local i = 1 + local count = 0 + while i <= #initial do + local e = initial[i] + if type(e) == "string" then + assert (count == 0, "illformed path") + if e == "moveto" then + count = 1 + elseif e == "lineto" then + count = 1 + elseif e == "closepath" then + count = 0 + elseif e == "curveto" then + count = 3 + else + error ("unknown path command " .. e) + end + new[#new+1] = e + elseif type(e) == "number" then + if count == 0 then + new[#new+1] = "lineto" + else + count = count - 1 + end + new[#new+1] = Coordinate.new(e,initial[i+1]) + i = i + 1 + elseif type(e) == "table" or type(e) == "function" then + if count == 0 then + new[#new+1] = "lineto" + else + count = count - 1 + end + new[#new+1] = e + else + error ("invalid object on path") + end + i = i + 1 + end + return setmetatable(new, Path) + else + return setmetatable({}, Path) + end +end + + +--- +-- Creates a copy of a path. +-- +-- @return A copy of the path + +function Path:clone() + local new = {} + for _,x in ipairs(self) do + if type(x) == "table" then + new[#new+1] = x:clone() + else + new[#new+1] = x + end + end + return setmetatable(new, Path) +end + + + +--- +-- Returns the path in reverse order. +-- +-- @return A copy of the reversed path + +function Path:reversed() + + -- First, build segments + local subpaths = {} + local subpath = {} + + local function closepath () + if subpath.start then + subpaths [#subpaths + 1] = subpath + subpath = {} + end + end + + local prev + local start + + local i = 1 + while i <= #self do + local x = self[i] + if x == "lineto" then + subpath[#subpath+1] = { + action = 'lineto', + from = prev, + to = self[i+1] + } + prev = self[i+1] + i = i + 2 + elseif x == "moveto" then + closepath() + prev = self[i+1] + start = prev + subpath.start = prev + i = i + 2 + elseif x == "closepath" then + subpath [#subpath + 1] = { + action = "closepath", + from = prev, + to = start, + } + prev = nil + start = nil + closepath() + i = i + 1 + elseif x == "curveto" then + local s1, s2, to = self[i+1], self[i+2], self[i+3] + subpath [#subpath + 1] = { + action = "curveto", + from = prev, + to = to, + support_1 = s1, + support_2 = s2, + } + prev = self[i+3] + i = i + 4 + else + error ("illegal path command '" .. x .. "'") + end + end + closepath () + + local new = Path.new () + + for _,subpath in ipairs(subpaths) do + if #subpath == 0 then + -- A subpath that consists only of a moveto: + new:appendMoveto(subpath.start) + else + -- We start with a moveto to the end point: + new:appendMoveto(subpath[#subpath].to) + + -- Now walk backwards: + for i=#subpath,1,-1 do + if subpath[i].action == "lineto" then + new:appendLineto(subpath[i].from) + elseif subpath[i].action == "closepath" then + new:appendLineto(subpath[i].from) + elseif subpath[i].action == "curveto" then + new:appendCurveto(subpath[i].support_2, + subpath[i].support_1, + subpath[i].from) + else + error("illegal path command") + end + end + + -- Append a closepath, if necessary + if subpath[#subpath].action == "closepath" then + new:appendClosepath() + end + end + end + + return new +end + + +--- +-- Transform all points on a path. +-- +-- @param t A transformation, see |pgf.gd.lib.Transform|. It is +-- applied to all |Coordinate| objects on the path. + +function Path:transform(t) + for _,c in ipairs(self) do + if type(c) == "table" then + c:apply(t) + end + end +end + + +--- +-- Shift all points on a path. +-- +-- @param x An $x$-shift +-- @param y A $y$-shift + +function Path:shift(x,y) + for _,c in ipairs(self) do + if type(c) == "table" then + c.x = c.x + x + c.y = c.y + y + end + end +end + + +--- +-- Shift by all points on a path. +-- +-- @param x A coordinate + +function Path:shiftByCoordinate(x) + for _,c in ipairs(self) do + if type(c) == "table" then + c.x = c.x + x.x + c.y = c.y + x.y + end + end +end + + +--- +-- Makes the path empty. +-- + +function Path:clear() + for i=1,#self do + self[i] = nil + end +end + + +--- +-- Appends a |moveto| to the path. +-- +-- @param x A |Coordinate| or |function| or, if the |y| parameter is +-- not |nil|, a number that is the $x$-part of a coordiante . +-- @param y The $y$-part of the coordinate. + +function Path:appendMoveto(x,y) + self[#self + 1] = "moveto" + self[#self + 1] = y and Coordinate.new(x,y) or x +end + + +--- +-- Appends a |lineto| to the path. +-- +-- @param x A |Coordinate| or |function|, if the |y| parameter is not +-- |nil|, a number that is the $x$-part of a coordiante . +-- @param y The $y$-part of the coordinate. + +function Path:appendLineto(x,y) + self[#self + 1] = "lineto" + self[#self + 1] = y and Coordinate.new(x,y) or x +end + + + +--- +-- Appends a |closepath| to the path. + +function Path:appendClosepath() + self[#self + 1] = "closepath" +end + + +--- +-- Appends a |curveto| to the path. There can be either three +-- coordinates (or functions) as parameters (the two support points +-- and the target) or six numbers, where two consecutive numbers form a +-- Coordinate. Which case is meant is detected by the presence of a +-- sixth non-nil parameter. + +function Path:appendCurveto(a,b,c,d,e,f) + self[#self + 1] = "curveto" + if f then + self[#self + 1] = Coordinate.new(a,b) + self[#self + 1] = Coordinate.new(c,d) + self[#self + 1] = Coordinate.new(e,f) + else + self[#self + 1] = a + self[#self + 1] = b + self[#self + 1] = c + end +end + + +--- +-- Makes a path ``rigid,'' meaning that all coordinates that are only +-- given as functions are replaced by the values these functions +-- yield. + +function Path:makeRigid() + for i=1,#self do + self[i] = rigid(self[i]) + end +end + + +--- +-- Returns an array of all coordinates that are present in a +-- path. This means, essentially, that all strings are filtered out. +-- +-- @return An array of all coordinate objects on the path. + +function Path:coordinates() + local cloud = {} + for i=1,#self do + local p = self[i] + if type(p) == "table" then + cloud[#cloud + 1] = p + elseif type(p) == "function" then + cloud[#cloud + 1] = p() + end + end + return cloud +end + + +--- +-- Returns a bounding box of the path. This will not necessarily be +-- the minimal bounding box in case the path contains curves because, +-- then, the support points of the curve are used for the computation +-- rather than the actual boinding box of the path. +-- +-- If the path contains no coordinates, all return values are 0. +-- +-- @return |min_x| The minimum $x$ value of the bounding box of the path +-- @return |min_y| The minimum $y$ value +-- @return |max_x| +-- @return |max_y| +-- @return |center_x| The center of the bounding box +-- @return |center_y| + +function Path:boundingBox() + if #self > 0 then + local min_x, min_y = math.huge, math.huge + local max_x, max_y = -math.huge, -math.huge + + for i=1,#self do + local c = rigid(self[i]) + if type(c) == "table" then + local x = c.x + local y = c.y + if x < min_x then min_x = x end + if y < min_y then min_y = y end + if x > max_x then max_x = x end + if y > max_y then max_y = y end + end + end + + if min_x ~= math.huge then + return min_x, min_y, max_x, max_y, (min_x+max_x) / 2, (min_y+max_y) / 2 + end + end + return 0, 0, 0, 0, 0, 0 +end + + +-- Forwards + +local segmentize, bb, boxes_intersect, intersect_curves + +local eps = 0.0001 + + + +--- +-- Computes all intersections of a path with another path and returns +-- them as an array of coordinates. The intersections will be sorted +-- ``along the path |self|.'' The implementation uses a +-- divide-and-conquer approach that should be reasonably fast in +-- practice. +-- +-- @param path Another path +-- +-- @return Array of all intersections of |path| with |self| in the +-- order they appear on |self|. Each entry of this array is a table +-- with the following fields: +-- \begin{itemize} +-- \item |index| The index of the segment in |self| where +-- the intersection occurs. +-- \item |time| The ``time'' at which a point travelling along the +-- segment from its start point to its end point. +-- \item |point| The point itself. +-- \end{itemize} + +function Path:intersectionsWith(path) + + local p1 = segmentize(self) + local memo1 = prepare_memo(p1) + local p2 = segmentize(path) + local memo2 = prepare_memo(p2) + + local intersections = {} + + local function intersect_segments(i1, i2) + + local s1 = p1[i1] + local s2 = p2[i2] + local r = {} + + if s1.action == 'lineto' and s2.action == 'lineto' then + local a = s2.to.x - s2.from.x + local b = s1.from.x - s1.to.x + local c = s2.from.x - s1.from.x + local d = s2.to.y - s2.from.y + local e = s1.from.y - s1.to.y + local f = s2.from.y - s1.from.y + + local det = a*e - b*d + + if math.abs(det) > eps*eps then + local t, s = (c*d - a*f)/det, (b*f - e*c)/det + + if t >= 0 and t<=1 and s>=0 and s <= 1 then + local p = s1.from:clone() + p:moveTowards(s1.to, t) + return { { time = t, point = p } } + end + end + elseif s1.action == 'lineto' and s2.action == 'curveto' then + intersect_curves (0, 1, + s1.from.x, s1.from.y, + s1.from.x*2/3+s1.to.x*1/3, s1.from.y*2/3+s1.to.y*1/3, + s1.from.x*1/3+s1.to.x*2/3, s1.from.y*1/3+s1.to.y*2/3, + s1.to.x, s1.to.y, + s2.from.x, s2.from.y, + s2.support_1.x, s2.support_1.y, + s2.support_2.x, s2.support_2.y, + s2.to.x, s2.to.y, + r) + elseif s1.action == 'curveto' and s2.action == 'lineto' then + intersect_curves (0, 1, + s1.from.x, s1.from.y, + s1.support_1.x, s1.support_1.y, + s1.support_2.x, s1.support_2.y, + s1.to.x, s1.to.y, + s2.from.x, s2.from.y, + s2.from.x*2/3+s2.to.x*1/3, s2.from.y*2/3+s2.to.y*1/3, + s2.from.x*1/3+s2.to.x*2/3, s2.from.y*1/3+s2.to.y*2/3, + s2.to.x, s2.to.y, + r) + else + intersect_curves (0, 1, + s1.from.x, s1.from.y, + s1.support_1.x, s1.support_1.y, + s1.support_2.x, s1.support_2.y, + s1.to.x, s1.to.y, + s2.from.x, s2.from.y, + s2.support_1.x, s2.support_1.y, + s2.support_2.x, s2.support_2.y, + s2.to.x, s2.to.y, + r) + end + return r + end + + local function intersect (i1, j1, i2, j2) + + local bb1 = bb(i1, j1, memo1) + local bb2 = bb(i2, j2, memo2) + + if boxes_intersect(bb1, bb2) then + -- Ok, need to do something + if i1 == j1 and i2 == j2 then + local intersects = intersect_segments (i1, i2) + for _,t in ipairs(intersects) do + intersections[#intersections+1] = { + time = t.time, + index = p1[i1].path_pos, + point = t.point + } + end + elseif i1 == j1 then + local m2 = math.floor((i2 + j2) / 2) + intersect(i1, j1, i2, m2) + intersect(i1, j1, m2+1, j2) + elseif i2 == j2 then + local m1 = math.floor((i1 + j1) / 2) + intersect(i1, m1, i2, j2) + intersect(m1+1, j1, i2, j2) + else + local m1 = math.floor((i1 + j1) / 2) + local m2 = math.floor((i2 + j2) / 2) + intersect(i1, m1, i2, m2) + intersect(m1+1, j1, i2, m2) + intersect(i1, m1, m2+1, j2) + intersect(m1+1, j1, m2+1, j2) + end + end + end + + -- Run the recursion + intersect(1, #p1, 1, #p2) + + -- Sort + table.sort(intersections, function(a,b) + return a.index < b.index or + a.index == b.index and a.time < b.time + end) + + -- Remove duplicates + local remains = {} + remains[1] = intersections[1] + for i=2,#intersections do + local next = intersections[i] + local prev = remains[#remains] + if math.abs(next.point.x - prev.point.x) + math.abs(next.point.y - prev.point.y) > eps then + remains[#remains+1] = next + end + end + + return remains +end + + +-- Returns true if two bounding boxes intersection + +function boxes_intersect (bb1, bb2) + return (bb1.max_x >= bb2.min_x - eps*eps and + bb1.min_x <= bb2.max_x + eps*eps and + bb1.max_y >= bb2.min_y - eps*eps and + bb1.min_y <= bb2.max_y + eps*eps) +end + + +-- Turns a path into a sequence of segments, each being either a +-- lineto or a curveto from some point to another point. It also sets +-- up a memoization array for the bounding boxes. + +function segmentize (path) + + local prev + local start + local s = {} + + local i = 1 + while i <= #path do + local x = path[i] + + if x == "lineto" then + x = rigid(path[i+1]) + s [#s + 1] = { + path_pos = i, + action = "lineto", + from = prev, + to = x, + bb = { + min_x = math.min(prev.x, x.x), + max_x = math.max(prev.x, x.x), + min_y = math.min(prev.y, x.y), + max_y = math.max(prev.y, x.y), + } + } + prev = x + i = i + 2 + elseif x == "moveto" then + prev = rigid(path[i+1]) + start = prev + i = i + 2 + elseif x == "closepath" then + s [#s + 1] = { + path_pos = i, + action = "lineto", + from = prev, + to = start, + bb = { + min_x = math.min(prev.x, start.x), + max_x = math.max(prev.x, start.x), + min_y = math.min(prev.y, start.y), + max_y = math.max(prev.y, start.y), + } + } + prev = nil + start = nil + i = i + 1 + elseif x == "curveto" then + local s1, s2, to = rigid(path[i+1]), rigid(path[i+2]), rigid(path[i+3]) + s [#s + 1] = { + action = "curveto", + path_pos = i, + from = prev, + to = to, + support_1 = s1, + support_2 = s2, + bb = { + min_x = math.min(prev.x, s1.x, s2.x, to.x), + max_x = math.max(prev.x, s1.x, s2.x, to.x), + min_y = math.min(prev.y, s1.y, s2.y, to.y), + max_y = math.max(prev.y, s1.y, s2.y, to.y), + } + } + prev = path[i+3] + i = i + 4 + else + error ("illegal path command '" .. x .. "'") + end + end + + return s +end + + +function prepare_memo (s) + + local memo = {} + + memo.base = #s + + -- Fill memo table + for i,e in ipairs (s) do + memo[i*#s + i] = e.bb + end + + return memo +end + + +-- This function computes the bounding box of all segments between i +-- and j (inclusively) + +function bb (i, j, memo) + local b = memo[memo.base*i + j] + if not b then + assert (i < j, "memoization table filled incorrectly") + + local mid = math.floor((i+j)/2) + local bb1 = bb (i, mid, memo) + local bb2 = bb (mid+1, j, memo) + b = { + min_x = math.min(bb1.min_x, bb2.min_x), + max_x = math.max(bb1.max_x, bb2.max_x), + min_y = math.min(bb1.min_y, bb2.min_y), + max_y = math.max(bb1.max_y, bb2.max_y) + } + memo[memo.base*i + j] = b + end + + return b +end + + + +-- Intersect two Bezier curves. + +function intersect_curves(t0, t1, + c1_ax, c1_ay, c1_bx, c1_by, + c1_cx, c1_cy, c1_dx, c1_dy, + c2_ax, c2_ay, c2_bx, c2_by, + c2_cx, c2_cy, c2_dx, c2_dy, + intersections) + + -- Only do something, if the bounding boxes intersect: + local c1_min_x = math.min(c1_ax, c1_bx, c1_cx, c1_dx) + local c1_max_x = math.max(c1_ax, c1_bx, c1_cx, c1_dx) + local c1_min_y = math.min(c1_ay, c1_by, c1_cy, c1_dy) + local c1_max_y = math.max(c1_ay, c1_by, c1_cy, c1_dy) + local c2_min_x = math.min(c2_ax, c2_bx, c2_cx, c2_dx) + local c2_max_x = math.max(c2_ax, c2_bx, c2_cx, c2_dx) + local c2_min_y = math.min(c2_ay, c2_by, c2_cy, c2_dy) + local c2_max_y = math.max(c2_ay, c2_by, c2_cy, c2_dy) + + if c1_max_x >= c2_min_x and + c1_min_x <= c2_max_x and + c1_max_y >= c2_min_y and + c1_min_y <= c2_max_y then + + -- Everything "near together"? + if c1_max_x - c1_min_x < eps and c1_max_y - c1_min_y < eps then + + -- Compute intersection of lines c1_a to c1_d and c2_a to c2_d + local a = c2_dx - c2_ax + local b = c1_ax - c1_dx + local c = c2_ax - c1_ax + local d = c2_dy - c2_ay + local e = c1_ay - c1_dy + local f = c2_ay - c1_ay + + local det = a*e - b*d + local t + + t = (c*d - a*f)/det + if t<0 then + t=0 + elseif t>1 then + t=1 + end + + intersections [#intersections + 1] = { + time = t0 + t*(t1-t0), + point = Coordinate.new(c1_ax + t*(c1_dx-c1_ax), c1_ay+t*(c1_dy-c1_ay)) + } + else + -- Cut 'em in half! + local c1_ex, c1_ey = (c1_ax + c1_bx)/2, (c1_ay + c1_by)/2 + local c1_fx, c1_fy = (c1_bx + c1_cx)/2, (c1_by + c1_cy)/2 + local c1_gx, c1_gy = (c1_cx + c1_dx)/2, (c1_cy + c1_dy)/2 + + local c1_hx, c1_hy = (c1_ex + c1_fx)/2, (c1_ey + c1_fy)/2 + local c1_ix, c1_iy = (c1_fx + c1_gx)/2, (c1_fy + c1_gy)/2 + + local c1_jx, c1_jy = (c1_hx + c1_ix)/2, (c1_hy + c1_iy)/2 + + local c2_ex, c2_ey = (c2_ax + c2_bx)/2, (c2_ay + c2_by)/2 + local c2_fx, c2_fy = (c2_bx + c2_cx)/2, (c2_by + c2_cy)/2 + local c2_gx, c2_gy = (c2_cx + c2_dx)/2, (c2_cy + c2_dy)/2 + + local c2_hx, c2_hy = (c2_ex + c2_fx)/2, (c2_ey + c2_fy)/2 + local c2_ix, c2_iy = (c2_fx + c2_gx)/2, (c2_fy + c2_gy)/2 + + local c2_jx, c2_jy = (c2_hx + c2_ix)/2, (c2_hy + c2_iy)/2 + + intersect_curves (t0, (t0+t1)/2, + c1_ax, c1_ay, c1_ex, c1_ey, c1_hx, c1_hy, c1_jx, c1_jy, + c2_ax, c2_ay, c2_ex, c2_ey, c2_hx, c2_hy, c2_jx, c2_jy, + intersections) + intersect_curves (t0, (t0+t1)/2, + c1_ax, c1_ay, c1_ex, c1_ey, c1_hx, c1_hy, c1_jx, c1_jy, + c2_jx, c2_jy, c2_ix, c2_iy, c2_gx, c2_gy, c2_dx, c2_dy, + intersections) + intersect_curves ((t0+t1)/2, t1, + c1_jx, c1_jy, c1_ix, c1_iy, c1_gx, c1_gy, c1_dx, c1_dy, + c2_ax, c2_ay, c2_ex, c2_ey, c2_hx, c2_hy, c2_jx, c2_jy, + intersections) + intersect_curves ((t0+t1)/2, t1, + c1_jx, c1_jy, c1_ix, c1_iy, c1_gx, c1_gy, c1_dx, c1_dy, + c2_jx, c2_jy, c2_ix, c2_iy, c2_gx, c2_gy, c2_dx, c2_dy, + intersections) + end + end +end + + +--- +-- Shorten a path at the beginning. We are given the index of a +-- segment inside the path as well as a point in time along this +-- segment. The path is now shortened so that everything before this +-- segment and everything in the segment before the given time is +-- removed from the path. +-- +-- @param index The index of a path segment. +-- @param time A time along the specified path segment. + +function Path:cutAtBeginning(index, time) + + local cut_path = Path:new () + + -- Ok, first, we need to find the segment *before* the current + -- one. Usually, this will be a moveto or a lineto, but things could + -- be different. + assert (type(self[index-1]) == "table" or type(self[index-1]) == "function", + "segment before intersection does not end with a coordinate") + + local from = rigid(self[index-1]) + local action = self[index] + + -- Now, depending on the type of segment, we do different things: + if action == "lineto" then + + -- Ok, compute point: + local to = rigid(self[index+1]) + + from:moveTowards(to, time) + + -- Ok, this is easy: We start with a fresh moveto ... + cut_path[1] = "moveto" + cut_path[2] = from + + -- ... and copy the rest + for i=index,#self do + cut_path[#cut_path+1] = self[i] + end + elseif action == "curveto" then + + local to = rigid(self[index+3]) + local s1 = rigid(self[index+1]) + local s2 = rigid(self[index+2]) + + -- Now, compute the support vectors and the point at time: + from:moveTowards(s1, time) + s1:moveTowards(s2, time) + s2:moveTowards(to, time) + + from:moveTowards(s1, time) + s1:moveTowards(s2, time) + + from:moveTowards(s1, time) + + -- Ok, this is easy: We start with a fresh moveto ... + cut_path[1] = "moveto" + cut_path[2] = from + cut_path[3] = "curveto" + cut_path[4] = s1 + cut_path[5] = s2 + cut_path[6] = to + + -- ... and copy the rest + for i=index+4,#self do + cut_path[#cut_path+1] = self[i] + end + + elseif action == "closepath" then + -- Let us find the start point: + local found + for i=index,1,-1 do + if self[i] == "moveto" then + -- Bingo: + found = i + break + end + end + + assert(found, "no moveto found in path") + + local to = rigid(self[found+1]) + from:moveTowards(to,time) + + cut_path[1] = "moveto" + cut_path[2] = from + cut_path[3] = "lineto" + cut_path[4] = to + + -- ... and copy the rest + for i=index+1,#self do + cut_path[#cut_path+1] = self[i] + end + else + error ("wrong path operation") + end + + -- Move cut_path back: + for i=1,#cut_path do + self[i] = cut_path[i] + end + for i=#cut_path+1,#self do + self[i] = nil + end +end + + + + +--- +-- Shorten a path at the end. This method works like |cutAtBeginning|, +-- only the path is cut at the end. +-- +-- @param index The index of a path segment. +-- @param time A time along the specified path segment. + +function Path:cutAtEnd(index, time) + + local cut_path = Path:new () + + -- Ok, first, we need to find the segment *before* the current + -- one. Usually, this will be a moveto or a lineto, but things could + -- be different. + assert (type(self[index-1]) == "table" or type(self[index-1]) == "function", + "segment before intersection does not end with a coordinate") + + local from = rigid(self[index-1]) + local action = self[index] + + -- Now, depending on the type of segment, we do different things: + if action == "lineto" then + + -- Ok, compute point: + local to = rigid(self[index+1]) + to:moveTowards(from, 1-time) + + for i=1,index do + cut_path[i] = self[i] + end + cut_path[index+1] = to + + elseif action == "curveto" then + + local s1 = rigid(self[index+1]) + local s2 = rigid(self[index+2]) + local to = rigid(self[index+3]) + + -- Now, compute the support vectors and the point at time: + to:moveTowards(s2, 1-time) + s2:moveTowards(s1, 1-time) + s1:moveTowards(from, 1-time) + + to:moveTowards(s2, 1-time) + s2:moveTowards(s1, 1-time) + + to:moveTowards(s2, 1-time) + + -- ... and copy the rest + for i=1,index do + cut_path[i] = self[i] + end + + cut_path[index+1] = s1 + cut_path[index+2] = s2 + cut_path[index+3] = to + + elseif action == "closepath" then + -- Let us find the start point: + local found + for i=index,1,-1 do + if self[i] == "moveto" then + -- Bingo: + found = i + break + end + end + + assert(found, "no moveto found in path") + + local to = rigid(self[found+1]:clone()) + to:moveTowards(from,1-time) + + for i=1,index-1 do + cut_path[i] = self[i] + end + cut_path[index] = 'lineto' + cut_path[index+1] = to + else + error ("wrong path operation") + end + + -- Move cut_path back: + for i=1,#cut_path do + self[i] = cut_path[i] + end + for i=#cut_path+1,#self do + self[i] = nil + end +end + + + + +--- +-- ``Pads'' the path. The idea is the following: Suppose we stroke the +-- path with a pen whose width is twice the value |padding|. The outer +-- edge of this stroked drawing is now a path by itself. The path will +-- be a bit longer and ``larger.'' The present function tries to +-- compute an approximation to this resulting path. +-- +-- The algorithm used to compute the enlarged part does not necessarily +-- compute the precise new path. It should work correctly for polyline +-- paths, but not for curved paths. +-- +-- @param padding A padding distance. +-- @return The padded path. +-- + +function Path:pad(padding) + + local padded = self:clone() + padded:makeRigid() + + if padding == 0 then + return padded + end + + -- First, decompose the path into subpaths: + local subpaths = {} + local subpath = {} + local start_index = 1 + + local function closepath(end_index) + if #subpath >= 1 then + subpath.start_index = start_index + subpath.end_index = end_index + start_index = end_index + 1 + + local start = 1 + if (subpath[#subpath] - subpath[1]):norm() < 0.01 and subpath[2] then + start = 2 + subpath.skipped = subpath[1] + end + subpath[#subpath + 1] = subpath[start] + subpath[#subpath + 1] = subpath[start+1] + subpaths[#subpaths + 1] = subpath + subpath = {} + end + end + + for i,p in ipairs(padded) do + if p ~= "closepath" then + if type(p) == "table" then + subpath[#subpath + 1] = p + end + else + closepath (i) + end + end + closepath(#padded) + + -- Second, iterate over the subpaths: + for _,subpath in ipairs(subpaths) do + local new_coordinates = {} + local _,_,_,_,c_x,c_y = Coordinate.boundingBox(subpath) + local c = Coordinate.new(c_x,c_y) + + -- Find out the orientation of the path + local count = 0 + for i=1,#subpath-2 do + local d2 = subpath[i+1] - subpath[i] + local d1 = subpath[i+2] - subpath[i+1] + + local diff = math.atan2(d2.y,d2.x) - math.atan2(d1.y,d1.x) + + if diff < -math.pi then + count = count + 1 + elseif diff > math.pi then + count = count - 1 + end + end + + for i=2,#subpath-1 do + local p = subpath[i] + local d1 = subpath[i] - subpath[i-1] + local d2 = subpath[i+1] - subpath[i] + + local orth1 = Coordinate.new(-d1.y, d1.x) + local orth2 = Coordinate.new(-d2.y, d2.x) + + orth1:normalize() + orth2:normalize() + + if count < 0 then + orth1:scale(-1) + orth2:scale(-1) + end + + -- Ok, now we want to compute the intersection of the lines + -- perpendicular to p + padding*orth1 and p + padding*orth2: + + local det = orth1.x * orth2.y - orth1.y * orth2.x + + local c + if math.abs(det) < 0.1 then + c = orth1 + orth2 + c:scale(padding/2) + else + c = Coordinate.new (padding*(orth2.y-orth1.y)/det, padding*(orth1.x-orth2.x)/det) + end + + new_coordinates[i] = c+p + end + + for i=2,#subpath-1 do + local p = subpath[i] + local new_p = new_coordinates[i] + p.x = new_p.x + p.y = new_p.y + end + + if subpath.skipped then + local p = subpath[1] + local new_p = new_coordinates[#subpath-2] + p.x = new_p.x + p.y = new_p.y + end + + -- Now, we need to correct the curveto fields: + for i=subpath.start_index,subpath.end_index do + if self[i] == 'curveto' then + local from = rigid(self[i-1]) + local s1 = rigid(self[i+1]) + local s2 = rigid(self[i+2]) + local to = rigid(self[i+3]) + + local p1x, p1y, _, _, h1x, h1y = + Bezier.atTime(from.x, from.y, s1.x, s1.y, s2.x, s2.y, + to.x, to.y, 1/3) + + local p2x, p2y, _, _, _, _, h2x, h2y = + Bezier.atTime(from.x, from.y, s1.x, s1.y, s2.x, s2.y, + to.x, to.y, 2/3) + + local orth1 = Coordinate.new (p1y - h1y, -(p1x - h1x)) + orth1:normalize() + orth1:scale(-padding) + + local orth2 = Coordinate.new (p2y - h2y, -(p2x - h2x)) + orth2:normalize() + orth2:scale(padding) + + if count < 0 then + orth1:scale(-1) + orth2:scale(-1) + end + + local new_s1, new_s2 = + Bezier.supportsForPointsAtTime(padded[i-1], + Coordinate.new(p1x+orth1.x,p1y+orth1.y), 1/3, + Coordinate.new(p2x+orth2.x,p2y+orth2.y), 2/3, + padded[i+3]) + + padded[i+1] = new_s1 + padded[i+2] = new_s2 + end + end + end + + return padded +end + + + +-- +-- @return The Path as string. +-- +function Path:__tostring() + local r = {} + local i = 1 + while i <= #self do + local p = self[i] + + if p == "lineto" then + r [#r+1] = " -- " .. tostring(rigid(self[i+1])) + i = i + 1 + elseif p == "moveto" then + r [#r+1] = " " .. tostring(rigid(self[i+1]) ) + i = i + 1 + elseif p == "curveto" then + r [#r+1] = " .. controls " .. tostring(rigid(self[i+1])) .. " and " .. + tostring(rigid(self[i+2])) .. " .. " .. tostring(rigid(self[i+3])) + i = i + 3 + elseif p == "closepath" then + r [#r+1] = " -- cycle" + else + error("illegal path command") + end + i = i + 1 + end + return table.concat(r) +end + + + +-- Done + +return Path \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua new file mode 100644 index 00000000000..f18aa43f450 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua @@ -0,0 +1,277 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/Vertex.lua,v 1.6 2013/12/20 14:44:47 tantau Exp $ + + +--- +-- A |Vertex| instance models a node of graphs. Each |Vertex| object can be an +-- element of any number of graphs (whereas an |Arc| object can only be an +-- element of a single graph). +-- +-- When a vertex is added to a digraph |g|, two tables are created in +-- the vertex' storage: An array of incoming arcs (with respect to +-- |g|) and an array of outgoing arcs (again, with respect to +-- |g|). The fields are managed by the |Digraph| class and should not +-- be modified directly. +-- +-- Note that a |Vertex| is an abstraction of \tikzname\ nodes; indeed +-- that objective is to ensure that, in principle, we can use them +-- independently of \TeX. For this reason, you will not find any +-- references to |tex| inside a |Vertex|; this information is only +-- available in the syntactic digraph. +-- +-- One important aspect of vertices are its anchors -- a concept well +-- familiar for users of \tikzname, but since we need to abstract from +-- \tikzname, a separate anchor management is available inside the +-- graph drawing system. It works as follows: +-- +-- First of all, every vertex has a path, which is a (typically +-- closed) line around the vertex. The display system will pass down +-- the vertex' path to the graph drawing system and this path will be +-- stored as a |Path| object in the |path| field of the vertex. This +-- path lives in a special ``local'' coordinate system, that is, all +-- coordinates of this path should actually be considered relative to +-- the vertex' |pos| field. Note that the path is typically, but not +-- alwyas, ``centered'' on the origin. A graph drawing algorithm +-- should arrange the vertices in such a way that the origins in the +-- path coordinate systems are aligned. +-- +-- To illustrate the difference between the origin and the vertex +-- center, conside a tree drawing algorithm in which a node |root| has +-- three children |a|, |b|, and |g|. Now, if we were to simply center +-- these three letters vertically and arrange them in a line, the +-- letters would appear to ``jump up and down'' since the height of +-- the three letters are quite different. A solution is to shift the +-- letters (and, thus, the paths of the vertices) in such a way that +-- in all three letters the baseline of the letters is exactly at the +-- origin. Now, when a graph drawing algorithm aligns these vertices +-- along the origins, the letters will all have the same baseline. +-- +-- Apart from the origin, there may be other positions in the path +-- coordinate system that are of interest -- such as the center of +-- the vertex. As mentioned above, this need not be the origin and +-- although a graph drawing algorithm should align the origins, +-- \emph{edges} between vertices should head toward these vertex +-- centers rather that toward the origins. Other points of interest +-- might be the ``top'' of the node. +-- +-- All points of special interest are called ``anchors''. The |anchor| +-- method allows you to retrieve them. By default, you always have +-- access to the |center| anchor, but other anchors may or may not be +-- available also, see the |anchor| method for details. +-- +-- @field pos A coordinate object that stores the position where the +-- vertex should be placed on the canvas. The main objective of graph drawing +-- algorithms is to update this coordinate. +-- +-- @field name An optional string that is used as a textual representation +-- of the node. +-- +-- @field path The path of the vertex's shape. This is a path along +-- the outer line resulting from stroking the vertex's original +-- shape. For instance, if you have a quadratic shape of size 1cm and +-- you stroke the path with a pen of 2mm thickness, this |path| field +-- would store a path of a square of edge length 12mm. +-- +-- @field anchors A table of anchors (in the TikZ sense). The table is +-- indexed by the anchor names (strings) and the values are +-- |Coordinate|s. Currently, it is only guaranteed that the |center| +-- anchor is present. Note that the |center| anchor need not lie at +-- the origin: A graph drawing system should align nodes relative to +-- the origin of the path's coordinate system. However, lines going to +-- and from the node will head towards the |center| anchor. See +-- Section~\ref{section-gd-anchors} for details. +-- +-- @field options A table of options that contains user-defined options. +-- +-- @field shape A string describing the shape of the node (like |rectangle| +-- or |circle|). Note, however, that this is more ``informative''; the +-- actual information that is used by the graph drawing system for +-- determining the extent of a node, its bounding box, convex hull, +-- and line intersections is the |path| field. +-- +-- @field kind A string describing the kind of the node. For instance, a +-- node of type |"dummy"| does not correspond to any real node in +-- the graph but is used by the graph drawing algorithm. +-- +-- @field event The |Event| when this vertex was created (may be |nil| +-- if the vertex is not part of the syntactic digraph). +-- +local Vertex = {} +Vertex.__index = Vertex + + +-- Namespace + +require("pgf.gd.model").Vertex = Vertex + + +-- Imports + +local Coordinate = require "pgf.gd.model.Coordinate" +local Path = require "pgf.gd.model.Path" +local Storage = require "pgf.gd.lib.Storage" + + +--- +-- Create a new vertex. The |initial| parameter allows you to setup +-- some initial values. +-- +-- @usage +--\begin{codeexample}[code only, tikz syntax=false] +--local v = Vertex.new { name = "hello", pos = Coordinate.new(1,1) } +--\end{codeexample} +-- +-- @param initial Values to override default node settings. The +-- following are permissible: +-- \begin{description} +-- \item[|pos|] Initial position of the node. +-- \item[|name|] The name of the node. It is optional to define this. +-- \item[|path|] A |Path| object representing the vertex's hull. +-- \item[|anchors|] A table of anchors. +-- \item[|options|] An options table for the vertex. +-- \item[|shape|] A string describing the shape. If not given, |"none"| is used. +-- \item[|kind|] A kind like |"node"| or |"dummy"|. If not given, |"dummy"| is used. +-- \end{description} +-- +-- @field incomings A table indexed by |Digraph| objects. For each +-- digraph, the table entry is an array of all vertices from which +-- there is an |Arc| to this vertex. This field is internal and may +-- not only be accessed by the |Digraph| class. +-- @field outgoings Like |incomings|, but for outgoing arcs. +-- +-- @return A newly allocated node. +-- +function Vertex.new(values) + local new = { + incomings = Storage.new(), + outgoings = Storage.new() + } + for k,v in pairs(values) do + new[k] = v + end + new.path = new.path or Path.new { 0, 0 } + new.shape = new.shape or "none" + new.kind = new.kind or "dummy" + new.pos = new.pos or Coordinate.new(0,0) + new.anchors = new.anchors or { center = Coordinate.new(0,0) } + return setmetatable (new, Vertex) +end + + + + +--- +-- Returns a bounding box of a vertex. +-- +-- @return |min_x| The minimum $x$ value of the bounding box of the path +-- @return |min_y| The minimum $y$ value +-- @return |max_x| +-- @return |max_y| +-- @return |center_x| The center of the bounding box +-- @return |center_y| + +function Vertex:boundingBox() + return self.path:boundingBox() +end + + + +local anchor_cache = Storage.new () + +local directions = { + north = function(min_x, min_y, max_x, max_y) + return (min_x+max_x)/2, max_y + end, + south = function(min_x, min_y, max_x, max_y) + return (min_x+max_x)/2, min_y + end, + east = function(min_x, min_y, max_x, max_y) + return max_x, (min_y+max_y)/2 + end, + west = function(min_x, min_y, max_x, max_y) + return min_x, (min_y+max_y)/2 + end, + ["north west"] = function(min_x, min_y, max_x, max_y) + return min_x, max_y + end, + ["north east"] = function(min_x, min_y, max_x, max_y) + return max_x, max_y + end, + ["south west"] = function(min_x, min_y, max_x, max_y) + return min_x, min_y + end, + ["south east"] = function(min_x, min_y, max_x, max_y) + return max_x, min_y + end, +} + +--- +-- Returns an anchor position in a vertex. First, we try to look +-- the anchor up in the vertex's |anchors| table. If it is not found +-- there, we test whether it is one of the direction strings |north|, +-- |south east|, and so on. If so, we consider a line from the center +-- of the node to the position on the bounding box that corresponds to +-- the given direction (so |south east| would be the lower right +-- corner). We intersect this line with the vertex's path and return +-- the result. Finally, if the above fails, we try to consider the +-- anchor as a number and return the intersection of a line starting +-- at the vertex's center with the number as its angle and the path of +-- the vertex. +-- +-- @param anchor An anchor as detailed above +-- @return A coordinate in the vertex's local coordinate system (so +-- add the |pos| field to arrive at the actual position). If the +-- anchor was not found, |nil| is returned + +function Vertex:anchor(anchor) + local c = self.anchors[anchor] + if not c then + local b + local d = directions [anchor] + if d then + b = Coordinate.new(d(self:boundingBox())) + else + local n = tonumber(anchor) + if n then + local x1, y1, x2, y2 = self:boundingBox() + local r = math.max(x2-x1, y2-y1) + b = Coordinate.new(r*math.cos(n/180*math.pi),r*math.sin(n/180*math.pi)) + b:shiftByCoordinate(self.anchors.center) + end + end + if not b then + return + end + local p = Path.new {'moveto', self.anchors.center, 'lineto', b} + local intersections = p:intersectionsWith(self.path) + if #intersections > 0 then + c = intersections[1].point + end + end + self.anchors[anchor] = c + return c +end + + + +-- +-- Returns a string representation of a vertex. This is mainly for debugging +-- +-- @return The Arc as string. +-- +function Vertex:__tostring() + return self.name or tostring(self.anchors) +end + + +-- Done + +return Vertex \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua new file mode 100644 index 00000000000..3bc491ec093 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua @@ -0,0 +1,15 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/model/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +-- Load declarations from: +require "pgf.gd.model.Hyperedge" diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua new file mode 100644 index 00000000000..aad6eb0a440 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua @@ -0,0 +1,26 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/ogdf.lua,v 1.1 2012/12/17 23:53:11 tantau Exp $ + + + +-- Imports + +require "pgf" +require "pgf.gd" + + +-- Declare namespace +pgf.gd.ogdf = {} + + +-- Done + +return pgf.gd.ogdf \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua new file mode 100644 index 00000000000..a06c732ed1d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua @@ -0,0 +1,33 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/ogdf/library.lua,v 1.12 2013/10/09 19:47:00 tantau Exp $ + + +--- +-- The Open Graph Drawing Framework (\textsc{ogdf}) is a large, +-- powerful graph drawing system written in C++. This library enables +-- its use inside \tikzname's graph drawing system by translating +-- back-and-forth between Lua and C++. +-- +-- Since C++ code is compiled and not interpreted (like Lua), in order +-- to use the present library, you need a compiled version of the +-- \pgfname\ interface code for the \textsc{ogdf} library +-- (|pgf/gd/ogdf/c/ogdf_script.so|) installed correctly for your particular +-- architecture. This is by no means trivial\dots +-- +-- @library + +local ogdf + + +-- Load the C++ code: + +require "pgf_gd_ogdf_c_ogdf_script" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua new file mode 100644 index 00000000000..75a78f4f478 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua @@ -0,0 +1,21 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics.lua,v 1.1 2013/02/08 17:14:04 tantau Exp $ + + +local phylogenetics = {} + +-- Declare namespace +require("pgf.gd").phylogenetics = tree + + +-- Done + +return phylogenetics \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua new file mode 100644 index 00000000000..dc5dea45b0f --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua @@ -0,0 +1,77 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/AuthorDefinedPhylogeny.lua,v 1.2 2013/03/20 17:16:38 tantau Exp $ + + + + +local AuthorDefinedPhylogeny = {} + + +-- Namespace +require("pgf.gd.phylogenetics").AuthorDefinedPhylogeny = AuthorDefinedPhylogeny + +-- Imports +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local Direct = require "pgf.gd.lib.Direct" + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "phylogenetic tree by author", + algorithm = AuthorDefinedPhylogeny, + phase = "phylogenetic tree generation", + phase_default = true, + + summary = [[" + When this key is used, the phylogenetic tree must be specified + by the author (rather than being generated algorithmically). + "]], + documentation = [[" + A spanning tree of the input graph will be computed first (it + must be connected, otherwise errors will result). + The evolutionary length of the edges must be specified through + the use of the |length| key for each edge. + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout] { + a -- { + b [>length=2] --[length=1] { c, d }, + e [>length=3] + } + }; + "]] +} + + + +function AuthorDefinedPhylogeny:run() + + local spanning_tree = self.main_algorithm.digraph.options.algorithm_phases["spanning tree computation"].new { + ugraph = self.main_algorithm.ugraph, + events = {} -- no events + }:run() + + local phylogenetic_tree = Direct.ugraphFromDigraph(spanning_tree) + local lengths = self.lengths + + for _,a in ipairs(phylogenetic_tree.arcs) do + lengths[a.tail][a.head] = a:options('length') + end + + return phylogenetic_tree +end + + + +return AuthorDefinedPhylogeny diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua new file mode 100644 index 00000000000..fd0fb62b3ad --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua @@ -0,0 +1,593 @@ +-- Copyright 2013 by Sarah Mäusle and Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedMinimumEvolution.lua,v 1.1 2013/02/08 17:14:05 tantau Exp $ + + + +local BalancedMinimumEvolution = {} + + +-- Namespace +require("pgf.gd.phylogenetics").BalancedMinimumEvolution = BalancedMinimumEvolution + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix") +local Storage = require("pgf.gd.lib.Storage") +local Digraph = require("pgf.gd.model.Digraph") +local lib = require("pgf.gd.lib") + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "balanced minimum evolution", + algorithm = BalancedMinimumEvolution, + phase = "phylogenetic tree generation", + + summary = [[" + The BME (Balanced Minimum Evolution) algorithm tries to minimize + the total tree length. + "]], + documentation = [[" + This algorithm is from Desper and Gascuel, \emph{Fast and + Accurate Phylogeny Reconstruction Algorithms Based on the + Minimum-Evolution Principle}, 2002. The tree is built in a way + that minimizes the total tree length. The leaves are inserted + into the tree one after another, creating new edges and new + nodes. After every insertion the distance matrix has to be + updated. + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + balanced minimum evolution, + grow'=right, sibling distance=0pt, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + + + +function BalancedMinimumEvolution:run() + + self.tree = Digraph.new(self.main_algorithm.digraph) + + self.distances = Storage.newTableStorage() + + local vertices = self.tree.vertices + + -- Sanity checks: + if #vertices == 2 then + self.tree:connect(vertices[1],vertices[2]) + return self.tree + elseif #vertices > 2 then + + -- Setup storages: + self.is_leaf = Storage.new() + + -- First, build the initial distance matrix: + local matrix = DistanceMatrix.graphDistanceMatrix(self.tree) + + -- Store distance information in the distance fields of the storages: + for _,u in ipairs(vertices) do + for _,v in ipairs(vertices) do + self.distances[u][v] = matrix[u][v] + end + end + + -- Run BME + self:runBME() + + -- Run postoptimizations + local optimization_class = self.tree.options.algorithm_phases['phylogenetic tree optimization'] + optimization_class.new { + main_algorithm = self.main_algorithm, + tree = self.tree, + matrix = self.matrix, + distances = self.distances, + is_leaf = self.is_leaf, + }:run() + end + + -- Finish + self:computeFinalLengths() + self:createFinalEdges() + + return self.tree +end + + + + +-- the BME (Balanced Minimum Evolution) algorithm +-- [DESPER and GASCUEL: Fast and Accurate Phylogeny Reconstruction +-- Algorithms Based on the Minimum-Evolution Principle, 2002] +-- +-- The tree is built in a way that minimizes the total tree length. +-- The leaves are inserted into the tree one after another, creating new edges and new nodes. +-- After every insertion the distance matrix has to be updated. +function BalancedMinimumEvolution:runBME() + local g = self.tree + local leaves = {} + local is_leaf = self.is_leaf + local distances = self.distances + + -- get user input + for i, vertex in ipairs (g.vertices) do + leaves[i] = vertex + is_leaf[vertex] = true + end + + -- create the new node which will be connected to the first three leaves + local new_node = InterfaceToAlgorithms.createVertex( + self.main_algorithm, + { + name = "BMEnode"..#g.vertices+1, + generated_options = { { key = "phylogenetic inner node" } } + } + ) + g:add {new_node} + -- set the distances of new_node to subtrees + local distance_1_2 = self:distance(leaves[1],leaves[2]) + local distance_1_3 = self:distance(leaves[1],leaves[3]) + local distance_2_3 = self:distance(leaves[2],leaves[3]) + distances[new_node][leaves[1]] = 0.5*(distance_1_2 + distance_1_3) + distances[new_node][leaves[2]] = 0.5*(distance_1_2 + distance_2_3) + distances[new_node][leaves[3]] = 0.5*(distance_1_3 + distance_2_3) + + --connect the first three leaves to the new node + for i = 1,3 do + g:connect(new_node, leaves[i]) + g:connect(leaves[i], new_node) + end + + for k = 4,#leaves do + -- compute distance from k to any subtree + local k_dists = Storage.newTableStorage() + for i = 1,k-1 do + -- note that the function called stores the k_dists before they are overwritten + self:computeAverageDistancesToAllSubtreesForK(g.vertices[i], { }, k,k_dists) + end + + -- find the best insertion point + local best_arc = self:findBestEdge(g.vertices[1],nil,k_dists) + local head = best_arc.head + local tail = best_arc.tail + + -- remove the old arc + g:disconnect(tail, head) + g:disconnect(head, tail) + + -- create the new node + local new_node = InterfaceToAlgorithms.createVertex( + self.main_algorithm, + { + name = "BMEnode"..#g.vertices+1, + generated_options = { + { key = "phylogenetic inner node" } + } + } + ) + g:add{new_node} + + -- gather the vertices that will be connected to the new node... + local vertices_to_connect = { head, tail, leaves[k] } + + -- ...and connect them + for _, vertex in pairs (vertices_to_connect) do + g:connect(new_node, vertex) + g:connect(vertex, new_node) + end + + if not is_leaf[tail] then + distances[leaves[k]][tail] = k_dists[head][tail] + end + if not is_leaf[head] then + distances[leaves[k]][head] = k_dists[tail][head] + end + -- insert distances from k to subtrees into actual matrix... + self:setAccurateDistancesForK(new_node,nil,k,k_dists,leaves) + + -- set the distance from k to the new node, which was created by inserting k into the graph + distances[leaves[k]][new_node] = 0.5*( self:distance(leaves[k], head) + self:distance(leaves[k],tail)) + + -- update the average distances + local values = {} + values.s = head -- s--u is the arc into which k has been inserted + values.u = tail + values.new_node = new_node -- the new node created by inserting k + self:updateAverageDistances(new_node, values,k,leaves) + end +end + +-- +-- Updates the average distances from k to all subtrees +-- +-- @param vertex The starting point of the recursion +-- @param values The values needed for the recursion +-- - s, u The nodes which span the edge into which k has been +-- inserted +-- - new_node The new_node which has been created to insert k +-- - l (l-1) is the number of edges between the +-- new_node and the current subtree Y +-- +-- values.new_node, values.u and values.s must be set +-- the depth first search must begin at the new node, thus vertex +-- must be set to the newly created node +function BalancedMinimumEvolution:updateAverageDistances(vertex, values, k, leaves) + local g = self.tree + local leaf_k = leaves[k] + local y, z, x + if not values.visited then + values.visited = {} + values.visited[leaf_k] = leaf_k -- we don't want to visit k! + end + -- there are (l-1) edges between new_node and y + if not values.l then values.l = 1 end + if not values.new_node then values.new_node = g:outgoing(leaf_k)[1].head end + --values.s and values.u must be set + + -- the two nodes which connect the edge on which k was inserted: s,u + + local new_node = values.new_node + local l = values.l + local visited = values.visited + + visited[vertex] = vertex + + -- computes the distances to Y{k} for all subtrees X of Z + function loop_over_x( x, y, values ) + local l = values.l + local y1= values.y1 + + -- calculate distance between Y{k} and X + local old_distance -- the distance between Y{/k} and X needed for calculating the new distance + if y == new_node then -- this y didn't exist in the former tree; so use y1 (see below) + old_distance = self:distance(x,y1) + else + old_distance = self:distance(x,y) + end + + local new_distance = old_distance + math.pow(2,-l) * ( self:distance(leaf_k,x) - self:distance(x,y1) ) + self.distances[x][y] = new_distance + self.distances[y][x] = new_distance -- symmetric matrix + + values.x_visited[x] = x + --go deeper to next x + for _, x_arc in ipairs (self.tree:outgoing(x)) do + if not values.x_visited[x_arc.head] then + local new_x = x_arc.head + loop_over_x( new_x, y, values ) + end + end + end + + --loop over Z's + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not visited[arc.head] then + -- set y1, which is the node which was pushed further away from + -- subtree Z by inserting k + if arc.head == values.s then + values.y1 = values.u + elseif arc.head == values.u then + values.y1 = values.s + else + assert(values.y1,"no y1 set!") + end + + z = arc.head -- root of the subtree we're looking at + y = arc.tail -- the root of the subtree-complement of Z + + x = z -- the first subtree of Z is Z itself + values.x_visited = {} + values.x_visited[y] = y -- we don't want to go there, as we want to stay within Z + loop_over_x( z,y, values ) -- visit all possible subtrees of Z + + -- go to next Z + values.l = values.l+1 -- moving further away from the new_node + self:updateAverageDistances(z,values,k,leaves) + values.l = values.l-1 -- moving back to the new_node + end + end +end + + +-- +-- Computes the average distances of a node, which does not yet belong +-- to the graph, to all subtrees. This is done using a depth first +-- search +-- +-- @param vertex The starting point of the depth first search +-- @param values The values for the recursion +-- - distances The table in which the distances are to be +-- stored +-- - outgoing_arcs The table containing the outgoing arcs +-- of the current vertex +-- +-- @return The average distance of the new node #k to any subtree +-- The distances are stored as follows: +-- example: distances[center][a] +-- center is any vertex, thus if center is an inner vertex +-- it has 3 neighbours a,b and c, which can all be seen as the +-- roots of subtrees A,B,C. +-- distances[center][a] gives us the distance of the new +-- node k to the subtree A. +-- if center is a leaf, it has only one neighbour, which +-- can also be seen as the root of the subtree T\{center} +-- +function BalancedMinimumEvolution:computeAverageDistancesToAllSubtreesForK(vertex, values, k, k_dists) + local is_leaf = self.is_leaf + local arcs = self.tree.arcs + local vertices = self.tree.vertices + local center_vertex = vertex + -- for every vertex a table is created, in which the distances to all + -- its subtrees will be stored + + values.outgoing_arcs = values.outgoing_arcs or self.tree:outgoing(center_vertex) + for _, arc in ipairs (values.outgoing_arcs) do + local root = arc.head -- this vertex can be seen as the root of a subtree + if is_leaf[root] then -- we know the distance of k to the leaf! + k_dists[center_vertex][root] = self:distance(vertices[k], root) + else -- to compute the distance we need the root's neighbouring vertices, which we can access by its outgoing arcs + local arc1, arc2 + local arc_back -- the arc we came from + for _, next_arc in ipairs (self.tree:outgoing(root)) do + if next_arc.head ~= center_vertex then + arc1 = arc1 or next_arc + arc2 = next_arc + else + arc_back = next_arc + end + end + + values.outgoing_arcs = { arc1, arc2, arc_back } + + -- go deeper, if the distances for the next center node haven't been set yet + if not (k_dists[root][arc1.head] and k_dists[root][arc2.head]) then + self:computeAverageDistancesToAllSubtreesForK(root, values, k,k_dists) + end + + -- set the distance between k and subtree + k_dists[center_vertex][root] = 1/2 * (k_dists[root][arc1.head] + k_dists[root][arc2.head]) + end + end +end + + +-- +-- Sets the distances from k to subtrees +-- In computeAverageDistancesToAllSubtreesForK the distances to ALL possbile +-- subtrees are computed. Once k is inserted many of those subtrees don't +-- exist for k, as k is now part of them. In this function all +-- still accurate subtrees and their distances to k are +-- extracted. +-- +-- @param center The vertex serving as the starting point of the depth-first search; +-- should be the new_node + +function BalancedMinimumEvolution:setAccurateDistancesForK(center,visited,k,k_dists,leaves) + local visited = visited or {} + local distances = self.distances + + visited[center] = center + local outgoings = self.tree:outgoing(center) + for _,arc in ipairs (outgoings) do + local vertex = arc.head + if vertex ~= leaves[k] then + local distance + -- set the distance + if not distances[leaves[k]][vertex] and k_dists[center] then + distance = k_dists[center][vertex] -- use previously calculated distance + distances[leaves[k]][vertex] = distance + distances[vertex][leaves[k]] = distance + end + -- go deeper + if not visited[vertex] then + self:setAccurateDistancesForK(vertex,visited,k,k_dists,leaves) + end + end + end +end + + +-- +-- Find the best edge for the insertion of leaf #k, such that the +-- total tree length is minimized. This function uses a depth first +-- search. +-- +-- @param vertex The vertex where the depth first search is +-- started; must be a leaf +-- @param values The values needed for the recursion +-- - visited: The vertices that already have been visited +-- - tree_length: The current tree_length +-- - best_arc: The current best_arc, such that the tree +-- length is minimzed +-- - min_length: The smallest tree_length found so far +function BalancedMinimumEvolution:findBestEdge(vertex, values, k_dists) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + values = values or { visited = {} } + values.visited[vertex] = vertex + + local c -- the arc we came from + local unvisited_arcs = {} --unvisited arcs + --identify arcs + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] then + unvisited_arcs[#unvisited_arcs+1] = arc + else + c = arc.head --last visited arc + end + end + + for i, arc in ipairs (unvisited_arcs) do + local change_in_tree_length = 0 + -- set tree length to 0 for first insertion arc + if not values.tree_length then + values.tree_length = 0 + values.best_arc = arc + values.min_length = 0 + else -- compute new tree length for the case that k is inserted into this arc + local b = arc.head --current arc + local a = unvisited_arcs[i%2+1].head -- the remaining arc + local k_v = vertices[k] -- the leaf to be inserted + change_in_tree_length = 1/4 * ( ( self:distance(a,c) + + k_dists[vertex][b]) + - (self:distance(a,b) + + k_dists[vertex][c]) ) + values.tree_length = values.tree_length + change_in_tree_length + end + -- if the tree length becomes shorter, this is the new best arc + -- for the insertion of leaf k + if values.tree_length < values.min_length then + values.best_arc = arc + values.min_length = values.tree_length + end + + -- go deeper + self:findBestEdge(arc.head, values, k_dists) + + values.tree_length = values.tree_length - change_in_tree_length + end + return values.best_arc +end + +-- Calculates the total tree length +-- This is done by adding up all the edge lengths +-- +-- @return the tree length +function BalancedMinimumEvolution:calculateTreeLength() + local vertices = self.tree.vertices + local sum = 0 + + for index, v1 in ipairs(vertices) do + for i = index+1,#vertices do + local v2 = vertices[i] + local dist = self.lengths[v1][v2] + if dist then + sum = sum + dist + end + end + end + return sum +end + +-- generates edges for the final graph +-- +-- throughout the process of creating the tree, arcs have been +-- disconnected and connected, without truly creating edges. this is +-- done in this function +function BalancedMinimumEvolution:createFinalEdges() + local g = self.tree + local o_arcs = {} -- copy arcs since createEdge is going to modify the arcs array... + for _,arc in ipairs(g.arcs) do + if arc.tail.event.index < arc.head.event.index then + o_arcs[#o_arcs+1] = arc + end + end + for _,arc in ipairs(o_arcs) do + InterfaceToAlgorithms.createEdge( + self.main_algorithm, arc.tail, arc.head, + { generated_options = { + { key = "phylogenetic edge", value = tostring(self.lengths[arc.tail][arc.head]) } + }}) + end +end + + +-- Gets the distance between two nodes as specified in their options +-- or storage fields. +-- Note: this function implies that the distance from a to b is the +-- same as the distance from b to a. +-- +-- @param a,b The nodes +-- @return The distance between the two nodes + +function BalancedMinimumEvolution:distance(a, b) + if a == b then + return 0 + else + local distances = self.distances + return distances[a][b] or distances[b][a] + end +end + + +-- +-- computes the final branch lengths +-- +-- goes over all arcs and computes the final branch lengths, +-- as neither the BME nor the BNNI main_algorithm does so. +function BalancedMinimumEvolution:computeFinalLengths() + local is_leaf = self.is_leaf + local lengths = self.lengths + local g = self.tree + for _, arc in ipairs(g.arcs) do + local head = arc.head + local tail = arc.tail + local distance + local a,b,c,d + -- assert, that the length hasn't already been computed for this arc + if not lengths[head][tail] then + if not is_leaf[head] then + -- define subtrees a and b + for _, arc in ipairs (g:outgoing(head)) do + local subtree = arc.head + if subtree ~= tail then + a = a or subtree + b = subtree + end + end + end + if not is_leaf[tail] then + -- define subtrees c and d + for _, arc in ipairs (g:outgoing(tail)) do + local subtree = arc.head + if subtree ~= head then + c = c or subtree + d = subtree + end + end + end + -- compute the distance using the formula for outer or inner edges, respectively + if is_leaf[head] then + distance = 1/2 * ( self:distance(head,c) + + self:distance(head,d) + - self:distance(c,d) ) + elseif is_leaf[tail] then + distance = 1/2 * ( self:distance(tail,a) + + self:distance(tail,b) + - self:distance(a,b) ) + else --inner edge + distance = self:distance(head, tail) + -1/2 * ( self:distance(a,b) + + self:distance(c,d) ) + end + lengths[head][tail] = distance + lengths[tail][head] = distance + end + end + +end + + + +return BalancedMinimumEvolution diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua new file mode 100644 index 00000000000..a4fbc0cc3b9 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua @@ -0,0 +1,372 @@ +-- Copyright 2013 by Sarah Mäusle and Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/BalancedNearestNeighbourInterchange.lua,v 1.2 2013/03/20 17:16:38 tantau Exp $ + + + +local BalancedNearestNeighbourInterchange = {} + + +-- Namespace +require("pgf.gd.phylogenetics").BalancedNearestNeighbourInterchange = BalancedNearestNeighbourInterchange + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix") +local lib = require("pgf.gd.lib") + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "balanced nearest neighbour interchange", + algorithm = BalancedNearestNeighbourInterchange, + phase = "phylogenetic tree optimization", + phase_default = true, + + summary = [[" + The BNNI (Balanced Nearest Neighbour Interchange) is a + postprocessing algorithm for phylogenetic trees. It swaps two + distant 3-subtrees if the total tree length is reduced by doing + so, until no such swaps are left. + "]], + documentation = [[" + This algorithm is from Desper and Gascuel, \emph{Fast and + Accurate Phylogeny Reconstruction Algorithms Based on the + Minimum-Evolution Principle}, 2002. + "]] +} + + +--- +declare { + key = "no phylogenetic tree optimization", + algorithm = { run = function(self) end }, + phase = "phylogenetic tree optimization", + + summary = [[" + Switches off any phylogenetic tree optimization. + "]], +} + + + +-- creates a binary heap, implementation as an array as described in +-- the respective wikipedia article +local function new_heap() + local heap = {} + + function heap:insert(element, value) + local object = { element = element, value = value } + heap[#heap+1]= object + + local i = #heap + local parent = math.floor(i/2) + + -- sort the new object into its correct place + while heap[parent] and heap[parent].value < heap[i].value do + heap[i] = heap[parent] + heap[parent] = object + i = parent + parent = math.floor(i/2) + end + end + + -- deletes the top element from the heap + function heap:remove_top_element() + -- replace first element with last and delete the last element + local element = heap[1].element + heap[1] = heap[#heap] + heap[#heap] = nil + + local i = 1 + local left_child = 2*i + local right_child = 2*i +1 + + -- sort the new top element into its correct place by swapping it + -- against its largest child + while heap[left_child] do + local largest_child = left_child + if heap[right_child] and heap[left_child].value < heap[right_child].value then + largest_child = right_child + end + + if heap[largest_child].value > heap[i].value then + heap[largest_child], heap[i] = heap[i], heap[largest_child] + i = largest_child + left_child = 2*i + right_child = 2*i +1 + else + return element + end + end + return element + end + + return heap +end + + +-- BNNI (Balanced Nearest Neighbour Interchange) +-- [DESPER and GASCUEL: Fast and Accurate Phylogeny Reconstruction Algorithms Based on the Minimum-Evolution Principle, 2002] +-- swaps two distant-3 subtrees if the total tree length is reduced by doing so, until no such swaps are left +-- +-- step 1: precomputation of all average distances between non-intersecting subtrees (already done by BME) +-- step 2: create heap of possible swaps +-- step 3: ( current tree with subtrees a,b,c,d: a--v-- {b, w -- {c, d}} ) +-- (a): edge (v,w) is the best swap on the heap. Remove (v,c) and (w,b) +-- (b), (c), (d) : update the distance matrix +-- (e): remove the edge (v,w) from the heap; check the four edges adjacent to it for new possible swaps +-- (d): if the heap is non-empty, return to (a) + +function BalancedNearestNeighbourInterchange:run() + local g = self.tree + -- create a heap of possible swaps + local possible_swaps = new_heap() + -- go over all arcs, look for possible swaps and add them to the heap [step 2] + for _, arc in ipairs (g.arcs) do + self:getBestSwap(arc, possible_swaps) + end + + -- achieve best swap and update the distance matrix, until there is + -- no more swap to perform + + while #possible_swaps > 0 do + -- get the best swap and delete it from the heap + local swap = possible_swaps:remove_top_element() --[part of step 3 (a)] + + -- Check if the indicated swap is still possible. Another swap may + -- have interfered. + if g:arc(swap.v, swap.subtree1) and g:arc(swap.w, swap.subtree2) and g:arc(swap.v, swap.w) and g:arc(swap.a, swap.v) and g:arc(swap.d, swap.w) then + -- insert new arcs and delete the old ones to perform the swap [part of step 3 (a)] + + -- disconnect old arcs + g:disconnect(swap.v, swap.subtree1) + g:disconnect(swap.subtree1, swap.v) + g:disconnect(swap.w, swap.subtree2) + g:disconnect(swap.subtree2, swap.w) + + -- connect new arcs + g:connect(swap.v, swap.subtree2) + g:connect(swap.subtree2, swap.v) + g:connect(swap.w, swap.subtree1) + g:connect(swap.subtree1, swap.w) + + --update distance matrix + self:updateBNNI(swap) + + -- update heap: check neighbouring arcs for new possible swaps + -- [step 3 (e)] + self:getBestSwap(g:arc(swap.a,swap.v), possible_swaps) + self:getBestSwap(g:arc(swap.subtree2, swap.v), possible_swaps) + self:getBestSwap(g:arc(swap.d,swap.w), possible_swaps) + self:getBestSwap(g:arc(swap.subtree1, swap.w), possible_swaps) + end + end + +end + + +-- +-- Gets the distance between two nodes as specified in the distances +-- fields. Note: this function assumes that the distance from a to b +-- is the +-- same as the distance from b to a. +-- +-- @param a,b The nodes +-- @return The distance between the two nodes +function BalancedNearestNeighbourInterchange:distance(a, b) + if a == b then + return 0 + else + local distances = self.distances + return distances[a][b] or distances[b][a] + end +end + +-- updates the distance matrix after a swap has been performed [step3(b),(c),(d)] +-- +-- @param swap A table containing the information on the performed swap +-- subtree1, subtree2: the two subtrees, which +-- were swapped +-- a, d: The other two subtrees bordering the +-- swapping edge +-- v, w : the two nodes connecting the swapping edge + +function BalancedNearestNeighbourInterchange:updateBNNI(swap) + local g = self.tree + local b = swap.subtree1 + local c = swap.subtree2 + local a = swap.a + local d = swap.d + local v = swap.v + local w = swap.w + local distances = self.distances + + -- updates the distances in one of the four subtrees adjacent to the + -- swapping edge + function update_BNNI_subtree(swap, values) + local g = self.tree + local b = swap.farther + local c = swap.nearer + local a = swap.subtree + local v = swap.v + local d = swap.same + local w = swap.w + + if not values then + values = { + visited = {[v] = v}, + possible_ys = {v}, + x = a, + y = v + } + -- if we're looking at subtrees in one of the swapped subtrees, + -- then need the old root (w) for the calculations + if swap.swapped_branch then values.possible_ys = {w} end + end + local visited = values.visited + local x = values.x + local y = values.y + local ys = values.possible_ys + local l = 0 -- number of edges between y and v + + local dist_x_b = self:distance(x,b) + local dist_x_c = self:distance(x,c) + visited[x] = x --mark current x as visited + + -- loop over possible y's: + for _, y in ipairs (ys) do + -- update distance [step 3(b)] + local distance = self:distance(x,y) - 2^(-l-2)*dist_x_b + 2^(-l-2)*dist_x_c + + if y == w then y = v end -- the old distance w,x was used for the new distance calculation, but it needs to be + -- saved under its appropriate new name according to its new root. this case only arises when looking at x's + -- in one of the swapped subtrees (b or c) + + distances[x][y] = distance + distances[y][x] = distance + l = l+1 -- length + 1, as the next y will be further away from v + end + + -- update the distance between x and w (root of subtree c and d) + -- [step 3(c)] + local distance = 1/2 * (self:distance(x,b) + self:distance(x,d)) + distances[x][w] = distance + distances[w][x] = distance + + -- go to next possible x's + table.insert(ys, x) -- when we're at the next possible x, y can also be the current x + for _,arc in ipairs (g:outgoing(x)) do + if not visited[arc.head] then + values.x = arc.head + --go deeper + update_BNNI_subtree(swap, values) + end + end + end + + -- name the nodes/subtrees in a general way that allows the use of the function update_BNNI_subtree + local update_a = {subtree = a, farther = b, nearer = c, v = v, same = d, w = w} + local update_b = {subtree = b, farther = a, nearer = d, v = w, same = c, w = v, swapped_branch = true} + local update_c = {subtree = c, farther = d, nearer = a, v = v, same = b, w = w, swapped_branch = true} + local update_d = {subtree = d, farther = c, nearer = b, v = w, same = a, w = v} + + -- update the distances within the subtrees a,b,c,d respectively + update_BNNI_subtree(update_a) + update_BNNI_subtree(update_b) + update_BNNI_subtree(update_c) + update_BNNI_subtree(update_d) + + -- update the distance between subtrees v and w [step 3 (d)]: + local distance = 1/4*( self:distance(a,b) + self:distance(a,d) + self:distance(c,b) + self:distance(c,d) ) + distances[v][w] = distance + distances[w][v] = distance +end + + + +-- finds the best swap across an arc and inserts it into the heap of +-- possible swaps +-- +-- @param arc The arc, which is to be checked for possible swaps +-- @param heap_of_swaps The heap, containing all swaps, which +-- improve the total tree length +-- +-- the following data of the swap are saved: +-- v,w = the nodes connecting the arc, across which the swap is +-- performed +-- subtree1,2 = the roots of the subtrees that are to be swapped +-- a,d = the roots of the two remaining subtrees adjacent to the arc + +function BalancedNearestNeighbourInterchange:getBestSwap(arc, heap_of_swaps) + local g = self.tree + local possible_swaps = heap_of_swaps + local v = arc.tail + local w = arc.head + local is_leaf = self.is_leaf + + -- only look at inner edges: + if not is_leaf[v] and not is_leaf[w] then + -- get the roots of the adjacent subtrees + local a, b, c, d + for _,outgoing in ipairs (g:outgoing(v)) do + local head = outgoing.head + if head ~= w then + a = a or head + b = head + end + end + + for _,outgoing in ipairs (g:outgoing(w)) do + local head = outgoing.head + if head ~= v then + c = c or head + d = head + end + end + + -- get the distances between the four subtrees + local a_b = self:distance(a,b) + local a_c = self:distance(a,c) + local a_d = self:distance(a,d) + local b_c = self:distance(b,c) + local b_d = self:distance(b,d) + local c_d = self:distance(c,d) + + -- difference in total tree length between old tree (T) and new tree (T') + -- when nodes b and c are swapped + local swap1 = 1/4*(a_b + c_d - a_c - b_d ) + + -- difference in total tree length between old tree and new tree when nodes b and d are swapped + local swap2 = 1/4*(a_b + c_d - a_d - b_c) + + -- choose the best swap that reduces the total tree length most (T-T' > 0) + if swap1 > swap2 and swap1 > 0 then + -- v,w = the nodes connecting the edge across which the swap is performed + -- subtree1 = one of the nodes to be swapped; connected to v + -- subtree2 = the other node to be swapped; connected to w + -- a = other node connected to v + -- d = other node connected to w + local swap = { v = v, w = w, subtree1 = b, subtree2 = c, a = a, d = d } + -- insert the swap into the heap + possible_swaps:insert(swap, swap1) + elseif swap2 > 0 then + local swap = { v = v, w = w, subtree1 = b, subtree2 = d, d = c, a = a } + possible_swaps:insert(swap, swap2) + end + end +end + + + +return BalancedNearestNeighbourInterchange diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua new file mode 100644 index 00000000000..0bca7773212 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua @@ -0,0 +1,440 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/DistanceMatrix.lua,v 1.2 2013/12/20 14:44:47 tantau Exp $ + + + + +local DistanceMatrix = {} + + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local declare = InterfaceToAlgorithms.declare + + +--- + +declare { + key = "distance matrix vertices", + type = "string", + + summary = [[" + A list of vertices that are used in the parsing of the + |distance matrix| key. If this key is not used at all, all + vertices of the graph will be used for the computation of a + distance matrix. + "]], + + documentation = [[" + The vertices must be separated by spaces and/or + commas. For vertices containing spaces or commas, the vertex + names may be surrounded by single or double quotes (as in + Lua). Typical examples are |a, b, c| or |"hello world", 'foo'|. + "]] +} + + + +--- + +declare { + key = "distance matrix", + type = "string", + + summary = [[" + A distance matrix specifies ``desired distances'' between + vertices in a graph. These distances are used, in particular, in + algorithms for computing phylogenetic trees. + "]], + + documentation = [[" + When this key is parsed, the key |distance matrix vertices| is + considered first. It is used to determine a list of vertices + for which a distance matrix is computed, see that key for + details. Let $n$ be the number of vertices derived from that + key. + + The string passed to the |distance matrix| key is basically + a sequence of numbers that are used to fill an $n \times n$ + matrix. This works as follows: We keep track of a \emph{current + position $p$} in the matrix, starting at the upper left corner + of the matrix. We read the numbers in the string + one by one, write it to the current position of the matrix, and + advance the current position by going right one step; if we go + past the right end of the matrix, we ``wrap around'' by going + back to the left border of the matrix, but one line down. If we + go past the bottom of the matrix, we start at the beginning once + more. + + This basic behaviour can be modified in different ways. First, + when a number is followed by a semicolon instead of a comma or a + space (which are the ``usual'' ways of indicating the end of a + number), we immediately go down to the next line. Second, + instead of a number you can directly provide a \emph{position} + in the matrix and the current position will be set to this + position. Such a position information is detected by a + greater-than sign (|>|). It must be followed by + \begin{itemize} + \item a number or a vertex name or + \item a number or a vertex name, a comma, and another number or + vertex name or + \item a comma and a number and a vertex name. + \end{itemize} + Examples of the respective cases are |>1|, |>a,b|, and + |>,5|. The semantics is as follows: In all cases, if a vertex + name rather than a number is given, it is converted into a + number (namely the index of the vertex inside the matrix). Then, + in the first case, the column of the current position is set to + the given number; in the second case, the columns is set to the + first number and the column is set to the second number; and in + the third case only the row is set to the given number. (This + idea is that following the |>|-sign comes a ``coordinate pair'' + whose components are separated by a comma, but part of that pair + may be missing.) If a vertex name contains special symbols like + a space or a comma, you must surround it by single or double + quotation marks (as in Lua). + + Once the string has been parsed completely, the matrix may be + filled only partially. In this case, for each missing entry + $(x,y)$, we try to set it to the value of the entry $(y,x)$, + provided that entry is set. If neither are set, the entry is set + to $0$. + + Let us now have a look at several examples that all produce the + same matrix. The vertices are |a|, |b|, |c|. +\begin{codeexample}[code only, tikz syntax=false] +0, 1, 2 +1, 0, 3 +2, 3, 0 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +0 1 2 1 0 3 2 3 0 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +; +1; +2 3 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>,b 1; 2 3 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>b 1 2 >c 3 +\end{codeexample} + "]] +} + + +--- + +declare { + key = "distances", + type = "string", + + summary = [[" + This key is used to specify the ``desired distances'' between + a vertex and the other vertices in a graph. + "]], + + documentation = [[" + This key works similar to the |distance matrix| key, only it is + passed to a vertex instead of to a whole graph. The syntax is + the same, only the notion of different ``rows'' is not + used. Here are some examples that all have the same effect, + provided the nodes are |a|, |b|, and |c|. +\begin{codeexample}[code only, tikz syntax=false] +0, 1, 2 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +0 1 2 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>b 1 2 +\end{codeexample} +\begin{codeexample}[code only, tikz syntax=false] +>c 2, >b 1 +\end{codeexample} + "]] +} + + + +local function to_index(s, indices) + if s and s ~= "" then + if s:sub(1,1) == '"' then + local _, _, m = s:find('"(.*)"') + return indices[InterfaceToAlgorithms.findVertexByName(m)] + elseif s:sub(1,1) == "'" then + local _, _, m = s:find("'(.*)'") + return indices[InterfaceToAlgorithms.findVertexByName(m)] + else + local num = tonumber(s) + if not num then + return indices[InterfaceToAlgorithms.findVertexByName(s)] + else + return num + end + end + end +end + +local function compute_indices(vertex_string, vertices) + local indices = {} + + if not vertex_string then + for i,v in ipairs(vertices) do + indices[i] = v + indices[v] = i + end + else + -- Ok, need to parse the vertex_string. Sigh. + local pos = 1 + while pos <= #vertex_string do + local start = vertex_string:sub(pos,pos) + if not start:find("[%s,]") then + local _, vertex + if start == '"' then + _, pos, vertex = vertex_string:find('"(.-)"', pos) + elseif start == "'" then + _, pos, vertex = vertex_string:find("'(.-)'", pos) + else + _, pos, vertex = vertex_string:find("([^,%s'\"]*)", pos) + end + local v = assert(InterfaceToAlgorithms.findVertexByName(vertex), "unknown vertex name '" .. vertex .. "'") + indices [#indices + 1] = v + indices [v] = #indices + end + pos = pos + 1 + end + end + + return indices +end + + +--- +-- Compute a distance matrix based on the values of a +-- |distance matrix| and a |distance matrix vertices|. +-- +-- @param matrix_string A distance matrix string +-- @param vertex_string A distance matrix vertex string +-- @param vertices An array of all vertices in the graph. +-- +-- @return A distance matrix. This matrix will contain both a +-- two-dimensional array (accessed through numbers) and also a +-- two-dimensional hash table (accessed through vertex indices). Thus, +-- you can write both |m[1][1]| and also |m[v][v]| to access the first +-- entry of this matrix, provided |v == vertices[1]|. +-- @return An index vector. This is an array of the vertices +-- identified for the |vertex_string| parameter. + +function DistanceMatrix.computeDistanceMatrix(matrix_string, vertex_string, vertices) + -- First, we create a table of the vertices we need to consider: + local indices = compute_indices(vertex_string, vertices) + + -- Second, build matrix. + local n = #indices + local m = {} + for i=1,n do + m[i] = {} + end + + local x = 1 + local y = 1 + local pos = 1 + -- Start scanning the matrix_string + while pos <= #matrix_string do + local start = matrix_string:sub(pos,pos) + if not start:find("[%s,]") then + if start == '>' then + local _, parse + _, pos, parse = matrix_string:find(">([^%s>;]*)", pos) + local a, b + if parse:find(",") then + _,_,a,b = parse:find("(.*),(.*)") + else + a = parse + end + x = to_index(a, indices) or x + y = to_index(b, indices) or y + elseif start == ';' then + x = 1 + y = y + 1 + elseif start == ',' then + x = x + 1 + else + local _, n + _, pos, n = matrix_string:find("([^,;%s>]*)", pos) + local num = assert(tonumber(n), "number expected in distance matrix") + m[x][y] = num + x = x + 1 + -- Skip everything up to first comma: + _, pos = matrix_string:find("(%s*,?)", pos+1) + end + end + pos = pos + 1 + if x > n then + x = 1 + y = y + 1 + end + if y > n then + y = 1 + end + end + + -- Fill up + for x=1,n do + for y=1,n do + if not m[x][y] then + m[x][y] = m[y][x] or 0 + end + end + end + + -- Copy to index version + for x=1,n do + local v = indices[x] + m[v] = {} + for y=1,n do + local u = indices[y] + m[v][u] = m[x][y] + end + end + + return m, indices +end + + + + +--- +-- Compute a distance vector. See the key |distances| for details. +-- +-- @param vector_string A distance vector string +-- @param vertex_string A distance matrix vertex string +-- @param vertices An array of all vertices in the graph. +-- +-- @return A distance vector. Like a distance matrix, this vector will +-- double indexed, once by numbers and once be vertex objects. +-- @return An index vector. This is an array of the vertices +-- identified for the |vertex_string| parameter. + +function DistanceMatrix.computeDistanceVector(vector_string, vertex_string, vertices) + -- First, we create a table of the vertices we need to consider: + local indices = compute_indices(vertex_string, vertices) + + -- Second, build matrix. + local n = #indices + local m = {} + local x = 1 + local pos = 1 + -- Start scanning the vector_string + while pos <= #vector_string do + local start = vector_string:sub(pos,pos) + if not start:find("[%s,]") then + if start == '>' then + local _, parse + _, pos, parse = vector_string:find(">([^%s>;]*)", pos) + x = to_index(parse, indices) or x + elseif start == ',' then + x = x + 1 + else + local _, n + _, pos, n = vector_string:find("([^,;%s>]*)", pos) + local num = assert(tonumber(n), "number expected in distance matrix") + m[x] = num + x = x + 1 + -- Skip everything up to first comma: + _, pos = vector_string:find("(%s*,?)", pos+1) + end + end + pos = pos + 1 + if x > n then + x = 1 + end + end + + -- Fill up + for x=1,n do + m[x] = m[x] or 0 + m[indices[x]] = m[x] + end + + return m, indices +end + + + +--- +-- Compute a distance matrix for a graph that incorporates all +-- information stored in the different options of the graph and the +-- vertices. +-- +-- @param graph A digraph object. +-- +-- @return A distance matrix for all vertices of the graph. + +function DistanceMatrix.graphDistanceMatrix(digraph) + local vertices = digraph.vertices + local n = #vertices + local m = {} + for i,v in ipairs(vertices) do + m[i] = {} + m[v] = {} + end + + local indices = {} + for i,v in ipairs(vertices) do + indices[i] = v + indices[v] = i + end + + if digraph.options['distance matrix'] then + local sub, vers = DistanceMatrix.computeDistanceMatrix( + digraph.options['distance matrix'], + digraph.options['distance matrix vertices'], + vertices + ) + + for x=1,#vers do + for y=1,#vers do + m[vers[x]][vers[y]] = sub[x][y] + end + end + end + + for i,v in ipairs(vertices) do + if v.options['distances'] then + local sub, vers = DistanceMatrix.computeDistanceVector( + v.options['distances'], + v.options['distance matrix vertices'], + vertices + ) + + for x=1,#vers do + m[vers[x]][v] = sub[x] + end + end + end + + -- Fill up number versions: + for x,vx in ipairs(vertices) do + for y,vy in ipairs(vertices) do + m[x][y] = m[vx][vy] + end + end + + return m +end + + + +return DistanceMatrix diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua new file mode 100644 index 00000000000..ef0909a6d00 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua @@ -0,0 +1,778 @@ +-- Copyright 2013 by Sarah Mäusle and Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/Maeusle2012.lua,v 1.4 2013/05/23 20:01:29 tantau Exp $ + + +-- Imports +local Digraph = require 'pgf.gd.model.Digraph' +local Coordinate = require 'pgf.gd.model.Coordinate' +local Path = require 'pgf.gd.model.Path' + +local layered = require 'pgf.gd.layered' + +local lib = require 'pgf.gd.lib' + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +-- Main class of this file: + +local Maeusle2012 = lib.class {} + +-- Namespace +require("pgf.gd.phylogenetics").Maeusle2012 = Maeusle2012 + + + + +--- +declare { + key = "rooted rectangular phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root = self:getRoot() + self:setPosForRectangularLayout(root) + end + }, + phase = "phylogenetic tree layout", + phase_default = true, + + summary = [[" + A rooted rectangular phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + rooted rectangular phylogram, + balanced minimum evolution, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + +--- +declare { + key = "rectangular phylogram", + use = { { key = "rooted rectangular phylogram" } }, + summary = "An alias for |rooted rectangular phylogram|" +} + +--- +declare { + key = "rooted straight phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root = self:getRoot() + self:setXPos(root) + self:setYPosForStraightLayout(root) + end + }, + phase = "phylogenetic tree layout", + + summary = [[" + A rooted straight phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + rooted straight phylogram, + balanced minimum evolution, grow=right, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]]} + +--- +declare { + key = "straight phylogram", + use = { { key = "rooted straight phylogram" } }, + summary = "An alias for |rooted straight phylogram|" +} + +--- +declare { + key = "unrooted rectangular phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root1, root2 = self:getRoot() + self:setPosForUnrootedRectangular(root2, root1) + end + }, + phase = "phylogenetic tree layout", + + summary = [[" + A unrooted rectangular phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + unrooted rectangular phylogram, + balanced minimum evolution, grow=right, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + +--- +declare { + key = "unrooted straight phylogram", + algorithm = { + base_class = Maeusle2012, + run = function (self) + local root1, root2 = self:getRoot() + self:setPosForUnrootedStraight(root2, root1) + end + }, + phase = "phylogenetic tree layout", + + summary = [[" + A unrooted straight phylogram is... + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, + unrooted straight phylogram, + balanced minimum evolution, grow=right, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + +--- +declare { + key = "evolutionary unit length", + type = "length", + initial = "1cm", + + summary = [[" + Specifies how long a ``unit'' of evolutionary time should be on + paper. For instance, if two nodes in a phylogenetic tree have an + evolutionary distance of 3 and this length is set to |1cm|, then + they will be |3cm| apart in a straight-line phylogram. + "]], + documentation = [[" + (This key used to be called |distance scaling factor|.) + "]], +} + + + +-- +-- Gets the edge length between two nodes +-- +-- @param vertex1, vertex2 The two nodes +-- +-- @return The length of the edge between the two nodes +function Maeusle2012:edgeLength(vertex1, vertex2) + return self.lengths[vertex1][vertex2] +end + + +-- Sets the x and y coordinates for all nodes, using a depth first +-- search +-- +-- @param vertex The starting point; should usually be the root +-- @param values Values needed for the recursion +-- @param vertex2 A node that will not be visited; this parameter should only be set +-- for an unrooted layout to ensure that only the half of the tree is set. +function Maeusle2012:setPosForRectangularLayout(vertex, values, vertex2) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + local adjusted_bb = self.main_algorithm.adjusted_bb + + values = values or { + length = 0, -- current path length + visited = {}, -- all nodes that have already been visited + leaves = {}, -- all leaves from left to right + } + + local vertex_is_leaf = true + values.visited[vertex] = true + + local children = {} -- a table containing all children of the + --current vertex (for the later determination of inner vertices + --x-positions) + + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + -- if arc.head hasn't been visited, the current vertex cannot be a leaf + vertex_is_leaf = false + local arc_length = self:edgeLength(vertex, arc.head) + + values.length = values.length + arc_length + + -- go deeper + self:setPosForRectangularLayout(arc.head, values, vertex2) + + -- get the children of the current vertex + children[#children+1] = arc.head + + values.length = values.length - arc_length + end + end + + if vertex_is_leaf then + -- subtract layer_pre, thus the leaf itself is NOT part of the + -- edge length + vertex.pos.y = - adjusted_bb[vertex].layer_pre + + values.leaves[#values.leaves+1] = vertex + + -- x coordinate: + -- the x coordinates of the leaves are the first to be set; the + -- first leave stays at x = 0, the x coordinates for the other + -- leaves is computed with help of the ideal_sibling_distance + -- function + if #values.leaves > 1 then + local left_sibling = values.leaves[#values.leaves-1] + local ideal_distance = layered.ideal_sibling_distance(adjusted_bb, self.tree, vertex, left_sibling ) + vertex.pos.x = left_sibling.pos.x + ideal_distance + end + + else -- the vertex is an inner node + -- the x position of an inner vertex is at the center of its children. + + -- determine the outer children + local left_child = children[1] + local right_child = left_child + for _, child in ipairs(children) do + if child.pos.x < left_child.pos.x then left_child = child end + if child.pos.x > right_child.pos.x then right_child = child end + end + + -- position between child with highest and child with lowest x-value, + -- if number of children is even + local index_of_middle_child = math.ceil(#children/2) + local even = #children/2 == index_of_middle_child + + if even then + vertex.pos.x = (left_child.pos.x + right_child.pos.x) / 2 + index_of_middle_child = 0 + else -- if number of children is odd, position above the middle child + vertex.pos.x = children[index_of_middle_child].pos.x + table.remove(children, index_of_middle_child) -- don't bend the edge to this node, as it it above it anyway + end + end + + -- set the node's y-coordinate, using the calculated length + -- and a scaling factor + vertex.pos.y = vertex.pos.y + (values.length * self.tree.options['evolutionary unit length']) + + -- if this is the second subtree to be set of an unrooted tree, have + -- it grow in the other direction + if values.second_subtree then + vertex.pos.y = -vertex.pos.y + end + + -- bend the edges for the rectangular layout + for i,child in ipairs(children) do + self:bendEdge90Degree(child, vertex) + end + + return values +end + + +-- Sets only the x-positions of all nodes using a depth-first search. +-- This is necessary for straight-edge layouts. +-- +-- @param vertex The starting point of the depth-first search; should usually be the root +-- @param values Values needed for the recursion +-- @param vertex2 A node that will not be visited; this parameter should only be set +-- for an unrooted layout to ensure that only the half of the tree is set. +function Maeusle2012:setXPos(vertex, values, vertex2) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + if not values then + values = { + visited = {}, -- all nodes that have already been visited + leaves = {}, -- all leaves from left to right + } + end + + local vertex_is_leaf = true + values.visited[vertex] = true + local children = {} -- a table containing all children of the current vertex (for the later determination of inner vertices x-positions) + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + -- if arc.head hasn't been visited, the current vertex cannot be a leaf + vertex_is_leaf = false + + -- go deeper + self:setXPos(arc.head, values, vertex2) + + -- get the children of the current vertex + table.insert(children, arc.head) + end + end + + -- set the x-position of a leaf + if vertex_is_leaf then + + table.insert(values.leaves, vertex) + + if #values.leaves > 1 then + local left_sibling = values.leaves[#values.leaves-1] + local ideal_distance = layered.ideal_sibling_distance(self.main_algorithm.adjusted_bb, self.tree, vertex, left_sibling ) + vertex.pos.x = left_sibling.pos.x + ideal_distance + end + + -- set x position of an inner node, which is at the center of its + -- children + else + -- determine the outer children + local left_child = children[1] + local right_child = left_child + for _, child in ipairs(children) do + if child.pos.x < left_child.pos.x then left_child = child end + if child.pos.x > right_child.pos.x then right_child = child end + end + + -- position between child with highest and child with lowest x-value, + -- if number of children is even + local index_of_middle_child = math.ceil(#children/2) + local even = #children/2 == index_of_middle_child + + if even then + vertex.pos.x = (left_child.pos.x + right_child.pos.x) / 2 + else -- if number of children is odd, position above the middle child + vertex.pos.x = children[index_of_middle_child].pos.x + end + end + return values +end + + +-- +-- Sets only the y-positions of all nodes using a depth-first search. +-- This is needed for a straight-edge layout, as the x-positions have +-- to bet first so that the y-coordinates can be calculated correctly +-- here. +-- +-- @param vertex1 The starting point of the depth-first search +-- @param values Values needed for the recursion +-- @param vertex2 For unrooted layout only: The root of the second subtree. +-- This node and all its children will not be visited. +function Maeusle2012:setYPosForStraightLayout(vertex, values, vertex2) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + local adjusted_bb = self.main_algorithm.adjusted_bb + + values = values or { + length = 0, -- current path length + visited = {}, -- all nodes that have already been visited + leaves = {}, -- all leaves from left to right + } + + local vertex_is_leaf = true + values.visited[vertex] = true + local children = {} -- a table containing all children of the current vertex (for the later determination of inner vertices x-positions) + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + -- if arc.head hasn't been visited, the current vertex cannot be a leaf + vertex_is_leaf = false + + -- calculate the arc length with the help of the Pythagorean + -- theorem + local a + local l = self:edgeLength(vertex, arc.head) * self.tree.options['evolutionary unit length'] + local b = math.abs(vertex.pos.x - arc.head.pos.x) + if b > l then + a = 0 + else + a = math.sqrt(l^2-b^2) + end + local arc_length = a + + + values.length = values.length + arc_length + + -- go deeper + self:setYPosForStraightLayout(arc.head, values, vertex2) + + -- get the children of the current vertex + table.insert(children, arc.head) + + values.length = values.length - arc_length + end + end + + if vertex_is_leaf then + -- subtract layer_pre, thus the leaf itself is NOT part of the + -- edge length + vertex.pos.y = - adjusted_bb[vertex].layer_pre + + table.insert(values.leaves, vertex) + end + + -- set the node's y-coordinate, using the calculated length + vertex.pos.y = vertex.pos.y + values.length + + -- if this is the second subtree to be set of an unrooted tree, have + -- it grow in the other direction + if values.second_subtree then vertex.pos.y = -vertex.pos.y end +end + +-- +-- Correct the x-positions in the unrooted layout for a more aesthetic result +-- +-- If the roots of the two subtrees have different x-positions, this is corrected +-- by shifting the x-positions of all nodes in one subtree by that difference. +-- +-- @param vertex1 The root of the first subtree +-- @param vertex2 The root of the second subtree. +function Maeusle2012:correctXPos(vertex1, vertex2, straight) + + -- correct the x-positions + -- + -- @param vertex Starting point of the depth-first search + -- @param values Values needed for the recursion + -- @param vertex2 The root of the subtree that will not be visited + local function x_correction(vertex, values, vertex2) + values.visited[vertex] = true + local children = {} + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] and arc.head ~= vertex2 then + + table.insert(children, arc.head) + x_correction(arc.head, values, vertex2) + end + end + + vertex.pos.x = vertex.pos.x + values.diff + if not straight then + for i,child in ipairs(children) do + self:bendEdge90Degree(child, vertex) + end + end + + return values + end + + -- compute the difference of the x-positions of the two subtrees' + -- roots + local diff = vertex1.pos.x - vertex2.pos.x + local values = { visited = {} } + if diff < 0 then + values.diff = - diff + x_correction(vertex1, values, vertex2) + elseif diff > 0 then + values.diff = diff + x_correction(vertex2, values, vertex1) + end +end + + +-- +-- Sets the x- and y-positions of the vertices in an unrooted layout +-- +-- This is done using the function for setting the positions for a rooted layout: +-- Two neighboring vertices are chosen as roots; one half of the tree +-- is drawn in one direction, the other half 180° to the other +-- direction. +-- +-- @param vertex1, vertex2: The vertices functioning as roots +function Maeusle2012:setPosForUnrootedRectangular(vertex1, vertex2) + -- set positions for first half of the tree... + self:setPosForRectangularLayout(vertex2,false,vertex1) + local vals={ + length = self:edgeLength(vertex1, vertex2), -- the length between the two roots + visited={}, + leaves={}, + path={}, + second_subtree = true + } + -- ... and for the second half. + self:setPosForRectangularLayout(vertex1,vals,vertex2) + -- if the two roots have different x-values, correct the x-positions for nicer layout + self:correctXPos(vertex1, vertex2, false) +end + + +-- +-- Sets the x- and y-positions of the vertices in an unrooted straight layout +-- +-- This is done using the function for setting the positions for a rooted straight layout: +-- Two neighboring vertices are chosen as roots; one half of the tree +-- is drawn in one direction, the other half 180° to the other +-- direction. +-- +-- @param vertex1, vertex2: The vertices functioning as roots +function Maeusle2012:setPosForUnrootedStraight(vertex1, vertex2) + -- first set the x-positions of the two subtrees... + local vals = {visited = {}, leaves = {} } + self:setXPos(vertex2, vals, vertex1) + self:setXPos(vertex1, vals, vertex2) + + -- ... and then the y-positions + self:setYPosForStraightLayout(vertex2, false, vertex1) + local vals={ + length = self:edgeLength(vertex1, vertex2) * self.tree.options['evolutionary unit length'], + visited={}, + leaves={}, + path={}, + second_subtree = true + } + self:setYPosForStraightLayout(vertex1, vals, vertex2) + + -- if the two roots have different x-values, correct the x-positions for nicer layout + -- as the length between the roots of the two subtrees is set to the calculated value, + -- this step is mandatory for the unrooted, straight layout + self:correctXPos(vertex1, vertex2, true) +end + + + +-- Bends the arc between two nodes by 90 degree by updating the arc's +-- path +-- +-- @param head The head of the arc +-- @param tail The tail of the arc +function Maeusle2012:bendEdge90Degree(head, tail) + local arc = self.tree:arc(tail,head) + local syntactic_tail = arc:syntacticTailAndHead() + arc:setPolylinePath { Coordinate.new(head.pos.x, tail.pos.y) } +end + + + +-- Finds the longest path in a graph +-- +-- @ return A table containing the path (an array of nodes) and the +-- path length +function Maeusle2012:findLongestPath() + local starting_point = self.tree.vertices[1] -- begin at any vertex + -- get the path lengths from the starting point to all leaves: + local paths_to_leaves = self:getPathLengthsToLeaves(starting_point) + local path_lengths = paths_to_leaves.path_lengths + local paths = paths_to_leaves.paths + + -- looks for the longest path and identifies its end-point + local function find_head_of_longest_path(path_lengths, paths) + local longest_path + local node + -- to make sure that the same path is chosen every time, we go over all vertices with "ipairs"; if we would go over path_lengths directly, we could only use "pairs" + for _, vertex in ipairs(self.tree.vertices) do + local path_length = path_lengths[vertex] + if path_length then + -- choose longest path. if two paths have the same length, take the path with more nodes + if not longest_path or path_length > longest_path or (path_length == longest_path and #paths[vertex]>#paths[node]) then + longest_path = path_length + node = vertex + end + end + end + return node + end + + -- find the longest path leading away from the starting point and identify + -- the leaf it leads to. Use that leaf as the tail for the next path + -- search + local tail = find_head_of_longest_path(path_lengths, paths) + paths_to_leaves = self:getPathLengthsToLeaves(tail) -- gets new path information + -- paths_to leaves now has all paths starting at vertex "tail"; one of these paths is the + -- longest (globally) + path_lengths = paths_to_leaves.path_lengths + paths = paths_to_leaves.paths + local head = find_head_of_longest_path(path_lengths, paths) + + local path_information = + { path = paths_to_leaves.paths[head], -- longest path + length = path_lengths[head] } -- length of that path + + return path_information +end + + +-- a depth first search for getting all path lengths from a +-- starting point to all leaves +-- +-- @param vertex The vertex where the search is to start +-- @param values Table of values needed for the recursive computation +-- +-- @return A table containing: +-- a table of the leaves with corresponding path lengths +-- and a table containing the path to each leaf (an array of +-- nodes) +function Maeusle2012:getPathLengthsToLeaves(vertex, values) + local arcs = self.tree.arcs + local vertices = self.tree.vertices + if not values then + values = { + paths = {}, -- all paths we've found so far + path_lengths = {}, -- all path lengths that have so far been computed + length = 0, -- current path length + visited = {}, -- all nodes that have already been visited + path = {}, -- the current path we're on + leaves = {} -- all leaves from left to right + } + table.insert(values.path,vertex) + end + + local vertex_is_leaf = true + values.visited[vertex] = true + + for _, arc in ipairs (self.tree:outgoing(vertex)) do + if not values.visited[arc.head] then + -- the current vertex is not a leaf! note: if the starting vertex is a leaf, vertex_is_leaf + -- will be set to 'false' for it anyway. as we're not interested in the distance + -- of the starting vertex to itself, this is fine. + vertex_is_leaf = false + local arc_length = self.lengths[vertex][arc.head] + values.length = values.length + arc_length + + -- add arc.head to path... + table.insert(values.path,arc.head) + + -- ... and go down that path + self:getPathLengthsToLeaves(arc.head, values) + + -- remove arc.head again to go a different path + table.remove(values.path) + values.length = values.length - arc_length + end + end + + if vertex_is_leaf then -- we store the information gained on the path to this leaf + values.path_lengths[vertex] = values.length + values.paths[vertex] = {} + table.insert(values.leaves, vertex) + for i,k in pairs(values.path) do + values.paths[vertex][i] = k + end + end + -- the path_lengths and the paths are stored in one table and + -- returned together + local path_information = + { path_lengths = values.path_lengths, + paths = values.paths, + leaves = values.leaves } + return path_information +end + + +-- Gets the root of a tree +-- checks whether a tree is already rooted, if not, computeCenterOfPath() is +-- called, which defines a node in the center of the graph as the root +-- +-- @return The root +function Maeusle2012:getRoot() + -- check whether a root exists (vertex with degree 2) + local root = lib.find (self.tree.vertices, function(v) return #self.tree:outgoing(v) == 2 end) + if root then + return root, self.tree:outgoing(root)[1].head + else + return self:computeCenterOfPath() + end +end + + +-- +-- @return The newly computed root and its nearest neighbor +function Maeusle2012:computeCenterOfPath() + local longest_path = self:findLongestPath() + local path = longest_path.path + local root, neighbor_of_root + + local length = 0 --length between first vertex on the path and the current vertex we're looking at + for i = 1, #path-1 do + local node1 = path[i] + local node2 = path[i+1] + local node3 = path[i+2] + + local dist_node_1_2, dist_node_2_3 --distances between node1 and node2, and node2 and node3 + dist_node_1_2 = self:edgeLength(node1, node2) + if node3 then dist_node_2_3 = self:edgeLength(node2, node3) end + length = length + dist_node_1_2 -- length between first vertex on the path and current node2 + + if length == longest_path.length/2 then + root = node2 -- if there is a node exactly at the half of the path, use this node as root + + -- and find nearest neighbor of the root + if node3 == nil or dist_node_1_2 < dist_node_2_3 then -- neu 3.8 + neighbor_of_root = node1 + else + neighbor_of_root = node3 + end + break + + elseif length > longest_path.length/2 then + -- else find node closest to the center of the path and use it as the root; + local node2_length = math.abs(longest_path.length/2 - length) + local node1_length = math.abs(longest_path.length/2 - (length - dist_node_1_2)) + if node2_length < node1_length then + root = node2 + neighbor_of_root = node1 + -- if node3 is closer to node2 than node1 is, use node3 as neighbor! + if node3 and dist_node_2_3 < dist_node_1_2 then neighbor_of_root = node3 end + else + root = node1 + neighbor_of_root = node2 + --check if node i-1 is closer to node1 + local dist_node_0_1 + if i>1 then + node0 = path[i-1] + dist_node_0_1 = self:edgeLength(node0, node1) + if dist_node_0_1 < dist_node_1_2 then neighbor_of_root = node0 end + end + end + break + end + end + + return root, neighbor_of_root +end + + +return Maeusle2012 diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua new file mode 100644 index 00000000000..16356aa7cfa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua @@ -0,0 +1,91 @@ +-- Copyright 2013 by Sarah Mäusle and Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/PhylogeneticTree.lua,v 1.2 2013/02/08 17:14:06 tantau Exp $ + + +local PhylogeneticTree = {} + + +-- Namespace +require("pgf.gd.phylogenetics").PhylogeneticTree = PhylogeneticTree + +-- Imports +local InterfaceToAlgorithms = require "pgf.gd.interface.InterfaceToAlgorithms" +local Storage = require "pgf.gd.lib.Storage" +local Direct = require "pgf.gd.lib.Direct" + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "phylogenetic tree layout", + algorithm = PhylogeneticTree, + + postconditions = { + upward_oriented = true + }, + + summary = [[" + Layout for drawing phylogenetic trees. + "]], + documentation = [[" + ... + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, upgma, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + +-- Computes a phylogenetic tree and/or visualizes it +-- - computes a phylogenetic tree according to what the "phylogenetic +-- algorithm" key is set to +-- - invokes a graph drawing algorithm according to what the +-- "phylogenetic layout" key is set to +function PhylogeneticTree:run() + + local options = self.digraph.options + + -- Two storages for some information computed by the phylogenetic + -- tree generation algorithm + local lengths = Storage.newTableStorage() + + -- First, compute the phylogenetic tree + local tree = options.algorithm_phases['phylogenetic tree generation'].new { + main_algorithm = self, + lengths = lengths + }:run() + + tree = Direct.ugraphFromDigraph(tree) + + -- Second, layout the tree + local layout_class = options.algorithm_phases['phylogenetic tree layout'] + layout_class.new { + main_algorithm = self, + distances = distances, + lengths = lengths, + tree = tree + }:run() + + tree:sync() +end + +return PhylogeneticTree diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua new file mode 100644 index 00000000000..c55a7a7467c --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua @@ -0,0 +1,261 @@ +-- Copyright 2013 by Sarah Mäusle and Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/SokalMichener1958.lua,v 1.1 2013/02/08 17:14:06 tantau Exp $ + + + + +local SokalMichener1958 = {} + + +-- Namespace +require("pgf.gd.phylogenetics").SokalMichener1958 = SokalMichener1958 + +-- Imports +local InterfaceToAlgorithms = require("pgf.gd.interface.InterfaceToAlgorithms") +local DistanceMatrix = require("pgf.gd.phylogenetics.DistanceMatrix") +local lib = require("pgf.gd.lib") +local Storage = require("pgf.gd.lib.Storage") +local Digraph = require("pgf.gd.model.Digraph") + +-- Shorthand: +local declare = InterfaceToAlgorithms.declare + + +--- +declare { + key = "unweighted pair group method using arithmetic averages", + algorithm = SokalMichener1958, + phase = "phylogenetic tree generation", + + summary = [[" + The UPGMA (Unweighted Pair Group Method using arithmetic + Averages) algorithm of Sokal and Michener, 1958. It generates a + graph on the basis of such a distance matrix by generating nodes + and computing the edge lengths. + "]], + documentation = [[" + This algorithm uses a distance matrix, ideally an ultrametric + one, to compute the graph. + "]], + examples = [[" + \tikz \graph [phylogenetic tree layout, sibling distance=0pt, sibling sep=2pt, + unweighted pair group method using arithmetic averages, + distance matrix={ + 0 4 9 9 9 9 9 + 4 0 9 9 9 9 9 + 9 9 0 2 7 7 7 + 9 9 2 0 7 7 7 + 9 9 7 7 0 3 5 + 9 9 7 7 3 0 5 + 9 9 7 7 5 5 0}] + { a, b, c, d, e, f, g }; + "]] +} + + +--- +declare { + key = "upgma", + use = { { key = "unweighted pair group method using arithmetic averages" } }, + summary = "An shorthand for |unweighted pair group method using arithmetic averages|" +} + + + + +-- +-- The run function of the upgma algorithm. +-- +-- You must setup the following fields: The |main_algorithm| must +-- store the main algorithm object (for phase |main|). The |distances| +-- field must be a |Storage| object that will get filled with the +-- distances computed by this algorithm. The |lengths| field must also +-- be a |Storage| for the computed distances. +-- + +function SokalMichener1958:run() + self.distances = Storage.newTableStorage() + + self.tree = Digraph.new(self.main_algorithm.digraph) + + -- store the phylogentic tree object, containing all user-specified + -- graph information + self:runUPGMA() + self:createFinalEdges() + + return self.tree +end + + + +-- UPGMA (Unweighted Pair Group Method using arithmetic Averages) algorithm +-- (Sokal and Michener, 1958) +-- +-- this function generates a graph on the basis of such a distance +-- matrix by generating nodes and computing the edge lengths; the x- +-- and y-positions of the nodes must be set separately +-- +-- requirement: a distance matrix, ideally an ultrametric +function SokalMichener1958:runUPGMA() + local matrix = DistanceMatrix.graphDistanceMatrix(self.tree) + + local g = self.tree + local clusters = {} + + -- create the clusters + for _,v in ipairs(g.vertices) do + clusters[#clusters+1] = self:newCluster(v) + end + + -- Iniitialise the distances of these clusters: + for _,cx in ipairs(clusters) do + for _,cy in ipairs(clusters) do + cx.distances[cy] = matrix[cx.root][cy.root] + end + end + + -- search for clusters with smallest distance and merge them + while #clusters > 1 do + local minimum_distance = math.huge + local min_cluster1 + local min_cluster2 + for i, cluster in ipairs (clusters) do + for j = i+1,#clusters do + local cluster2 = clusters[j] + local cluster_distance = self:getClusterDistance(cluster, cluster2) + if cluster_distance < minimum_distance then + minimum_distance, min_cluster1, min_cluster2 = cluster_distance, i, j + end + end + end + self:mergeClusters(clusters, min_cluster1, min_cluster2, minimum_distance) + end +end + + +-- a new cluster is created +-- +-- @param vertex The vertex the cluster is initialized with +-- +-- @return The new cluster +function SokalMichener1958:newCluster(vertex) + return { + root = vertex, -- the root of the cluster + size = 1, -- the number of vertices in the cluster, + distances = {}, -- cached cluster distances to all other clusters + cluster_height = 0 -- this value is equivalent to half the distance of the last two clusters + -- that have been merged to form the current cluster; + -- necessary for determining the distances of newly generated nodes to their children. + } +end + + +-- gets the distance between two clusters +-- +-- @param cluster1, cluster2 The two clusters +-- +-- @return the distance between the clusters +function SokalMichener1958:getClusterDistance(c,d) + return c.distances[d] or d.distances[c] or 0 +end + + +-- merges two clusters by doing the following: +-- - deletes cluster2 from the clusters table +-- - adds all vertices from cluster2 to the vertices table of cluster1 +-- - updates the distances of the new cluster to all remaining clusters +-- - generates a new node, as the new root of the cluster +-- - computes the distance of the new node to the former roots (for +-- later computation of the y-positions) +-- - generates edges, connecting the new node to the former roots +-- - updates the cluster height +-- +-- @param clusters The array of clusters +-- @param index_of_first_cluster The index of the first cluster +-- @param index_of_second_cluster The index of the second cluster +-- @param distance The distance between the two clusters + +function SokalMichener1958:mergeClusters(clusters, index_of_first_cluster, index_of_second_cluster, distance) + + local g = self.tree + local cluster1 = clusters[index_of_first_cluster] + local cluster2 = clusters[index_of_second_cluster] + + --update cluster distances + for i,cluster in ipairs (clusters) do + if cluster ~= cluster1 and cluster ~= cluster2 then + local dist1 = self:getClusterDistance (cluster1, cluster) + local dist2 = self:getClusterDistance (cluster2, cluster) + local dist = (dist1*cluster1.size + dist2*cluster2.size)/ (cluster1.size+cluster2.size) + cluster1.distances[cluster] = dist + cluster.distances[cluster1] = dist + end + end + + -- delete cluster2 + table.remove(clusters, index_of_second_cluster) + + --add node and connect last vertex of each cluster with new node + local new_node = InterfaceToAlgorithms.createVertex( + self.main_algorithm, + { + name = "UPGMA-node ".. #self.tree.vertices+1, + generated_options = { { key = "phylogenetic inner node" } }, + } + ) + g:add{new_node} + -- the distance of the new node ( = the new root of the cluster) to its children (= the former roots) is + -- equivalent to half the distance between the two former clusters + -- minus the respective cluster height + local distance1 = distance/2-cluster1.cluster_height + self.distances[new_node][cluster1.root] = distance1 + local distance2 = distance/2-cluster2.cluster_height + self.distances[new_node][cluster2.root] = distance2 + + -- these distances are also the final edge lengths, thus: + self.lengths[new_node][cluster1.root] = distance1 + self.lengths[cluster1.root][new_node] = distance1 + + self.lengths[new_node][cluster2.root] = distance2 + self.lengths[cluster2.root][new_node] = distance2 + + g:connect(new_node, cluster1.root) + g:connect(new_node, cluster2.root) + + cluster1.root = new_node + cluster1.size = cluster1.size + cluster2.size + cluster1.cluster_height = distance/2 -- set new height of the cluster +end + + + +-- generates edges for the final graph +-- +-- throughout the process of creating the tree, arcs have been +-- disconnected and connected, without truly creating edges. this is +-- done in this function +function SokalMichener1958:createFinalEdges() + local g = self.tree + local o_arcs = {} -- copy arcs since createEdge is going to modify the arcs array... + for _,arc in ipairs(g.arcs) do + o_arcs[#o_arcs+1] = arc + end + for _,arc in ipairs(o_arcs) do + InterfaceToAlgorithms.createEdge( + self.main_algorithm, arc.tail, arc.head, + { generated_options = { + { key = "phylogenetic edge", value = tostring(self.lengths[arc.tail][arc.head]) } + }}) + end +end + + +return SokalMichener1958 diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua new file mode 100644 index 00000000000..194e809ef2e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua @@ -0,0 +1,35 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/phylogenetics/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- A phylogenetic tree (or network) depicts the evolutionary histroy +-- of species or, more generally, so called taxa. The present library +-- includes a number of algorithms for drawing phylogenetic trees. +-- +-- @library + +local phylogenetics -- Library name + +-- Main layout: +require "pgf.gd.phylogenetics.PhylogeneticTree" + +-- Phylogenetic tree drawing: +require "pgf.gd.phylogenetics.Maeusle2012" + +-- Phylogenetic tree generation: +require "pgf.gd.phylogenetics.SokalMichener1958" +require "pgf.gd.phylogenetics.BalancedMinimumEvolution" +require "pgf.gd.phylogenetics.BalancedNearestNeighbourInterchange" +require "pgf.gd.phylogenetics.AuthorDefinedPhylogeny" + + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua new file mode 100644 index 00000000000..b433e73a652 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua @@ -0,0 +1,183 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/tools/make_gd_wrap.lua,v 1.2 2013/01/01 17:10:09 tantau Exp $ + + + +--- +-- This program generates a C wrap file around graph drawing +-- algorithms. The idea is that when you have a graph drawing +-- algorithm implemented in C and wish to invoke it from Lua, you need +-- a wrapper that manages the translation between Lua and C. This +-- program is intended to make it (reasonably) easy to produce such a +-- wraper. + + + +-- Sufficient number of arguments? + +if #arg < 4 or arg[1] == "-h" or arg[1] == "-?" or arg[1] == "--help" then + print([[" +Usage: make_gd_wrap library1 library2 ... libraryn template library_name target_c_file + +This program will read all of the graph drawing library files using +Lua's require. Then, it will iterate over all declared algorithm keys +(declared using declare { algorithm_written_in_c = ... }) and will +produce the code for library for the required target C files based on +the template. +"]]) + os.exit() +end + + +-- Imports + +local InterfaceToDisplay = require "pgf.gd.interface.InterfaceToDisplay" +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" + + +-- Ok, setup: + +InterfaceToDisplay.bind(require "pgf.gd.bindings.Binding") + + +-- Now, read all libraries: + +for i=1,#arg-3 do + require(arg[i]) +end + + +-- Now, read the template: + +local file = io.open(arg[#arg-2]) +local template = file:read("*a") +file:close() + +-- Let us grab the declaration: + +local functions_dec = (template:match("%$functions(%b{})") or ""):match("^{(.*)}$") +local functions_reg_dec = (template:match("%$functions_registry(%b{})") or ""):match("^{(.*)}$") +local factories_dec = (template:match("%$factories(%b{})") or ""):match("^{(.*)}$") +local factories_reg_dec = (template:match("%$factories_registry(%b{})") or ""):match("^{(.*)}$") + +-- Now, handle all keys with a algorithm_written_in_c field + +local keys = InterfaceCore.keys +local filename = arg[#arg] +local target = arg[#arg-1] + +local includes = {} +local functions = {} +local functions_registry = {} + +local factories = {} +local factories_reg = {} + +for _,k in ipairs(keys) do + + if k.algorithm_written_in_c and k.code then + + local library, fun_name = k.algorithm_written_in_c:match("(.*)%.(.*)") + + if target == library then + -- First, gather the includes: + if type(k.includes) == "string" then + if not includes[k.includes] then + includes[#includes + 1] = k.includes + includes[k.includes] = true + end + elseif type(k.includes) == "table" then + for _,i in ipairs(k.includes) do + if not includes[i] then + includes[#includes + 1] = i + includes[i] = true + end + end + end + + -- Second, create a code block: + functions[#functions+1] = functions_dec:gsub("%$([%w_]-)%b{}", + { + function_name = fun_name, + function_body = k.code + }) + + -- Third, create functions_registry entry + functions_registry[#functions_registry + 1] = functions_reg_dec:gsub("%$([%w_]-)%b{}", + { + function_name = fun_name, + function_body = k.code + }) + end + end + + + if k.module_class then + + -- First, gather the includes: + if type(k.includes) == "string" then + if not includes[k.includes] then + includes[#includes + 1] = k.includes + includes[k.includes] = true + end + elseif type(k.includes) == "table" then + for _,i in ipairs(k.includes) do + if not includes[i] then + includes[#includes + 1] = i + includes[i] = true + end + end + end + + -- Second, create a code block: + factories[#factories+1] = factories_dec:gsub( + "%$([%w_]-)%b{}", + { + factory_class = k.module_class, + factory_code = k.code, + factory_base = k.module_base, + factory_name = k.module_class .. '_factory' + }) + + -- Third, create factories_registry entry + factories_reg[#factories_reg + 1] = factories_reg_dec:gsub( + "%$([%w_]-)%b{}", + { + factory_class = k.module_class, + factory_code = k.code, + factory_base = k.module_base, + factory_name = k.module_class .. '_factory' + }) + end +end + + +local file = io.open(filename, "w") + +if not file then + print ("failed to open file " .. filename) + os.exit(-1) +end + +file:write ((template:gsub( + "%$([%w_]-)%b{}", + { + factories = table.concat(factories, "\n\n"), + factories_registry = table.concat(factories_reg, "\n"), + functions = table.concat(functions, "\n\n"), + functions_registry = table.concat(functions_registry, "\n"), + includes = table.concat(includes, "\n"), + library_c_name = target:gsub("%.", "_"), + library_name = target + }))) +file:close() + + \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua new file mode 100644 index 00000000000..9aff2aaf1d7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua @@ -0,0 +1,21 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +--- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/trees.lua,v 1.1 2012/11/27 17:24:24 tantau Exp $ + + +local trees = {} + +-- Declare namespace +require("pgf.gd").trees = tree + + +-- Done + +return trees \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua new file mode 100644 index 00000000000..272af54e55e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua @@ -0,0 +1,227 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/trees/ChildSpec.lua,v 1.4 2013/05/23 20:01:29 tantau Exp $ + + + +--- +-- @section subsection {Specifying Missing Children} +-- +-- \label{section-gd-missing-children} +-- +-- In the present section we discuss keys for specifying missing children +-- in a tree. For many certain kind of trees, in particular for binary +-- trees, there are not just ``a certain number of children'' at each +-- node, but, rather, there is a designated ``first'' (or ``left'') child +-- and a ``second'' (or ``right'') child. Even if one of these children +-- is missing and a node actually has only one child, the single child will +-- still be a ``first'' or ``second'' child and this information should +-- be taken into consideration when drawing a tree. +-- +-- The first useful key for specifying missing children is +-- |missing number of children| which allows you to state how many +-- children there are, at minimum. +-- +-- Once the minimum number of children has been set, we still need a way +-- of specifying ``missing first children'' or, more generally, missing +-- children that are not ``at the end'' of the list of children. For +-- this, there are three methods: +-- +-- \begin{enumerate} +-- \item When you use the |child| syntax, you can use the |missing| key +-- with the |child| command to indicate a missing child: +-- \begin{codeexample}[] +-- \tikz [binary tree layout, level distance=5mm] +-- \node {a} +-- child { node {b} +-- child { node {c} +-- child { node {d} } +-- } } +-- child { node {e} +-- child [missing] +-- child { node {f} +-- child [missing] +-- child { node {g} +-- } } }; +-- \end{codeexample} +-- \item When using the |graph| syntax, you can use an ``empty node'', +-- which really must be completely empty and may not even contain a +-- slash, to indicate a missing node: +-- \begin{codeexample}[] +-- \tikz [binary tree layout, level distance=5mm] +-- \graph { a -> { b -> c -> d, e -> { , f -> { , g} } } }; +-- \end{codeexample} +-- \item You can simply specify the index of a child directly using +-- the key |desired child index|. +-- \end{enumerate} +-- +-- @end + + +-- Imports +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + +--- +-- +declare { + key = "minimum number of children", + type = "number", + initial = "0", + + summary = [[" + Specifies how many children a tree node must have at least. If + there are less, ``virtual'' children are added. + "]], + documentation = [[" + When this key is set to |2| or more, the following happens: We first + compute a spanning tree for the graph, see + Section~\ref{subsection-gd-spanning-tree}. Then, whenever a node is + not a leaf in this spanning tree (when it has at least one child), + we add ``virtual'' or ``dummy'' nodes as children of the node until + the total number of real and dummy children is at least + \meta{number}. If there where at least \meta{number} children at the + beginning, nothing happens. + + The new children are added after the existing children. This means + that, for instance, in a tree with \meta{number} set to |2|, for + every node with a single child, this child will be the first child + and the second child will be missing. + "]], + examples = [[" + \tikz \graph [binary tree layout,level distance=5mm] + { a -> { b->c->d, e->f->g } }; + "]] +} + +--- + +declare { + key = "desired child index", + type = "number", + + summary = [[" + Pass this key to a node to tell the graph drawing engine which child + number you ``desired'' for the node. Whenever all desires for the + children of a node are conflict-free, they will all be met; children + for which no desired indices were given will remain at their + position, whenever possible, but will ``make way'' for children with + a desired position. + "]], + documentation = [[" + In detail, the following happens: We first + determine the total number of children (real or dummy) needed, which + is the maximum of the actual number of children, of the + \texttt{minimum number of children}, and of the highest desired + child index. Then we go over all children that have a desired child + index and put they at this position. If the position is already + taken (because some other child had the same desired index), the + next free position is used with a wrap-around occurring at the + end. Next, all children without a desired index are place using the + same mechanism, but they want to be placed at the position they had + in the original spanning tree. + + While all of this might sound a bit complicated, the application of + the key in a binary tree is pretty straightforward: To indicate that + a node is a ``right'' child in a tree, just add \texttt{desired child index=2} + to it. This will make it a second child, possibly causing the fist + child to be missing. If there are two nodes specified as children of + a node, by saying \texttt{desired child index=}\meta{number} for one + of them, you will cause it be first or second child, depending on + \meta{number}, and cause the \emph{other} child to become the other + child. + + Since |desired child index=2| is a bit long, the following shortcuts + are available: |first|, |second|, |third|, and |fourth|. + You might wonder why |second| is used rather than |right|. The + reason is that trees may also grow left and right and, additionally, + the |right| and |left| keys are already in use for + anchoring. Naturally, you can locally redefine them, if you want. + "]], + examples = { + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> b[second] }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b[second], c} }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b, c[first]} }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b[second], c[second]} }; + "]], + [[" + \tikz \graph [binary tree layout, level distance=5mm] + { a -> { b[third], c[first], d} }; + "]] + } +} + + +--- + +declare { + key = "first", + use = { + { key = "desired child index", value = 1}, + }, + + summary = [[" + A shorthand for setting the desired child number to |1|. + "]] + } + +--- + +declare { + key = "second", + use = { + { key = "desired child index", value = 2}, + }, + + summary = [[" + A shorthand for setting the desired child number to |2|. + "]] + } + + +--- + +declare { + key = "third", + use = { + { key = "desired child index", value = 3}, + }, + + summary = [[" + A shorthand for setting the desired child number to |3|. + "]] + } + + +--- + +declare { + key = "fourth", + use = { + { key = "desired child index", value = 4} + }, + + summary = [[" + A shorthand for setting the desired child number to |4|. + "]] + } + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua new file mode 100644 index 00000000000..2bcade8b967 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua @@ -0,0 +1,211 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/trees/ReingoldTilford1981.lua,v 1.10 2013/05/23 20:01:29 tantau Exp $ + + + +--- +-- @section subsubsection {The Reingold--Tilford Layout} +-- +-- @end + +local ReingoldTilford1981 = {} + +-- Imports +local layered = require "pgf.gd.layered" +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare +local Storage = require "pgf.gd.lib.Storage" + +--- +declare { + key = "tree layout", + algorithm = ReingoldTilford1981, + + preconditions = { + connected = true, + tree = true + }, + + postconditions = { + upward_oriented = true + }, + + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + +--- +declare { + key = "missing nodes get space", + type = "boolean", + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + + +--- +declare { + key = "significant sep", + type = "length", + initial = "0", + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + +--- +declare { + key = "binary tree layout", + use = { + { key = "tree layout" }, + { key = "minimum number of children" , value=2 }, + { key = "significant sep", value = 10 }, + }, + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + +--- +declare { + key = "extended binary tree layout", + use = { + { key = "tree layout" }, + { key = "minimum number of children" , value=2 }, + { key = "missing nodes get space" }, + { key = "significant sep", value = 0 }, + }, + documentation_in = "pgf.gd.doc.trees.ReingoldTilford1981" +} + + + + +-- Now comes the implementation: + +function ReingoldTilford1981:run() + + local root = self.spanning_tree.root + + local layers = Storage.new() + local descendants = Storage.new() + + self.extended_version = self.digraph.options['missing nodes get space'] + + self:precomputeDescendants(root, 1, layers, descendants) + self:computeHorizontalPosition(root, layers, descendants) + layered.arrange_layers_by_baselines(layers, self.adjusted_bb, self.ugraph) + +end + + +function ReingoldTilford1981:precomputeDescendants(node, depth, layers, descendants) + local my_descendants = { node } + + for _,arc in ipairs(self.spanning_tree:outgoing(node)) do + local head = arc.head + self:precomputeDescendants(head, depth+1, layers, descendants) + for _,d in ipairs(descendants[head]) do + my_descendants[#my_descendants + 1] = d + end + end + + layers[node] = depth + descendants[node] = my_descendants +end + + + +function ReingoldTilford1981:computeHorizontalPosition(node, layers, descendants) + + local children = self.spanning_tree:outgoing(node) + + node.pos.x = 0 + + local child_depth = layers[node] + 1 + + if #children > 0 then + -- First, compute positions for all children: + for i=1,#children do + self:computeHorizontalPosition(children[i].head, layers, descendants) + end + + -- Now, compute minimum distances and shift them + local right_borders = {} + + for i=1,#children-1 do + + local local_right_borders = {} + + -- Advance "right border" of the subtree rooted at + -- the i-th child + for _,d in ipairs(descendants[children[i].head]) do + local layer = layers[d] + local x = d.pos.x + if self.extended_version or not (layer > child_depth and d.kind == "dummy") then + if not right_borders[layer] or right_borders[layer].pos.x < x then + right_borders[layer] = d + end + if not local_right_borders[layer] or local_right_borders[layer].pos.x < x then + local_right_borders[layer] = d + end + end + end + + local left_borders = {} + -- Now left for i+1 st child + for _,d in ipairs(descendants[children[i+1].head]) do + local layer = layers[d] + local x = d.pos.x + if self.extended_version or not (layer > child_depth and d.kind == "dummy") then + if not left_borders[layer] or left_borders[layer].pos.x > x then + left_borders[layer] = d + end + end + end + + -- Now walk down the lines and try to find out what the minimum + -- distance needs to be. + + local shift = -math.huge + local first_dist = left_borders[child_depth].pos.x - local_right_borders[child_depth].pos.x + local is_significant = false + + for layer,n2 in pairs(left_borders) do + local n1 = right_borders[layer] + if n1 then + shift = math.max( + shift, + layered.ideal_sibling_distance(self.adjusted_bb, self.ugraph, n1, n2) + n1.pos.x - n2.pos.x + ) + end + if local_right_borders[layer] then + if layer > child_depth and + (left_borders[layer].pos.x - local_right_borders[layer].pos.x <= first_dist) then + is_significant = true + end + end + end + + if is_significant then + shift = shift + self.ugraph.options['significant sep'] + end + + -- Shift all nodes in the subtree by shift: + for _,d in ipairs(descendants[children[i+1].head]) do + d.pos.x = d.pos.x + shift + end + end + + -- Finally, position root in the middle: + node.pos.x = (children[1].head.pos.x + children[#children].head.pos.x) / 2 + end +end + + + +return ReingoldTilford1981 \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua new file mode 100644 index 00000000000..24e9a69c385 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua @@ -0,0 +1,637 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/trees/SpanningTreeComputation.lua,v 1.7 2013/05/23 20:01:29 tantau Exp $ + + + +--- +-- @section subsection {Spanning Tree Computation} +-- +-- \label{subsection-gd-spanning-tree} +-- Although the algorithms of this library are tailored to layout trees, +-- they will work for any graph as input. First, if the graph is not +-- connected, it is decomposed into connected components and these are +-- laid out individiually. Second, for each component, a spanning tree of +-- the graph is computed first and the layout is computed for this +-- spanning tree; all other edges will still be drawn, but they have no +-- impact on the placement of the nodes. If the graph is already a tree, +-- the spanning tree will be the original graph. +-- +-- The computation of the spanning tree is a non-trivial process since +-- a non-tree graph has many different possible spanning trees. You can +-- choose between different methods for deciding on a spanning tree, it +-- is even possible to implement new algorithms. (In the future, the +-- computation of spanning trees and the cylce removal in layered graph +-- drawing algorithms will be unified, but, currently, they are +-- implemented differently.) +-- +-- Selects the (sub)algorithm that is to be used for computing spanning +-- trees whenever this is requested by a tree layout algorithm. The +-- default algorithm is |breadth first spanning tree|. +-- +--\begin{codeexample}[] +--\tikz \graph [tree layout, breadth first spanning tree] +--{ +-- 1 -- {2,3,4,5} -- 6; +--}; +--\end{codeexample} +--\begin{codeexample}[] +--\tikz \graph [tree layout, depth first spanning tree] +--{ +-- 1 --[bend right] {2,3,4,5 [>bend left]} -- 6; +--}; +--\end{codeexample} +-- +-- @end + +local SpanningTreeComputation = {} + + + +-- Namespace +require("pgf.gd.trees").SpanningTreeComputation = SpanningTreeComputation + + +-- Imports +local lib = require "pgf.gd.lib" + +local Vertex = require "pgf.gd.model.Vertex" +local Digraph = require "pgf.gd.model.Digraph" + + +local declare = require("pgf.gd.interface.InterfaceToAlgorithms").declare + + + + +-- ------------------------- -- +-- General tree parameters -- +-- ------------------------- -- + + + + +--- +-- +declare { + key = "breadth first spanning tree", + algorithm = { + run = + function (self) + return SpanningTreeComputation.computeSpanningTree(self.ugraph, false, self.events) + end + }, + phase = "spanning tree computation", + phase_default = true, + + summary = [[" + This key selects ``breadth first'' as the (sub)algorithm for + computing spanning trees. Note that this key does not cause a graph + drawing scope to start; the key only has an effect in conjunction + with keys like |tree layout|. + "]], + documentation = [[" + The algorithm will be called whenever a graph drawing algorithm + needs a spanning tree on which to operate. It works as follows: + \begin{enumerate} + \item It looks for a node for which the |root| parameter is + set. If there are several such nodes, the first one is used. If there + are no such nodes, the first node is used. + + Let call the node determined in this way the \emph{root node}. + \item For every edge, a \emph{priority} is determined, which is a + number between 1 and 10. How this happens, exactly, will be + explained in a moment. Priority 1 means ``most important'' while + priority 10 means ``least important''. + \item Starting from the root node, we now perform a breadth first + search through the tree, thereby implicitly building a spanning + tree: Suppose for a moment that all edges have priority~1. Then, + the algorithm works just the way that a normal breadth first + search is performed: We keep a queue of to-be-visited nodes and + while this queue is not empty, we remove its first node. If this + node has not yet been visited, we add all its neighbors at the + end of the queue. When a node is taken out of the queue, we make + it the child of the node whose neighbor it was when it was + added. Since the queue follows the ``first in, first out'' + principle (it is a fifo queue), the children of the root will be + all nodes at distance $1$ form the root, their children will be + all nodes at distance $2$, and so on. + \item Now suppose that some edges have a priority different + from~1, in which case things get more complicated. We now keep + track of one fifo queue for each of the ten possible + priorities. When we consider the neighbors of a node, we actually + consider all its incident edges. Each of these edges has a certain + priority and the neighbor is put into the queue of the edge's + priority. Now, we still remove nodes normally from the queue for + priority~1; only if this queue is empty and there is still a node + in the queue for priority~2 we remove the first element from this + queue (and proceed as before). If the second queue is also empty, + we try the third, and so on up to the tenth queue. If all queues + are empty, the algorithm stops. + \end{enumerate} + + The effect of the ten queues is the following: If the edges of + priority $1$ span the whole graph, a spanning tree consisting solely + of these edges will be computed. However, if they do not, once we + have visited reachable using only priority 1 edges, we will extend + the spanning tree using a priority 2 edge; but then we once switch + back to using only priority 1 edges. If neither priority~1 nor + priority~2 edges suffice to cover the whole graph, priority~3 edges + are used, and so on. + "]] + } + +--- + +declare { + key = "depth first spanning tree", + algorithm = { + run = + function (self) + return SpanningTreeComputation.computeSpanningTree(self.ugraph, true, self.events) + end + }, + phase = "spanning tree computation", + + summary = [[" + Works exactly like |breadth first spanning tree| (same handling of + priorities), only the queues are now lifo instead of + fifo. + "]] + } + +--- +-- +declare { + key = "root", + type = "boolean", + default = true, + + summary = [[" + This Boolean parameter is used in the computation of spanning + trees. When can be set for a node, this node will be used as the + root for the spanning tree computation. If several nodes have this + option set, the first node will be used. + "]] + } + + +--- +-- +declare { + key = "span priority", + type = "number", + + summary = [[" + Explicitly sets the ``span priority'' of an edge to \meta{number}, which must be + a number between |1| and |10|. The priority of edges is used by + spanning tree computations, see |breadth first spanning tree|. + "]] + } + + + +--- +-- when it comes to choosing which edges are part of the spanning tree. +declare { + key = "span edge", + use = { + { key = "span priority", value = 1 }, + }, + + summary = [[" + An easy-to-remember shorthand for |span priority=1|. When this key + is used with an edge, it will always be preferred over other edges + "]] + } + + + + +--- +-- +declare { + key = "no span edge", + use = { + { key = "span priority", value = 10 }, + }, + + summary = [[" + An easy-to-remember shorthand for |span priority=10|. This causes + the edge to be used only as a last resort as part of a spanning + tree. + "]], + documentation = [[" + In the example, we add lots of edges that would normally be + preferred in the computation of the spanning tree, but use + |no span edge| to cause the algorithm to ignore these edges. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw}, sibling distance=0pt, + every group/.style={ + default edge kind=->, no span edge, + path=source}] + { + 5 -> { + "1,3" -> {0,2,4}, + 11 -> { + "7,9" -> { 6, 8, 10 } + } + } + }; + "]] +} + + + +--- +declare { + key = "span priority ->", + type = "number", + initial = "3", + + summary = [[" + This key stores the span priority of all edges whose direction is + |->|. There are similar keys for all other directions, such as + |span priority <-| and so on. + "]], + documentation = [[" + When you write +\begin{codeexample}[code only] +graph { a -> b -- c <- [span priority=2] d } +\end{codeexample} + the priority of the edge from |a| to |b| would be the current + value of the key |span priority ->|, the priority of the edge from + |b| to |c| would be the current value of |span priority --|, and + the priority of the edge from |c| to |d| would be |2|, regardless + of the value of |span priority <-|. + + The defaults for the priorities are: + \begin{itemize} + \item |span priority -> = 3| + \item |span priority -- = 5| + \item |span priority <-> = 5| + \item |span priority <- = 8| + \item |span priority -!- = 10| + \end{itemize} + "]] +} + + + +--- + +declare { + key = "span priority reversed ->", + type = "number", + initial = "9", + + documentation = [[" + This key stores the span priority of traveling across reversed + edges whose actual direction is |->| (again, there are similar keys + for all other directions). + "]], + documentation = [[" + When you write +\begin{codeexample}[code only] +graph { a -> b -- c <- [span priority=2] d } +\end{codeexample} + there are, in addition to the priorities indicated above, also + further edge priorities: The priority of the (reversed) edge |b| + to |a| is |span priority reversed ->|, the priority of the + (reversed) edge |c| to |b| is |span priority reversed --|, and the + span priority of the reversed edge |d| to |c| is |2|, regardless + of the value of |span priority reversed <-|. + + The defaults for the priorities are: + \begin{itemize} + \item |span priority reversed -> = 9| + \item |span priority reversed -- = 5| + \item |span priority reversed <-> = 5| + \item |span priority reversed <- = 7| + \item |span priority reversed -!- = 10| + \end{itemize} + + The default priorities are set in such a way, that non-reversed |->| + edges have top priorities, |--| and |<->| edges have the same + priorities in either direction, and |<-| edges have low priority in + either direction (but going |a <- b| from |b| to |a| is given higher + priority than going from |a| to |b| via this edge and also higher + priority than going from |b| to |a| in |a -> b|). + + Keys like |span using directed| change the priorities ``en bloc''. + "]] +} + + +declare { + key = "span priority <-", + type = "number", + initial = "8", +} + +declare { + key = "span priority reversed <-", + type = "number", + initial = "7", +} + +declare { + key = "span priority --", + type = "number", + initial = "5", +} + +declare { + key = "span priority reversed --", + type = "number", + initial = "5", +} + +declare { + key = "span priority <->", + type = "number", + initial = "5", +} + +declare { + key = "span priority reversed <->", + type = "number", + initial = "5", +} + +declare { + key = "span priority -!-", + type = "number", + initial= "10", +} + +declare { + key = "span priority reversed -!-", + type = "number", + initial= "10", +} + +--- + +declare { + key = "span using directed", + use = { + { key = "span priority reversed <-", value = 3}, + { key = "span priority <->", value = 3}, + { key = "span priority reversed <->", value = 3}, + }, + summary = [[" + This style sets a priority of |3| for all edges that are directed + and ``go along the arrow direction'', that is, we go from |a| to + |b| with a priority of |3| for the cases |a -> b|, |b <- a|, + |a <-> b|, and |b <-> a|. + This strategy is nice with trees specified with both forward and + backward edges. + "]], + examples = [[" + \tikz \graph [tree layout, nodes={draw}, sibling distance=0pt, + span using directed] + { + 3 <- 5[root] -> 8, + 1 <- 3 -> 4, + 7 <- 8 -> 9, + 1 -- 4 -- 7 -- 9 + }; + "]] +} + +--- + +declare { + key = "span using all", + use = { + { key = "span priority <-", value = 5}, + { key = "span priority ->", value = 5}, + { key = "span priority <->", value = 5}, + { key = "span priority --", value = 5}, + { key = "span priority -!-", value = 5}, + { key = "span priority reversed <-", value = 5}, + { key = "span priority reversed ->", value = 5}, + { key = "span priority reversed <->", value = 5}, + { key = "span priority reversed --", value = 5}, + { key = "span priority reversed -!-", value = 5}, + }, + + summary = [[" + Assings a uniform priority of 5 to all edges. + "]] +} + + +-- The implementation + +-- +-- Compute a spanning tree of a graph +-- +-- The algorithm will favor nodes according to their priority. This is +-- determined through an edge priority function. +-- +-- @param ugraph An undirected graph for which the spanning tree +-- should be computed +-- @param dfs True if depth first should be used, false if breadth +-- first should be used. +-- +-- @return A new graph that is a spanning tree. + +function SpanningTreeComputation.computeSpanningTree (ugraph, dfs, events) + + local tree = Digraph.new (ugraph) -- copy vertices + + local edge_priorities = ugraph.options['/graph drawing/edge priorities'] + + local root = lib.find(ugraph.vertices, function (v) return v.options['root'] end) or ugraph.vertices[1] + + -- Traverse tree, giving preference to directed edges and, that + -- failing, to undirected and bidirected edges, and, that failing, + -- all other edges. + local marked = {} + + local stacks = { -- 10 stacks for 10 priorities, with 1 being the highest + { { parent = nil, node = root}, top = 1, bottom = 1 }, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1}, + { top = 0, bottom = 1} + } + + local function stack_is_non_empty (s) return s.top >= s.bottom end + + while lib.find(stacks, stack_is_non_empty) do + local parent, node + + for _,stack in ipairs(stacks) do + if stack_is_non_empty(stack) then + -- Pop + parent = stack[stack.top].parent + node = stack[stack.top].node + + stack[stack.top] = nil + stack.top = stack.top - 1 + + break + end + end + + if not marked[node] then + + -- The node is good! + marked[node] = true + + if parent then + tree:connect(parent,node) + end + + local arcs = ugraph:outgoing(node) + + for j=1,#arcs do + local arc = arcs[dfs and j or #arcs - j + 1] + local head = arc.head + + if not marked[head] then + local priority = arc:spanPriority() + local stack = assert(stacks[priority], "illegal edge priority") + if dfs then + stack.top = stack.top + 1 + stack[stack.top] = { parent = node, node = head} + else + stack.bottom = stack.bottom - 1 + stack[stack.bottom] = { parent = node, node = head} + end + end + end + end + end + + -- Now, copy vertex list + local copy = {} + for i,v in ipairs(tree.vertices) do + copy[i] = v + end + + -- Now, setup child lists + for _,v in ipairs(copy) do + + -- Children as they come from the spanning tree computation + tree:sortOutgoing(v, function (a,b) return a:eventIndex() < b:eventIndex() end) + local outgoings = tree:outgoing(v) + + -- Compute children as they come in the event list: + local children = {} + + local i = (v.event.index or 0)+1 + while i <= #events and events[i].kind == "edge" do + i = i + 1 + end + + if events[i] and events[i].kind == "begin" and events[i].parameters == "descendants" then + -- Ok, the node is followed by a descendants group + -- Now scan for nodes that are not inside a descendants group + local stop = events[i].end_index + local j = i+1 + while j <= stop do + if events[j].kind == "node" then + children[#children+1] = events[j].parameters + elseif events[j].kind == "begin" and events[j].parameters == "descendants" then + j = events[j].end_index + end + j = j + 1 + end + + -- Test, whether outgoings and children contain the same nodes: + local function same_elements() + local hash = {} + for v,c in ipairs(outgoings) do + hash[c.head] = true + end + local count = 0 + for _,c in pairs(children) do + if c ~= "" then + count = count + 1 + if not hash[c] or count > #outgoings then + return false + end + end + end + return count == #outgoings + end + + if same_elements() and #outgoings > 0 then + + -- increase number of children, if necessary + local needed = math.max(#children, lib.lookup_option('minimum number of children', v, ugraph)) + for i=1,#children do + if children[i] ~= "" then + local d = children[i].options['desired child index'] + needed = d and math.max(needed, d) or needed + end + end + + local new_children = {} + for i=1,#children do + if children[i] ~= "" then + local d = children[i].options['desired child index'] + if d then + local target = d + + while new_children[target] do + target = 1 + (target % #children) + end + new_children[target] = children[i] + end + end + end + for i=1,#children do + if children[i] ~= "" then + local d = children[i].options['desired child index'] + if not d then + local target = i + + while new_children[target] do + target = 1 + (target % #children) + end + new_children[target] = children[i] + end + end + end + for i=1,needed do + if not new_children[i] then + local new_child = Vertex.new{ kind = "dummy" } + new_children[i] = new_child + tree:add {new_child} + tree:connect(v,new_child) + end + end + + tree:orderOutgoing(v,new_children) + end + end + end + + tree.root = root + + return tree +end + + + +-- Done + +return SpanningTreeComputation \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua new file mode 100644 index 00000000000..f34aee06792 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua @@ -0,0 +1,35 @@ +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/trees/library.lua,v 1.2 2013/04/04 20:43:45 tantau Exp $ + + + +--- +-- \tikzname\ offers several different syntax to specify trees (see +-- Sections \ref{section-library-graphs} +-- and~\ref{section-trees}). The job of the graph drawing algorithms from +-- this library is to turn the specification of trees into beautiful +-- layouts. +-- +-- We start this section with a description of algorithms, then we have a +-- look at how missing children can be specified and at what happens when +-- the input graph is not a tree. +-- +-- @library + +local trees -- Library name + +-- Load declarations from: +require "pgf.gd.trees.ChildSpec" +require "pgf.gd.trees.SpanningTreeComputation" + +-- Load algorithms from: +require "pgf.gd.trees.ReingoldTilford1981" + diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex new file mode 100644 index 00000000000..9c017b5577d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex @@ -0,0 +1,16 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.circular.code.tex,v 1.4 2012/11/20 23:34:18 tantau Exp $ + + +\usegdlibrary{circular} + +\endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex new file mode 100644 index 00000000000..02d4d8ffa30 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex @@ -0,0 +1,1126 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.code.tex,v 1.38 2013/08/28 11:47:35 tantau Exp $ + + + +% check if luatex is running + +\ifx\directlua\relax% + \pgferror{You need to run LuaTeX to use the graph drawing library} + \expandafter\endinput +\fi +\ifx\directlua\undefined% + \pgferror{You need to run LuaTeX to use the graph drawing library} + \expandafter\endinput +\fi + + + + +% +% All graph drawing keys normally live in the following namespace: +% /graph drawing. +% + +\def\pgfgdset{\pgfqkeys{/graph drawing}} + + +% Setup a key +% +% #1 = key +% +% Description: +% +% An internal macro that sets up #1 as a graph drawing key. + +\def\pgfgd@callbackkey#1{ + \pgf@gd@setup@forwards{#1} + \pgfutil@g@addto@macro\pgf@gd@forwards@list{\pgf@gd@setup@forwards{#1}} +} +\def\pgf@gd@setup@forwards#1{ + \let\pgf@temp\pgfutil@empty + \foreach \pgf@gd@path in \pgf@gd@forwarding@list { + \ifx\pgf@gd@path\pgfutil@empty\else% + \expandafter\pgfutil@g@addto@macro% + \expandafter\pgf@temp\expandafter{% + \expandafter\pgfkeys\expandafter{\pgf@gd@path#1/.forward to=/graph drawing/#1}} + \fi% + }% + \pgf@temp +} + +\let\pgf@gd@forwards@list\pgfutil@empty + + +% Append to the forwarding list: +% +% #1 = paths to append to the forwarding list +% +% Description: +% +% Append the paths in #1 (with trailing slashes) to the forwarding +% list. +% +% If algorithms have already been declared, forwarding will also be +% setup for them (using a bit of magic...). + +\def\pgfgdappendtoforwardinglist#1{% + \let\pgf@gd@forwarding@list@orig\pgf@gd@forwarding@list + \def\pgf@gd@forwarding@list{#1}% + \pgf@gd@forwards@list% + \expandafter\def\expandafter\pgf@gd@forwarding@list\expandafter{\pgf@gd@forwarding@list@orig,#1} +} +\let\pgf@gd@forwarding@list\pgfutil@empty + + + +% +% +% Callbacks +% +% The following macros are called *from* the binding layer. You do not +% call them from the pgf layer. +% +% + + +% Callback for declaring a graph parameter key +% +% #1 = Parameter key +% #2 = Parameter type +% +% Description: +% +% When a graph drawing algorithm starts working, a set of options, +% called "graph drawing parameters" in the following, can influence the +% way the algorithm works. For instance, an graph drawing parameter +% might be the average distance between vertices which the algorithm +% should take into account. Another example might be the fact the +% certain nodes are special nodes and that a certain edge should have +% a large label. +% +% These graph drawing parameters are different from "usual" pgf +% options: An alogrithmic parameter influenced the way the algorithm +% works, while usual options normally only influence how the result +% looks like. For instance, the fact that a node is red is not an +% graph drawing parameter (usually, at least), while the shape of a node +% might be an graph drawing parameter. +% +% Graph drawing parameters are declared by the algorithmic layer +% (since only this layer "knows" which parameters there are). The +% binding to TeX will call the \pgfgddeclareparameter function +% internally. +% +% Specifying the set of graph drawing parameters for a given graph or +% node or edge works as follows: When the graph drawing engine is +% started for a graph (using \pgfgdbeginscope), a snapshot is taken of +% all graph drawing parameters currently setup at this +% point. Similarly, when a node is created inside such a scope, a +% snapshot is taken of the set of all graph drawing parameters in +% force at this point is taken and stored together with the +% node. Finally, when an edge is created, a snapshot of the setting of +% the graph drawing parameters is taken. + +\def\pgfgdcallbackdeclareparameter#1#2{% + \pgfkeysdef{/graph drawing/#1}{\pgf@gd@handle@parameter{#1}{#2}{##1}}% + \pgfgd@callbackkey{#1}% +} +\def\pgf@gd@handle@parameter#1#2#3{% + \def\pgf@temp{#3}% + \ifx\pgf@temp\pgfkeysnovalue@text% + \let\pgfgdresult\pgfgd@niltext% + \else% + \pgfkeys{/graph drawing/conversions/#2={#3}}% + \fi% + \advance\pgf@gd@parameter@stack@height by1\relax% + \pgf@gd@parameter@stack@height\directlua{% + local new, main = pgf.gd.interface.InterfaceToDisplay.pushOption('\pgfutil@luaescapestring{#1}',\pgfgdresult,\the\pgf@gd@parameter@stack@height) + tex.print(new..'\pgfutil@luaescapestring{\relax}') + if main then + tex.print('\pgfutil@luaescapestring{\noexpand\pgfgdtriggerrequest}') + end}% +}% +\newcount\pgf@gd@parameter@stack@height + +\def\pgfgdtriggerrequest{\pgfgdset{@request scope and layout}} + + +% Conversions are used to adapt the syntactic description of a +% parameter on the TikZ layer to the one expected by Lua. The set of +% permissible conversions is described in +% InterfaceToAlgorithms.declareParameter. + +\pgfgdset{ + conversions/string/.code=\def\pgfgdresult{'\pgfutil@luaescapestring{\detokenize{#1}}'}, + conversions/raw/.code=\def\pgfgdresult{#1}, + conversions/nil/.code=\let\pgfgdresult\pgfgd@niltext, + conversions/boolean/.code=\def\pgf@test{#1}\ifx\pgf@test\pgf@truetext\def\pgfgdresult{true}\else\ifx\pgf@test\pgfkeysnovalue@text\def\pgfgdresult{true}\else\def\pgfgdresult{false}\fi\fi, + conversions/number/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult, + conversions/length/.code=\pgfmathparse{#1}\let\pgfgdresult\pgfmathresult, + conversions/direction/.code=\pgf@lib@gd@grow@dir{#1}\let\pgfgdresult\pgfmathresult, + conversions/canvas coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{pgf.gd.model.Coordinate.new(#1,#2)}}, + % deprecated, will be removed: + conversions/coordinate/.code args={(#1pt,#2pt)}{\edef\pgfgdresult{{#1,#2}}} +} +\def\pgf@truetext{true} +\def\pgfgd@niltext{nil} + +\def\pgf@lib@gd@grow@dir#1{% + \def\pgf@temp{#1}% + \ifx\pgf@temp\pgf@gd@lib@active@bar% + \def\pgfmathresult{-90} + \else% + \ifcsname pgf@orient@direction@#1\endcsname% + \expandafter\let\expandafter\pgfmathresult\csname pgf@orient@direction@#1\endcsname% + \else + \pgfmathparse{#1}% + \fi + \fi +} + +\def\pgf@orient@direction@down{-90} +\def\pgf@orient@direction@up{90} +\def\pgf@orient@direction@left{180} +\def\pgf@orient@direction@right{0} + +\def\pgf@orient@direction@south{-90} +\def\pgf@orient@direction@north{90} +\def\pgf@orient@direction@west{180} +\def\pgf@orient@direction@east{0} + +\expandafter\def\csname pgf@orient@direction@north east\endcsname{45} +\expandafter\def\csname pgf@orient@direction@north west\endcsname{135} +\expandafter\def\csname pgf@orient@direction@south east\endcsname{-45} +\expandafter\def\csname pgf@orient@direction@south west\endcsname{-135} + +\expandafter\def\csname pgf@orient@direction@-\endcsname{0} +\expandafter\def\csname pgf@orient@direction@|\endcsname{-90} + +{ + \catcode`\|=13 + \gdef\pgf@gd@lib@active@bar{|} +} + + + + + +% Callback for starting the rendering of a collection kind +% +% #1 = Kind +% #2 = Layer +% +% Description: +% +% Executes /graph drawing/#1/begin rendering/.try +% + +\def\pgfgdcallbackrendercollectionkindstart#1#2{% + \ifnum#2<0\relax + \setbox\pgf@gd@prekind@box=\hbox\bgroup% + \unhbox\pgf@gd@prekind@box% + \else% + \setbox\pgf@gd@postkind@box=\hbox\bgroup% + \unhbox\pgf@gd@postkind@box% + \fi% + \pgfgdset{/graph drawing/#1/begin rendering/.try}% +} + +% Callback for ending the rendering of a collection kind +% +% #1 = Kind +% #2 = Layer +% +% Description: +% +% Executes /graph drawing/#1/end rendering/.try +% + +\def\pgfgdcallbackrendercollectionkindstop#1#2{% + \pgfgdset{/graph drawing/#1/end rendering/.try}% + \egroup % close box +} + + + +% Callback for rendering a collection +% +% #1 = Kind +% #2 = Options +% +% Description: +% +% Executes /graph drawing/#1/render/.try={#2} +% + +\def\pgfgdcallbackrendercollection#1#2{ + \pgfgdset{/graph drawing/#1/render/.try={#2}} +} + + + + + +% Graph events +% +% Although a graph consists of nodes and edges, during the +% construction of the graph a lot of information concerning the +% structure of the graph is often available. For instance, as we +% specify a graph using the child-syntax, we do not only which edges +% are present, but we can implicitly specify an ordering on the +% nodes. Even more, there is even information availble concerning +% nodes that are not present at all: A child[missing] is not present +% as a node or an edge, but a tree drawing algorithm will want to know +% about this child nevertheless. +% +% In order to communicate such information to the graph drawing +% engine, "events" are used. As a graph is created, in addition to +% nodes and edges, "events" may happen. The events come in a +% sequential order and they are stored together with the graph. For +% each node and each edge, its index in the event sequence is +% stored, that is, it is stored how many events happened before the +% node or edge was created. +% +% Internally, an event consists of a name and, possibly, some +% parameters. When the parameter is created on the tikz level, it will +% be a string that is passed down to Lua. Internally created events +% will also have parameters that are objects. +% +% Two events are a bit special since they get special internal +% support: The begin and end events. The first signals that some kind +% of group has started; which is closed by the corresponding end +% event. The "kind" of group is indicated by the parameter of the +% begin event. +% +% +% +% Standard events are: +% +% For each node entered into a graph, a "node" event is automatically +% created internally with the parameter being the node. However, you +% can also create this event yourself. In this case, the parameter +% will be a string and will mean that the node is "virtual" or +% "missing", but space should be reserved for it, if possible (this is +% use, for instance, by certain tree layouts). +% +% For each edge entered into a graph, an "edge" event is automatically +% created, with the edge as the parameter. Again, an event with a +% string parameter corresponds to a "non-existing" node. +% +% +% Standard event groups are: +% +% +% The "descendants" event group include a set of nodes that, at least +% inside the specification, are descendants of the last node +% +% begin descendants +% ... +% end +% +% +% The "array" event group collects together some nodes in an array of +% nodes. This can be used, for instance, to specify matrices. +% +% begin array +% ... +% end + + + +% Create a new event +% +% #1 = event name (should be a valid lua identifier name) +% #2 = parameter (some text) +% +% Description: +% +% Adds a new event to the event sequence of the graph + +\def\pgfgdevent#1#2{% + \directlua{pgf.gd.interface.InterfaceToDisplay.createEvent('\pgfutil@luaescapestring{#1}', '\pgfutil@luaescapestring{#2}')}% +} + + +% Start an event group +% +% #1 = kind of event group +% +% Description: +% +% Creates a begin event with #1 as the parameter of the begin +% event. + +\def\pgfgdbegineventgroup#1{% + \pgfgdevent{begin}{#1}% +} + +% End an event group +% +% Description: +% +% Creates an end event. + +\def\pgfgdendeventgroup{% + \pgfgdevent{end}{}% +} + + +% Creates an event group for the current TeX group +% +% #1 = event group name +% +% Description: +% +% Issues a begin event for #1 and, using \aftergroup, adds an end +% event at the end of the current tex group. + +\def\pgfgdeventgroup#1{% + \pgfgdbegineventgroup{#1}% + \aftergroup\pgfgdendeventgroup% +} + + + + + +% +% Nodes +% + + + +% +% Callback method for \pgfpositionnodelater +% +% This function is called by \pgfnode whenever a node has been newly +% created inside a graph drawing scope. It will create a new vertex on +% the Lua layer. +% +\def\pgf@gd@positionnode@callback{% + {% + % evaluate coordinates + \pgfmathsetmacro{\pgf@gd@node@minx}{\pgfpositionnodelaterminx}% + \pgfmathsetmacro{\pgf@gd@node@miny}{\pgfpositionnodelaterminy}% + \pgfmathsetmacro{\pgf@gd@node@maxx}{\pgfpositionnodelatermaxx}% + \pgfmathsetmacro{\pgf@gd@node@maxy}{\pgfpositionnodelatermaxy}% + % Assemble the Path object: + \directlua{pgf.temp = require 'pgf.gd.model.Path'.new ()}% + \let\pgfsyssoftpath@movetotoken\pgf@gd@movetotoken% + \let\pgfsyssoftpath@linetotoken\pgf@gd@linetotoken% + \let\pgfsyssoftpath@rectcornertoken\pgf@gd@rectcornertoken% + \let\pgfsyssoftpath@curvetosupportatoken\pgf@gd@curvetosupportatoken% + \let\pgfsyssoftpath@closepathtoken\pgf@gd@closepathtoken% + \pgfpositionnodelaterpath% + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + % + {% + \pgf@process{\pgfpointanchor{\pgfpositionnodelatername}{center}} + \pgfsettransform{\csname pgf@sh@nt@\pgfpositionnodelatername\endcsname}% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x=\pgf@x% + \global\pgf@y=\pgf@y% + }% + % call lua system library to create a lua node object + \directlua{ + pgf.gd.interface.InterfaceToDisplay.createVertex( + string.sub('\pgfutil@luaescapestring{\pgfpositionnodelatername}',30), % strip "not yet positionedPGFINTERNAL" + '\pgfutil@luaescapestring{\csname pgf@sh@ns@\pgfpositionnodelatername\endcsname}', + pgf.temp:pad((\pgf@sys@tonumber\pgf@xa+\pgf@sys@tonumber\pgf@ya)/2), % Padded path + \the\pgf@gd@parameter@stack@height, % Stack height + {% Binding info + x_min = \pgf@gd@node@minx, + y_min = \pgf@gd@node@miny, + x_max = \pgf@gd@node@maxx, + y_max = \pgf@gd@node@maxy, + tex_box_number = \pgfpositionnodelaterbox + }, + {% Anchors + center = require 'pgf.gd.model.Coordinate'.new(\pgf@sys@tonumber\pgf@x,\pgf@sys@tonumber\pgf@y) + } + ) + pgf.temp = nil + } + }% +} + + +\def\pgf@gd@movetotoken#1#2{\directlua{pgf.temp:appendMoveto(\Pgf@geT#1,\Pgf@geT#2)}} +\def\pgf@gd@linetotoken#1#2{\directlua{pgf.temp:appendLineto(\Pgf@geT#1,\Pgf@geT#2)}} +\def\pgf@gd@rectcornertoken#1#2#3#4#5{% + \directlua{% + local x,y,dx,dy=\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5 + pgf.temp:appendMoveto(x,y) + pgf.temp:appendLineto(x,y+dy) + pgf.temp:appendLineto(x+dx,y+dy) + pgf.temp:appendLineto(x+dx,y) + pgf.temp:appendClosepath()% + }% +} +\def\pgf@gd@curvetosupportatoken#1#2#3#4#5#6#7#8{\directlua{pgf.temp:appendCurveto(\Pgf@geT#1,\Pgf@geT#2,\Pgf@geT#4,\Pgf@geT#5,\Pgf@geT#7,\Pgf@geT#8)}} +\def\pgf@gd@closepathtoken#1#2{\directlua{pgf.temp:appendClosepath()}} + + +% Set options for an already existing node +% +% #1 = node name +% +% These node parameters of #1 will be updated with the current values +% of the node parameters. The node #1 must previously have been passed +% to the gd engine. If some of the options have already been set for +% the node, these settings will be overruled. + +\def\pgfgdsetlatenodeoption#1{% + \directlua{ + pgf.gd.interface.InterfaceToDisplay.addToVertexOptions('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height) + } +} + + + +% +% A callback for rendering (finally positioning) a node +% +% #1 = name of the node +% #2 = x min of the bounding box +% #3 = x max of the bounding box +% #4 = y min of the bounding box +% #5 = y max of the bounding box +% #6 = desired x pos of the node +% #7 = desired y pos of the node +% #8 = box register number of the TeX node +% +% This callback will be called by the engine for every original node +% when it finally needs to placed at a final position. + +\def\pgfgdcallbackrendernode#1#2#3#4#5#6#7#8{% + {% + \def\pgfpositionnodelatername{#1} + \def\pgfpositionnodelaterminx{#2} + \def\pgfpositionnodelatermaxx{#3} + \def\pgfpositionnodelaterminy{#4} + \def\pgfpositionnodelatermaxy{#5} + \directlua{pgf.gd.interface.InterfaceCore.binding:retrieveBox(#8,\pgfpositionnodelaterbox)} + \pgfpositionnodenow{\pgfqpoint{#6}{#7}} + }% +} + + + +% Adds an edge to the graph +% +% #1 = first node +% #2 = second node +% #3 = edge direction +% #4 = edge options (will be executed in a protected environment) +% #5 = aux stuff (curtesy for TikZ -- edge nodes) +% +% Description: +% +% Creating an edge means that you tell the graph drawing algorithm +% that #1 and #2 are connected. The "kind" of connection is indicated +% by #3, which may be one of the following: +% +% -> = a directed edge (also known as an arc) from #1 to #2 +% -- = an undirected edge between #1 and #2 +% <- = a directed edge from #2 to #1, but with the "additional hint" +% that this is a "backward" edge. A graph drawing algorithm may +% or may not take this hint into account +% <-> = a bi-directed edge between #1 and #2. +% +% +% The parameters #4 and #5 are a bit more tricky. When an edge between +% two vertices of a graph is created via \pgfgdedge, nothing is +% actually done immediately. After all, without knowing the final +% positions of the nodes #1 and #2, there is no way of +% creating the actual drawing commands for the edge. Thus, the actual +% drawing of the edge is done only when the graph drawing algorithm is +% done (namely in the macro \pgfgdcallbackedge, see later). +% +% Because of this "delayed" drawing of edges, options that influence +% the edge must be retained until the moment when the edge is actually +% drawn. Parameters #4 and #5 store such options. +% +% Let us start with #4. This parameter should be set to a list of +% key-value pairs like +% +% /tikz/.cd, color=red, very thick, this edge must be vertical +% +% Some of these options may be of interest to the graph drawing +% algorithm (like the last option) while others will +% only be important during the drawing of edge (like the first +% option). The options that are important for the graph drawing +% algorithm must be passed to the algorithm via setting keys that have +% been declared using the handler .edge parameter (see +% above). +% +% The tricky part is that options that are of interest to the graph +% drawing algorithm must be executed *before* the algorithm starts, +% but the options as a whole are usually only executed during the +% drawing of the edges, which is *after* the algorithm has finished. +% +% To overcome this problem, the following happens: +% +% The options in #4 are executed "tentatively" inside +% \pgfgdedge. However, this execution is done in a "heavily guarded +% sandbox" where all effects of the options (like changing the +% color or the line width) do not propagate beyond the sandbox. Only +% the changes of the graph drawing edge parameters leave the +% sandbox. These parameters are then passed down to the graph drawing +% engine. +% +% Later, when the edge is drawn using \pgfgdcallbackedge, the options #4 +% are available once more and then they are executed normally. +% +% Note that when the options in #4 are executed, no path is +% preset. Thus, you typically need to start it with, say, /tikz/.cd. +% +% +% The text in #5 is some "auxilliary" text that is simply stored away +% and later directly to \pgfgdcallbackedge. This is a curtesy to TikZ, +% which can use it to store its node labels. +% +% Example: +% +% \pgfgdedge{A}{B}{->}{red}{} +% +\def\pgfgdedge#1#2#3#4#5{% + % Ok, setup sandbox + \begingroup% + \setbox0=\hbox{{% + \pgfinterruptpath% + \pgfgdprepareedge% + \pgfkeys{#4}% + % create edge in Lua + \toks0={#4}% + \toks1={#5}% + \directlua{ + pgf.gd.interface.InterfaceToDisplay.createEdge( + '\pgfutil@luaescapestring{#1}','\pgfutil@luaescapestring{#2}','\pgfutil@luaescapestring{#3}', + \the\pgf@gd@parameter@stack@height, + { pgf_options = '\pgfutil@luaescapestring{\the\toks0}', + pgf_edge_nodes = '\pgfutil@luaescapestring{\the\toks1}', + }) + }% + \endpgfinterruptpath% + }}% + \endgroup% +} + +\let\pgfgdprepareedge=\pgfutil@empty +\def\pgfgdaddprepareedgehook#1{\expandafter\def\expandafter\pgfgdprepareedge\expandafter{\pgfgdprepareedge#1}} + + +\newif\ifpgf@gd@nodes@behind@edges + + + +% Define a callback for rendering edges +% +% #1 = macro name +% +% Descriptions: +% +% This is a callback from the graph drawing engine. At the end of the +% creation of a graph, when the nodes have been positioned, this macro +% is called once for each edge. The macro should take the following +% parameters: +% +% #1 = from node, optionally followed by "." and the tail anchor +% #2 = to node, optionally followed by "." and the head anchor +% #3 = direction (<-, --, ->, or <->) +% #4 = original options +% #5 = aux text (typically edge nodes) +% #6 = algorithm-generated options +% #7 = bend information +% +% The first five parameters are the original values that were passed +% down to the \pgfgdedge command. +% +% #6 contains options that have been "computed by the algorithm". For +% instance, an algorithm might have determined, say, flow capacities +% for edges and it might now wish to communicate this information back +% to the upper layers. These options should be executed with the path +% /graph drawing. +% +% #7 contains algorithmically-computed information concerning how the +% edge should bend. This will be a text like +% "--(10pt,20pt)--(30pt,40pt)" in tikz-syntax, using the path +% operations "--", "..controls" and "--cycle". +% +% By default, a simple line is drawn between the nodes. Usually, you +% will wish to install a more "fancy" callback, here. + +\def\pgfgdsetedgecallback#1{\let\pgfgdcallbackedge=#1} + +\def\pgfgddefaultedgecallback#1#2#3#4#5#6#7{% + {% + \pgfscope + \pgfpathmoveto{ + \pgfutil@in@.{#1}% + \ifpgfutil@in@ + \pgf@gd@unravel#1\relax% + \else + \pgfpointshapeborder{#1}{\pgfpointanchor{#2}{center}} + \fi + } + \pgfpathlineto{ + \pgfutil@in@.{#2}% + \ifpgfutil@in@ + \pgf@gd@unravel#2\relax% + \else + \pgfpointshapeborder{#2}{\pgfpointanchor{#1}{center}} + \fi + } + \pgfusepath{stroke} + \endpgfscope + } +} + +\pgfgdsetedgecallback{\pgfgddefaultedgecallback} + +\def\pgf@gd@unravel#1.#2\relax{% + \pgfpointanchor{#1}{#2}% +} + + + + +% Callbacks: Called before the shipout of nodes and edges starts +% +% First, the general begin shipout is called. Then, the node shipout +% starts, the nodes are created, and then the end of the node shipout +% is signaled. Next, the edge shipout starts and ends. Finally, the +% end shipout is called. + +\def\pgfgdcallbackbeginshipout{% + \pgfscope% + \catcode`\@=11\relax% + \setbox\pgf@gd@prekind@box=\box\pgfutil@voidb@x% + \setbox\pgf@gd@postkind@box=\box\pgfutil@voidb@x% +} +\def\pgfgdcallbackendshipout{% + \box\pgf@gd@prekind@box% + \ifpgf@gd@nodes@behind@edges% + \box\pgf@gd@node@box% + \box\pgf@gd@edge@box% + \else% + \box\pgf@gd@edge@box% + \box\pgf@gd@node@box% + \fi% + \box\pgf@gd@postkind@box% + \endpgfscope +} + +\newbox\pgf@gd@node@box +\newbox\pgf@gd@edge@box +\newbox\pgf@gd@prekind@box +\newbox\pgf@gd@postkind@box + +\def\pgfgdcallbackbeginnodeshipout{% + \setbox\pgf@gd@node@box=\hbox\bgroup% +} +\def\pgfgdcallbackendnodeshipout{% + \egroup% +} + +\def\pgfgdcallbackbeginedgeshipout{% + \setbox\pgf@gd@edge@box=\hbox\bgroup% +} + +\def\pgfgdcallbackendedgeshipout{% + \egroup +} + + + + +% Generate a node +% +% This callback is called from the engine whenever an algorithm +% generates a new node internally. +% +% #1 = name of the node +% #2 = shape of the node +% #3 = options generated by the algorithm in key-value syntax. The set +% of generated options is algorithm-dependent. +% #4 = text +% +% This is an internal function and will be called by the binding layer + +\def\pgfgdcallbackcreatevertex#1#2#3#4{% + { + \pgfkeys{#3} + \pgfnode{#2}{\pgfkeysvalueof{/graph drawing/generated + node/anchor}}{#4}{#1}{\pgfkeysvalueof{/graph drawing/generated + node/use path}} + } +} + +\pgfkeys{ + /graph drawing/generated node/anchor/.initial=center, + /graph drawing/generated node/use path/.initial=\pgfusepath{} +} + + + +% +% Sublayouts +% +% Description: For a general introduction to (sub)layouts, see +% Section~\ref{section-gd-sublayouts} in the manual. +% + +\def\pgfgdbeginlayout{ + \begingroup + \pgfgdlayoutscopeactivetrue + \advance\pgf@gd@parameter@stack@height by1\relax% + \directlua{pgf.gd.interface.InterfaceToDisplay.pushLayout(\the\pgf@gd@parameter@stack@height)} +} + +\def\pgfgdendlayout{ + \endgroup% +} + + + + +% Creates a subgraph node +% +% #1 = name +% #2 = node options +% #3 = node text +% +% Description: +% +% A subgraph node is a node that "surrounds" the nodes of a +% subgraph. The special property of a subgraph node opposed to a +% normal node is that it is created only after the subgraph has been +% laid out. However, the difference to a collection like "hyper" is +% that the node is availble immediately as a normal node in the sense +% that you can connect edges to it. +% +% What happens internally is that subgraph nodes get "registered" +% immediately both on the pgf level and on the lua level, but the +% actual node is only created inside the layout pipeline using a +% callback. The actual node creation happens when the innermost layout +% in which the subgraph node is declared has finished. +% +% When you create a subgraph node using this macro, you also start a +% collection (of an internal kind) that stores the subgraph. All +% following nodes in the current TeX scope will become part of this +% collection. +% +% See |InterfaceToDisplay.pushSubgraphVertex| for details. + +\def\pgfgdsubgraphnode#1#2#3{% + \advance\pgf@gd@parameter@stack@height by1\relax% + {% + % create edge in Lua + \toks0={#2}% + \toks1={#3}% + \directlua{pgf.gd.interface.InterfaceToDisplay.pushSubgraphVertex% + ('\pgfutil@luaescapestring{#1}',\the\pgf@gd@parameter@stack@height, + { + shape = 'rectangle', % typically overwritten by the pgf_options: + pgf_options = '\pgfutil@luaescapestring{\the\toks0}', + text = '\pgfutil@luaescapestring{\the\toks1}', + }) + }% + } +} + +\def\pgfgdsubgraphnodecontents#1{% helper function + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \vrule width0pt height\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\hfil}% +} + +\pgfgdset{ + subgraph point cloud/.initial=, + subgraph bounding box width/.initial=, + subgraph bounding box height/.initial=, +} + + +% +% Requests +% +% Description: +% +% This key is used to ``request'' a graph drawing scope and a +% layout. The objective of this key is to make it easier for users and +% algorithm designers to control the slightly involved +% back-and-forth-calling between the different layers. +% +% This key does the following: When called inside a pgfpicture +% (otherwise, the call is "illegal"), it will call a call-back with +% two parameters. This callback will get passed some code that should +% be executed at the beginning of ``the next scope'' and some code +% that should be executed at the end of that scope. +% +% The code passed to the callbacks will have a different effect, +% depending on whether we are currently inside a layout scope or not +% (if no graph drawing scope is open, we are +% not inside a layout). If we are not inside a layout scope (or if the +% layout scope has been interrupted), the code will issue a +% \pgfgdbeginscope command in the opening code and a corresponding +% scope ending command in the closing code. Next, the two code pieces +% always contain \pgfgdbeginlayout and \pgfgdendlayout. +% +% Note that the "@request scope and layout" key will not immediately +% trigger a layout scope to be created; rather, the TikZ callback will +% call it only at the beginning of the scope, which will be after +% other options in the current list of options have been parsed. So, +% when you write \graph [binary tree layout, significant sep=2em] ..., +% the "significant sep" option has an effect despite being given +% *after* the "@request scope and layout" key since the actual opening +% of the scope happens only before the "..." part is parsed. + +\pgfgdset{@request scope and layout/.code=\pgfgd@requestcallback{\pgfgdbeginrequest}{\pgfgdendrequest}} + +\def\pgfgd@requestcallback#1#2{% + #1\def\pgf@gd@after@request{#2\egroup}\bgroup\aftergroup\pgf@gd@after@request% +} % Default for basic layer + +\def\pgfgdbeginrequest{% + \ifpgfgdlayoutscopeactive% + \else% + \expandafter\pgfgdbeginscope% + \fi% + \pgfgdbeginlayout% +} +\def\pgfgdendrequest{% + \pgfgdendlayout% + \ifpgfgdlayoutscopeactive% + \else% + \expandafter\pgfgdendscope% + \fi% +} +\newif\ifpgfgdlayoutscopeactive + + +% Set the request callback +% +% #1 = A macro +% +% Description: +% +% Sets the request callback as described in the "@request scope and +% layout" key. + +\def\pgfgdsetrequestcallback#1{\let\pgfgd@requestcallback#1} + + + + +% +% An if that is true exactly if we are inside a graph drawing scope +% + +\newif\ifpgfgdgraphdrawingscopeactive + + +% Begins a new graph drawing scope +% +% Description: +% +% Inside a graph drawing scope, all pgf nodes that are newly created +% are automatically passed to the graph drawing engine. In contrast, +% edges have to be indicated explicitly using the macro \pgfgdedge +% (this is because it is somewhat unclear what, exactly, should count +% as an edge). Naturally, users typically will not call \pgfgdedge +% explicitly, but have styles and keys invoke it internally. +% +% Usage: +% +% \pgfgdset{algorithm=somealgorithm} +% \pgfgdbeginscope +% \pgfnode{rectangle}{center}{A}{A}{} +% \pgfnode{rectangle}{center}{B}{B}{} +% \pgfnode{rectangle}{center}{C}{C}{} +% \pgfgdedge{A}{B}{->}{}{} +% \pgfgdedge{B}{C}{->}{}{} +% \pgfgdedge{C}{A}{->}{}{} +% \pgfgdendscope +% +% Naturally, users will typically use TikZ's somewhat simpler syntax: ' +% +% \tikz \graph [some algorithm] { A -> B -> C -> A }; + +\def\pgfgdbeginscope{% + \begingroup % Protecting scope + % get options + \directlua{ + pgf.gd.interface.InterfaceToDisplay.beginGraphDrawingScope(\the\pgf@gd@parameter@stack@height) + }% + \begingroup % Inner scope, the actual nodes will be inserted after + % this scope has been closed + % Indicate that we are now inside a graph drawing scope + \pgfgdgraphdrawingscopeactivetrue + % Switch on late positioning + \pgfpositionnodelater{\pgf@gd@positionnode@callback} + % Switch on late edges + \pgfgd@latecallback% + % Kill transformations (will be added by the position now + % macros) + \pgftransformreset +} + + +% Ends a graph drawing scope +% +% Description: +% +% This macro invokes the selected graph drawing algorithm and +% ships out all nodes within this scope +% +% See \pgfgdbeginscope + +\def\pgfgdendscope{% + \directlua{ + pgf.gd.interface.InterfaceToDisplay.runGraphDrawingAlgorithm() + } + \endgroup + % Late positioning has ended + \directlua{pgf.gd.interface.InterfaceToDisplay.renderGraph()} + \directlua{pgf.gd.interface.InterfaceToDisplay.endGraphDrawingScope()} + \endgroup +} + + + + + + +% Hook into graph specification +% +% #1 = code +% +% Description: +% +% Allows you to specify code that should be active while the graph +% drawing engine collects the information concerning the graph, but +% which should no longer be active when the graph is rendered. + +\def\pgfgdaddspecificationhook#1{ + \expandafter\def\expandafter\pgfgd@latecallback\expandafter{\pgfgd@latecallback#1} +} +\let\pgfgd@latecallback\pgfutil@empty + + + + + + + + +% Loading further libraries + +% Include a graph drawing library file. +% +% #1 = List of names of library file. +% +% Description: +% +% This command includes a list of graph drawing library files. For +% each file X in the list, the file pgf.gd.X.lua is included using +% |require|. +% +% For the convenience of Context users, both round and square brackets +% are possible for the argument. +% +% +% Example: +% +% \usegdlibrary{trees} +% \usegdlibrary[force,circular] + +\def\usegdlibrary{\pgfutil@ifnextchar[{\use@gdlibrary}{\use@@gdlibrary}}%} +\def\use@gdlibrary[#1]{\use@@gdlibrary{#1}} +\def\use@@gdlibrary#1{% + \edef\pgf@list{#1}% + \pgfutil@for\pgf@temp:=\pgf@list\do{% + \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% + \ifx\pgf@temp\pgfutil@empty + \else + \directlua{if not pgf_lookup_and_require('\pgf@temp') then + tex.print('\pgfutil@luaescapestring{\noexpand\pgferror{Graph drawing library '\pgf@temp' not found}}') + end} + \fi + } +} + +% In the following code: Does anyone know how to determine the +% file-system separator in Lua? Or in TeX? +{ + \catcode`\%=11 +\directlua{ + function pgf_lookup_and_require(name) + local sep = '/' + if string.find(os.getenv('PATH'),';') then + sep = '\string\\' + end + local function lookup(name) + local sub = name:gsub('%.',sep) + local find_func = function (name, suffix) + if resolvers then + local n = resolvers.findfile (name, suffix) + return (not (n == '')) and n or nil + else + return kpse.find_file(name,suffix) + end + end + if find_func(sub, 'lua') then + require(name) + elseif find_func(sub, 'clua') then + collectgarbage('stop') + require(name) + collectgarbage('restart') + else + return false + end + return true + end + return + lookup('pgf.gd.' .. name .. '.library') or + lookup('pgf.gd.' .. name) or + lookup(name .. '.library') or + lookup(name) + end +} +} + + +% +% Ok, fire up the system by creating the binding! +% +\directlua{ + require 'pgf.gd.interface.InterfaceToDisplay' + pgf.gd.interface.InterfaceToDisplay.bind(require 'pgf.gd.bindings.BindingToPGF') +} + + + +% +% Special setup for keys that are declared by the above libraries, but +% that have a special meaning on the display layer. +% + +\pgfkeys{/graph drawing/nodes behind edges/.append code=\csname pgf@gd@nodes@behind@edges#1\endcsname} +\pgfkeys{/graph drawing/nodes behind edges/.default=true} + + + + +\endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex new file mode 100644 index 00000000000..4bfe4a839a3 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex @@ -0,0 +1,17 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.examples.code.tex,v 1.2 2012/11/20 23:34:18 tantau Exp $ + +\usepgflibrary{graphdrawing} + +\usegdlibrary{examples} + + +\endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex new file mode 100644 index 00000000000..3950a9062e1 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex @@ -0,0 +1,136 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.force.code.tex,v 1.7 2012/11/20 23:34:18 tantau Exp $ + + + +\usepgflibrary{graphdrawing} + +\usegdlibrary{force} + +\endinput + + + +% +% Definition of spring algorithms as well as options to configure them. +% + +\pgfgdset{ + force based/.cd, + % + iterations/.graph parameter=number, + iterations/.parameter initial=500, + % + cooling factor/.graph parameter=number, + cooling factor/.parameter initial=0.95, + % + initial step dimension/.graph parameter=number, + initial step dimension/.parameter initial=0, + % + convergence tolerance/.graph parameter=number, + convergence tolerance/.parameter initial=0.01, + % + spring constant/.graph parameter=number, + spring constant/.parameter initial=0.01, + % + approximate electric forces/.graph parameter=boolean, + approximate electric forces/.parameter initial=false, + approximate electric forces/.default=true, + % + electric force order/.graph parameter=number, + electric force order/.parameter initial=1, + % + % Parameters related to the multilevel approach where the input graph + % is iteratively coarsened into graphs with fewer nodes, until either + % the number of nodes is small enough or the number of nodes in the + % could not be reduced by at least a user-defined ratio. + % + coarsen/.graph parameter=boolean, + coarsen/.parameter initial=true, + coarsen/.default=true, + % + coarsening/.code=\pgfkeys{ + /graph drawing/force based/coarsening/.cd, + #1 + }, + % + coarsening/downsize ratio/.graph parameter=number, + coarsening/downsize ratio/.parameter initial=0.25, + % + coarsening/minimum graph size/.graph parameter=number, + coarsening/minimum graph size/.parameter initial=2, + % + coarsening/collapse independent edges/.graph parameter=boolean, + coarsening/collapse independent edges/.parameter initial=true, + coarsening/collapse independent edges/.default=true, + % + coarsening/connect independent nodes/.graph parameter=boolean, + coarsening/connect independent nodes/.parameter initial=false, + coarsening/connect independent nodes/.default=true, + % + % Node parameters for spring algorithms. + % + % + % Edge parameters for spring algorithms. + % +} + +\pgfgddeclareforwardedkeys{/graph drawing}{ + % + electric charge/.node parameter=number, + electric charge/.parameter initial=1, +} + + +% +% Spring algorithm based on the paper +% +% "Efficient, High-Quality Force-Directed Graph Drawing" +% Yifan Hu, 2006 +% +\pgfgddeclarealgorithmkey + {spring layout} + {force based} + { + algorithm=pgf.gd.force.SpringHu2006 + } + + +% +% Spring-electrical algorithm based on the paper +% +% "Efficient, High-Quality Force-Directed Graph Drawing" +% Yifan Hu, 2006 +% +\pgfgddeclarealgorithmkey + {spring electrical layout} + {force based} + { + algorithm=pgf.gd.force.SpringElectricalHu2006, + force based/spring constant=0.2, + } + + + +% +% Spring-electrical algorithm based on the paper +% +% "A Multilevel Algorithm for Force-Directed Graph Drawing" +% C. Walshaw, 2000 +% +\pgfgddeclarealgorithmkey + {spring electrical layout'} + {force based} + { + algorithm=pgf.gd.force.SpringElectricalWalshaw2000, + force based/spring constant=0.01, + force based/convergence tolerance=0.001, + } diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex new file mode 100644 index 00000000000..37f28bc304a --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex @@ -0,0 +1,17 @@ +% Copyright 2011 by Jannis Pohlmann +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.layered.code.tex,v 1.5 2012/11/20 23:34:18 tantau Exp $ + +\usepgflibrary{graphdrawing} + +\usegdlibrary{layered} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex new file mode 100644 index 00000000000..7d0a9ed35b0 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex @@ -0,0 +1,19 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/pgflibrarygraphdrawing.trees.code.tex,v 1.8 2012/11/20 23:34:18 tantau Exp $ + + +\usepgflibrary{graphdrawing} +\usepgflibrary{graphdrawing.layered} + +\usegdlibrary{trees} + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex new file mode 100644 index 00000000000..3c3532b394d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex @@ -0,0 +1,240 @@ +% Copyright 2010 by Renée Ahrens, Olof Frahm, Jens Kluttig, Matthias Schulz, Stephan Schuster +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/tex/tikzlibrarygraphdrawing.code.tex,v 1.20 2013/08/05 18:22:47 tantau Exp $ + +\usepgflibrary{graphdrawing} + +\def\tikz@lib@ensure@gd@loaded{} + + +% Patch the level and sibling distances so that gd and plain tikz are +% in sync +\tikzset{level distance=1cm, sibling distance=1cm} + +% Patch node distance because of its special syntax. + +\pgfkeysgetvalue{/graph drawing/node distance/.@cmd}\tikz@lib@gd@node@dist@path +\pgfkeyslet{/graph drawing/node distance/orig/.@cmd}\tikz@lib@gd@node@dist@path + +\pgfkeysdef{/graph drawing/node distance}{ + \pgfutil@in@{ and }{#1}% + \ifpgfutil@in@% + \tikz@gd@convert@and#1\pgf@stop% + \else% + \tikz@gd@convert@and#1 and #1\pgf@stop% + \fi% +} +\def\tikz@gd@convert@and#1 and #2\pgf@stop{\pgfkeys{/graph drawing/node distance/orig={#1}}} + + + + +% +% Setup graph drawing for tikz +% + +\def\tikz@gd@request@callback#1#2{% + \tikzset{ + execute at begin scope={ + \tikzset{ + --/.style={arrows=-}, + -!-/.style={draw=none,fill=none}, + } + \pgfgdsetedgecallback{\pgfgdtikzedgecallback}% + % + % Setup for plain syntax + % + \pgfgdaddspecificationhook{\tikz@lib@gd@spec@hook}% + #1 + \let\tikzgdeventcallback\pgfgdevent% + \let\tikzgdeventgroupcallback\pgfgdeventgroup% + \let\tikzgdlatenodeoptionacallback\pgfgdsetlatenodeoption% + }, + execute at end scope={% + #2% + } + }% +} + +\pgfgdsetrequestcallback\tikz@gd@request@callback + + + +\pgfgdappendtoforwardinglist{/tikz/,/tikz/graphs/} + +\def\tikz@lib@gd@spec@hook{% + \tikzset{ + edge macro=\tikz@gd@plain@edge@macro, + /tikz/at/.style={/graph drawing/desired at={##1}}, + % + % Setup for the tree syntax (do this late so that grow options + % are still valid after a layout has been chosen) + % + /tikz/growth function=\relax, + /tikz/edge from parent macro=\tikz@gd@edge@from@parent@macro, + % + % Setup for the graphs syntax + % + /tikz/graphs/new ->/.code n args={4}{\pgfgdedge{##1}{##2}{->}{/tikz,##3}{##4}}, + /tikz/graphs/new <-/.code n args={4}{\pgfgdedge{##1}{##2}{<-}{/tikz,##3}{##4}}, + /tikz/graphs/new --/.code n args={4}{\pgfgdedge{##1}{##2}{--}{/tikz,##3}{##4}}, + /tikz/graphs/new <->/.code n args={4}{\pgfgdedge{##1}{##2}{<->}{/tikz,##3}{##4}}, + /tikz/graphs/new -!-/.code n args={4}{\pgfgdedge{##1}{##2}{-!-}{/tikz,##3}{##4}}, + /tikz/graphs/placement/compute position/.code=,% + } +} + +\pgfgdaddprepareedgehook{ + \tikz@enable@edge@quotes% + \let\tikz@transform=\pgfutil@empty% + \let\tikz@options=\pgfutil@empty% + \let\tikz@tonodes=\pgfutil@empty% +} + + +\tikzset{ + parent anchor/.forward to=/graph drawing/tail anchor, + child anchor/.forward to=/graph drawing/head anchor +} + +\def\pgfgdtikzedgecallback#1#2#3#4#5#6#7{% + \draw (#1) + edge [to path={#7 \tikztonodes},#3,#4,/graph drawing/.cd,#6,/tikz/.cd] + #5 + (#2); +} + +\def\tikz@gd@edge@from@parent@macro#1#2{ + [/utils/exec=\pgfgdedge{\tikzparentnode}{\tikzchildnode}{--}{/tikz,#1}{#2}] +} + +\def\tikz@gd@plain@edge@macro#1#2{ + \pgfgdedge{\tikztostart}{\tikztotarget}{--}{/tikz,#1}{#2} +} + + + +% +% Conversions: Convert coordinates into pairs of values surrounded by +% braces. +% + +\pgfgdset{ + conversions/canvas coordinate/.code={% + \tikz@scan@one@point\pgf@process#1% + \pgfmathsetmacro{\tikz@gd@temp@x}{\pgf@x} + \pgfmathsetmacro{\tikz@gd@temp@y}{\pgf@y} + \edef\pgfgdresult{pgf.gd.model.Coordinate.new(\tikz@gd@temp@x,\tikz@gd@temp@y)} + }, + conversions/coordinate/.code={% + \tikz@scan@one@point\pgf@process#1% + \pgfmathsetmacro{\tikz@gd@temp@x}{\pgf@x} + \pgfmathsetmacro{\tikz@gd@temp@y}{\pgf@y} + \edef\pgfgdresult{pgf.gd.model.Coordinate.new(\tikz@gd@temp@x,\tikz@gd@temp@y)} + } +} + + + +% +% Overwrite node callback +% + +\def\pgfgdcallbackcreatevertex#1#2#3#4{% + \node[every generated node/.try,name={#1},shape={#2},/graph drawing/.cd,#3]{#4};% +} + + +% +% Subgraph handling +% + +% "General" text placement for subgraph nodes that works with all node +% kinds. + +\tikzset{ + subgraph text top/.code=\tikz@lg@simple@contents@top{#1},% + subgraph text top/.default=text ragged, + subgraph text bottom/.code=\tikz@lg@simple@contents@bottom{#1},% + subgraph text bottom/.default=text ragged, + subgraph text sep/.initial=.1em, + subgraph text none/.code={ + \def\pgfgdsubgraphnodecontents##1{% + \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \vrule width0pt height.5\pgf@y depth.5\pgf@y\hfil}% + }% + }, +} + +\def\tikz@lg@simple@contents@top#1{% + \def\pgfgdsubgraphnodecontents##1{% + \vbox{% + \def\pgf@temp{##1}% + \ifx\pgf@temp\pgfutil@empty% + \else% + \ifx\pgf@temp\pgfutil@sptoken% + \else% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \hsize=\pgfkeysvalueof{/graph drawing/subgraph bounding box width}\relax% + \vbox{\noindent\strut\tikzset{#1}\tikz@text@action\pgf@temp}% + }% + \fi% + \fi% + \pgfmathparse{\pgfkeysvalueof{/tikz/subgraph text sep}}% + \kern\pgfmathresult pt\relax% + \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \vrule width0pt height.5\pgf@y depth.5\pgf@y\hfil}% + }% + }% +} + +\def\tikz@lg@simple@contents@bottom#1{% + \def\pgfgdsubgraphnodecontents##1{% + {% + \pgf@y=\pgfkeysvalueof{/graph drawing/subgraph bounding box height}\relax% + \setbox0=\vbox{% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{\vrule width0pt height\pgf@y\hfil}% + \pgfmathparse{\pgfkeysvalueof{/tikz/subgraph text sep}}% + \kern\pgfmathresult pt\relax% + \def\pgf@temp{##1}% + \ifx\pgf@temp\pgfutil@empty% + \else% + \ifx\pgf@temp\pgfutil@sptoken% + \else% + \hbox to \pgfkeysvalueof{/graph drawing/subgraph bounding box width}{% + \hsize=\pgfkeysvalueof{/graph drawing/subgraph bounding box width}\relax% + \vbox{\noindent\strut\tikzset{#1}\tikz@text@action\pgf@temp}% + }% + \fi% + \fi% + }% + \pgf@ya=\ht0\relax% + \advance\pgf@ya by-.5\pgf@y\relax% + \ht0=.5\pgf@y\relax% + \dp0=\pgf@ya\relax% + \box0\relax% + }% + }% +} + +\tikzset{subgraph text top} + +\tikzset{ + subgraph nodes/.style={/tikz/every subgraph node/.style={#1}}, + graphs/subgraph nodes/.style={/tikz/every subgraph node/.style={#1}}, + graphs/@graph drawing setup/.style={/graph drawing/anchor at={(\tikz@lastx,\tikz@lasty)}} +} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex index a5af1c95e17..ae62fd31839 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex,v 1.3 2008/12/09 00:12:10 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.formats.functions.code.tex,v 1.4 2011/03/14 23:17:52 tantau Exp $ \usepgfmodule{datavisualization} @@ -131,12 +131,17 @@ \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@eval@func{#1}{#2}} \pgf@lib@dv@func@parse% } -\def\pgf@lib@dv@var var #1 :#2interval#3[#4:#5]{% +\def\pgf@lib@dv@var var #1 :{\pgfutil@ifnextchar\bgroup{\pgf@lib@dv@var@group{#1}}{\pgf@lib@dv@var@int{#1}}} +\def\pgf@lib@dv@var@group#1#2;{% + \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{\pgf@lib@dv@parsed\pgf@lib@dv@group@var{#1}{#2}}% + \pgf@lib@dv@func@parse% +} +\def\pgf@lib@dv@var@int#1#2[#3:#4]{% \pgfutil@ifnextchar s{% - \pgf@lib@dv@samplesorsteps{#1}{#4}{#5}% + \pgf@lib@dv@samplesorsteps{#1}{#3}{#4}% }{% \expandafter\def\expandafter\pgf@lib@dv@parsed\expandafter{% - \pgf@lib@dv@parsed\pgf@lib@dv@samples@var{#1}{#4}{#5}{\pgfkeysvalueof{/pgf/data/samples}}}% + \pgf@lib@dv@parsed\pgf@lib@dv@samples@var{#1}{#3}{#4}{\pgfkeysvalueof{/pgf/data/samples}}}% \expandafter\pgf@lib@dv@func@parse\pgfutil@gobble% } } @@ -188,6 +193,13 @@ }% } +\def\pgf@lib@dv@group@var#1#2#3\pgf@stop{% + \foreach \pgf@lib@dv@iterator in {#2} {% + \pgfkeyslet{/data point/#1}{\pgf@lib@dv@iterator}% + #3\pgf@stop% + }% +} + \def\pgf@lib@dv@eval@func#1#2{% \pgfkeysvalueof{/pgf/data/evaluator}{#2}% \pgfkeyslet{/data point/#1}{\pgfmathresult}% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex index f39adbbedaa..36e51541cee 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex,v 1.2 2008/11/24 18:31:22 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/datavisualization/pgflibrarydatavisualization.polar.code.tex,v 1.4 2011/02/22 22:07:24 tantau Exp $ \usepgfmodule{datavisualization} @@ -90,6 +90,10 @@ \fi \ifx\pgf@dv@radius\pgfutil@empty\else% \ifx\pgf@dv@radius\relax\else% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@angle}% + \pgfdvmathexitbyscientificformat{\pgf@dv@angle}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@radius}% + \pgfdvmathexitbyscientificformat{\pgf@dv@radius}{\pgf@dv@val}% \pgfmathsincos{\pgf@dv@angle}% \pgfmathmultiply{\pgfmathresultx}{\pgf@dv@radius}% \let\pgf@dv@polar@temp=\pgfmathresult @@ -126,15 +130,23 @@ \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@current@rad \ifx\pgf@dv@current@rad\relax \else - \ifdim\pgf@dv@current@rad pt=\pgf@dv@prev@rad pt% + \ifx\pgf@dv@current@rad\pgf@dv@prev@rad% \pgfooget{prev angle}\pgf@dv@prev@angle \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@current@angle \ifx\pgf@dv@current@angle\relax \else - \ifdim\pgf@dv@current@angle pt=\pgf@dv@prev@angle pt% + \ifx\pgf@dv@current@angle\pgf@dv@prev@angle% % do nothing \else% % Do arc: + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@angle}% + \pgfdvmathexitbyscientificformat{\pgf@dv@prev@angle}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@prev@rad}% + \pgfdvmathexitbyscientificformat{\pgf@dv@prev@rad}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@angle}% + \pgfdvmathexitbyscientificformat{\pgf@dv@current@angle}{\pgf@dv@val}% + \pgfdvmathenter{\pgf@dv@val}{\pgf@dv@current@rad}% + \pgfdvmathexitbyscientificformat{\pgf@dv@current@rad}{\pgf@dv@val}% \pgfpatharcaxes{\pgf@dv@prev@angle}{\pgf@dv@current@angle} {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 0 degrees}}} {\pgfpointscale{\pgf@dv@current@rad}{\pgfoovalueof{unit vector 90 degrees}}}% @@ -157,32 +169,28 @@ % \method direction(#1) {% \ifx#1\pgfdvdirectionfromtoken - % Record angle and radius + % Record from angle and radius \xdef\pgf@dv@polar@from@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} \xdef\pgf@dv@polar@from@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} + \else\ifx#1\pgfdvdirectiontotoken% + % Record to angle and radius + \xdef\pgf@dv@polar@to@angle{\pgfkeysvalueof{/data point/\pgfoovalueof{angle}}} + \xdef\pgf@dv@polar@to@radius{\pgfkeysvalueof{/data point/\pgfoovalueof{radius}}} \else% - \pgfkeysgetvalue{/data point/\pgfoovalueof{radius}}\pgf@dv@polar@to@radius - \ifx\pgf@dv@polar@to@radius\relax - \else - \ifdim\pgf@dv@polar@to@radius pt=\pgf@dv@polar@from@radius pt% - \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@dv@polar@to@angle - \ifx\pgf@dv@polar@to@angle\relax - \else - \ifdim\pgf@dv@polar@to@angle pt=\pgf@dv@polar@from@angle pt% - % do nothing - \else% - % Output vector that it orthogonal to start angle: - \ifdim\pgf@dv@polar@to@angle pt>\pgf@dv@polar@from@angle pt% - \pgf@process{\pgfpointpolar{\pgf@dv@polar@from@angle+90}{1pt}} - \else - \pgf@process{\pgfpointpolar{\pgf@dv@polar@from@angle-90}{1pt}} - \fi - \pgfdvhandledtrue - \fi% - \fi% + \ifx\pgf@dv@polar@from@radius\pgf@dv@polar@to@radius% + \pgfdvmathenter{\pgf@dv@a}{\pgf@dv@polar@from@angle}% + \pgfdvmathenter{\pgf@dv@b}{\pgf@dv@polar@to@angle}% + \pgfdvmathifless{\pgf@dv@a}{\pgf@dv@b}{\def\pgf@dv@temp@sign{+}}{\def\pgf@dv@temp@sign{-}}% + \pgfkeysgetvalue{/data point/\pgfoovalueof{angle}}\pgf@temp% + \ifx\pgf@temp\relax% + \else% + \pgfdvmathenter{\pgf@dv@val}{\pgf@temp}% + \pgfdvmathexitbyscientificformat{\pgf@dv@polar@angle}{\pgf@dv@val}% + \pgf@process{\pgfpointpolar{\pgf@dv@polar@angle\pgf@dv@temp@sign90}{1pt}}% + \pgfdvhandledtrue% \fi% \fi% - \fi% + \fi\fi% } } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex index dcb98da9119..546301c4d07 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.markings.code.tex @@ -14,7 +14,7 @@ % scopes, essentially) at certain positions of a path. \pgfkeys{ - /pgf/decoration/reset marks/.code=\let\pgf@lib@dec@mark@marks=\pgfutil@empty, + /pgf/decoration/reset marks/.code=\let\pgf@lib@dec@mark@marks\pgfutil@empty, /pgf/decoration/mark/.code=\pgf@lib@dec@parsemark#1\pgf@lib@dec@stop, } @@ -33,17 +33,8 @@ } \def\pgf@lib@dec@arrowhead#1#2{% - \expandafter\ifx\csname tikz@special@arrow@end#2\endcsname\relax% be nice to TikZ - \pgfsetarrowsend{#2} - \else% - \pgfsetarrowsend{\csname tikz@special@arrow@end#2\endcsname}% - \fi% - \pgf@x=0pt% - \pgf@shorten@end% - \pgftransformxshift{-\pgf@x} \pgftransformxscale{#1} - \pgflowlevelsynccm% - \pgflowlevelobj{}{\pgf@endarrow}% + \pgfarrowdraw{#2}% } \def\pgf@lib@dec@doarrowhead#1{% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex index 6e1b25101bd..8cf75a739bd 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.shapes.code.tex @@ -163,9 +163,9 @@ % Check the shape exists. % \pgfutil@ifundefined{pgf@sh@bg@\pgfkeysvalueof{/pgf/decoration/shape}}{% - \PackageError{PGF}{I do not know the shape `\pgfkeysvalueof{/pgf/decoration/shape}', + \pgferror{I do not know the shape `\pgfkeysvalueof{/pgf/decoration/shape}', so I cannot use it in a decoration. Check if its library been loaded or if you - simply mistyped the name}{}}{}% + simply mistyped the name}}{}% % % Calculate a `default' path size. % diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex new file mode 100644 index 00000000000..b06695a87fa --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex @@ -0,0 +1,499 @@ +% Copyright 2011 by Christophe Jorssen and Mark Wibrow +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. +% +% $Id: pgflibraryluamath.code.tex,v 1.11 2012/03/06 16:06:09 cjorssen Exp $ +% +% !!! Warning: this library does not work with fpu!!! + +% ******************************************************************* +% Some luatex stuff. Should be put elsewhere (e.g. in +% pgfutil-luatex-engine). + +% We assume luatex version > 0.39: +% - \directlua will work +% - \directlua is the only luatex primitive that we can assume +% accessible without being prefixed by the format via +% tex.enableprimitives. +% Ideas taken from the ifluatex package (Heiko Oberdiek) +\let\pgfutil@ifluatex\iffalse +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname directlua\endcsname\relax +\else + \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname + \csname iftrue\endcsname +\fi + +\pgfutil@ifluatex + \let\pgfutil@directlua\directlua + \pgfutil@directlua{% + tex.enableprimitives('pgfutil@',{'luaescapestring'})} +\else + \def\pgfutil@directlua#1{} + \def\pgfutil@luaescapestring#1{} +\fi + +% End of luatex stuff +% ******************************************************************* + +% Loading part: based on fpu library + +\newif\ifpgfluamathcomputationactive +\newif\ifpgfluamathparseractive + +\def\pgfluamath@makecomputationactive{% + \ifpgfluamathcomputationactive + \else + \pgfluamath@checkuninstallcmd% + \pgfluamath@install% + \pgfluamathcomputationactivetrue + \fi} + +\def\pgfluamath@makecomputationinactive{% + \ifpgfluamathcomputationactive + \pgfluamath@uninstall% + \pgfluamathcomputationactivefalse + \fi} + +\def\pgfluamath@makeparseractive{% + \ifpgfluamathparseractive + \else + \let\pgfluamath@pgfmathparse\pgfmathparse + \let\pgfmathparse\pgfluamathparse + \pgfluamathparseractivetrue + \fi} + +\def\pgfluamath@makeparserinactive{% + \ifpgfluamathparseractive + \let\pgfmathparse\pgfluamath@pgfmathparse + \pgfluamathparseractivefalse + \fi} + +\pgfqkeys{/pgf}{% + % Enable lua-side computation of \pgfmathresult + % (will be deactivated after the current TeX group) + luamath/.is choice, + luamath/only computation/.code={% + \pgfutil@ifluatex + \pgfluamath@makecomputationactive + \pgfluamath@makeparserinactive + \else + \pgfmath@error{Sorry, you need the luaTeX engine to use the + luamath library}% + \fi}, + luamath/parser and computation/.code={% + \pgfutil@ifluatex + \pgfluamath@makecomputationactive + \pgfluamath@makeparseractive + \else + \pgfmath@error{Sorry, you need the luaTeX engine to use the + luamath library}% + \fi}, + luamath/off/.code={% + \pgfluamath@makecomputationinactive + \pgfluamath@makeparserinactive}, + luamath/.default=only computation} + +\def\pgfluamath@uninstall@appendcmd#1{% + \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{% + \pgfluamath@uninstall #1}} + +% If the uninstall command is already assembled, it will skip the +% uninstall assemblation. +\def\pgfluamath@checkuninstallcmd{% + \pgfutil@ifundefined{pgfluamath@uninstall}{% + \pgfutil@directlua{% + pgfluamathfunctions = require("pgfluamath.functions") + pgfluamathparser = require("pgfluamath.parser")} + \global\let\pgfluamath@uninstall=\pgfutil@empty + }{% + % We already HAVE an uninstall command (prepared globally). + % So: don't waste time assembling one! + \def\pgfluamath@uninstall@appendcmd##1{}% + \def\pgfluamath@prepareuninstallcmd##1{}% + }% +} + +% This assembles an uninstall command globally ON FIRST USAGE. +% See \pgfmathfloat@plots@checkuninstallcmd +\def\pgfluamath@prepareuninstallcmd#1{% + \expandafter\global\expandafter\let + \csname pgfluamath@backup@\string#1\endcsname=#1% + \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{% + \pgfluamath@uninstall + \expandafter\let\expandafter#1\csname pgfluamath@backup@\string#1\endcsname}% +} + +\def\pgfluamath@install@function#1=#2{% + \pgfluamath@prepareuninstallcmd{#1}% + \let#1=#2% +} + +\def\pgfluamath@install{% + \pgfluamath@install@function\pgfmathadd@=\pgfluamathadd@% + \pgfluamath@install@function\pgfmathsubtract@=\pgfluamathsubtract@% + \pgfluamath@install@function\pgfmathneg@=\pgfluamathneg@% + \pgfluamath@install@function\pgfmathmultiply@=\pgfluamathmultiply@% + \pgfluamath@install@function\pgfmathdivide@=\pgfluamathdivide@% + % \pgfluamath@install@function\pgfmathdiv@=\pgfluamathdiv@% + \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@% + \pgfluamath@install@function\pgfmathsqrt@=\pgfluamathsqrt@% + % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@% + \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% + \pgfluamath@install@function\pgfmathexp@=\pgfluamathexp@% + \pgfluamath@install@function\pgfmathln@=\pgfluamathln@% + \pgfluamath@install@function\pgfmathlogten@=\pgfluamathlogten@% + % \pgfluamath@install@function\pgfmathlogtwo@=\pgfluamathlogtwo@% + \pgfluamath@install@function\pgfmathabs@=\pgfluamathabs@% + \pgfluamath@install@function\pgfmathmod@=\pgfluamathmod@% + \pgfluamath@install@function\pgfmathMod@=\pgfluamathMod@% + \pgfluamath@install@function\pgfmathround@=\pgfluamathround@% + \pgfluamath@install@function\pgfmathfloor@=\pgfluamathfloor@% + \pgfluamath@install@function\pgfmathceil@=\pgfluamathceil@% + % \pgfluamath@install@function\pgfmathint@=\pgfluamathint@% + % \pgfluamath@install@function\pgfmathfrac@=\pgfluamathfrac@% + % \pgfluamath@install@function\pgfmathreal@=\pgfluamathreal@% + \pgfluamath@install@function\pgfmathgcd@=\pgfluamathgcd@% + \pgfluamath@install@function\pgfmathisprime@=\pgfluamathisprime@% + \pgfluamath@install@function\pgfmathpi@=\pgfluamathpi@% + \pgfluamath@install@function\pgfmathrad@=\pgfluamathrad@% + \pgfluamath@install@function\pgfmathdeg@=\pgfluamathdeg@% + \pgfluamath@install@function\pgfmathsin@=\pgfluamathsin@% + \pgfluamath@install@function\pgfmathcos@=\pgfluamathcos@% + \pgfluamath@install@function\pgfmathtan@=\pgfluamathtan@% + \pgfluamath@install@function\pgfmathsec@=\pgfluamathsec@% + \pgfluamath@install@function\pgfmathcosec@=\pgfluamathcosec@% + \pgfluamath@install@function\pgfmathcot@=\pgfluamathcot@% + \pgfluamath@install@function\pgfmathasin@=\pgfluamathasin@% + \pgfluamath@install@function\pgfmathacos@=\pgfluamathacos@% + \pgfluamath@install@function\pgfmathatan@=\pgfluamathatan@% + \pgfluamath@install@function\pgfmathatantwo@=\pgfluamathatantwo@% + \pgfluamath@install@function\pgfmathmax@=\pgfluamathmax@% + \pgfluamath@install@function\pgfmathmin@=\pgfluamathmin@% + % \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@% + % \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@% + % \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% + % \pgfluamath@install@function\pgfmathe=\pgfluamathe@% + % \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@% + % \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@% + % \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@% + % \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@% + % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@ + \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@ + \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@ + \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@ + \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@ + % \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@ + % \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@ + % \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@ + % \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@ + % \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@ + % \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@ + % \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@ + % \pgfluamath@install@function\pgfmathand@=\pgfluamathand@ + % \pgfluamath@install@function\pgfmathor@=\pgfluamathor@ + % \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@ + % \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@ + % \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@ + % \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@ + % \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@ + % \pgfluamath@install@function@unimplemented{ceil}% + % \pgfluamath@install@function@unimplemented{frac}% + % \pgfluamath@install@function@unimplemented{log2}% + % \pgfluamath@install@function@unimplemented{log10}% + % \pgfluamath@install@function@unimplemented{equalto}% + % \pgfluamath@install@function@unimplemented{random}% + % \pgfluamath@install@function@unimplemented{setseed}% + % \pgfluamath@install@function@unimplemented{Mod}% + % \pgfluamath@install@function@unimplemented{real}% + % \pgfluamath@install@function@unimplemented{notequal}% + \pgfluamath@install@function\pgfmathreciprocal=\pgfluamathreciprocal% + \pgfluamath@install@function\pgfpointnormalised=\pgfluamathpointnormalised +} + +\def\pgfluamathgetresult#1{% + \edef\pgfmathresult{\pgfutil@directlua{tex.print(-1,#1)}}} + +\def\pgfluamathpi@{% + \pgfluamathgetresult{pgfluamathfunctions.pi()}} +\def\pgfluamathe@{% + \pgfluamathgetresult{pgfluamathfunctions.e()}} +\def\pgfluamathadd@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.add(#1,#2)}} +\def\pgfluamathsubtract@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.substract(#1,#2)}} +\def\pgfluamathneg@#1{% + \pgfluamathgetresult{pgfluamathfunctions.neg(#1)}} +\def\pgfluamathmultiply@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.multiply(#1,#2)}} +\def\pgfluamathdivide@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.divide(#1,#2)}} +\def\pgfluamathabs@#1{% + \pgfluamathgetresult{pgfluamathfunctions.abs(#1)}} +\def\pgfluamathround@#1{% + \pgfluamathgetresult{pgfluamathfunctions.round(#1)}} +\def\pgfluamathfloor@#1{% + \pgfluamathgetresult{pgfluamathfunctions.floor(#1)}} +\def\pgfluamathceil@#1{% + \pgfluamathgetresult{pgfluamathfunctions.ceil(#1)}} +\def\pgfluamathgcd@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.gcd(#1,#2)}} +\def\pgfluamathisprime@#1{% + \pgfluamathgetresult{pgfluamathfunctions.isprime(#1)}} +\def\pgfluamathmax@#1{% + \pgfluamathgetresult{% + math.max(pgfluamathfunctions.split_braces_to_explist("#1"))}} +\def\pgfluamathmin@#1{% + \pgfluamathgetresult{% + math.min(pgfluamathfunctions.split_braces_to_explist("#1"))}} +\def\pgfluamathsin@#1{% + \pgfluamathgetresult{pgfluamathfunctions.Sin(#1)}} +\def\pgfluamathcos@#1{% + \pgfluamathgetresult{pgfluamathfunctions.Cos(#1)}} +\def\pgfluamathtan@#1{% + \pgfluamathgetresult{pgfluamathfunctions.Tan(#1)}} +\def\pgfluamathmod@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.mod(#1,#2)}} +\def\pgfluamathMod@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.Mod(#1,#2)}} +\def\pgfluamathrad@#1{% + \pgfluamathgetresult{pgfluamathfunctions.rad(#1)}} +\def\pgfluamathdeg@#1{% + \pgfluamathgetresult{pgfluamathfunctions.deg(#1)}} +\def\pgfluamathatan@#1{% + \pgfluamathgetresult{pgfluamathfunctions.aTan(#1)}} +\def\pgfluamathatantwo@#1#2{% + \pgfluamathgetresult{pgfluamathfunctions.aTan2(#1,#2)}} +\def\pgfluamathasin@#1{% + \pgfluamathgetresult{pgfluamathfunctions.aSin(#1)}} +\def\pgfluamathacos@#1{% + \pgfluamathgetresult{pgfluamathfunctions.aCos(#1)}} +\def\pgfluamathcot@#1{% + \pgfluamathgetresult{1/pgfluamathfunctions.Tan(#1)}} +\def\pgfluamathsec@#1{% + \pgfluamathgetresult{1/pgfluamathfunctions.Cos(#1)}} +\def\pgfluamathcosec@#1{% + \pgfluamathgetresult{1/pgfluamathfunctions.Sin(#1)}} +\def\pgfluamathexp@#1{% + \pgfluamathgetresult{pgfluamathfunctions.exp(#1)}} +\def\pgfluamathln@#1{% + \pgfluamathgetresult{pgfluamathfunctions.log(#1)}} +\def\pgfluamathlogten@#1{% + \pgfluamathgetresult{pgfluamathfunctions.log10(#1)}} +\def\pgfluamathsqrt@#1{% + \pgfluamathgetresult{pgfluamathfunctions.sqrt(#1)}} +\def\pgfluamathrnd@{% + \pgfluamathgetresult{pgfluamathfunctions.rnd()}} +\def\pgfluamathrand@{% + \pgfluamathgetresult{pgfluamathfunctions.rand(-1,1)}} +\def\pgfluamathfactorial@#1{% + \pgfluamathgetresult{pgfluamathfunctions.factorial(#1)}} +\def\pgfluamathreciprocal#1{% + \pgfluamathgetresult{1/#1}} +% \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@% +% \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@% +% \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% +% \pgfluamath@install@function\pgfmathe=\pgfluamathe@% +% \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@% +% \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@% +% \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@% +% \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@% +% \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@ +% \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@ +% \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@ +% \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@ +% \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@ +% \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@ +% \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@ +% \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@ +% \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@ +% \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@ +% \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@ +% \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@ +% \pgfluamath@install@function\pgfmathand@=\pgfluamathand@ +% \pgfluamath@install@function\pgfmathor@=\pgfluamathor@ +% \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@ +% \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@ +% \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@ +% \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@ +% \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@ + +\def\pgfluamathpointnormalised#1{% + \pgf@process{#1}% + \pgfutil@directlua{% + pgfluamathfunctions.pointnormalised(% + \pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})}% + \ignorespaces} + +% Parser + +\newif\ifpgfluamathunitsdeclared + +\def\pgfluamathparse#1{% + \pgfluamathunitsdeclaredfalse + % The following "two passes" (TeX -> lua -> TeX -> lua -> TeX) is + % required for chadef'ed named boxes. The parser + % adds \number in front of the box name (e.g. \mybox -> + % \number\mybox). Then this is expanded to the chardef'ed number via + % \edef expansion. + \edef\pgfluamath@temp{% + \pgfutil@directlua{% + % Double quotes " are needed here. On the lua side, single quotes + % ' are used. Take care to don't mix them. + pgfluamathparser.parse("\pgfutil@luaescapestring{#1}") + tex.sprint(parsed_expression)}}% + % We can now feed back the evaluator. + \edef\pgfluamathresult{% + \pgfutil@directlua{% + pgfluamathparser.eval('\pgfluamath@temp') + if pgfluamathparser.result == nil then + tex.print('nil') + else + tex.print(pgfluamathparser.result) + end}}% + \csname pgfluamathunitsdeclared\pgfutil@directlua{% + if pgfluamathparser.units_declared == true then + tex.print('true') + else + tex.print('false') + end}\endcsname + \ifpgfluamathparseractive + \let\pgfmathresult\pgfluamathresult + \let\ifpgfmathunitsdeclared=\ifpgfluamathunitsdeclared + \fi} + +\endinput +% NEW: CJ (06 March 2012) Work in progress +\documentclass{minimal} + +\usepackage{pgfmath} + +\makeatletter +\let\pgfutil@directlua\directlua + +\directlua{dofile('pgfmathparser.lua')} + +\def\pgfluamathdeclarefunction#1#2#3{% + \pgfutil@directlua{% + pgfluamath.declare_new_function('#1',#2,#3)}} + +\pgfluamathdeclarefunction{add}{2}{% + function (a,b) return a + b end} + +\pgfluamathdeclarefunction{substract}{2}{% + function (a,b) return a - (b) end} + +\pgfluamathdeclarefunction{neg}{1}{% + function (a) return -(a) end} + +\pgfluamathdeclarefunction{multiply}{2}{% + function (a,b) return a * b end} + +\pgfluamathdeclarefunction{divide}{2}{% + function (a,b) return a / b end} + +\pgfluamathdeclarefunction{pow}{2}{% + function (a,b) return math.pow(a,b) end} + +\pgfluamathdeclarefunction{deg}{1}{% + function (a) return math.deg(a) end} + +\pgfluamathdeclarefunction{ifthenelse}{3}{% + function (a,b,c) if a == 1 then return b else return c end end} + +\pgfluamathdeclarefunction{equal}{2}{% + function (a,b) if a == b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{greater}{2}{% + function (a,b) if a > b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{less}{2}{% + function (a,b) if a < b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{notequal}{2}{% + function (a,b) if a < b or a > b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{notless}{2}{% + function (a,b) if a >= b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{notgreater}{2}{% + function (a,b) if a <= b then return 1 else return 0 end end} + +\pgfluamathdeclarefunction{andPGF}{2}{% + function (a,b) if (a < 0 or a > 0) and (b < 0 or b > 0) then return + 1 else return 0 end end} + +\pgfluamathdeclarefunction{orPGF}{2}{% + function (a,b) if (a < 0 or a > 0) or (b < 0 or b > 0) then return 1 + else return 0 end end} + +\pgfluamathdeclarefunction{modulo}{2}{% + % This is the definition of the lua % modulo operator + % The % operator cannot be used here (catcode issue) + function (a,b) return a - math.floor(a/b)*b end} + +\pgfluamathdeclarefunction{int}{1}{% + function (a) return a - pgfluamath.defined_functions.modulo.code(a,1) end} + +\pgfluamathdeclarefunction{frac}{1}{% + function (a) return pgfluamath.defined_functions.modulo.code(a,1) end} + +\pgfluamathdeclarefunction{factorial}{1}{% + function (a) + a = math.abs(pgfluamath.defined_functions.int.code(a)) + if a == 1 then + return 1 + else + return a * pgfluamath.defined_functions.factorial.code(a-1) + end + end} + +\pgfluamathdeclarefunction{sqrt}{1}{% + function (a) return math.sqrt(a) end} + + + +\def\pgfluamathparseandresult#1{% + \pgfutil@directlua{% + local s = pgfluamath.transform_math_expr('#1',pgfluamath.defined_functions_pattern) + texio.write_nl('pgfluamath: parsed expression "' .. s .. '"') + loadstring('tex.sprint(-1,' .. s .. ')')()}} + +\makeatother +\begin{document} + +$\pgfluamathparseandresult{1+2} = 3$ + +$\pgfluamathparseandresult{2*3} = 6$ + +$\pgfluamathparseandresult{1--1} = 2$ + +$\pgfluamathparseandresult{6/2} = 3$ + +$\pgfluamathparseandresult{2^2} = 4$ + +$\pgfluamathparseandresult{1>2} = 0$ + +$\pgfluamathparseandresult{2>1} = 1$ + +$\pgfluamathparseandresult{1!=1} = 0$ + +$\pgfluamathparseandresult{1?2:3} = 2$ + +$\pgfluamathparseandresult{1.0||0} = 1$ + +$\pgfluamathparseandresult{1&&0} = 0$ + +$\pgfluamathparseandresult{sqrt(2)} = \pgfmathparse{sqrt(2)}\pgfmathresult$ + +%\pgfluamathparseandresult{{1,{2,3-7}[1],4}[1]^2} + +\end{document} +% Local Variables: +% TeX-engine: luatex +% End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua new file mode 100644 index 00000000000..fa3c1872a58 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua @@ -0,0 +1,313 @@ +-- Copyright 2011 by Christophe Jorssen +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License. +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more details. +-- +-- $Id: pgfluamath.functions.lua,v 1.9 2013/07/25 10:39:34 tantau Exp $ +-- + +local pgfluamathfunctions = pgfluamathfunctions or {} + +local mathabs, mathacos, mathasin = math.abs, math.acos, math.asin +local mathatan, mathatan2, mathceil = math.atan, math.atan2, math.ceil +local mathcos, mathcosh, mathdeg = math.cos, math.cosh, math.deg +local mathexp, mathfloor, mathfmod = math.exp, math.floor, math.fmod +local mathfrexp, mathhuge, mathldexp = math.frexp, math.huge, math.ldexp +local mathlog, mathlog10, mathmax = math.log, math.log10, math.max +local mathmin, mathmodf, mathpi = math.min, math.modf, math.pi +local mathpow, mathrad, mathrandom = math.pow, math.rad, math.random +local mathrandomseed, mathsin = math.randomseed, math.sin +local mathsinh, mathsqrt, mathtanh = math.sinh, math.sqrt, math.tanh +local mathtan = math.tan + +function pgfluamathfunctions.add(x,y) + return x+y +end + +function pgfluamathfunctions.substract(x,y) + return x-y +end + +function pgfluamathfunctions.neg(x) + return -x +end + +function pgfluamathfunctions.multiply(x,y) + return x*y +end + +function pgfluamathfunctions.divide(x,y) + return x/y +end + +function pgfluamathfunctions.pow(x,y) + return mathpow(x,y) +end + +function pgfluamathfunctions.factorial(x) +-- TODO: x must be an integer + if x == 0 then + return 1 + else + return x * factorial(x-1) + end +end + +function pgfluamathfunctions.deg(x) + return mathdeg(x) +end + +function pgfluamathfunctions.ifthenelse(x,y,z) + if x~= 0 then + return y + else + return z + end +end + +function pgfluamathfunctions.equal(x,y) + if x == y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.greater(x,y) + if x > y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.less(x,y) + if x < y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notequal(x,y) + if x ~= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notless(x,y) + if x >= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notgreater(x,y) + if x <= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.andPGF(x,y) + if (x ~= 0) and (y ~= 0) then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.orPGF(x,y) + if (x ~= 0) or (y ~= 0) then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notPGF(x) + if x == 0 then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.pi() + return mathpi +end + +function pgfluamathfunctions.e() + return mathexp(1) +end + +function pgfluamathfunctions.abs(x) + return mathabs(x) +end + +function pgfluamathfunctions.floor(x) + return mathfloor(x) +end + +function pgfluamathfunctions.ceil(x) + return mathceil(x) +end + +function pgfluamathfunctions.exp(x) + return mathexp(x) +end + +function pgfluamathfunctions.log(x) + return mathlog(x) +end + +function pgfluamathfunctions.log10(x) + return mathlog10(x) +end + +function pgfluamathfunctions.sqrt(x) + return mathsqrt(x) +end + +function pgfluamathfunctions.rnd() + return mathrandom() +end + +function pgfluamathfunctions.rand() + return mathrandom(-1,1) +end + +function pgfluamathfunctions.deg(x) + return mathdeg(x) +end + +function pgfluamathfunctions.rad(x) + return mathrad(x) +end + +function pgfluamathfunctions.round(x) + if x<0 then + return -mathceil(mathabs(x)) + else + return mathceil(x) + end +end + +function pgfluamathfunctions.gcd(a, b) + if b == 0 then + return a + else + return gcd(b, a%b) + end +end + +function pgfluamathfunctions.isprime(a) + local ifisprime = true + if a == 1 then + ifisprime = false + elseif a == 2 then + ifisprime = true +-- if a > 2 then + else + local i, imax = 2, mathceil(mathsqrt(a)) + 1 + while ifisprime and (i < imax) do + if gcd(a,i) ~= 1 then + ifisprime = false + end + i = i + 1 + end + end + if ifisprime then + return 1 + else + return 0 + end +end + + +function pgfluamathfunctions.split_braces_to_explist(s) + -- (Thanks to mpg and zappathustra from fctt) + -- Make unpack available whatever lua version is used + -- (unpack in lua 5.1 table.unpack in lua 5.2) + local unpack = table.unpack or unpack + local t = {} + for i in s:gmatch('%b{}') do + table.insert(t, tonumber(i:sub(2, -2))) + end + return unpack(t) +end + +function pgfluamathfunctions.split_braces_to_table(s) + local t = {} + for i in s:gmatch('%b{}') do + table.insert(t, tonumber(i:sub(2, -2))) + end + return t +end + +function pgfluamathfunctions.mod(x,y) + if x/y < 0 then + return -(mathabs(x)%mathabs(y)) + else + return mathabs(x)%mathabs(y) + end +end + +function pgfluamathfunctions.Mod(x,y) + return mathabs(x)%mathabs(y) +end + +function pgfluamathfunctions.Sin(x) + return mathsin(mathrad(x)) +end + +function pgfluamathfunctions.Cos(x) + return mathcos(mathrad(x)) +end + +function pgfluamathfunctions.Tan(x) + return mathtan(mathrad(x)) +end + +function pgfluamathfunctions.aSin(x) + return mathdeg(mathasin(x)) +end + +function pgfluamathfunctions.aCos(x) + return mathdeg(mathacos(x)) +end + +function pgfluamathfunctions.aTan(x) + return mathdeg(mathatan(x)) +end + +function pgfluamathfunctions.aTan2(y,x) + return mathdeg(mathatan2(y,x)) +end + +function pgfluamathfunctions.pointnormalised (pgfx, pgfy) + local pgfx_normalised, pgfy_normalised + if pgfx == 0. and pgfy == 0. then + -- Orginal pgf macro gives this result + tex.dimen['pgf@x'] = "0pt" + tex.dimen['pgf@y'] = "1pt" + else + pgfx_normalised = pgfx/math.sqrt(pgfx^2 + pgfy^2) + pgfx_normalised = pgfx_normalised - pgfx_normalised%0.00001 + pgfy_normalised = pgfy/math.sqrt(pgfx^2 + pgfy^2) + pgfy_normalised = pgfy_normalised - pgfy_normalised%0.00001 + tex.dimen['pgf@x'] = tostring(pgfx_normalised) .. "pt" + tex.dimen['pgf@y'] = tostring(pgfy_normalised) .. "pt" + end + return nil +end + +return pgfluamathfunctions \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua new file mode 100644 index 00000000000..b059e334358 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua @@ -0,0 +1,647 @@ +-- Copyright 2011 by Christophe Jorssen and Mark Wibrow +-- +-- This file may be distributed and/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License. +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more details. +-- +-- $Id: pgfluamath.parser.lua,v 1.14 2012/04/29 20:36:29 ludewich Exp $ + +local pgfluamathparser = pgfluamathparser or {} + +require("pgfluamath.functions") + +-- lpeg is always present in luatex +local lpeg = require("lpeg") + +local S, P, R = lpeg.S, lpeg.P, lpeg.R +local C, Cc, Ct = lpeg.C, lpeg.Cc, lpeg.Ct +local Cf, Cg, Cs = lpeg.Cf, lpeg.Cg, lpeg.Cs +local V = lpeg.V + +local space_pattern = S(" \n\r\t")^0 + +local exponent_pattern = S("eE") + +local one_digit_pattern = R("09") +local positive_integer_pattern = one_digit_pattern^1 +local integer_pattern = P("-")^-1 * positive_integer_pattern +-- Valid positive decimals are |xxx.xxx|, |.xxx| and |xxx.| +local positive_decimal_pattern = (one_digit_pattern^1 * P(".") * + one_digit_pattern^1) + + (P(".") * one_digit_pattern^1) + + (one_digit_pattern^1 * P(".")) +local decimal_pattern = P("-")^-1 * positive_decimal_pattern +local float_pattern = decimal_pattern * exponent_pattern * integer_pattern +local number_pattern = float_pattern + decimal_pattern + integer_pattern + +local at_pattern = P("@") + +local underscore_pattern = P("_") + +local lower_letter_pattern = R("az") +local upper_letter_pattern = R("AZ") +local letter_pattern = lower_letter_pattern + upper_letter_pattern +local alphanum_pattern = letter_pattern + one_digit_pattern +local alphanum__pattern = alphanum_pattern + underscore_pattern +local alpha__pattern = letter_pattern + underscore_pattern + +local openparen_pattern = P("(") +local closeparen_pattern = P(")") +local opencurlybrace_pattern = P("{") +local closecurlybrace_pattern = P("}") +local openbrace_pattern = P("[") +local closebrace_pattern = P("]") + +-- local string = P('"') * C((1 - P('"'))^0) * P('"') + +local orop_pattern = P("||") +local andop_pattern = P("&&") + +local neqop_pattern = P("!=") + +local then_pattern = P("?") +local else_pattern = P(":") +local factorial_pattern = P("!") +local not_mark_pattern = P("!") +local radians_pattern = P("r") + +local comma_pattern = P(",") + +--[[ +local grammar = P { + -- "E" stands for expression + "ternary_logical_E", + ternary_logical_E = Cf(V("logical_or_E") * + Cg( then_mark * V("logical_or_E") * else_mark * V("logical_or_E"))^0,evalternary); + logical_or_E = Cf(V("logical_and_E") * Cg(orop * V("logical_and_E"))^0,evalbinary); + logical_and_E = Cf(V("equality_E") * Cg(andop * V("equality_E"))^0,evalbinary); + equality_E = Cf(V("relational_E") * + Cg((eqop * V("relational_E")) + (neqop * V("relational_E")))^0,evalbinary); + relational_E = Cf(V("additive_E") * Cg((lessop * V("additive_E")) + + (greatop * V("additive_E")) + + (lesseqop * V("additive_E")) + + (greateqop * V("additive_E")))^0,evalbinary); + additive_E = Cf(V("multiplicative_E") * Cg((addop * V("multiplicative_E")) + + (subop * V("multiplicative_E")))^0,evalbinary); + multiplicative_E = Cf(V("power_E") * Cg((mulop * V("power_E")) + + divop * V("power_E"))^0,evalbinary); + power_E = Cf(V("postfix_unary_E") * Cg(powop * V("postfix_unary_E"))^0,evalbinary); + postfix_unary_E = Cf(V("prefix_unary_E") * Cg(radians + factorial)^0,evalpostfixunary); + prefix_unary_E = Cf(Cg(not_mark + negop)^0 * V("E"),evalprefixunary), + E = string + float + decimal + integer / tonumber + + (openparen * V("ternary_logical_E") * closeparen) + + (func * param_beg * V("ternary_logical_E") * + (comma * V("ternary_logical_E"))^0 * param_end); +} + +local parser = space_pattern * grammar * -1 +--]] + +-- NOTE: \pgfmathparse{pi/3.14} will fail giving pgfluamathfunctions.pi()3.14 +-- (the / is missing, probably gobbled by one of the captures of the grammar). + +pgfluamathparser.transform_operands = P({ + 'transform_operands'; + + one_char = lpeg.P(1), + lowercase = lpeg.R('az'), + uppercase = lpeg.R('AZ'), + numeric = lpeg.R('09'), + dot = lpeg.P('.'), + exponent = lpeg.S('eE'), + sign_prefix = lpeg.S('-+'), + begingroup = lpeg.P('('), + endgroup = lpeg.P(')'), + backslash = lpeg.P'\\', + at = lpeg.P'@', + + alphabetic = lpeg.V'lowercase' + lpeg.V'uppercase', + alphanumeric = lpeg.V'alphabetic' + lpeg.V'numeric', + + integer = lpeg.V'numeric'^1, + real = lpeg.V'numeric'^0 * lpeg.V'dot' * lpeg.V'numeric'^1, + scientific = (lpeg.V'real' + lpeg.V'integer') * lpeg.V'exponent' * lpeg.V'sign_prefix'^0 * lpeg.V'integer', + + number = lpeg.V'scientific' + lpeg.V'real' + lpeg.V'integer', + function_name = lpeg.V('alphabetic') * lpeg.V('alphanumeric')^0, + + tex_cs = lpeg.V'backslash' * (lpeg.V'alphanumeric' + lpeg.V'at')^1, + tex_box_dimension_primative = lpeg.V'backslash' * (lpeg.P'wd' + lpeg.P'ht' + lpeg.P'dp'), + tex_register_primative = lpeg.V'backslash' * (lpeg.P'count' + lpeg.P'dimen'), + + tex_primative = lpeg.V'tex_box_dimension_primative' + lpeg.V'tex_register_primative', + tex_macro = -lpeg.V'tex_primative' * lpeg.V'tex_cs', + + tex_unit = + lpeg.P('pt') + lpeg.P('mm') + lpeg.P('cm') + lpeg.P('in') + + lpeg.P('ex') + lpeg.P('em') + lpeg.P('bp') + lpeg.P('pc') + + lpeg.P('dd') + lpeg.P('cc') + lpeg.P('sp'), + + tex_register_named = lpeg.C(lpeg.V'tex_macro'), + tex_register_numbered = lpeg.C(lpeg.V'tex_register_primative') * lpeg.C(lpeg.V'integer'), + tex_register_basic = lpeg.Cs(lpeg.Ct(lpeg.V'tex_register_numbered' + lpeg.V'tex_register_named') / pgfluamathparser.process_tex_register), + + tex_multiplier = lpeg.Cs((lpeg.V'tex_register_basic' + lpeg.C(lpeg.V'number')) / pgfluamathparser.process_muliplier), + + tex_box_width = lpeg.Cs(lpeg.P('\\wd') / 'width'), + tex_box_height = lpeg.Cs(lpeg.P('\\ht') / 'height'), + tex_box_depth = lpeg.Cs(lpeg.P('\\dp') / 'depth'), + tex_box_dimensions = lpeg.V'tex_box_width' + lpeg.V'tex_box_height' + lpeg.V'tex_box_depth', + tex_box_named = lpeg.Cs(lpeg.Ct(lpeg.V'tex_box_dimensions' * lpeg.C(lpeg.V'tex_macro')) / pgfluamathparser.process_tex_box_named), + tex_box_numbered = lpeg.Cs(lpeg.Ct(lpeg.V'tex_box_dimensions' * lpeg.C(lpeg.V'number')) / pgfluamathparser.process_tex_box_numbered), + tex_box_basic = lpeg.V'tex_box_named' + lpeg.V'tex_box_numbered', + + tex_register = lpeg.Cs(lpeg.V'tex_multiplier' * lpeg.V'tex_register_basic') + lpeg.V'tex_register_basic', + tex_box = lpeg.Cs(lpeg.Cs(lpeg.V'tex_multiplier') * lpeg.V'tex_box_basic') + lpeg.V'tex_box_basic', + tex_dimension = lpeg.Cs(lpeg.V'number' * lpeg.V'tex_unit' / pgfluamathparser.process_tex_dimension), + + tex_operand = lpeg.Cs(lpeg.V'tex_dimension' + lpeg.V'tex_box' + lpeg.V'tex_register'), + + function_name = lpeg.V'alphabetic' * (lpeg.V'alphanumeric'^1), + function_operand = lpeg.Cs(lpeg.Ct(lpeg.C(lpeg.V'function_name') * lpeg.C(lpeg.V'one_char') + lpeg.C(lpeg.V'function_name')) / pgfluamathparser.process_function), + + -- order is (always) important! + operands = lpeg.V'tex_operand' + lpeg.V'number' + lpeg.V'function_operand', + + transform_operands = lpeg.Cs((lpeg.V'operands' + 1)^0) + }) + +-- Namespaces will be searched in the following order. +pgfluamathparser.function_namespaces = { + 'pgfluamathfunctions', 'math', '_G'} + +pgfluamathparser.units_declared = false + +function pgfluamathparser.get_tex_box(box, dimension) + -- assume get_tex_box is only called when a dimension is required. + pgfluamathparser.units_declared = true + if dimension == 'width' then + return tex.box[box].width / 65536 -- return in points. + elseif dimension == 'height' then + return tex.box[box].height / 65536 + else + return tex.box[box].depth / 65536 + end +end + +function pgfluamathparser.get_tex_register(register) + -- register is a string which could be a count or a dimen. + if pcall(tex.getcount, register) then + return tex.count[register] + elseif pcall(tex.getdimen, register) then + pgfluamathparser.units_declared = true + return tex.dimen[register] / 65536 -- return in points. + else + pgfluamathparser.error = 'I do not know the TeX register "' .. register '"' + return nil + end + +end + +function pgfluamathparser.get_tex_count(count) + -- count is expected to be a number + return tex.count[tonumber(count)] +end + +function pgfluamathparser.get_tex_dimen(dimen) + -- dimen is expected to be a number + pgfluamathparser.units_declared = true + return tex.dimen[tonumber(dimen)] / 65536 +end + +function pgfluamathparser.get_tex_sp(dimension) + -- dimension should be a string + pgfluamathparser.units_declared = true + return tex.sp(dimension) / 65536 +end + + + +-- transform named box specification +-- e.g., \wd\mybox -> pgfluamathparser.get_tex_box["mybox"].width +-- +function pgfluamathparser.process_tex_box_named(box) + return 'pgfluamathparser.get_tex_box(\\number' .. box[2] .. ', "' .. box[1] .. '")' +end + +-- transform numbered box specification +-- e.g., \wd0 -> pgfluamathparser.get_tex_box["0"].width +-- +function pgfluamathparser.process_tex_box_numbered(box) + return 'pgfluamathparser.get_tex_box("' .. box[2] .. '", "' .. box[1] .. '")' +end + +-- transform a register +-- e.g., \mycount -> pgfluamathparser.get_tex_register["mycount"] +-- \dimen12 -> pgfluamathparser.get_tex_dimen[12] +-- +function pgfluamathparser.process_tex_register(register) + if register[2] == nil then -- a named register + return 'pgfluamathparser.get_tex_register("' .. register[1]:sub(2, register[1]:len()) .. '")' + else -- a numbered register + return 'pgfluamathparser.get_tex_' .. register[1]:sub(2, register[1]:len()) .. '(' .. register[2] .. ')' + end +end + +-- transform a 'multiplier' +-- e.g., 0.5 -> 0.5* (when followed by a box/register) +-- +function pgfluamathparser.process_muliplier(multiplier) + return multiplier .. '*' +end + +-- transform an explicit dimension to points +-- e.g., 1cm -> pgfluamathparser.get_tex_sp("1cm") +-- +function pgfluamathparser.process_tex_dimension(dimension) + return 'pgfluamathparser.get_tex_sp("' .. dimension .. '")' +end + +-- Check the type and 'namespace' of a function F. +-- +-- If F cannot be found as a Lua function or a Lua number in the +-- namespaces in containted in pgfluamathparser.function_namespaces +-- then an error results. +-- +-- if F is a Lua function and isn't followd by () (a requirement of Lua) +-- then the parentheses are inserted. +-- +-- e.g., random -> random() (if random is a function in the _G namespace) +-- pi -> math.pi (if pi is a constant that is only in the math namespace) +-- +function pgfluamathparser.process_function(function_table) + local function_name = function_table[1] + local char = function_table[2] + if (char == nil) then + char = '' + end + for _, namespace in pairs(pgfluamathparser.function_namespaces) do + local function_type = assert(loadstring('return type(' .. namespace .. '.' .. function_name .. ')'))() + if function_type == 'function' then + if not (char == '(') then + char = '()' + end + return namespace .. '.' .. function_name .. char + elseif function_type == 'number' then + return namespace .. '.' .. function_name .. char + end + end + pgfluamathparser.error = 'I don\'t know the function or constant \'' .. function_name .. '\'' +end + + +pgfluamathparser.remove_spaces = lpeg.Cs((lpeg.S' \n\t' / '' + 1)^0) + + +function pgfluamathparser.evaluate(expression) + assert(loadstring('pgfluamathparser._result=' .. expression))() + pgfluamathparser.result = pgfluamathparser._result +end + +function pgfluamathparser.parse(expression) + pgfluamathparser.write_to_log("Parsing expression:" .. expression) + pgfluamathparser.units_declared = false + + pgfluamathparser.error = nil + pgfluamathparser.result = nil + + -- Remove spaces + expression = pgfluamathparser.remove_spaces:match(expression) + + parsed_expression = + pgfluamathparser.transform_operands:match(expression) + pgfluamathparser.write_to_log("Transformed expression:" + .. parsed_expression) +end + +function pgfluamathparser.eval(expression) + pgfluamathparser.write_to_log("Evaluating expression:" .. expression) + pcall(pgfluamathparser.evaluate, expression) + pgfluamathparser.write_to_log("Result:" .. pgfluamathparser.result) + if pgfluamathparser.result == nil then + pgfluamathparser.error = "Sorry, I could not evaluate '" .. expression .. "'" + return nil + else + return pgfluamathparser.result + end +end + +pgfluamathparser.trace = true + +function pgfluamathparser.write_to_log (s) + if pgfluamathparser.trace then + texio.write_nl(s) + end +end + +return pgfluamathparser + +--[[ NEW: 2012/02/21, CJ, work in progress +-- We need 3 parsers (or 2, 2 and 3 could be merged) +-- (1) To get the number associated with a (\chardef'ed) box (e.g. +-- \ht\mybox -> \ht26) +-- This is part of a TeX ->(\directlua == \edef) -> lua -> (lpeg parser 1) +-- -> TeX -> (\directlua == \edef) +-- (2) To transform math and functions operands +-- (3) To transform units, dimen and count register + +-- TODO: strings delimited by "..." +-- TODO: units. \pgfmathparse{12+1cm}\pgfmathresult and \the\dimexpr 12pt+1cm\relax have the same result. Note: \pgfmathparse{(12+1)cm} won't work in plain pgfmath. +-- TODO: Parser 3 + + +pgfluamath = pgfluamath or {} + +pgfluamath.debug = true + +local lpeg = require('lpeg') +local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V +local C, Cc, Cs = lpeg.C, lpeg.Cc, lpeg.Cs +local Cf, Cg, Ct = lpeg.Cf, lpeg.Cg, lpeg.Ct +local match = lpeg.match + +local space = S(' \n\t') + +local lowercase = R('az') +local uppercase = R('AZ') +local alphabetic = lowercase + uppercase + +local digit = R('09') + +local alphanumeric = alphabetic + digit + +local dot = P('.') +local exponent = S('eE') +local sign_prefix = S('+-') + +local integer = digit^1 +local float = (digit^1 * dot * digit^0) + (digit^0 * dot * digit^1) +local scientific = (float + integer) * exponent * sign_prefix^-1 * integer + +local number = scientific + float + integer + +local at = P('@') + +local backslash = P('\\') + +local box_width = P('\\wd') +local box_height = P('\\ht') +local box_depth = P('\\dp') +local box_dimension = box_width + box_height + box_depth + +local tex_cs = backslash * (alphabetic + at)^1 + +local lparen = P('(') +local rparen = P(')') + +local lbrace = P('{') +local rbrace = P('}') + +local lbracket = P('[') +local rbracket = P(']') + +local thenop = P('?') +local elseop = P(':') + +local orop = P('||') +local andop = P('&&') + +local eqop = P('==') +local neqop = P('!=') + +local greaterop = P('>') +local lessop = P('<') +local greatereqop = P('>=') +local lesseqop = P('<=') + +local addop = P('+') +local subop = P('-') + +local mulop = P('*') +local divop = P('/') + +local powop = P('^') + +local radop = P('r') + +local notop = P('!') +local negop = P('-') + +local comma = P(',') + +function pgfluamath.namedbox_to_numberedbox (s) + -- Transforms '{\wd|\ht|\dp}\mybox' to '{\wd|\ht|\dp}\number\mybox' + local function transform (capture) + print('Captured ' .. capture) + return '\\number' .. capture + end + local dimension_of_a_named_box = + box_dimension * space^0 * (tex_cs / transform) + -- P(1) matches exactly one character + -- V(1) is the entry of the grammar with index 1. It defines the initial rule. + -- The manual says: + -- "If that entry is a string, it is assumed to be the name of the initial rule. + -- Otherwise, LPeg assumes that the entry 1 itself is the initial rule." + local grammar = + P({ + [1] = (dimension_of_a_named_box + P(1)) * V(1) + P(true) + }) + return print(match(Cs(grammar),s)) +end +--[[ +namedbox_to_numberedbox('test') +namedbox_to_numberedbox('\\test') +namedbox_to_numberedbox('\\wd\\test') +namedbox_to_numberedbox('\\wd\\test0') +namedbox_to_numberedbox('\\wd\\test01') +namedbox_to_numberedbox('\\wd\\test@t 012') +namedbox_to_numberedbox(' \\wd \\test012') +namedbox_to_numberedbox('\\wd\\test012\\test \\ht\\zozo0') +namedbox_to_numberedbox('\\wd0') +--]] + +-- Grammar (from lowest to highest precedence) +-- Need to adjust to the precedences in plain pgfmath parser +-- IfThenElse Expression +local ITE_E = V('ITE_E') +-- logical OR Expression +local OR_E = V('OR_E') +-- logical AND Expression +local AND_E = V('AND_E') +-- EQuality Expression +local EQ_E = V('EQ_E') +-- Relational EQuality Expression +local REQ_E = V('REQ_E') +-- ADDitive Expression +local ADD_E = V('ADD_E') +-- MULtiplicative Expression +local MUL_E = V('MUL_E') +-- POWer Expression +local POW_E = V('POW_E') +-- POSTfix Expression +local POST_E = V('POST_E') +-- PREfix Expression +local PRE_E = V('PRE_E') +-- ARRAY Expression +local ARRAY_E = V('ARRAY_E') +-- Expression +local E = V('E') + +function pgfluamath.transform_math_expr (s, f_patt) + if pgfluamath.debug then + texio.write_nl('pgfluamath: parsing expression "' .. s ..'"') + end + -- f_patt extends the grammar dynamically at the time of the call to the + -- parser. + -- The idea is to have a set of predefined acceptable functions (via e.g. + -- \pgfmathdeclarefunction) + if not f_patt then + -- P(false) is a pattern that always fails + -- (neutral element for the + operator on patterns) + f_patt = P(false) + end + local function transform_ITE(a, b, c) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.ifthenelse.code(%s,%s,%s)', a, b, c) + end + end + local function transform_binary(a, b, c) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.%s.code(%s,%s)', b, a, c) + end + end + local function transform_postunary(a, b) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.%s.code(%s)', b, a) + end + end + local function transform_preunary(a, b) + if not b then + return a + else + return string.format('pgfluamath.defined_functions.%s.code(%s)', a, b) + end + end + local function transform_array(a, b) + -- One exception to the mimmic of plain pgfmath. I do not use the equivalent array function to transform the arrays because I don't know how to handle both cases {1,{2,3}[1],4}[1] and {1,{2,3},4}[1][1] with the parser and the array function. + -- So I convert a pgf array to a lua table. One can access one entry of the table like this ({1,2})[1] (note the parenthesis, ie {1,2}[1] won't work). + local s + if not b then + s = '{' + else + s = '({' + end + for i = 1,#a do + -- We change the index to fit with pgfmath plain convention (index starts at 0 while in lua index starts at 1) + s = s .. '[' .. tostring(i-1) .. ']=' .. a[i] + if i < #a then + s = s .. ',' + end + end + if b then + s = s .. '})' + for i = 1,#b do + s = s .. '[' .. b[i] .. ']' + end + else + s = s .. '}' + end + return s + end + local grammar = + lpeg.P({ + 'ITE_E', + ITE_E = (OR_E * (thenop * OR_E * elseop * OR_E)^-1) / transform_ITE, + OR_E = (AND_E * (orop * Cc('orPGF') * AND_E)^-1) / transform_binary, + AND_E = (EQ_E * (andop * Cc('andPGF') * EQ_E)^-1) / transform_binary, + EQ_E = (REQ_E * ((eqop * Cc('equal') + neqop * Cc('notequal')) * REQ_E)^-1) / transform_binary, + REQ_E = (ADD_E * ((lessop * Cc('less') + greaterop * Cc('greater') + lesseqop * Cc('notgreater') + greatereqop * Cc('notless')) * ADD_E)^-1) / transform_binary, + ADD_E = Cf(MUL_E * Cg((addop * Cc('add') + subop * Cc('substract')) * MUL_E)^0,transform_binary), + MUL_E = Cf(POW_E * Cg((mulop * Cc('multiply') + divop * Cc('divide')) * POW_E)^0,transform_binary), + POW_E = Cf(POST_E * Cg(powop * Cc('pow') * POST_E)^0,transform_binary), + POST_E = (PRE_E * (radop * Cc('rad'))^-1) / transform_postunary, + PRE_E = ((notop * Cc('notPGF') + negop * Cc('neg'))^-1 * E) / transform_preunary, + ARRAY_E = (lbrace * Ct(ITE_E * (comma * ITE_E)^0) * rbrace * Ct((lbracket * ITE_E * rbracket)^0)) / transform_array, + E = ((integer + float)^-1 * tex_cs^1) + f_patt + C(number) + (lparen * ITE_E * rparen) + ARRAY_E + lbrace * ITE_E * rbrace + }) + return lpeg.match(Cs(grammar),s) +end + +function pgfluamath.ptransform_math_expr(s, f_patt) + local st = pgfluamath.transform_math_expr(s, f_patt) + if st ~= nil then + return texio.write_nl(st) + end +end + +pgfluamath.defined_functions = {} +pgfluamath.defined_functions_pattern = P(false) + +function pgfluamath.declare_new_function (name, nargs, code) + -- nil is true + -- The function name CANNOT be a lua reserved word (so no 'and' nor 'or') + if pgfluamath.defined_functions[name] then + print('Function ' .. name .. ' is already defined. ' .. + 'I overwrite it!') + end + pgfluamath.defined_functions[name] = {['name'] = name, ['nargs'] = nargs, ['code'] = code} + + -- TODO + -- We need a function to dynamically (depending on the number of arguments) define a patten (in order to avoid the long ifcase-type structure). + local pattern + if nargs == 0 then + pattern = P(name) / function (s) return name .. '()' end + else if nargs == 1 then + pattern = ((P(name) * lparen * Cs(ITE_E) * rparen) / function (s) return 'pgfluamath.defined_functions.' .. name .. '.code(' .. s .. ')' end) + else if nargs == 2 then + pattern = (P(name) * lparen * Cs(ITE_E) * comma * Cs(ITE_E) * rparen / function (s1,s2) return 'pgfluamath.defined_functions.' .. name .. 'code(' .. s1 .. ',' .. s2 .. ')' end) + else if nargs == 3 then + pattern = (P(name) * lparen * Cs(ITE_E) * comma * Cs(ITE_E) * comma * Cs(ITE_E) * rparen / function (s1,s2,s3) return 'pgfluamath.defined_functions.' .. name .. 'code(' .. s1 .. ',' .. s2 .. ',' .. s3 .. ')' end) + end + end + end + end + -- TODO + -- This needs to be regenerated every time a new function is added, in conjunction with a sort of the table (see IMPORTANT below) + pgfluamath.defined_functions_pattern = pgfluamath.defined_functions_pattern + pattern +end + +-- IMPORTANT: for 'function' with *0* argument, the longest string, the first +-- ie declaring pi before pit won't work. +pgfluamath.declare_new_function('pit',0) +pgfluamath.declare_new_function('pi',0) +pgfluamath.declare_new_function('exp',1) +pgfluamath.declare_new_function('toto',1) +pgfluamath.declare_new_function('gauss',2) + +pgfluamath.ptransform_math_expr('exp(exp(1+1))',pgfluamath.defined_functions_pattern) + +pgfluamath.ptransform_math_expr('1?(2?3:4^5):gauss(6+toto(7),8+9>10?11:12))',pgfluamath.defined_functions_pattern) + +pgfluamath.ptransform_math_expr('!(1!=-2)>3?(4+5*6+7?8||9&&10:11):12^13r||14') +pgfluamath.ptransform_math_expr('-1^2\\test\\toto^3') +pgfluamath.ptransform_math_expr('{1,{2+3,4}[1],5}[2]+6') +pgfluamath.ptransform_math_expr('{1,{2+3,4},5}[1][1]') +pgfluamath.ptransform_math_expr('{1,{2,3},4}[1][1]') +pgfluamath.ptransform_math_expr('{1,{2,3}[1],4}[1]') + +--Loadstring: If it succeeds in converting the string to a *function*, it returns that function; otherwise, it returns nil and an error message. +toto = loadstring('texio.write_nl(' .. pgfluamath.transform_math_expr('{1,{2,3},4}[1][1]') .. ')') +toto() + +-- IMPORTANT NOTE!! +-- local function add (a,b) will fail within loadstring. Needs to be global. loadstring opens a new chunk that does not know the local variables of other chunks. + +--toto = loadstring('texio.write_nl(' .. pgfluamath.transform_math_expr('{1,{2,3E-1+7}[1],4}[1]') .. ')') +--toto() + +return pgfluamath diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex index d91a83b111f..9c4a48aeaca 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.code.tex @@ -7,12 +7,12 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.code.tex,v 1.9 2008/10/27 21:00:46 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.code.tex,v 1.16 2013/09/23 18:04:35 tantau Exp $ % A square bracket shaped arrow -\pgfarrowsdeclare{[}{]} +\pgfarrowsdeclare{square bracket}{square bracket} { \pgfutil@tempdima=1pt% \advance\pgfutil@tempdima by1.25\pgflinewidth% @@ -33,6 +33,7 @@ \pgfpathlineto{\pgfqpoint{-.5\pgfutil@tempdimb}{\pgfutil@tempdima}} \pgfusepathqstroke } +\pgfdeclarearrow{name=[-], means=square bracket} \pgfarrowsdeclarereversed{]}{[}{[}{]} @@ -148,7 +149,7 @@ { \pgfutil@tempdima=0.4pt% \advance\pgfutil@tempdima by.2\pgflinewidth% - \pgfutil@tempdimb=5.5\pgfutil@tempdima\advance\pgfutil@tempdimb by\pgflinewidth + \pgfutil@tempdimb=7.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth \pgfarrowsleftextend{+-\pgfutil@tempdimb} \pgfutil@tempdimb=1.5\pgfutil@tempdima\advance\pgfutil@tempdimb by.5\pgflinewidth \pgfarrowsrightextend{+\pgfutil@tempdimb} @@ -234,7 +235,7 @@ { \arrowsize=0.4pt \advance\arrowsize by.275\pgflinewidth% - \pgfarrowsleftextend{+-\arrowsize} + \pgfarrowsleftextend{-7\arrowsize-.5\pgflinewidth} \advance\arrowsize by.5\pgflinewidth \pgfarrowsrightextend{+\arrowsize} } @@ -509,6 +510,7 @@ {\pgfqpoint{-1\pgfutil@tempdima}{-1.5\pgfutil@tempdima}} {\pgfqpoint{3.5\pgfutil@tempdima}{-.5\pgfutil@tempdima}} {\pgfqpoint{6\pgfutil@tempdima}{0\pgfutil@tempdima}} + \pgfpathclose \pgfusepathqfill } @@ -825,6 +827,7 @@ \pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}} \pgfpathlineto{\pgfqpoint{.5\pgflinewidth}{-.5\pgflinewidth}} \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-0.5\pgflinewidth}} + \pgfpathclose \pgfusepathqfill } @@ -839,6 +842,7 @@ \pgfpathlineto{\pgfqpoint{-.1\pgflinewidth}{-.5\pgflinewidth}} \pgfpathlineto{\pgfqpoint{1\pgflinewidth}{-.5\pgflinewidth}} \pgfpathlineto{\pgfqpoint{0.5\pgflinewidth}{0\pgflinewidth}} + \pgfpathclose \pgfusepathqfill } @@ -904,12 +908,13 @@ { \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}% \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}% - \pgfarrowsrightextend{2\pgfutil@tempdima+.5\pgfutil@tempdimb} - \pgfarrowsleftextend{1.3\pgfutil@tempdima+.5\pgfutil@tempdimb} + \pgfarrowsrightextend{2.06\pgfutil@tempdima+.5\pgfutil@tempdimb} + \pgfarrowsleftextend{-1.36\pgfutil@tempdima-.5\pgfutil@tempdimb} } { \pgfmathsetlength{\pgfutil@tempdima}{.25\pgflinewidth+.25*\pgfinnerlinewidth}% \pgfmathsetlength{\pgfutil@tempdimb}{.5\pgflinewidth-.5*\pgfinnerlinewidth}% + \pgftransformxshift{.06\pgfutil@tempdima} \pgfsetlinewidth{\pgfutil@tempdimb} \pgfsetdash{}{+0pt} \pgfsetroundcap diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex new file mode 100644 index 00000000000..77edfcd8dc6 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex @@ -0,0 +1,1612 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.meta.code.tex,v 1.12 2013/12/13 15:11:58 tantau Exp $ + + + +% +% +% Meta keys +% +% + + +\newdimen\pgfarrowinset +\newdimen\pgfarrowlength +\newdimen\pgfarrowwidth +\newdimen\pgfarrowlinewidth +\newif\ifpgfarrowroundcap +\newif\ifpgfarrowroundjoin + +\pgfarrowsaddtolengthscalelist\pgfarrowlength +\pgfarrowsaddtolengthscalelist\pgfarrowinset +\pgfarrowsaddtowidthscalelist\pgfarrowwidth + + +\pgfkeys{ + /pgf/arrow keys/.cd, + length/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowlength\pgf@x}% + }, + inset/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowinset\pgf@x}% + }, + inset'/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowinset}% + }, + line width/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowlinewidth\pgf@x}% + }, + line width'/.code={ + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowlinewidth}% + }, + width/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslinewidthdependent\pgfarrowstheparameters\pgfarrowwidth\pgf@x}% + }, + width'/.code={% + \pgfarrowsthreeparameters{#1}% + \expandafter\pgfarrowsaddtolateoptions\expandafter{\expandafter\pgfarrowslengthdependent\pgfarrowstheparameters\pgfarrowwidth}% + }, + angle/.code={% + \pgfarrowsfourparameters{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\pgfarrows@angle@setup\pgfarrowstheparameters}% + }, + angle'/.code={ + \pgfarrowsaddtolateoptions{\pgfarrows@angle@setup@prime{#1}}% + }, + % + line cap/.is choice, + line cap/butt/.code=\pgfarrowsaddtooptions{\pgfarrowroundcapfalse}, + line cap/round/.code=\pgfarrowsaddtooptions{\pgfarrowroundcaptrue}, + line join/.is choice, + line join/miter/.code=\pgfarrowsaddtooptions{\pgfarrowroundjoinfalse}, + line join/round/.code=\pgfarrowsaddtooptions{\pgfarrowroundjointrue}, + round/.style={line cap=round,line join=round}, + sharp/.style={line cap=butt,line join=miter}, +} + + + + +% +% +% Classificaiton of arrow tips: +% +% +% Barbs +% ----- +% +% These arrow tips consisting of stroked lines starting at the tip, +% typically going backward. They cannot be filled, only stroked +% +% A special case are the arrows mimicking the tip at the end of a +% \rightarrow command. +% +% +% Geometric +% --------- +% +% The arrow tips have a geometric form like a triangle or a +% "stealth" fighter or a kite. They can be filled and/or stroked. +% +% +% Caps +% ---- +% +% These arrow tips have their width fixed to the line width and +% provide different ways of adding a "cap" to the end of a line. This +% allows one to use more than just the standard "round cap", "butt +% cap" and "rect cap" and, additionally, one can one kind of cap at +% one end and another at the other end. +% +% +% Other +% ----- +% +% Special purpose arrow tips. +% + + + +% +% +% Barbs arrow tips +% +% + + +% An Straight Barb yields a simple angle + +\pgfdeclarearrow{ + name = Straight Barb, + defaults = { + length = +1.5pt 2, + width' = +0pt 2, + line width = +0pt 1 1, + }, + setup code = { + % Compute front miter length: + \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + % Set ends + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi} + \fi + \pgfarrowssetvisualbackend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth} + \pgfarrowssetbackend{-.5\pgfarrowlinewidth} + % harpoon miter correction + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by.5\pgfarrowlinewidth\fi} + \else + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + \fi + % The hull: + \ifpgfarrowroundjoin + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \else% + \ifpgfarrowharpoon + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgf@xc\advance\pgf@x by\pgf@xa}{-.5\pgfarrowlinewidth}% + \else + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgf@xc\advance\pgf@x by\pgf@xa}{0pt}% + \fi% + \fi + \pgfarrowsupperhullpoint{.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}% + \pgfarrowsupperhullpoint{-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}% + \ifpgfarrowharpoon + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}% + \fi + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth}} + \pgfpathlineto{\pgfqpoint{\pgfarrowlength}{0pt}} + \ifpgfarrowharpoon + \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by\ifpgfarrowreversed\else-\fi\pgfarrowlinewidth}{0pt}} + \else + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth}} + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + + +% Hooks are barbs that consist of an arc going forward from the line +% end and curving back by a given angle speficied using the |arc| +% key. + +\pgfkeys{ + /pgf/arrow keys/.cd, + arc/.code={% + \pgfmathparse{#1}% + \expandafter\pgfarrowsaddtooptions\expandafter{\expandafter\def\expandafter\pgfarrowarc\expandafter{\pgfmathresult}} + } +} + +\def\pgfarrowarc{180} + +\pgfdeclarearrow{ + name = Hooks, + defaults = { + length = +0.75pt 1.25, + width' = +0pt 4 -1, + line width = +0pt 1 1, + }, + setup code = { + \ifpgfarrowharpoon + \pgfarrowshullpoint{.5\pgfarrowlength}{-.5\pgfarrowlinewidth} + \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth\advance\pgf@y by.125\pgfarrowwidth} + \fi + \ifdim\pgfarrowarc pt<90.1pt + \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth\ifpgfarrowroundcap\else\advance\pgf@y by-.25\pgfarrowlinewidth\fi} + \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth\ifpgfarrowroundcap\else\advance\pgf@y by-.25\pgfarrowlinewidth\fi} + \else% + \pgfarrowsupperhullpoint{\pgfarrowlength}{.375\pgfarrowwidth} + \pgfarrowsupperhullpoint{.5\pgfarrowlength}{.5\pgfarrowwidth} + \ifdim\pgfarrowarc pt>180pt + \pgfarrowsupperhullpoint{-.5\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowsupperhullpoint{-\pgfarrowlength}{.375\pgfarrowwidth} + \pgfarrowsupperhullpoint{-\pgfarrowlength}{.25\pgfarrowwidth} + \else + \pgfarrowsupperhullpoint{\ifpgfarrowroundcap-.5\pgfarrowlinewidth\else0pt\fi}{.25\pgfarrowwidth} + \pgfarrowsupperhullpoint{\ifpgfarrowroundcap-.5\pgfarrowlinewidth\else0pt\fi}{.5\pgfarrowwidth} + \fi + \fi + % Adjust width and length: Take line thickness into account: + \advance\pgfarrowlength by-.5\pgfarrowlinewidth + \advance\pgfarrowwidth by-\pgfarrowlinewidth + \ifpgfarrowreversed + \ifpgfarrowroundjoin + \pgfarrowssetbackend{-.5\pgfarrowlinewidth} + \fi + \fi + % There are four different intervals for the values of + % \pgfarrowsarc that give rise to four different settings of tip + % ends and so on: + % + % Case 1: 0 <= Angle < 90 + % + \ifdim\pgfarrowarc pt<90pt% + % Tip end is given by sin(pgfarrowarc)*length + \pgfmathsin@{\pgfarrowarc} + \pgfarrowssettipend{\pgfmathresult\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \else\ifdim\pgfarrowarc pt<180pt% + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \ifpgfarrowroundcap\pgfarrowssetbackend{-.5\pgfarrowlinewidth}\fi% + \else\ifdim\pgfarrowarc pt<270pt% + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \ifdim\pgfarrowarc pt>180pt + % Back end is given by sin(pgfarrowarc)*length + \pgfmathsin@{\pgfarrowarc} + \pgfarrowssetbackend{\pgfmathresult\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}% + \else + \ifpgfarrowroundcap\pgfarrowssetbackend{-.5\pgfarrowlinewidth}\fi% + \fi% + \else% + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by.5\pgfarrowlinewidth}% + \pgfarrowssetbackend{-\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}% + \fi\fi\fi% + \ifpgfarrowreversed + \pgfarrowssetlineend{.5\pgfarrowlinewidth} + \else% + \ifpgfarrowharpoon + \pgfarrowssetlineend{0pt} + \else + \pgfarrowssetlineend{.25\pgfarrowlinewidth} + \fi + \fi + % Adjust arc: + \pgf@x\pgfarrowarc pt% + \advance\pgf@x by-90pt% + \edef\pgfarrowarc{\pgf@sys@tonumber\pgf@x}% + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssave\pgfarrowarc + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + {% + \pgftransformxscale{+\pgfarrowlength} + \pgftransformyscale{+.25\pgfarrowwidth} + \pgfpathmoveto{\pgfpointpolar{+\pgfarrowarc}{+1pt}\advance\pgf@y by1pt} + \pgfpatharc{\pgfarrowarc}{+-90}{+1pt} + \ifpgfarrowharpoon + \else + \pgfpatharc{+90}{+-\pgfarrowarc}{+1pt} + \fi + } + \ifpgfarrowharpoon\ifpgfarrowreversed + \pgfpathlineto{\pgfqpoint{\pgflinewidth}{0pt}} + \fi\fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \pgfarrowarc,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + +\pgfdeclarearrow{ + name = Arc Barb, + defaults = { + length = +1.5pt 2, + width' = +0pt 2, + line width = +0pt 1 1, + }, + setup code = { + % Adjust arc: + \pgf@x\pgfarrowarc pt% + \pgf@x.5\pgf@x% + \edef\pgfarrowarc{\pgf@sys@tonumber\pgf@x}% + % The tips: + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetvisualbackend{\pgfarrowlength} + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + % The hull: + \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth} + \ifpgfarrowharpoon\pgfarrowshullpoint{\pgfarrowlength}{-.5\pgflinewidth}\fi + \pgfmathsincos@{\pgfarrowarc}% + \pgf@xa.5\pgfarrowwidth% + \pgfarrowsupperhullpoint{\pgfmathresultx\pgfarrowlength}{\pgfmathresulty\pgf@xa} + \ifdim\pgfarrowarc pt>60pt + \pgfarrowsupperhullpoint{.5\pgfarrowlength}{\ifdim\pgfarrowarc pt<90pt\pgfmathresulty\pgf@xa\else.5\pgfarrowwidth\fi} + \fi + \ifdim\pgfarrowarc pt>90pt + \ifdim\pgfarrowarc pt<120pt + \pgfarrowsupperhullpoint{\pgfmathresultx\pgfarrowlength}{.5\pgfarrowwidth} + \else + \pgfarrowsupperhullpoint{-.5\pgfarrowlength}{.5\pgfarrowwidth} + \ifdim\pgfarrowarc pt>150pt + \pgfarrowsupperhullpoint{-\pgfarrowlength}{.25\pgfarrowwidth} + \fi + \fi + \fi + \pgfutil@tempswafalse + \ifdim\pgfarrowarc pt<90pt + \pgfutil@tempswatrue + \fi + \ifpgfarrowharpoon + \pgfutil@tempswatrue + \fi + \ifpgfutil@tempswa + \pgf@xa.5\pgfarrowwidth\advance\pgf@xa by-\pgfarrowlinewidth% + \pgf@ya\pgfarrowlength\advance\pgf@ya by-\pgfarrowlinewidth% + \pgfarrowsupperhullpoint{\pgfmathresultx\pgf@ya}{\pgfmathresulty\pgf@xa} + \fi + % Compute back end + \ifpgfarrowroundcap + \pgf@y\pgfarrowlength + \advance\pgf@y by-.5\pgfarrowlinewidth + \pgf@x\pgfmathresultx\pgf@y% + \else + \ifdim\pgfarrowarc pt<90pt + \pgf@y\pgfarrowlength + \advance\pgf@y by-\pgfarrowlinewidth + \pgf@x\pgfmathresultx\pgf@y% + \else + \pgf@x\pgfmathresultx\pgfarrowlength% + \fi + \fi + \pgfarrowssetbackend{\pgf@x\ifpgfarrowroundcap\advance\pgf@x by-.5\pgfarrowlinewidth\fi} + % Adjust width and length: Take line thickness into account: + \advance\pgfarrowlength by-.5\pgfarrowlinewidth + \advance\pgfarrowwidth by-\pgfarrowlinewidth + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssave\pgfarrowarc + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + {% + \pgftransformxscale{+\pgfarrowlength} + \pgftransformyscale{+.5\pgfarrowwidth} + \pgfpathmoveto{\pgfpointpolar{+\pgfarrowarc}{+1pt}} + \ifpgfarrowharpoon + \pgfpatharc{+\pgfarrowarc}{0pt}{+1pt} + \else + \pgfpatharc{+\pgfarrowarc}{+-\pgfarrowarc}{+1pt} + \fi + } + \ifpgfarrowharpoon + \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by\ifpgfarrowreversed\else-\fi.5\pgflinewidth}{0pt}} + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \pgfarrowarc,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundcap c\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + +% Tee Barb are barb arrows heads that look like a T + +\pgfdeclarearrow{ + name = Tee Barb, + defaults = { + length = +1.5pt 2, + width = +3pt 4, + inset' = +0pt .5, + line width = +0pt 1 1, + }, + bending mode=polar, + setup code = { + % Two useful numbers... + \pgfutil@tempswafalse% + \pgfutil@tempswbfalse% + \pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset\ifdim\pgfutil@tempdima<.5\pgfarrowlinewidth\pgfutil@tempdima.5\pgfarrowlinewidth\pgfutil@tempswatrue\fi% + \pgfutil@tempdimb-\pgfarrowinset\ifdim\pgfutil@tempdimb>-.5\pgfarrowlinewidth\pgfutil@tempdimb-.5\pgfarrowlinewidth\pgfutil@tempswbtrue\fi + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + % Infos: + \pgfarrowssettipend{\pgfutil@tempdima\ifpgfarrowroundcap\ifpgfutil@tempswa\else\advance\pgf@x by.5\pgfarrowlinewidth\fi\fi} + \pgfarrowssetvisualbackend{.5\pgfarrowlinewidth} + \pgfarrowssetbackend{\pgfutil@tempdimb\ifpgfarrowroundcap\ifpgfutil@tempswb\else\advance\pgf@x by-.5\pgfarrowlinewidth\fi\fi} + \pgfarrowssetlineend{\ifpgfarrowreversed\else-\fi.25\pgfarrowlinewidth}% + % The hull: + \pgfarrowsupperhullpoint{\pgfutil@tempdima\ifpgfarrowroundcap\ifpgfutil@tempswa\else\advance\pgf@x by.5\pgfarrowlinewidth\fi\fi}{.5\pgfarrowwidth}% + \pgfarrowsupperhullpoint{\pgfutil@tempdimb\ifpgfarrowroundcap\ifpgfutil@tempswb\else\advance\pgf@x by-.5\pgfarrowlinewidth\fi\fi}{.5\pgfarrowwidth}% + \ifpgfarrowharpoon + \pgfarrowshullpoint{.5\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}% + \fi + }, + drawing code = { + \pgfsetdash{}{+0pt} + \pgf@yc\pgflinewidth% save... + \ifdim\pgflinewidth=\pgfarrowlinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \pgf@x\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth% + \pgf@y\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth% + % Case 1: No bar atop the I: + \ifdim\pgf@x=\pgf@y% + \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth}} + \pgfpathlineto{\pgfqpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}} + \else + % Case 2: Bar, but only in one direction: + \ifdim\pgfutil@tempdima=.5\pgfarrowlinewidth% + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \ifpgfarrowharpoon% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgf@yc}}% + \else% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdimb}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \fi + \else% Case 3: Complete I: + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathmoveto{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \ifpgfarrowharpoon% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgf@yc}}% + \else% + \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdimb}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth}} + \fi + \fi + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowwidth,% + \the\pgfarrowlength,% + \the\pgfarrowinset,% + \the\pgfarrowlinewidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + +% Math barbs that resemble \rightarrow in different fonts: + + + +% The original default arrow head used in TikZ. It is modeled on an +% old version of the \rightarrow head of the *old* Computer Modern +% fonts. + +\pgfdeclarearrow{ + name = Classical TikZ Rightarrow, + defaults = { + length = +1.05pt 1.925, + width' = +0pt 1.9237, + line width = 0pt 0.8 1, + round + }, + setup code = + { + \ifpgfarrowharpoon\pgfarrowroundjointrue\fi + % inner length: + \pgfutil@tempdima\pgfarrowlength + \advance\pgfutil@tempdima by-\pgfarrowlinewidth + \pgfutil@tempdimb\pgfarrowwidth + \advance\pgfutil@tempdimb by-\pgfarrowlinewidth + \ifpgfarrowroundjoin% + \else% + \pgfmathdivide@\pgfutil@tempdima\pgfutil@tempdimb% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x40.96\pgf@x% + \advance\pgf@x by1pt% \pgflinewidth^2 + (6.4 \pgftempdim@a / \pgfutil@tempdimb) \pgflinewidth^2 + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \fi% + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + % The extend: + \pgfarrowssettipend{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}% + \pgfarrowssetvisualbackend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}% + \ifpgfarrowreversed% + \ifpgfarrowharpoon% + % A reversed arrow needs a slightly different line end: + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by.5\pgflinewidth}% + \else% + % A reversed arrow needs a slightly different line end: + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.25\pgflinewidth}% + \fi% + \else% + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.6\pgflinewidth}% + \fi% + \pgfarrowssetbackend{-.5\pgfarrowlinewidth}% + % The hull: + % Tip: + \pgfarrowshullpoint{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}{.5\pgfarrowlinewidth}% + \pgfarrowshullpoint{\pgfutil@tempdima\ifpgfarrowroundjoin\advance\pgf@x by.5\pgfarrowlinewidth\else\advance\pgf@x by\pgf@xc\fi}{-.5\pgfarrowlinewidth}% + % Upper end: + \pgfarrowsupperhullpoint{.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + \pgfarrowsupperhullpoint{-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + % Lower end: + \ifpgfarrowharpoon + \pgfarrowshullpoint{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth}{-.5\pgflinewidth}% + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by-.5\pgflinewidth}% + \fi + }, + drawing code = + { + \pgfsetdash{}{+0pt} + \edef\pgf@orig@linewidth{\the\pgflinewidth} + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \ifpgfarrowharpoon\pgfarrowroundjointrue\fi + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \pgfpathmoveto + {\pgfqpoint{0pt}{.5\pgfutil@tempdimb}} + \ifpgfarrowharpoon + \pgf@arrows@old@tikz@harpoon + \else + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathcurveto + {\pgfqpoint{.8\pgfutil@tempdima}{-.03125\pgfutil@tempdimb}} + {\pgfqpoint{0.066666\pgfutil@tempdima}{-.3125\pgfutil@tempdimb}} + {\pgfqpoint{0pt}{-.5\pgfutil@tempdimb}} + \pgfsetlinewidth{+\pgfarrowlinewidth} + \pgfusepathqstroke + \fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + +\def\pgf@arrows@old@tikz@harpoon{ + \ifpgfarrowreversed + \pgf@arrows@old@tikz@harpoon@reversed + \else + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathcurveto + {\pgfqpoint{0.95\pgfutil@tempdima}{-0.125\pgflinewidth}} + {\pgfqpoint{0.933333\pgfutil@tempdima}{-0.125\pgflinewidth}} + {\pgfqpoint{0.933333\pgfutil@tempdima}{-0.125\pgflinewidth}} + \pgfpathlineto + {\pgfqpoint{0.8\pgfutil@tempdima\advance\pgf@x by-.5\pgflinewidth}{-0.125\pgflinewidth}} + \pgfusepathqstroke + \fi +} +\def\pgf@arrows@old@tikz@harpoon@reversed{ + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0.125\pgflinewidth}} + \pgfpathmoveto + {\pgfqpoint{0pt}{.5\pgfutil@tempdimb}} + \pgfpathcurveto + {\pgfqpoint{0.066666\pgfutil@tempdima}{0.3125\pgfutil@tempdimb}} + {\pgfqpoint{.8\pgfutil@tempdima}{0.03125\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{-0.125\pgflinewidth}} + \pgfusepathqstroke + \pgfsetlinewidth{+\pgf@orig@linewidth} + \pgfsetroundcap + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by0.6\pgflinewidth}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfusepathqstroke +} + + +% An approximation to the new (past 1992) Computer Modern math arrow +% heads. This would be a better version of "to", so consider saying +% to/.tips=Computer Modern Rightarrow + +\pgfdeclarearrow{ + name = Computer Modern Rightarrow, + defaults = { + length = +1.6pt 2.2, % 0pt 5.2 + width' = +0pt 2.096774, + line width = 0pt 1 1, + round + }, + setup code = + { + % inner length: + \pgfutil@tempdima\pgfarrowlength + \advance\pgfutil@tempdima by-\pgfarrowlinewidth + \pgfutil@tempdimb\pgfarrowwidth + \advance\pgfutil@tempdimb by-\pgfarrowlinewidth + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + % Front miter: + \ifpgfarrowroundjoin% + \else% + \pgfmathdivide@\pgfutil@tempdima\pgfutil@tempdimb% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x49.44662\pgf@x% + \advance\pgf@x by1pt% \pgfarrowlinewidth^2 + (0.41019/0.0583333 \pgftempdim@a / \pgfutil@tempdimb) \pgfarrowlinewidth^2 + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + \pgf@xa3.51591\pgf@xa% xa is extra harpoon miter + \fi% + % The extend: + \pgfarrowssettipend{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}% + \pgfarrowssetvisualbackend{.5\pgfarrowlinewidth}% + \ifpgfarrowreversed% + \ifpgfarrowharpoon% + \pgfarrowssetlineend{.5\pgfarrowlinewidth}% + \else% + \pgfarrowssetlineend{-.5\pgfarrowlinewidth}% + \fi% + \else% + \pgfarrowssetlineend{-.5\pgfarrowlinewidth}% + \fi% + \pgfarrowssetbackend{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}% + % The hull: + % Tip: + \pgfarrowshullpoint{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{.5\pgfarrowlinewidth}% + \pgfarrowshullpoint{\ifpgfarrowroundjoin.5\pgfarrowlinewidth\else\pgf@xc\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{-.5\pgfarrowlinewidth}% + % Upper end: + \pgfarrowsupperhullpoint{-\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + \pgfarrowsupperhullpoint{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by.5\pgfarrowlinewidth}% + % Lower end: + \ifpgfarrowharpoon + \pgfarrowshullpoint{-\pgfarrowlinewidth}{-.5\pgfarrowlinewidth}% + \pgfarrowshullpoint{-\pgfutil@tempdima\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfutil@tempdimb\advance\pgf@y by-.5\pgfarrowlinewidth}% + \fi + }, + drawing code = + { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto + {\pgfqpoint{-\pgfutil@tempdima}{.5\pgfutil@tempdimb}} + \pgfpathcurveto + {\pgfqpoint{-0.81731\pgfutil@tempdima}{.2\pgfutil@tempdimb}} + {\pgfqpoint{-0.41019\pgfutil@tempdima}{0.05833333\pgfutil@tempdimb}} + {\pgfpointorigin} + \ifpgfarrowharpoon + \pgfpathlineto + {\pgfqpoint{\ifpgfarrowreversed.5\else-\fi\pgfarrowlinewidth}{0pt}} + \else + \pgfpathcurveto + {\pgfqpoint{-0.41019\pgfutil@tempdima}{-0.05833333\pgfutil@tempdimb}} + {\pgfqpoint{-0.81731\pgfutil@tempdima}{-.2\pgfutil@tempdimb}} + {\pgfqpoint{-\pgfutil@tempdima}{-.5\pgfutil@tempdimb}} + \fi + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi + \ifpgfarrowharpoon r\fi + \ifpgfarrowroundjoin j\fi% + \ifpgfarrowroundcap c\fi% + }, +} + + + +% The arrow tip of an \implies arrow, to be used with an inner +% line. Cannot be configured otherwise. + +\pgfdeclarearrow{ + name = Implies, + setup code = { + \pgf@xa\pgfinnerlinewidth + \pgfutil@tempdima.25\pgflinewidth + \advance\pgfutil@tempdima by.25\pgf@xa% + \pgfutil@tempdimb.5\pgflinewidth + \advance\pgfutil@tempdimb by-.5\pgf@xa% + \pgfarrowssettipend{2.06\pgfutil@tempdima\advance\pgf@x by.5\pgfutil@tempdimb} + \pgfarrowssetbackend{-1.36\pgfutil@tempdima\advance\pgf@x by.5\pgfutil@tempdimb} + \pgfarrowsupperhullpoint{-1.4\pgfutil@tempdima}{2.8\pgfutil@tempdima} + \pgfarrowsupperhullpoint{2\pgfutil@tempdima}{.5\pgfutil@tempdimb} + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + }, + drawing code = { + \pgftransformxshift{.06\pgfutil@tempdima} + \pgfsetlinewidth{\pgfutil@tempdimb} + \pgfsetdash{}{+0pt} + \pgfsetroundcap + \pgfsetroundjoin + \pgfpathmoveto{\pgfpoint{-1.4\pgfutil@tempdima}{2.65\pgfutil@tempdima}} + \pgfpathcurveto + {\pgfpoint{-0.75\pgfutil@tempdima}{1.25\pgfutil@tempdima}} + {\pgfpoint{1\pgfutil@tempdima}{0.05\pgfutil@tempdima}} + {\pgfpoint{2\pgfutil@tempdima}{0pt}} + \pgfpathcurveto + {\pgfpoint{1\pgfutil@tempdima}{-0.05\pgfutil@tempdima}} + {\pgfpoint{-.75\pgfutil@tempdima}{-1.25\pgfutil@tempdima}} + {\pgfpoint{-1.4\pgfutil@tempdima}{-2.65\pgfutil@tempdima}} + \pgfusepathqstroke + }, + parameters = {\the\pgfarrowlength} +} + + + + +% +% +% Geomatric arrow tips +% +% + + +% Generic "latex-like" arrow tip. This is the basic arrow tip used in +% latex's picture environment. You can configure its length and width. + +\pgfdeclarearrow{ + name = Latex, + defaults = { + length = +3pt 4.5 .8,% +2.8pt 3 0.8, + width' = +0pt .75, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/4th distance from inset to tip + \pgf@x.2\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \pgfarrowssavethe\pgfarrowlinewidth% + % Compute front miter length: + \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x9\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth + % Inner length (pgfutil@tempdima) is now arrowlength - front miter + % - 0.5 linewidth (back thickness) + \pgfutil@tempdima\pgfarrowlength% + \advance\pgfutil@tempdima by-.5\pgf@xc% + \advance\pgfutil@tempdima by-.5\pgfarrowlinewidth% + % harpoon miter correction + \pgfarrowssetbackend{-.5\pgfarrowlinewidth} + \ifpgfarrowreversed + \ifdim\pgfinnerlinewidth>0pt + \pgfarrowssetlineend{0pt} + \else + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-.5\pgflinewidth} + \fi + \else + \pgfarrowssetlineend{0pt} + \fi + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth\ifpgfarrowharpoon\advance\pgf@x by1.5\pgf@xa\fi} + \fi + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + % Now, compute back tip miter limit: + \pgf@process{\pgfpointnormalised{\pgfqpoint{.3\pgfarrowlength}{.2333333\pgfarrowwidth}}}% + \advance\pgf@y by1pt% + \pgf@yc\pgf@y\pgf@xc\pgf@x% + \pgfmathdivide@\pgf@yc\pgf@xc% + \pgfutil@tempdimb\pgfmathresult\pgfarrowlinewidth% + \pgfutil@tempdimb-.5\pgfutil@tempdimb% + \advance\pgfutil@tempdimb by.5\pgfarrowwidth% + \pgfarrowssavethe\pgfutil@tempdimb% + % The hull: + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by1.5\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\ifpgfarrowharpoon\advance\pgf@y by-.5\pgfarrowlinewidth\fi}% + \pgfarrowshullpoint{-.5\pgfarrowlinewidth}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi}% + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathcurveto {\pgfqpoint{.877192\pgfutil@tempdima}{.077922\pgfutil@tempdimb}} + {\pgfqpoint{.337381\pgfutil@tempdima}{.519480\pgfutil@tempdimb}} + {\pgfqpoint{0pt}{\pgfutil@tempdimb}} + \ifpgfarrowharpoon + \pgfpathlineto {\pgfpointorigin} + \else + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdimb}} + \pgfpathcurveto {\pgfqpoint{.337381\pgfutil@tempdima}{-.519480\pgfutil@tempdimb}} + {\pgfqpoint{.877192\pgfutil@tempdima}{-.077922\pgfutil@tempdimb}} + {\pgfqpoint{\pgfutil@tempdima}{0pt}} + \fi + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + +% A basic stealth-fighter-like pointed arrow + +\pgfdeclarearrow{ + name = Stealth, + defaults = { + length = +3pt 4.5 .8, + width' = +0pt .75, + inset' = +0pt 0.325, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/4th distance from inset to tip + \pgf@x\pgfarrowlength + \advance\pgf@x by-\pgfarrowinset + \pgf@x.25\pgf@x + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + % Compute front miter length: + \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + % Compute back miter length: + \pgf@ya.5\pgfarrowwidth% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowlength}{\pgfmath@tonumber\pgf@ya}% + \pgf@yb\pgfmathresult pt% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgf@ya}% + \pgf@ya\pgfmathresult pt% + \advance\pgf@yb by-\pgf@ya% + \pgf@yb.5\pgf@yb% half angle in yb + \pgfmathtan@{\pgf@yb}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% + \pgf@yc.5\pgf@yc% + \advance\pgf@ya by\pgf@yb% + \pgfmathsincos@{\pgf@ya}% + \pgf@ya\pgfmathresulty\pgf@yc% ya is the back miter + \pgf@yb\pgfmathresultx\pgf@yc% yb is the top miter + \ifdim\pgfarrowinset=0pt% + \pgf@ya.5\pgfarrowlinewidth% easy: back miter is half linewidth + \fi + % Compute inset miter length: + \pgfmathdivide@\pgfarrowinset\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is inset miter + \pgf@yc.5\pgf@yc% + % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter + \pgfutil@tempdima\pgfarrowlength% + \advance\pgfutil@tempdima by-\pgf@xc% + \advance\pgfutil@tempdima by-\pgf@ya% + \pgfutil@tempdimb.5\pgfarrowwidth% + \advance\pgfutil@tempdimb by-\pgf@yb% + % harpoon miter correction + \ifpgfarrowroundjoin + \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetbackend{0pt} + \fi + \ifpgfarrowharpoon + \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x + by\pgf@yc\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x by\pgf@yc\advance\pgf@x by-.25\pgfarrowlinewidth} + \ifpgfarrowreversed + \ifdim\pgfinnerlinewidth>0pt + \pgfarrowssetlineend{\pgfarrowinset} + \else + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by-.25\pgfarrowlinewidth} + \fi + \fi + \fi + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi} + \fi + % The hull: + \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \pgfarrowsupperhullpoint{0pt}{.5\pgfarrowwidth}% + \pgfarrowshullpoint{\pgfarrowinset}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else 0pt\fi}% + % Adjust inset + \pgfarrowssetvisualbackend{\pgfarrowinset} + \advance\pgfarrowinset by\pgf@yc% + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgf@ya + \pgfarrowssavethe\pgfarrowinset + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by\pgf@ya}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgf@ya}{\pgfutil@tempdimb}} + \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{0pt}} + \ifpgfarrowharpoon \else + \pgfpathlineto{\pgfqpoint{\pgf@ya}{-\pgfutil@tempdimb}} + \fi + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \the\pgfarrowinset,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + +% A Kite is like a Stealth, only the inset counts in the other direction + +\pgfdeclarearrow{ + name = Kite, + defaults = { + length = +3.6pt +5.4, + width' = +0pt +0.5, + inset' = +0pt 0.25, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/4th of the length + \pgf@x.4\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \pgf@x.4\pgfarrowwidth + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + % Compute front miter length: + \pgf@xa\pgfarrowlength% + \advance\pgf@xa by-\pgfarrowinset% + \pgfmathdivide@\pgf@xa\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter + \pgf@xc.5\pgf@xc + \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter + % Compute back miter length: + \pgfmathdivide@\pgfarrowinset\pgfarrowwidth% + \let\pgf@temp@quot\pgfmathresult% + \pgf@x\pgfmathresult pt% + \pgf@x\pgfmathresult\pgf@x% + \pgf@x4\pgf@x% + \advance\pgf@x by1pt% + \pgfmathsqrt@\pgf@x% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is back miter + \pgf@yc.5\pgf@yc + \pgf@ya\pgf@temp@quot\pgfarrowlinewidth% ya is extra harpoon miter + % Compute top miter length: + {% + \pgfutil@tempdimb.5\pgfarrowwidth% + \pgfutil@tempdima\pgfarrowlength\advance\pgfutil@tempdima by-\pgfarrowinset% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfutil@tempdima}{\pgfmath@tonumber\pgfutil@tempdimb}% + \pgf@yb\pgfmathresult pt% + \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgfutil@tempdimb}% + \pgf@ya\pgfmathresult pt% + \advance\pgf@yb by\pgf@ya% + \pgf@yb.5\pgf@yb% half angle in yb + \ifdim\pgf@yb=45pt% + \def\pgfmathresult{1.414213}% + \else% + \pgfmathsin@{\pgf@yb}% + \pgfmathreciprocal@{\pgfmathresult}% + \fi% + \pgf@yc\pgfmathresult\pgfarrowlinewidth% + \pgf@yc.5\pgf@yc% + \pgf@ya-\pgf@ya% + \advance\pgf@ya by-90pt% + \advance\pgf@ya by\pgf@yb% + \pgfmathsincos@{\pgf@ya}% + \pgf@xb\pgfmathresultx\pgf@yc% ya is the back miter + \pgf@yb\pgfmathresulty\pgf@yc% yb is the top miter + \expandafter\expandafter\expandafter% + }\expandafter\expandafter\expandafter\pgf@xb\expandafter\the\expandafter\pgf@xb\expandafter\pgf@yb\the\pgf@yb% + % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter + \pgfutil@tempdima\pgfarrowlength% + \advance\pgfutil@tempdima by-\pgf@xc% + \pgfutil@tempdimb.5\pgfarrowwidth% + \advance\pgfutil@tempdimb by\pgf@yb% + % Set back end + \ifpgfarrowroundjoin + \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetbackend{0pt} + \fi + % harpoon miter correction + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by-\pgflinewidth\advance\pgf@x by\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{\pgf@yc\advance\pgf@x by\pgflinewidth\advance\pgf@x by-\pgfarrowlinewidth} + \fi + \ifpgfarrowroundjoin + \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by.5\pgfarrowlinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi} + \fi + % The hull: + \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + \pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgfarrowwidth}% + \pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% + % Adjust the inset: + \advance\pgfarrowinset by\pgf@xb% + % The following are needed in the code: + \pgfarrowssavethe\pgfutil@tempdima + \pgfarrowssavethe\pgfutil@tempdimb + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgf@yc + \pgfarrowssavethe\pgfarrowinset + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima}{0pt}} + \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdimb}} + \pgfpathlineto{\pgfqpoint{\pgf@yc}{0pt}} + \ifpgfarrowharpoon \else + \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdimb}} + \fi + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \the\pgfarrowinset,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + + + +% A simple rectangle shape + +\pgfdeclarearrow{ + name = Square, + defaults = { + length = +2.12132pt +2.828427, + width' = +0pt +1, + line width = +0pt +1 +1, + }, + setup code = { + % Cap the line width at 1/2th of the length + \pgf@x.5\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{.5\pgfarrowlinewidth} + \fi + \pgfarrowssettipend{\pgfarrowlength} + % The hull: + \pgfarrowshullpoint{\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowshullpoint{0pt}{.5\pgfarrowwidth} + \pgfarrowshullpoint{\pgfarrowlength}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi} + \pgfarrowshullpoint{0pt}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else-.5\pgfarrowwidth\fi} + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{.5\pgfarrowlinewidth}{.5\pgfarrowwidth\advance\pgf@y by-.5\pgfarrowlinewidth}} + \pgfpathlineto{\pgfqpoint{.5\pgfarrowlinewidth}{\ifpgfarrowharpoon0pt\else-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth\fi}} + \pgfpathlineto{\pgfqpoint{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth}{\ifpgfarrowharpoon0pt\else-.5\pgfarrowwidth\advance\pgf@y by.5\pgfarrowlinewidth\fi}} + \pgfpathclose + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + + +% A simple rectangle shape + +\pgfdeclarearrow{ + name = Circle, + defaults = { + length = +2.39365pt +3.191538, + width' = +0pt 1, + line width = +0pt 1 1, + }, + setup code = { + % Cap the line width at 1/2th of the length + \pgf@x.5\pgfarrowlength + \ifdim\pgf@x<\pgfarrowlinewidth + \pgfarrowlinewidth\pgf@x + \fi + \ifpgfarrowreversed + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by-.5\pgfarrowlinewidth} + \else + \pgfarrowssetlineend{.5\pgfarrowlinewidth} + \fi + \pgfarrowssettipend{\pgfarrowlength} + % The hull: + \pgfarrowsupperhullpoint{\pgfarrowlength}{.25\pgfarrowwidth} + \pgfarrowsupperhullpoint{.75\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth} + \pgfarrowsupperhullpoint{0pt}{.25\pgfarrowwidth} + \ifpgfarrowharpoon% + \pgfarrowshullpoint{0pt}{-.5\pgfarrowlinewidth} + \pgfarrowshullpoint{\pgfarrowlength}{-.5\pgfarrowlinewidth} + \fi% + % The following are needed in the code: + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + \ifpgfarrowharpoon + \pgfpathmoveto{\pgfqpoint{\pgfarrowlength\advance\pgf@x + by-.5\pgfarrowlinewidth}{0pt}} + {% + \pgf@xa.5\pgfarrowlength + \advance\pgf@xa by-.5\pgfarrowlinewidth + \pgftransformxscale{+\the\pgf@xa} + \pgf@xa.5\pgfarrowwidth + \advance\pgf@xa by-.5\pgfarrowlinewidth + \pgftransformyscale{+\the\pgf@xa} + \pgfpatharc{0}{180}{1pt} + } + \pgfpathclose + \else% + \pgfpathellipse{\pgfqpoint{.5\pgfarrowlength}{0pt}}{\pgfqpoint{.5\pgfarrowlength\advance\pgf@x + by-.5\pgfarrowlinewidth}{0pt}}{\pgfqpoint{0pt}{.5\pgfarrowwidth\advance\pgf@y + by-.5\pgfarrowlinewidth}} + \fi + \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt\pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowopen o\fi% + \ifpgfarrowroundjoin j\fi% + }, +} + +% Round cap + +\pgfdeclarearrow{ + name = Round Cap, + defaults = { + length = +0pt .5 + }, + setup code = { + \ifpgfarrowreversed + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by.5\pgflinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{-.5\pgflinewidth} + \fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowlength}{.5\pgflinewidth} + }, + drawing code = { + \ifpgfarrowreversed + \pgftransformxscale{-1} + \pgftransformxshift{-\pgfarrowlength} + \fi + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \ifpgfarrowreversed + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}} + \begingroup + \pgftransformxshift{\pgfarrowlength} + \pgftransformxscale{-1} + \fi + \pgfpathcurveto {\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathcurveto {\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}} + {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}} + {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \ifpgfarrowreversed + \endgroup + \fi + \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength} +} + + + +\pgfdeclarearrow{ + name = Butt Cap, + defaults = { + length = +0pt .5 + }, + setup code = { + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{-.5\pgflinewidth} + \pgfarrowssavethe\pgfarrowlength + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowlength}{.5\pgflinewidth} + }, + drawing code = { + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength} +} + + + +\pgfkeys{ + /pgf/arrow keys/.cd, + cap angle/.code={% + \pgfmathsetlength\pgf@x{#1}% + \pgf@x.5\pgf@x + \pgfmathtan@{\pgf@x}% + \pgfmathreciprocal@{\pgfmathresult}% + \pgf@x\pgfmathresult pt% + \pgf@x.5\pgf@x% + \edef\pgf@marshal{\noexpand\pgfarrowsaddtooptions{\noexpand\pgfarrowslinewidthdependent{+0pt}{\pgf@sys@tonumber\pgf@x}{0}\pgfarrowlength\pgf@x}} + \pgf@marshal + } +} + + +\pgfdeclarearrow{ + name = Triangle Cap, + defaults = { + length = +0pt .5 + }, + setup code = { + \ifpgfarrowreversed + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by.5\pgflinewidth} + \else + \pgfarrowssettipend{\pgfarrowlength} + \pgfarrowssetlineend{-.5\pgflinewidth} + \fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowshullpoint{\pgfarrowlength}{0pt} + }, + drawing code = { + \ifpgfarrowreversed + \pgftransformxscale{-1} + \pgftransformxshift{-\pgfarrowlength} + \fi + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{-0.75\pgflinewidth}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \ifpgfarrowreversed + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{\pgfutil@tempdima}} + \begingroup + \pgftransformxshift{\pgfarrowlength} + \pgftransformxscale{-1} + \fi + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{0pt}} + \ifpgfarrowreversed + \endgroup + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{-\pgfutil@tempdima}} + \fi + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{-.75\pgflinewidth}{-\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength} +} + + + +\pgfdeclarearrow{ + name = Fast Triangle, + defaults = { + length = +0pt .5, + inset = +0pt .5, + }, + setup code = { + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset} + \ifpgfarrowreversed\pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}\fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowinset + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowinset}{.5\pgflinewidth} + \pgfarrowshullpoint{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}{0pt} + }, + drawing code = { + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset\advance\pgf@x by\pgfarrowlength}{0pt}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength,\the\pgfarrowinset} +} + + +\pgfdeclarearrow{ + name = Fast Round, + defaults = { + length = +0pt .5, + inset = +0pt .5, + }, + setup code = { + \pgfarrowssettipend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset} + \ifpgfarrowreversed\pgfarrowssetlineend{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}\fi + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowinset + \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth} + \pgfarrowsupperhullpoint{\pgfarrowlength\advance\pgf@x by\pgfarrowinset}{.5\pgflinewidth} + }, + drawing code = { + \pgfutil@tempdima.5\pgflinewidth + \pgfpathmoveto {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathlineto {\pgfqpoint{\pgfarrowinset}{\pgfutil@tempdima}} + { + \pgftransformxshift{\pgfarrowinset} + \pgfpathcurveto{\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathcurveto{\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}} + {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}} + {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + } + \pgfpathlineto {\pgfqpoint{0pt}{-\pgfutil@tempdima}} + \pgfpathcurveto {\pgfqpoint{0.55228475\pgfarrowlength}{-\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{-0.55228475\pgfutil@tempdima}} + {\pgfqpoint{\pgfarrowlength}{0pt}} + \pgfpathcurveto {\pgfqpoint{\pgfarrowlength}{0.55228475\pgfutil@tempdima}} + {\pgfqpoint{0.55228475\pgfarrowlength}{\pgfutil@tempdima}} + {\pgfqpoint{0pt}{\pgfutil@tempdima}} + \pgfpathclose + \pgfusepathqfill + }, + parameters = {\the\pgfarrowlength,\the\pgfarrowinset} +} + + + + +% +% +% Other arrow tips. +% +% + + +\pgfkeys{ + /pgf/arrow keys/.cd, + n/.code={% + \pgfmathparse{#1}% + \expandafter\pgf@lib@meta@strip@dot\pgfmathresult.\relax% + } +} +\def\pgf@lib@meta@strip@dot#1.#2\relax{% + \pgfarrowsaddtooptions{\def\pgfarrown{#1}}% +} + +\def\pgfarrown{4} + +\pgfdeclarearrow{ + name = Rays, + defaults = { + length = +3pt 4, + width' = +0pt 1, + line width = +0pt 1 1, + }, + setup code = { + \pgfmathdivide@{360}{\pgfarrown}% + \let\pgfarrow@inc\pgfmathresult% + % Compute tips: + \pgf@xa\pgfarrow@inc pt% + \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi% + \pgfmathsincos@\pgf@ya% + \pgf@x.5\pgfarrowlength% + \pgf@xa\pgfmathresultx\pgf@x% + \ifpgfarrowroundcap + \advance\pgf@xa by.5\pgfarrowlinewidth + \else + \pgf@process{\pgfpointnormalised{\pgfqpoint{\pgfmathresultx\pgfarrowlength}{\pgfmathresulty\pgfarrowwidth}}}% + \pgf@x.5\pgfarrowlinewidth% + \advance\pgf@xa by\pgf@sys@tonumber{\pgf@y}\pgf@x% + \fi% + \pgfarrowssettipend{\pgf@xa} + \pgfarrowssetbackend{-\pgf@xa} + % Hull is alwyas 8-point hull, except for tip + % The following are needed in the code: + \pgfarrowsupperhullpoint{\pgf@xa}{.25\pgfarrowwidth} + \pgfarrowsupperhullpoint{.25\pgfarrowlength}{.5\pgfarrowwidth\ifpgfarrowroundcap\advance\pgf@y by.5\pgfarrowlinewidth\fi} + \pgfarrowsupperhullpoint{-.25\pgfarrowlength}{.5\pgfarrowwidth\ifpgfarrowroundcap\advance\pgf@y by.5\pgfarrowlinewidth\fi} + \pgfarrowsupperhullpoint{-\pgf@xa}{.25\pgfarrowwidth} + \ifpgfarrowharpoon + \pgfarrowshullpoint{-.5\pgfarrowlength\ifpgfarrowroundcap\advance\pgf@x by-.5\pgfarrowlinewidth\fi}{-.5\pgfarrowlinewidth} + \pgfarrowshullpoint{.5\pgfarrowlength\ifpgfarrowroundcap\advance\pgf@x by.5\pgfarrowlinewidth\fi}{-.5\pgfarrowlinewidth} + \fi + \pgfarrowssavethe\pgfarrowlinewidth + \pgfarrowssavethe\pgfarrowlength + \pgfarrowssavethe\pgfarrowwidth + \pgfarrowssave\pgfarrow@inc + \pgfarrowssave\pgfarrown + }, + drawing code = { + \pgfsetdash{}{+0pt} + \ifpgfarrowroundcap\pgfsetroundcap\else\pgfsetbuttcap\fi + \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{+\pgfarrowlinewidth}\fi + {% + \pgfgettransform\pgf@temp@trans + \pgftransformxscale{+.5\pgfarrowlength} + \pgftransformyscale{+.5\pgfarrowwidth} + \pgf@xa\pgfarrow@inc pt% + \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi% + \ifpgfarrowharpoon\pgf@yb180pt\else\pgf@yb360pt\fi + \pgfutil@loop% + \ifdim\pgf@ya<\pgf@yb% + \pgfpathmoveto{\pgfpointpolar{+\pgf@ya}{+1pt}} + \pgfpathlineto{\pgfpointorigin} + \ifpgfarrowharpoon\ifdim\pgf@ya>\pgf@xa\else{\pgfsettransform\pgf@temp@trans\pgfpathlineto{\pgfqpoint{-.5\pgflinewidth}{0pt}}}\fi\fi + \advance\pgf@ya by\pgf@xa\relax% + \pgfutil@repeat% + } + \pgfusepathqstroke + }, + parameters = { + \the\pgfarrowlinewidth,% + \the\pgfarrowlength,% + \the\pgfarrowwidth,% + \pgfarrown,% + \ifpgfarrowharpoon h\fi% + \ifpgfarrowroundcap c\fi% + } +} + + + +% Shorthands and Aliases: + +\pgfkeys{ + LaTeX /.tip = {Latex}, + Triangle /.tip = {Stealth[inset=+0pt, angle=+60:+2.7pt +3.6]}, + Rectangle /.tip = {Square[length=+3pt +4.5,width'=+0pt +.5]}, + Ellipse /.tip = {Circle[length=+3.3pt +4.95, width'=+0pt +0.5]}, + Diamond /.tip = {Kite[inset'=+0pt .5]}, + Turned Square /.tip = {Kite[length=+3pt 4,width'= +0pt 1,inset'= +0pt 0.5]}, + To /.tip = {Computer Modern Rightarrow}, + Bar /.tip = {Tee Barb[length=+0pt]}, + Bracket /.tip = {Tee Barb[inset'=+0pt +1,length=+0.75pt +1]}, + Parenthesis /.tip = {Arc Barb[arc=+120,length=+1.725pt +2.3]} +} + + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex new file mode 100644 index 00000000000..b6d1728363d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex @@ -0,0 +1,92 @@ +% Copyright 2012 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.spaced.code.tex,v 1.3 2013/09/23 18:04:36 tantau Exp $ + + +\usepgflibrary{arrows} + + +% This library offers "spaced" versions of existing arrows, where a +% bit of additional space is inserted at the tip. This often looks +% better than the normal arrow. +% +% These arrows are called "spaced whatever" where "whatever" is the +% original name of the arrow. + + +\pgfarrowsdeclarecombine*{spaced to}{spaced to}{to}{to}{space}{space} +\pgfarrowsdeclarecombine*{spaced to reversed}{spaced to reversed}{to reversed}{to reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced implies}{spaced implies}{implies}{implies}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex}{spaced latex}{latex}{latex}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex reversed}{spaced latex reversed}{latex reversed}{latex reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex'}{spaced latex'}{latex'}{latex'}{space}{space} +\pgfarrowsdeclarecombine*{spaced latex' reversed}{spaced latex' reversed}{latex' reversed}{latex' reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth}{spaced stealth}{stealth}{stealth}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth reversed}{spaced stealth reversed}{stealth reversed}{stealth reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth'}{spaced stealth'}{stealth'}{stealth'}{space}{space} +\pgfarrowsdeclarecombine*{spaced stealth' reversed}{spaced stealth' reversed}{stealth' reversed}{stealth' reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90}{spaced triangle 90}{triangle 90}{triangle 90}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90 reversed}{spaced triangle 90 reversed}{triangle 90 reversed}{triangle 90 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 60}{spaced triangle 60}{triangle 60}{triangle 60}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 60 reversed}{spaced triangle 60 reversed}{triangle 60 reversed}{triangle 60 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 45}{spaced triangle 45}{triangle 45}{triangle 45}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 45 reversed}{spaced triangle 45 reversed}{triangle 45 reversed}{triangle 45 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 90}{spaced open triangle 90}{open triangle 90}{open triangle 90}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 90 reversed}{spaced open triangle 90 reversed}{open triangle 90 reversed}{open triangle 90 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 60}{spaced open triangle 60}{open triangle 60}{open triangle 60}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 60 reversed}{spaced open triangle 60 reversed}{open triangle 60 reversed}{open triangle 60 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 45}{spaced open triangle 45}{open triangle 45}{open triangle 45}{space}{space} +\pgfarrowsdeclarecombine*{spaced open triangle 45 reversed}{spaced open triangle 45 reversed}{open triangle 45 reversed}{open triangle 45 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 90}{spaced angle 90}{angle 90}{angle 90}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 90 reversed}{spaced angle 90 reversed}{angle 90 reversed}{angle 90 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 60}{spaced angle 60}{angle 60}{angle 60}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 60 reversed}{spaced angle 60 reversed}{angle 60 reversed}{angle 60 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 45}{spaced angle 45}{angle 45}{angle 45}{space}{space} +\pgfarrowsdeclarecombine*{spaced angle 45 reversed}{spaced angle 45 reversed}{angle 45 reversed}{angle 45 reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced hooks}{spaced hooks}{hooks}{hooks}{space}{space} +\pgfarrowsdeclarecombine*{spaced hooks reversed}{spaced hooks reversed}{hooks reversed}{hooks reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced o}{spaced o}{o}{o}{space}{space} +\pgfarrowsdeclarecombine*{spaced *}{spaced *}{*}{*}{space}{space} +\pgfarrowsdeclarecombine*{spaced diamond}{spaced diamond}{diamond}{diamond}{space}{space} +\pgfarrowsdeclarecombine*{spaced open diamond}{spaced open diamond}{open diamond}{open diamond}{space}{space} +\pgfarrowsdeclarecombine*{spaced square}{spaced square}{square}{square}{space}{space} +\pgfarrowsdeclarecombine*{spaced open square}{spaced open square}{open square}{open square}{space}{space} +\pgfarrowsdeclarecombine*{spaced serif cm}{spaced serif cm}{serif cm}{serif cm}{space}{space} +\pgfarrowsdeclarecombine*{spaced left to}{spaced left to}{left to}{left to}{space}{space} +\pgfarrowsdeclarecombine*{spaced left to reversed}{spaced left to reversed}{left to reversed}{left to reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced right to}{spaced right to}{right to}{right to}{space}{space} +\pgfarrowsdeclarecombine*{spaced right to reversed}{spaced right to reversed}{right to reversed}{right to reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced left hook}{spaced left hook}{left hook}{left hook}{space}{space} +\pgfarrowsdeclarecombine*{spaced left hook reversed}{spaced left hook reversed}{left hook reversed}{left hook reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced right hook}{spaced right hook}{right hook}{right hook}{space}{space} +\pgfarrowsdeclarecombine*{spaced right hook reversed}{spaced right hook reversed}{right hook reversed}{right hook reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced round cap}{spaced round cap}{round cap}{round cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced butt cap}{spaced butt cap}{butt cap}{butt cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90 cap}{spaced triangle 90 cap}{triangle 90 cap}{triangle 90 cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced triangle 90 cap reversed}{spaced triangle 90 cap reversed}{triangle 90 cap reversed}{triangle 90 cap reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced fast cap}{spaced fast cap}{fast cap}{fast cap}{space}{space} +\pgfarrowsdeclarecombine*{spaced fast cap reversed}{spaced fast cap reversed}{fast cap reversed}{fast cap reversed}{space}{space} +\pgfarrowsdeclarecombine*{spaced (}{spaced )}{(}{)}{space}{space} +\pgfarrowsdeclarecombine*{spaced )}{spaced (}{)}{(}{space}{space} +\pgfarrowsdeclarecombine*{spaced |}{spaced |}{|}{|}{space}{space} + +\pgfdeclarearrow{ + name = spaced [-spaced ], + means = square bracket[].space +} + +\pgfdeclarearrow{ + name = spaced ]-spaced [, + means = square bracket[reversed].space +} + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex new file mode 100644 index 00000000000..18fa1951b05 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex @@ -0,0 +1,378 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarycurvilinear.code.tex,v 1.3 2013/10/07 15:51:46 tantau Exp $ + +% +% This file defines commands for computing points in curvilinear +% coordinate systems. +% + + +% +% Curvilinear coordinate systems defined in terms of a Bezier curve. +% +% For the following coordinate systems, you must first provide a +% Bezier curve (using, as always, four points), which will be set for +% the current scope. When the curve is "installed" some expensive +% precomputations are done; subsequent calls to +% \pgfpointcurvilinearxxx based on this Bezier curve will be +% relatively quick. +% + + + +% Install a Bezier curve +% +% #1 = start point +% #2 = first control point +% #3 = second control point +% #4 = end point +% +% Description: +% +% Subsequent calls to functions like +% \pgfpointcurvilinearbezierorthogonal will be relative to the curve +% installed using this command. The main job of this macro is a +% precomputation for computing length along the curve. +% All lengths along the Bezier curve are approximated using a lookup table +% of four time/length points. For this, an approximate time for length +% 1pt is computed first, and then the length for twice this time, four +% times this time, and eight times this time are approximated. A +% distance-to-time conversion is then done by a linear interpolation +% of distance-to-time for these four points. Note that all of these +% computations are not particularly precise, but a compromise trading +% speed against precision. Also note that the results will only be +% best near the start of the curve and may be far off near the end if +% that end is degenerate (second control point very near to end +% point). +% +% Example: +% +% \pgfsetcurvilinearbeziercurve +% {\pgfpoint{0mm}{10mm}} +% {\pgfpoint{5.5mm}{10mm}} +% {\pgfpoint{10mm}{5.5mm}} +% {\pgfpoint{10mm}{0mm}} % nearly a quarter circle +% \pgfpointcurvilinearbezierorthogonal{5mm}{5mm} +% % should be 5mm along the circle, put at +% % distance 15mm from the origin (5mm from the circle line). + +\def\pgfsetcurvilinearbeziercurve#1#2#3#4{% + \pgf@process{#1}% + \edef\pgf@curvilinear@line@a{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xa=-\pgf@x% + \pgf@ya=-\pgf@y% + \pgf@process{#2}% + \edef\pgf@curvilinear@line@b{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \let\pgf@curvilinear@lenab\pgfmathresult% + \pgf@process{#3}% + \edef\pgf@curvilinear@line@c{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \pgf@xc=-\pgf@x% + \pgf@yc=-\pgf@y% + \advance\pgf@x by\pgf@xb% + \advance\pgf@y by\pgf@yb% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \let\pgf@curvilinear@lenbc\pgfmathresult% + \pgf@process{#4}% + \edef\pgf@curvilinear@line@d{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \advance\pgf@x by\pgf@xc% + \advance\pgf@y by\pgf@yc% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \let\pgf@curvilinear@lencd\pgfmathresult + % + \pgf@x=\pgf@curvilinear@lenab pt% + \advance\pgf@x by\pgf@curvilinear@lenbc pt% + \advance\pgf@x by\pgf@curvilinear@lencd pt% + \pgfmathreciprocal@{\pgf@x}% + \pgf@curvilinear@time@a\pgfmathresult pt% + \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@a\pgfmathresult pt% + \ifdim\pgf@curvilinear@length@a>1pt\relax% + % Ok, too large, let us make this smaller + \pgfmathdivide@{\pgf@curvilinear@time@a}{\pgf@curvilinear@length@a}% + \pgf@curvilinear@time@a\pgfmathresult pt% + \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@a\pgfmathresult pt% + \fi% + % Compute three positions: + \pgf@process{\pgfpointcurveattime{2\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \pgf@xa=-\pgf@x% + \pgf@ya=-\pgf@y% + \advance\pgf@x by\pgf@xb% + \advance\pgf@y by\pgf@yb% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@b\pgfmathresult pt% + \advance\pgf@curvilinear@length@b by\pgf@curvilinear@length@a% + \pgf@process{\pgfpointcurveattime{4\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \pgf@xb=-\pgf@x% + \pgf@yb=-\pgf@y% + \advance\pgf@x by\pgf@xa% + \advance\pgf@y by\pgf@ya% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@c\pgfmathresult pt% + \advance\pgf@curvilinear@length@c by\pgf@curvilinear@length@b% + \pgf@process{\pgfpointcurveattime{8\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} + \advance\pgf@x by\pgf@xb% + \advance\pgf@y by\pgf@yb% + \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgf@curvilinear@length@d\pgfmathresult pt% + \advance\pgf@curvilinear@length@d by\pgf@curvilinear@length@c% + \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@initial% + \let\pgf@curvilinear@comp@b\pgf@curvilinear@comp@b@initial% + \let\pgf@curvilinear@comp@c\pgf@curvilinear@comp@c@initial% + \let\pgf@curvilinear@comp@d\pgf@curvilinear@comp@d@initial% + \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@initial% + \let\pgf@curvilinear@point\pgf@curvilinear@curve@point% +} +\newdimen\pgf@curvilinear@time@a +\newdimen\pgf@curvilinear@length@a +\newdimen\pgf@curvilinear@length@b +\newdimen\pgf@curvilinear@length@c +\newdimen\pgf@curvilinear@length@d + + +\def\pgf@curvilinear@comp@a@initial{% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@curvilinear@length@a% + \let\pgf@curvilinear@quot@a\pgfmathresult% + \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@cont% + \pgf@curvilinear@comp@a@cont% +} +\def\pgf@curvilinear@comp@a@cont{% + \pgf@x\pgf@curvilinear@quot@a\pgf@x% +} + +\def\pgf@curvilinear@comp@b@initial{% + \pgf@y=\pgf@curvilinear@length@b% + \advance\pgf@y by-\pgf@curvilinear@length@a% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \let\pgf@curvilinear@quot@b\pgfmathresult% + \pgf@y\pgfmathresult\pgf@curvilinear@length@a% + \pgf@y-\pgf@y% + \advance\pgf@y by\pgf@curvilinear@time@a% + \edef\pgf@curvilinear@correct@b{\pgf@sys@tonumber\pgf@y}% + \let\pgf@curvilinear@comp@b\pgf@curvilinear@comp@b@cont% + \pgf@curvilinear@comp@b@cont% +} +\def\pgf@curvilinear@comp@b@cont{% + \pgf@x\pgf@curvilinear@quot@b\pgf@x% + \advance\pgf@x by\pgf@curvilinear@correct@b pt% +} + +\def\pgf@curvilinear@comp@c@initial{% + \pgf@y=\pgf@curvilinear@length@c% + \advance\pgf@y by-\pgf@curvilinear@length@b% + \pgf@y.5\pgf@y% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \let\pgf@curvilinear@quot@c\pgfmathresult% + \pgf@y\pgf@curvilinear@quot@c\pgf@curvilinear@length@b% + \pgf@y-\pgf@y% + \advance\pgf@y by2\pgf@curvilinear@time@a% + \edef\pgf@curvilinear@correct@c{\pgf@sys@tonumber\pgf@y}% + \let\pgf@curvilinear@comp@c\pgf@curvilinear@comp@c@cont% + \pgf@curvilinear@comp@c@cont% +} +\def\pgf@curvilinear@comp@c@cont{% + \pgf@x\pgf@curvilinear@quot@c\pgf@x% + \advance\pgf@x by\pgf@curvilinear@correct@c pt% +} + +\def\pgf@curvilinear@comp@d@initial{% + \pgf@y=\pgf@curvilinear@length@d% + \advance\pgf@y by-\pgf@curvilinear@length@c% + \pgf@y.25\pgf@y% + \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \let\pgf@curvilinear@quot@d\pgfmathresult% + \pgf@y\pgf@curvilinear@quot@d\pgf@curvilinear@length@c% + \pgf@y-\pgf@y% + \advance\pgf@y by4\pgf@curvilinear@time@a% + \edef\pgf@curvilinear@correct@d{\pgf@sys@tonumber\pgf@y}% + \let\pgf@curvilinear@comp@d\pgf@curvilinear@comp@d@cont% + \pgf@curvilinear@comp@d@cont% +} +\def\pgf@curvilinear@comp@d@cont{% + \pgf@x\pgf@curvilinear@quot@d\pgf@x% + \advance\pgf@x by\pgf@curvilinear@correct@d pt% +} + +\def\pgf@curvilinear@comp@e@initial{% + \pgfmathdivide@{8\pgf@curvilinear@time@a}{\pgf@curvilinear@length@d}% + \let\pgf@curvilinear@quot@e\pgfmathresult% + \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@cont% + \pgf@curvilinear@comp@e@cont% +} +\def\pgf@curvilinear@comp@e@cont{% + \pgf@x\pgf@curvilinear@quot@e\pgf@x% +} + + +% Convert a distance into a time +% +% #1 = a distance +% +% Description: +% +% After having called \pgfsetcurvilinearbeziercurve, you can use this +% macro to convert a distance into a time along the curve set in that +% command. The result will be stored in \pgf@x. It will only be +% reasonably precise for small nonnegative #1 (in particular, #1 +% should not be more than about half the length of the curve). + +\def\pgfcurvilineardistancetotime#1{% + \pgfmathsetlength{\pgf@x}{#1}% + \ifdim\pgf@x<\pgf@curvilinear@length@c\relax% + \ifdim\pgf@x<\pgf@curvilinear@length@a\relax% + \pgf@curvilinear@comp@a% + \else\ifdim\pgf@x<\pgf@curvilinear@length@b\relax% + \pgf@curvilinear@comp@b% + \else% + \pgf@curvilinear@comp@c% + \fi\fi% + \else\ifdim\pgf@x<\pgf@curvilinear@length@d\relax% + \pgf@curvilinear@comp@d% + \else% + \pgf@curvilinear@comp@e% + \fi\fi% +} + + + +% Compute a "Bezier-orthogonal" point for use in a nonlinear transformation. +% +% #1 = x +% #2 = y +% +% Description: +% +% In this coordinate system, the x-axis "goes along" the Bezier curve +% installed using \pgfsetcurvilinearbeziercurve +% and the y-axis is always perpendicular to the (Bezier) curve at the +% given x-coordinate. Formally, given a pair (x,y), let B(x) be the point on +% the Bezier curve B at distance x from the start of the curve. Let +% T(x) be the tangent of B at B(x) and let P(x) be the (normalized) +% vector perpendicular to T(x). Then (x,y) would be mapped to B(x) + +% y*P(x). As an example, if B is a circle, then the corresponding +% curvilinear coordinate system is (essentially, except for an offset in +% the y value) the polar coordinate system. +% +% In addition to setting \pgf@x and \pgf@y, \pgf@xa/ya will be set to +% a tangent along the curve at the given point and \pgf@xb/yb to a +% tanget orthogonal to the curve. + +\def\pgfpointcurvilinearbezierorthogonal#1#2{% + \pgfmathsetmacro\pgf@curvilinear@yfactor{#2}% + \pgfcurvilineardistancetotime{#1}% + \pgfpointcurveattime{\pgf@x}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d} + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + % compute normal: + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \ifdim\pgf@xb<0.0001pt\ifdim\pgf@xb>-0.0001pt\ifdim\pgf@yb<0.0001pt\ifdim\pgf@yb>-0.0001pt\pgf@diff@curvi@ac\fi\fi\fi\fi + \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@yb\pgf@y=-\pgf@xb}} + \pgf@x\pgf@curvilinear@yfactor\pgf@x% + \pgf@y\pgf@curvilinear@yfactor\pgf@y% + \advance\pgf@x by\pgf@xc% + \advance\pgf@y by\pgf@yc% +} + +\def\pgf@diff@curvi@ac{% + \pgf@curvilinear@line@a% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + \pgf@curvilinear@line@c% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \ifdim\pgf@xb<0.0001pt\ifdim\pgf@xb>-0.0001pt\ifdim\pgf@yb<0.0001pt\ifdim\pgf@yb>-0.0001pt% still degenerate! + \pgf@curvilinear@line@d% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \fi\fi\fi\fi% + \pgf@xb-\pgf@xb% + \pgf@yb-\pgf@yb% +} + + + +% Compute a "Bezier-polar" point. +% +% #1 = x +% #2 = y +% +% Description: +% +% Let (r:d) be the point (x,y) in polar coordinates, that is, r is the +% angle and d the distance of (x,y) to the origin. The point returned +% by \pgfpointcurvilinearbezierpolar is now defined as follows: First, +% we compute that point at distance d along the Bezier curve B. Let +% B(d) be this point. Then, we rotate this point around the start of +% the curve (B(0)) by r degrees. +% +% As an example, consider a triangle with one tip at the origin and +% the other tips as (4cm,3cm) and (4cm,-3cm). Then this triangle would be +% transformed as follows: We take the first 5cm of the Bezier curve +% and rotate it by roughly 37 degrees to the left and by 37 degrees to +% the right. +% +% Note that this command is pretty expensive. + +\def\pgfpointcurvilinearbezierpolar#1#2{% + \pgfmathsetlength\pgfutil@tempdima{#1}% + \pgfmathsetlength\pgfutil@tempdimb{#2}% + % Compute angle: + \pgfpointnormalised{\pgfqpoint{\pgfutil@tempdima}{\pgfutil@tempdimb}}% + \ifdim\pgfutil@tempdimb=0pt\relax\ifdim\pgfutil@tempdima=0pt\pgf@x1pt\pgf@y0pt\fi\fi% + \ifdim\pgfutil@tempdima<0pt% + \pgf@x-\pgf@x% + \pgf@y-\pgf@y% + \fi% + \pgf@ya=-\pgf@y% + \pgfsettransformentries% + {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% + {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{0pt}{0pt}% + \pgftransformshift{\pgfpointscale{-1}{\pgf@curvilinear@line@a}}% + \pgfmathveclen@{\pgfutil@tempdima}{\pgfutil@tempdimb}% + \ifdim\pgfutil@tempdima<0pt% + \edef\pgfmathresult{-\pgfmathresult}% + \fi% + \pgfcurvilineardistancetotime{\pgfmathresult}% + % Now, transform: + \pgf@process{% + \pgfpointadd{% + \pgfpointtransformed{% + \pgfpointcurveattime% + {\pgf@x}% + {\pgf@curvilinear@line@a}% + {\pgf@curvilinear@line@b}% + {\pgf@curvilinear@line@c}% + {\pgf@curvilinear@line@d}% + }% + }% + \pgf@curvilinear@line@a% + }% +} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex index 240eddf4435..f82f8640c4f 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex @@ -83,8 +83,8 @@ \def\pgfmathfp@parser@install{% % \expandafter\ifx\csname FP@version\endcsname\relax% - \PackageError{pgf}{You need to say `\string\usepackage{fp}' to use % - fixed point arithmetic}{}% + \pgferror{You need to say `\string\usepackage{fp}' to use % + fixed point arithmetic}% \else% % % Don't want messages. diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex index cecc76d593e..dbaf9847cd1 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex @@ -157,11 +157,26 @@ \expandafter\let\expandafter#1\csname pgfmathfloat@backup@\string#1\endcsname% }% } +\def\pgfmathfloat@prepareuninstallcmd@csname#1{% + % and store backup information (globally - I don't want to do that + % all the time when the FPU is used!): + {% + \globaldefs=1 + \pgfutil@namelet{pgfmathfloat@backup@#1}{#1}% + \expandafter\gdef\expandafter\pgfmathfloat@uninstall\expandafter{\pgfmathfloat@uninstall + \pgfutil@namelet{#1}{pgfmathfloat@backup@#1}% + }% + }% +} \def\pgfmathfloat@install#1=#2{% \pgfmathfloat@prepareuninstallcmd{#1}% \let#1=#2% } +\def\pgfmathfloat@install@csname#1#2{% + \pgfmathfloat@prepareuninstallcmd@csname{#1}% + \pgfutil@namelet{#1}{#2}% +} \def\pgfmathfloat@install@unimplemented#1{% \expandafter\pgfmathfloat@prepareuninstallcmd\csname pgfmath@#1@\endcsname% \expandafter\def\csname pgfmath#1@\endcsname##1{\pgfmathfloat@notimplemented{#1}}% @@ -216,15 +231,24 @@ \pgfmathfloat@install\pgfmathcosec@=\pgfmathfloatcosec@% \pgfmathfloat@install\pgfmathexp@=\pgfmathfloatexp@% \pgfmathfloat@install\pgfmathln@=\pgfmathfloatln@% + \pgfmathfloat@install@csname{pgfmathlog10@}{pgfmathfloatlog10@}% + \pgfmathfloat@install@csname{pgfmathlog2@}{pgfmathfloatlog2@}% \pgfmathfloat@install\pgfmathsqrt@=\pgfmathfloatsqrt@% \pgfmathfloat@install\pgfmath@pi=\pgfmathfloatpi@% \pgfmathfloat@install\pgfmathpi=\pgfmathfloatpi@% \pgfmathfloat@install\pgfmathe@=\pgfmathfloate@% \pgfmathfloat@install\pgfmathe=\pgfmathfloate@% \pgfmathfloat@install\pgfmathlessthan@=\pgfmathfloatlessthan@% + \pgfmathfloat@install\pgfmathnotless@=\pgfmathfloatnotless@% + \pgfmathfloat@install\pgfmathnotgreater@=\pgfmathfloatnotgreater@% \pgfmathfloat@install\pgfmathless@=\pgfmathfloatlessthan@% \pgfmathfloat@install\pgfmathgreaterthan@=\pgfmathfloatgreaterthan@% \pgfmathfloat@install\pgfmathgreater@=\pgfmathfloatgreaterthan@% + \pgfmathfloat@install\pgfmathifthenelse@=\pgfmathfloatifthenelse@% + \pgfmathfloat@install\pgfmathequal@=\pgfmathfloatequal@% + \pgfmathfloat@install\pgfmathequalto@=\pgfmathfloatequal@% + \pgfmathfloat@install\pgfmathnotequal@=\pgfmathfloatnotequal@% + \pgfmathfloat@install\pgfmathnotequalto@=\pgfmathfloatnotequal@% \pgfmathfloat@install\pgfmathpow@=\pgfmathfloatpow@ \pgfmathfloat@install\pgfmathrand@=\pgfmathfloatrand@ \pgfmathfloat@install\pgfmathrand=\pgfmathfloatrand@ @@ -246,14 +270,10 @@ \pgfmathfloat@install\pgfmathtanh@=\pgfmathfloattanh@ \pgfmathfloat@install@unimplemented{ceil}% \pgfmathfloat@install@unimplemented{frac}% - \pgfmathfloat@install@unimplemented{log2}% - \pgfmathfloat@install@unimplemented{log10}% - \pgfmathfloat@install@unimplemented{equalto}% \pgfmathfloat@install@unimplemented{random}% \pgfmathfloat@install@unimplemented{setseed}% \pgfmathfloat@install@unimplemented{Mod}% \pgfmathfloat@install@unimplemented{real}% - \pgfmathfloat@install@unimplemented{notequal}% % \pgfmathfloat@install@unimplemented{atan2}% % \pgfmathfloat@install@unimplemented{height}% % @@ -551,6 +571,7 @@ \let\pgfmath@basic@lessthan@=\pgfmathlessthan@ \let\pgfmath@basic@greaterthan@=\pgfmathgreaterthan@ \let\pgfmath@basic@equalto@=\pgfmathequalto@ +\let\pgfmath@basic@equal@=\pgfmathequal@ \let\pgfmath@basic@true@=\pgfmathtrue@ \let\pgfmath@basic@false@=\pgfmathfalse@ @@ -628,6 +649,25 @@ \let\pgfmathfloatlessthan=\pgfmathfloatlessthan@ \let\pgfmathfloatless@=\pgfmathfloatlessthan@ +% ! (#1 < #2) <=> (#1 >= #2) +\def\pgfmathfloatnotless@#1#2{% + \pgfmathfloatless@{#1}{#2}% + \ifpgfmathfloatcomparison + \def\pgfmathresult{0.0}% + \else + \def\pgfmathresult{1.0}% + \fi +}% +% ! (#1 > #2) <=> (#1 <= #2) +\def\pgfmathfloatnotgreater@#1#2{% + \pgfmathfloatless@{#2}{#1}% + \ifpgfmathfloatcomparison + \def\pgfmathresult{0.0}% + \else + \def\pgfmathresult{1.0}% + \fi +}% + % compares \pgfmathfloat@a@[SME] < \pgfmathfloat@b@[SME] \def\pgfmathfloatlessthan@positive{% \ifnum\pgfmathfloat@a@E<\pgfmathfloat@b@E @@ -730,7 +770,7 @@ % 100 <= m < 1000 % instead of 1 <= m < 10. % -% The 'extended precision' means we have higher accuracy when we apply pgfmath operations to mantisses. +% The 'extended precision' means we have higher accuracy when we apply pgfmath operations to mantissas. % % The input argument is expected to be a normalized floating point number; the output argument is a non-normalized floating point number (well, normalized to extended precision). % @@ -885,6 +925,34 @@ \ifnum\pgfmathfloatiffinite@>2 #3\else #2\fi }% +\def\pgfmathfloatifthenelse@#1#2#3{% + \pgfmathfloatifflags{#1}{0}{% + \edef\pgfmathresult{#3}%% + }{% + \edef\pgfmathresult{#2}% + }% +} +\def\pgfmathfloatequal@#1#2{% + \pgfmathfloatifapproxequalrel{#1}{#2}{% + \def\pgfmathresult{1}% + \pgfmathfloatcomparisontrue + }{% + \def\pgfmathresult{0}% + \pgfmathfloatcomparisonfalse + }% +} +\let\pgfmathfloatequalto@=\pgfmathfloatequal@ + +\def\pgfmathfloatnotequal@#1#2{% + \pgfmathfloatifapproxequalrel{#1}{#2}{% + \def\pgfmathresult{0}% + \pgfmathfloatcomparisonfalse + }{% + \def\pgfmathresult{1}% + \pgfmathfloatcomparisontrue + }% +} +\let\pgfmathfloatnotequalto@=\pgfmathfloatnotequal@ % Computes the relative error between #1 and #2 (assuming #2 != 0) and % invokes #3 if the relative error is below `/pgf/fpu/rel thresh' and @@ -933,7 +1001,7 @@ #4\relax \fi \else - \if\pgfmathfloat@loc@TMPa#2 + \if\pgfmathfloat@loc@TMPa#2% #3\relax \else #4\relax @@ -1421,8 +1489,13 @@ % assuming #2 != 0. \def\pgfmathfloatrelerror@#1#2{% \pgfmathfloatsubtract@{#1}{#2}% - \pgfmathfloatdivide@{\pgfmathresult}{#2}% - \pgfmathfloatabs@{\pgfmathresult}% + \let\pgfmathfloat@subtract=\pgfmathresult + \pgfmathfloatifflags{#2}{0}{% + \let\pgfmathresult=\pgfmathfloat@subtract + }{% + \pgfmathfloatdivide@{\pgfmathfloat@subtract}{#2}% + \pgfmathfloatabs@{\pgfmathresult}% + }% }% \let\pgfmathfloatrelerror=\pgfmathfloatrelerror@ @@ -1589,6 +1662,19 @@ } \let\pgfmathfloatln=\pgfmathfloatln@ +\expandafter\def\csname pgfmathfloatlog10@\endcsname#1{% + \pgfmathfloatln@{#1}% + \let\pgfmathfloat@log@ten=\pgfmathresult + \pgfmathfloatcreate{1}{4.34294481903252}{-1}% 1/ln(10) + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@ten}% +}% +\expandafter\def\csname pgfmathfloatlog2@\endcsname#1{% + \pgfmathfloatln@{#1}% + \let\pgfmathfloat@log@two=\pgfmathresult + \pgfmathfloatcreate{1}{1.44269504088896}{0}% 1/ln(2) + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@two}% +}% + % Computes log(x) into \pgfmathresult. % % This allows numbers such at 10000000 or 5.23e-10 to be represented @@ -1794,12 +1880,25 @@ \divide\c@pgfmath@counta by2\relax% \repeatpgfmathloop% \else - % employ #1^#2 = exp( #2 * ln(#1) ) - \pgfmathfloatln@{#1}% - \let\pgfmathfloat@loc@TMPa=\pgfmathresult - \edef\pgfmathfloat@loc@TMPb{#2}% - \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}% - \pgfmathfloatexp@{\pgfmathresult}% + \pgfmathfloatgetflags{#1}\c@pgfmath@counta + \ifnum0=\c@pgfmath@counta + % ah: 0^x + \pgfmathfloatgetflags{#2}\c@pgfmath@counta + \ifnum0=\c@pgfmath@counta + % ah: 0^0 + \pgfmathfloatcreate{1}{1.0}{0}% + \else + % ah: 0^x with x!=0: + \pgfmathfloatcreate{0}{0.0}{0}% + \fi + \else + % employ #1^#2 = exp( #2 * ln(#1) ) + \pgfmathfloatln@{#1}% + \let\pgfmathfloat@loc@TMPa=\pgfmathresult + \edef\pgfmathfloat@loc@TMPb{#2}% + \pgfmathfloatmultiply@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}% + \pgfmathfloatexp@{\pgfmathresult}% + \fi \fi } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex index 698ec524ba8..b90e96c8b5a 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex @@ -7,6 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +% Note: at the time of this writing, the library has quadratic runtime. +% Experimentally, it performed well while computing ~12 intersections of two +% plots, each with 600 samples. It failed when the number of samples exceeded 700. \newcount\pgf@intersect@solutions @@ -23,6 +26,8 @@ \pgf@intersect@sort@by@second@pathtrue% } +% #1: the index. It starts at 1 and ends with \pgfintersectionsolutions (inclusive). +% Invalid values will implicitly result in the origin. \def\pgfpointintersectionsolution#1{% \ifnum#1<1\relax% \pgfpoint@intersect@solution@orgin% @@ -35,6 +40,31 @@ \fi% } +% Gets the segment indices of solution #1. +% +% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution) +% #2: [output] a macro name which will contain the segment index of the first path which contains the solution +% #3: [output] a macro name which will contain the segment index of the second path which contains the solution +% +% Example: \pgfintersectiongetsolutionsegmentindices{0}{\first}{\second} +% +% -> \first may be 0 if point #0 is in the 0'th segment +% -> \second may be 42 if point #0 is in the 42'th segment +\def\pgfintersectiongetsolutionsegmentindices#1#2#3{% + \ifnum#1<1\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \edef#2{\csname pgf@intersect@solution@segment@a@#1\endcsname}% + \edef#3{\csname pgf@intersect@solution@segment@b@#1\endcsname}% + \fi% + \fi% +}% + \def\pgfpoint@intersect@solution@orgin{% \begingroup% \pgftransforminvert% @@ -45,6 +75,11 @@ \endgroup% } +% #1 code which assigns the first path using \pgfsetpath. +% #2 code which assigns the second path using \pgfsetpath. +% +% On output, the points, their properties, and the number of points are set. +% Use \pgfintersectionsolutions which expands to the number of intersections \long\def\pgfintersectionofpaths#1#2{% \begingroup% \pgfinterruptpath% @@ -72,6 +107,10 @@ \let\pgf@intersect@path@a=\pgf@intersect@path@b% \let\pgf@intersect@path@b=\pgf@intersect@temp% \fi% + % + \pgfprocessround\pgf@intersect@path@a\pgf@intersect@path@a% + \pgfprocessround\pgf@intersect@path@b\pgf@intersect@path@b% + % \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% \expandafter\pgf@intersectionofpaths\pgf@intersect@path@a\pgf@stop% \edef\pgfintersectionsolutions{\the\pgf@intersect@solutions}% @@ -80,6 +119,8 @@ \else% \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@g@intersect@solution@\pgfmathcounter}% + \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}% + \pgf@marshal \ifpgf@intersect@sort% \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@g@intersect@solution@\pgfmathcounter @time@a}% @@ -90,6 +131,17 @@ \fi% } +\def\pgf@intersection@set@properties#1#2{% + \pgfutil@namedef{pgf@intersect@solution@segment@a@\pgfmathcounter}{#1}% + \pgfutil@namedef{pgf@intersect@solution@segment@b@\pgfmathcounter}{#2}% +}% + +% #1 a global name prefix to store properties. +\def\pgf@intersection@store@properties#1{% + % we store the time offsets as well and make them available programmatically: + \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}}% +} + \def\pgf@intersectionofpaths#1{% \ifx#1\pgf@stop% \let\pgf@intersect@next=\relax% @@ -152,6 +204,7 @@ \def\pgf@intersect@path@process@a{% \pgf@intersect@path@getpoints@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@b% + \def\pgf@intersect@time@offset@b{0}% \expandafter\pgf@intersectionofpaths\pgf@intersect@path@b\pgf@stop% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% @@ -173,6 +226,9 @@ \pgf@intersect@path@getpoints@b% \csname pgf@intersect@\pgf@intersect@type@a @and@\pgf@intersect@type@b\endcsname% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@b% + \c@pgf@counta=\pgf@intersect@time@offset@b\relax% + \advance\c@pgf@counta by1\relax% + \edef\pgf@intersect@time@offset@b{\the\c@pgf@counta}% \pgf@intersectionofpaths} \def\pgf@intersect@path@getpoints@b{% @@ -224,6 +280,8 @@ \pgfpointintersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}% {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}% }% + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + % \ifpgf@intersect@sort% \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% @@ -567,6 +625,7 @@ \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}% {% \global\advance\pgf@intersect@solutions by1\relax% + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% \expandafter\global\expandafter\let% \csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=% \pgf@intersect@solution@candidate% @@ -747,15 +806,16 @@ \csname pgf@intersect@solution@\the\pgfutil@tempcnta @time@a\endcsname pt\relax% \pgf@intersect@solutions@sortfinishfalse% % - \pgfutil@namelet{pgf@intersect@temp}{pgfpoint@intersect@solution@\pgfmathcounter}% - \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% + \pgfintersectionsolutionsortbytime@swap{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@intersect@solution@\the\pgfutil@tempcnta}% - \pgfutil@namelet{pgfpoint@intersect@solution@\the\pgfutil@tempcnta}{pgf@intersect@temp}% % - \pgfutil@namelet{pgf@intersect@temp}{pgf@intersect@solution@\pgfmathcounter @time@a}% - \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}% - \pgfutil@namelet{pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}{pgf@intersect@temp}% + % + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@a@\pgfmathcounter}% + {pgf@intersect@solution@segment@a@\the\pgfutil@tempcnta}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@b@\pgfmathcounter}% + {pgf@intersect@solution@segment@b@\the\pgfutil@tempcnta}% \fi% \repeatpgfmathloop% \ifpgf@intersect@solutions@sortfinish% @@ -764,4 +824,10 @@ \fi% } +\def\pgfintersectionsolutionsortbytime@swap#1#2{% + \pgfutil@namelet{pgf@intersect@temp}{#1}% + \pgfutil@namelet{#1}{#2}% + \pgfutil@namelet{#2}{pgf@intersect@temp}% +}% + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex index d7bb3d9dd57..ab6a067835e 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarylindenmayersystems.code.tex @@ -56,7 +56,7 @@ #2% \endgroup% }% - {\PackageError{pgf}{Lindenmayer system `#1' is already defined}{}}% + {\pgferror{Lindenmayer system `#1' is already defined}}% } \def\pgf@lsystem@symbol#1#2{% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex index 5ab9e84a796..38ccd94d0b9 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplothandlers.code.tex @@ -7,9 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplothandlers.code.tex,v 1.15 2010/05/31 10:11:22 tantau Exp $ - -\newif\ifpgf@plot@started +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplothandlers.code.tex,v 1.20 2013/08/31 13:02:59 ludewich Exp $ % This handler converts each plot stream command into a curveto @@ -23,13 +21,16 @@ % \pgfplothandlercurveto % \pgfplotxyfile{mytable} -\def\pgfplothandlercurveto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@curveto@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgf@plot@curveto@handler@finish% - \global\pgf@plot@startedfalse% - }% +\pgfdeclareplothandler{\pgfplothandlercurveto}{}{% + point macro=\pgf@plot@curveto@handler@initial, + jump macro=\pgf@plot@smooth@next@moveto, + end macro=\pgf@plot@curveto@handler@finish +} + +\def\pgf@plot@smooth@next@moveto{% + \pgf@plot@curveto@handler@finish% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreampoint\pgf@plot@curveto@handler@initial% } \def\pgf@plot@curveto@handler@initial#1{% @@ -113,12 +114,16 @@ % \pgfplothandlerclosedcurve % \pgfplotxyfile{mytable} -\def\pgfplothandlerclosedcurve{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@closedcurve@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgf@plot@closedcurve@handler@finish% - }% +\pgfdeclareplothandler{\pgfplothandlerclosedcurve}{}{% + point macro=\pgf@plot@closedcurve@handler@initial, + end macro=\pgf@plot@closedcurve@handler@finish, + jump macro=\pgf@plot@closedsmooth@next@moveto +} + +\def\pgf@plot@closedsmooth@next@moveto{% + \pgf@plot@closedcurve@handler@finish% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreampoint\pgf@plot@closedcurve@handler@initial% } \def\pgf@plot@closedcurve@handler@initial#1{% @@ -276,13 +281,10 @@ % \pgfplothandlerxcomb % \pgfplotxyfile{mytable} -\def\pgfplothandlerxcomb{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@xcomb@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% - \pgfplotxzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerxcomb}{}{% + start macro=\pgfplotxzerolevelstreamstart, + point macro=\pgf@plot@xcomb@handler, + end macro=\pgfplotxzerolevelstreamend, } \def\pgf@plot@xcomb@handler#1{% @@ -307,13 +309,10 @@ % \pgfplothandlerycomb % \pgfplotxyfile{mytable} -\def\pgfplothandlerycomb{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@ycomb@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% - \pgfplotyzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerycomb}{}{% + start macro=\pgfplotyzerolevelstreamstart, + point macro=\pgf@plot@ycomb@handler, + end macro=\pgfplotyzerolevelstreamend } \def\pgf@plot@ycomb@handler#1{% @@ -375,12 +374,19 @@ \pgfplotyzerolevelstreamconstant{0pt}% \def\pgfplotbarwidth{\pgfkeysvalueof{/pgf/bar width}} +\def\pgfplotbarshift{\pgfkeysvalueof{/pgf/bar shift}} \pgfqkeys{/pgf}{% bar width/.initial=10pt, bar shift/.initial=0pt, bar interval width/.initial=1, bar interval shift/.initial=0.5, + % + % hook which is executed right before a new bar is begun. + at begin bar/.initial=, + % hook which is executed right after a bar path has been finished. + % In this context, the bar's path has not been used. + at end bar/.initial=, } % This handler places a rectangle at each point in the plot stream, a @@ -395,20 +401,21 @@ % % \pgfplothandlerybar % \pgfplotxyfile{mytable} -\def\pgfplothandlerybar{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@ybar@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% - \pgfmathparse{\pgfplotbarwidth}% - \xdef\pgfplotbarwidth@{\pgfmathresult pt}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar shift}}% - \xdef\pgfplotbarshift@{\pgfmathresult pt}% - \pgfplotyzerolevelstreamstart - }% + +\pgfdeclareplothandler{\pgfplothandlerybar}{}{% + start={ + \pgfmathparse{\pgfplotbarwidth}% + \xdef\pgfplotbarwidth@{\pgfmathresult pt}% + \pgfmathparse{\pgfplotbarshift}% + \xdef\pgfplotbarshift@{\pgfmathresult pt}% + \pgfplotyzerolevelstreamstart + }, + end macro=\pgfplotyzerolevelstreamend, + point macro=\pgf@plot@ybar@handler } \def\pgf@plot@ybar@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@y \expandafter\pgf@xb\pgfplotbarwidth@\relax @@ -423,6 +430,7 @@ \pgfpathrectangle {\pgfqpoint{\pgf@xc}{\pgf@yb}}% {\pgfqpoint{\pgf@xb}{\pgf@ya}}% + \pgfkeysvalueof{/pgf/at end bar}% } % This handler places a rectangle at each point in the plot stream, a @@ -437,20 +445,20 @@ % % \pgfplothandlerxbar % \pgfplotxyfile{mytable} -\def\pgfplothandlerxbar{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@xbar@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% - \pgfmathparse{\pgfplotbarwidth}% - \xdef\pgfplotbarwidth@{\pgfmathresult pt}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar shift}}% - \xdef\pgfplotbarshift@{\pgfmathresult pt}% - \pgfplotxzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerxbar}{}{% + start={ + \pgfmathparse{\pgfplotbarwidth}% + \xdef\pgfplotbarwidth@{\pgfmathresult pt}% + \pgfmathparse{\pgfplotbarshift}% + \xdef\pgfplotbarshift@{\pgfmathresult pt}% + \pgfplotxzerolevelstreamstart + }, + end macro=\pgfplotxzerolevelstreamend, + point macro=\pgf@plot@xbar@handler } \def\pgf@plot@xbar@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@x \expandafter\pgf@xb\pgfplotbarwidth@\relax @@ -465,6 +473,7 @@ \pgfpathrectangle {\pgfqpoint{\pgf@yb}{\pgf@xc}}% {\pgfqpoint{\pgf@ya}{\pgf@xb}}% + \pgfkeysvalueof{/pgf/at end bar}% } % This handler is a variant of \pgfplothandlerybar which works with @@ -500,17 +509,16 @@ % % \pgfplothandlerybarinterval % \pgfplotxyfile{mytable} -\def\pgfplothandlerybarinterval{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler@first% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotyzerolevelstreamend% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% - \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% - \xdef\pgfplotbarintervalshift@{\pgfmathresult}% - \pgfplotyzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerybarinterval}{}{% + start={ + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% + \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% + \xdef\pgfplotbarintervalshift@{\pgfmathresult}% + \pgfplotyzerolevelstreamstart + }, + end macro=\pgfplotyzerolevelstreamend, + point macro=\pgf@plot@ybarinterval@handler@first } \def\pgf@plot@ybarinterval@handler@first#1{% @@ -520,6 +528,7 @@ \global\let\pgf@plotstreampoint=\pgf@plot@ybarinterval@handler% } \def\pgf@plot@ybarinterval@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@plot@barinterval@bar \xdef\pgf@plot@barinterval@bar{\the\pgf@y}% @@ -538,20 +547,20 @@ \pgfpathrectangle {\pgfqpoint{\pgf@xc}{\pgf@yb}}% {\pgfqpoint{\pgf@xb}{\pgf@ya}}% + \pgfkeysvalueof{/pgf/at end bar}% } % Like \pgfplothandlerybarinterval but for xbar. -\def\pgfplothandlerxbarinterval{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler@first% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfplotxzerolevelstreamend% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% - \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% - \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% - \xdef\pgfplotbarintervalshift@{\pgfmathresult}% - \pgfplotxzerolevelstreamstart - }% +\pgfdeclareplothandler{\pgfplothandlerxbarinterval}{}{% + start={ + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval width}}% + \xdef\pgfplotbarintervalwidth@{\pgfmathresult}% + \pgfmathparse{\pgfkeysvalueof{/pgf/bar interval shift}}% + \xdef\pgfplotbarintervalshift@{\pgfmathresult}% + \pgfplotxzerolevelstreamstart + }, + end macro=\pgfplotxzerolevelstreamend, + point macro=\pgf@plot@xbarinterval@handler@first } \def\pgf@plot@xbarinterval@handler@first#1{% @@ -561,6 +570,7 @@ \global\let\pgf@plotstreampoint=\pgf@plot@xbarinterval@handler% } \def\pgf@plot@xbarinterval@handler#1{% + \pgfkeysvalueof{/pgf/at begin bar}% \pgf@process{#1}% \pgf@ya=\pgf@plot@barinterval@bar \xdef\pgf@plot@barinterval@bar{\the\pgf@x}% @@ -579,6 +589,7 @@ \pgfpathrectangle {\pgfqpoint{\pgf@yb}{\pgf@xc}}% {\pgfqpoint{\pgf@ya}{\pgf@xb}}% + \pgfkeysvalueof{/pgf/at end bar}% } @@ -595,13 +606,11 @@ % % \pgfplothandlerconstantlineto % \pgfplotxyfile{mytable} -\def\pgfplothandlerconstantlineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@const@line@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerconstantlineto}{}{% + point macro=\pgf@plot@const@line@handler } + \def\pgf@plot@const@line@handler#1{% \pgf@process{#1}% \xdef\pgf@plot@const@line@handler@last{\the\pgf@y}% @@ -630,13 +639,11 @@ % % \pgfplothandlerconstantlinetomarkright % \pgfplotxyfile{mytable} -\def\pgfplothandlerconstantlinetomarkright{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@right@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerconstantlinetomarkright}{}{% + point macro=\pgf@plot@const@line@mark@right@handler } + \def\pgf@plot@const@line@mark@right@handler#1{% \pgf@process{#1}% \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}% @@ -653,6 +660,43 @@ \xdef\pgf@plot@const@line@handler@last{\the\pgf@xa}% } +% A variant of \pgfplothandlerconstantlineto which places its mark on +% the middle of the line segment. +% +% ----x +% | +% --x--- | +% | |--x---- +% x-- +% +% Example: +% +% \pgfplothandlerconstantlinetomarkmid +% \pgfplotxyfile{mytable} + +\pgfdeclareplothandler{\pgfplothandlerconstantlinetomarkmid}{}{% + point macro=\pgf@plot@const@line@mark@mid@handler +} + +\def\pgf@plot@const@line@mark@mid@handler#1{% + \pgf@process{#1}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% + \pgf@plot@first@action{}% + \global\let\pgf@plotstreampoint=\pgf@plot@const@line@mark@mid@handler@@% +} +\def\pgf@plot@const@line@mark@mid@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgf@plot@const@line@handler@last + \pgf@xc=.5\pgf@xa + \advance\pgf@xc by.5\pgf@x + \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@y}}% + \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% +} + % This handler is in fact a variant of \pgfplothandlerconstantlineto, % but it does not draw vertical lines. It produces a sequence of % line-to and move-to operations such that plot marks are placed at @@ -667,13 +711,11 @@ % % \pgfplothandlerjumpmarkright % \pgfplotxyfile{mytable} -\def\pgfplothandlerjumpmarkright{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkright@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerjumpmarkright}{}{% + point macro=\pgf@plot@jumpmarkright@handler } + \def\pgf@plot@jumpmarkright@handler#1{% \pgf@process{#1}% \xdef\pgf@plot@const@line@handler@last{\the\pgf@x}% @@ -704,12 +746,9 @@ % % \pgfplothandlerjumpmarkleft % \pgfplotxyfile{mytable} -\def\pgfplothandlerjumpmarkleft{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@jumpmarkleft@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% + +\pgfdeclareplothandler{\pgfplothandlerjumpmarkleft}{}{% + point macro=\pgf@plot@jumpmarkleft@handler } \def\pgf@plot@jumpmarkleft@handler#1{% \pgf@process{#1}% @@ -727,6 +766,44 @@ \xdef\pgf@plot@const@line@handler@last{\the\pgf@ya}% } +% This handler is in fact a variant of +% \pgfplothandlerconstantlinetomarkmid, +% but it does not draw vertical lines. It produces a sequence of +% line-to and move-to operations such that plot marks are placed like +% +% ----x +% +% --x-- +% --x---- +% x-- +% +% Example: +% +% \pgfplothandlerjumpmarkmid +% \pgfplotxyfile{mytable} + +\pgfdeclareplothandler{\pgfplothandlerjumpmarkmid}{}{% + point macro=\pgf@plot@jump@mark@mid@handler +} + +\def\pgf@plot@jump@mark@mid@handler#1{% + \pgf@process{#1}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% + \pgf@plot@first@action{}% + \global\let\pgf@plotstreampoint=\pgf@plot@jump@mark@mid@handler@@% +} +\def\pgf@plot@jump@mark@mid@handler@@#1{% + \pgf@process{#1}% + \pgf@xa=\pgf@x + \pgf@ya=\pgf@y + \pgf@plot@const@line@handler@last + \pgf@xc=.5\pgf@xa + \advance\pgf@xc by.5\pgf@x + \pgfpathlineto{\pgfqpoint{\pgf@xc}{\pgf@y}}% + \pgfpathmoveto{\pgfqpoint{\pgf@xc}{\pgf@ya}}% + \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@ya}}% + \xdef\pgf@plot@const@line@handler@last{\global\pgf@x=\the\pgf@x\space\global\pgf@y=\the\pgf@y\space}% +} % This handler converts each point in a stream into a line from the @@ -737,12 +814,8 @@ % \pgfplothandlerpolarcomb % \pgfplotxyfile{mytable} -\def\pgfplothandlerpolarcomb{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@polarcomb@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlerpolarcomb}{}{% + point macro=\pgf@plot@polarcomb@handler } \def\pgf@plot@polarcomb@handler#1{% @@ -767,30 +840,24 @@ % \pgfplothandlermark{\pgfuseplotmark{*}} % \pgfplotxyfile{mytable} -\def\pgfplothandlermark#1{% - \pgf@plothandlermark{% - \ifnum\pgf@plot@mark@count<\pgf@plot@mark@repeat\relax% - \else% - \global\pgf@plot@mark@count=0\relax% - #1% - \fi% +\pgfdeclareplothandler{\pgfplothandlermark}{#1}{% + start={ + \def\pgf@plot@mark{% + \ifnum\pgf@plot@mark@count<\pgf@plot@mark@repeat\relax% + \else% + \global\pgf@plot@mark@count=0\relax% + #1% + \fi% }% + \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% + \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% + }, + point macro=\pgf@plot@mark@handler } \newcount\pgf@plot@mark@count \def\pgf@plot@mark@phase{0} -\def\pgf@plothandlermark#1{% - \def\pgf@plot@mark{#1}% - \def\pgf@plotstreamstart{% - \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% - \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% - \global\let\pgf@plotstreampoint=\pgf@plot@mark@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% -} - \def\pgf@plot@mark@handler#1{% \global\advance\pgf@plot@mark@count by1\relax% {\pgftransformshift{#1}\pgf@plot@mark}% @@ -837,16 +904,32 @@ % \pgfplothandlermarklisted{\pgfuseplotmark{*}}{1,2,4,...,9} % \pgfplotxyfile{mytable} -\def\pgfplothandlermarklisted#1#2{% - \let\pgf@plot@mark@list=\pgfutil@empty% - \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} - \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% - \pgf@plothandlermark{% - \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% - \pgf@marshal% - \ifpgfutil@in@#1\fi}% +\pgfdeclareplothandler{\pgfplothandlermarklisted}{#1#2}{% + start={ + \let\pgf@plot@mark@list=\pgfutil@empty% + \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} + \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% + \def\pgf@plot@mark{% + \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% + \pgf@marshal% + \ifpgfutil@in@#1\fi% + }% + \global\pgf@plot@mark@count=\pgf@plot@mark@repeat\relax% + \global\advance\pgf@plot@mark@count by-\pgf@plot@mark@phase\relax% + }, + point macro=\pgf@plot@mark@handler } +% \def\pgfplothandlermarklisted#1#2{% +% \let\pgf@plot@mark@list=\pgfutil@empty% +% \edef\pgf@marshal{\noexpand\foreach\noexpand\pgf@temp in{#2}} +% \pgf@marshal{\xdef\pgf@plot@mark@list{\pgf@plot@mark@list(\pgf@temp)}}% +% \pgf@plothandlermark{% +% \edef\pgf@marshal{\noexpand\pgfutil@in@{(\the\pgf@plot@mark@count)}{\pgf@plot@mark@list}}% +% \pgf@marshal% +% \ifpgfutil@in@#1\fi}% +% } + % Define a new plot mark for use with \pgfplotmark. % @@ -888,7 +971,7 @@ \pgfdeclareplotmark{*} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} + \pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfplotmarksize}{0sp}}{\pgfqpoint{0sp}{\pgfplotmarksize}}% \pgfusepathqfillstroke } @@ -932,12 +1015,13 @@ \pgfkeys{/pgf/gap around stream point/.initial=1.5pt} -\def\pgfplothandlergaplineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@gap@lineto@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlergaplineto}{}{% + point macro=\pgf@plot@gap@lineto@handler@initial, + jump macro=\pgf@plot@gap@next@moveto +} + +\def\pgf@plot@gap@next@moveto{% + \global\let\pgf@plotstreampoint=\pgf@plot@gap@lineto@handler@initial% } \def\pgf@plot@gap@lineto@handler@initial#1{% @@ -976,13 +1060,17 @@ % \pgfplothandlergapcycle % \pgfplotxyfile{mytable} -\def\pgfplothandlergapcycle{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@gap@cycle@handler@initial% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgf@plot@gap@cycle@handler@finish% - \global\let\pgf@plot@gap@cycle@first=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlergapcycle}{}{% + point macro=\pgf@plot@gap@cycle@handler@initial, + jump macro=\pgf@plot@gapcycle@next@moveto, + end macro=\pgf@plot@gap@cycle@handler@finish, + start={\global\let\pgf@plot@gap@cycle@first\relax} +} + +\def\pgf@plot@gapcycle@next@moveto{% + \pgf@plot@gap@cycle@handler@finish% + \global\let\pgf@plot@gap@cycle@first=\relax% + \global\let\pgf@plotstreampoint=\pgf@plot@gap@cycle@handler@initial% } \def\pgf@plot@gap@cycle@handler@initial#1{% @@ -1020,3 +1108,7 @@ \endinput + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex index 57df579e3f3..94862191a3a 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex @@ -7,14 +7,14 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplotmarks.code.tex,v 1.12 2010/10/15 07:34:06 ludewich Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplotmarks.code.tex,v 1.13 2013/07/20 13:56:18 ludewich Exp $ % A stroked circle mark \pgfdeclareplotmark{o} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} + \pgfpathellipse{\pgfpointorigin}{\pgfqpoint{\pgfplotmarksize}{0sp}}{\pgfqpoint{0sp}{\pgfplotmarksize}}% \pgfusepathqstroke } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex index 1043825d60f..ea1f469abe8 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryprofiler.code.tex @@ -20,9 +20,24 @@ %-------------------------------------------- \pgfutil@ifundefined{pdfelapsedtime}{% - \PackageError{pgf}{library 'profiler' can only be used with pdftex Rev. >= 1.671 because it needs the \string\pdfelapsedtime\space command}{}% - \global\let\pdfelapsedtime=\c@pgf@counta -}{} + % Ok, \pdfelapsedtime is not defined. + % Maybe we run luatex? + \pgfutil@ifluatex + % Yes. So we emulate the primitive by a macro. + % (see http://tex.stackexchange.com/q/32507/8425) + \def\pgfutil@pdfelapsedtime{% + \numexpr\pgfutil@directlua{% + tex.print(math.floor((os.clock())*65536+0.5))}\relax} + \else + % Raise an error + \pgferror{% + Library 'profiler' can only be used with pdftex Rev. >= 1.671 + because it needs the \string\pdfelapsedtime\space command or + with luatex}% + \global\let\pgfutil@pdfelapsedtime=\c@pgf@counta + \fi}{% + % We run pdftex. That's ok. + \let\pgfutil@pdfelapsedtime\pdfelapsedtime} % Defines a new profiler entry named `#1'. @@ -64,7 +79,7 @@ \def\pgfprofilenewforenvironment@[#1]#2{% \expandafter\pgfprofile@@to@pgfretval\pgfprofile@TeX@DIALECT@toenvironment@begin{#2}% \ifx\pgfretval\relax - \PackageError{pgf}{\string\pgfprofilenewforenvironment{#2} doesn't work: the environment `#2' is (not yet?) known or not known in this context}{}% + \pgferror{\string\pgfprofilenewforenvironment{#2} doesn't work: the environment `#2' is (not yet?) known or not known in this context}{}% \else \expandafter\global\expandafter\let\csname pgfprofile@orig@begin@#2\endcsname=\pgfretval \expandafter\pgfprofile@@to@pgfretval\pgfprofile@TeX@DIALECT@toenvironment@end{#2}% @@ -132,7 +147,7 @@ \or \pgfprofilenewforcommandpattern[#1]{#2}{##1##2##3##4##5##6##7}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}% \else - \PackageError{pgf}{library 'profiler' can't replace control sequences with '#3' arguments automatically, sorry.}% + \pgferror{library 'profiler' can't replace control sequences with '#3' arguments automatically, sorry.}{}% \fi \fi }% @@ -155,7 +170,7 @@ \fi \fi \if\pgfprofile@known0% - \PackageError{pgf}{\string\pgfprofilenewforcommandpattern{\string#2} doesn't work: the command `\string#2' is (not yet?) known or not known in this context}{}% + \pgferror{\string\pgfprofilenewforcommandpattern{\string#2} doesn't work: the command `\string#2' is (not yet?) known or not known in this context}% \else \begingroup \pgfprofile@cs@to@name{#2}% @@ -189,7 +204,7 @@ \def\pgfprofileshowinvocationsfor#1{% \pgfutil@ifundefined{b@pgfprofile@show@#1}{% - \PackageError{pgf}{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}{}% + \pgferror{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}% }{% \expandafter\gdef\csname b@pgfprofile@show@#1\endcsname{1}% \expandafter\gdef\csname b@pgfprofile@show@edef@#1\endcsname{0}% @@ -197,7 +212,7 @@ }% \def\pgfprofileshowinvocationsexpandedfor#1{% \pgfutil@ifundefined{b@pgfprofile@show@#1}{% - \PackageError{pgf}{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}{}% + \pgferror{\string\pgfprofileshowinvocationsfor{#1} doesn't work: the argument is no profiler entry}% }{% \expandafter\gdef\csname b@pgfprofile@show@#1\endcsname{1}% \expandafter\gdef\csname b@pgfprofile@show@edef@#1\endcsname{1}% @@ -290,7 +305,7 @@ \pgfprofileifisrunning{#1}{% \relax }{% - \expandafter\xdef\csname c@pgfprofile@elapsed@at@start@#1\endcsname{\the\pdfelapsedtime}% + \expandafter\xdef\csname c@pgfprofile@elapsed@at@start@#1\endcsname{\the\pgfutil@pdfelapsedtime}% \expandafter\gdef\csname c@pgfprofile@subtractforself@#1\endcsname{0}% \pgfprofile@advance{c@pgfprofile@numinvocations@#1}{1}% \pgfprofilestackpush{#1}% @@ -305,7 +320,7 @@ \relax }{% \begingroup - \c@pgf@countb=\pdfelapsedtime\relax + \c@pgf@countb=\pgfutil@pdfelapsedtime\relax \advance\c@pgf@countb by-\csname c@pgfprofile@elapsed@at@start@#1\endcsname\relax % \pgfprofilestackpop\pgfretval diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex index f6c89af3efe..90f26eb7211 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysnakes.code.tex @@ -7,10 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysnakes.code.tex,v 1.24 2008/01/19 16:52:30 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysnakes.code.tex,v 1.25 2013/07/15 12:05:34 tantau Exp $ -\PackageWarning{pgf}{Snakes have been superseded by decorations. Use -the decoration libraries instead of the snakes library} +\pgfwarning{Snakes have been superseded by decorations. Use the decoration libraries instead of the snakes library} \usepgflibrary{decorations.pathmorphing,decorations.pathreplacing,decorations.shapes} diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex index 16d1b2eab0e..a385cf199f5 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarysvg.path.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysvg.path.code.tex,v 1.6 2009/01/24 17:07:14 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarysvg.path.code.tex,v 1.7 2013/09/23 18:04:36 tantau Exp $ \usepgfmodule{parser} @@ -179,6 +179,10 @@ } +% Ignore spaces if no other rules says differently: + +\pgfparserdef{svgpath}{all}{blank space \space}{} + diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex index ddf8a29f629..30ecbff3c4d 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.ee.code.tex @@ -88,17 +88,14 @@ \pgfdeclareshape{direction ee} { \savedanchor\northeast{ - % Right border is given by right extend \pgf@x=0pt% - \csname pgf@arrow@right@\pgfkeysvalueof{/pgf/direction ee arrow}\endcsname % Height is given by minimum height/2 \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/minimum height}}% \pgf@y=.5\pgf@y } \savedanchor\southwest{ % Left border is given by left extend - \pgf@x=0pt% - \csname pgf@arrow@left@\pgfkeysvalueof{/pgf/direction ee arrow}\endcsname + \pgfarrowtotallength{\pgfkeysvalueof{/pgf/direction ee arrow}}% \pgf@x=-\pgf@x% % Height is given by minimum height/2 \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/minimum height}}% @@ -131,10 +128,8 @@ \beforebackgroundpath{ { - \pgfsetarrowsend{\pgfkeysvalueof{/pgf/direction ee arrow}} \pgfsys@beginscope - \pgflowlevelsynccm% - \pgflowlevelobj{}{\pgf@endarrow}% + \pgfarrowdraw{\pgfkeysvalueof{/pgf/direction ee arrow}}% \pgfsys@endscope } } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex index 5b2beb2b0fb..e137e113cdc 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.IEC.code.tex @@ -10,131 +10,131 @@ \usepgflibrary{shapes.gates.logic} \pgfkeys{/pgf/.cd, - and gate IEC symbol/.initial=$\char`\&$, - nand gate IEC symbol/.initial=$\char`\&$, - or gate IEC symbol/.initial=$\geq1$, - nor gate IEC symbol/.initial=$\geq1$, - xor gate IEC symbol/.initial={$=1$}, - xnor gate IEC symbol/.initial={$=1$}, - not gate IEC symbol/.initial=1, - buffer gate IEC symbol/.initial=1, - logic gate IEC symbol align/.initial=top, - logic gate IEC symbol color/.initial=% no value + and gate IEC symbol/.initial=$\char`\&$, + nand gate IEC symbol/.initial=$\char`\&$, + or gate IEC symbol/.initial=$\geq1$, + nor gate IEC symbol/.initial=$\geq1$, + xor gate IEC symbol/.initial={$=1$}, + xnor gate IEC symbol/.initial={$=1$}, + not gate IEC symbol/.initial=1, + buffer gate IEC symbol/.initial=1, + logic gate IEC symbol align/.initial=top, + logic gate IEC symbol color/.initial=% no value } \pgfkeys{/pgf/logic gate IEC symbol align/.cd, - top/.code=\pgftransformyshift{\innerhalfheight}, - bottom/.code=\pgftransformyshift{-\innerhalfheight}, - left/.code=\pgftransformxshift{-\innerhalfwidth}, - right/.code=\pgftransformxshift{\innerhalfwidth} + top/.code=\pgftransformyshift{\innerhalfheight}, + bottom/.code=\pgftransformyshift{-\innerhalfheight}, + left/.code=\pgftransformxshift{-\innerhalfwidth}, + right/.code=\pgftransformxshift{\innerhalfwidth} } \def\pgf@lib@sh@logicgates@IEC@foregroundpath#1{% - \dimensions% - {% - \pgftransformshift{\centerpoint}% - \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate IEC symbol align}}% - \edef\pgf@lib@sh@@temp{/pgf/logic gate IEC symbol align/.cd, \pgf@lib@sh@temp}% - \expandafter\pgfkeys\expandafter{\pgf@lib@sh@@temp}% - \expandafter\pgftext\expandafter[\pgf@lib@sh@temp]{% - \pgfkeysgetvalue{/pgf/logic gate IEC symbol color}{\pgf@lib@sh@temp}% - \ifx\pgf@lib@sh@temp\pgfutil@empty% - \else% - \expandafter\color\expandafter{\pgf@lib@sh@temp}% - \fi% - \pgfkeysvalueof{/pgf/#1 gate IEC symbol}% - }% - }% -} + \dimensions% + {% + \pgftransformshift{\centerpoint}% + \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate IEC symbol align}}% + \edef\pgf@lib@sh@@temp{/pgf/logic gate IEC symbol align/.cd, \pgf@lib@sh@temp}% + \expandafter\pgfkeys\expandafter{\pgf@lib@sh@@temp}% + \expandafter\pgftext\expandafter[\pgf@lib@sh@temp]{% + \pgfkeysgetvalue{/pgf/logic gate IEC symbol color}{\pgf@lib@sh@temp}% + \ifx\pgf@lib@sh@temp\pgfutil@empty% + \else% + \expandafter\color\expandafter{\pgf@lib@sh@temp}% + \fi% + \pgfkeysvalueof{/pgf/#1 gate IEC symbol}% + }% + }% +} \def\pgf@lib@sh@logicgates@dimensions@IEC#1{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y.5\dp\pgfnodeparttextbox% - % - % Adjust for the width of the gate symbol. - % - \setbox\pgf@hbox\hbox{{\pgfkeysvalueof{/pgf/#1 gate IEC symbol}}}% add braces as color-aftergroup-fix TT - \pgf@xa.5\wd\pgf@hbox% - \pgf@ya.5\ht\pgf@hbox% - \advance\pgf@ya.5\dp\pgf@hbox% - \ifdim\pgf@x<\pgf@xa% - \pgf@x\pgf@xa% - \fi% - \ifdim\pgf@y<\pgf@ya% - \pgf@y\pgf@ya% - \fi% - \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% - \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% - % - % Adjust for minimum height and width. - % - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% - \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@x<.5\pgf@xa% - \pgf@x.5\pgf@xa% - \fi% - \ifdim\pgf@y<.5\pgf@ya% - \pgf@y.5\pgf@ya% - \fi% - % - % Adjust the height for the number of inputs. - % - \c@pgf@counta\pgf@lib@sh@logicgate@numinputs% - \advance\c@pgf@counta1\relax% - \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \pgf@yb2.0\pgf@yb% - \advance\pgf@yb\pgflinewidth% - \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/logic gate input sep}}% - \edef\inputsep{\the\pgf@yc}% - \addtosavedmacro\inputsep% - \ifdim\pgf@yb<\pgf@yc% - \pgf@yb\pgf@yc% - \fi% - \multiply\pgf@yb\c@pgf@counta% - \ifdim\pgf@y<.5\pgf@yb% - \pgf@y.5\pgf@yb% - \fi% - % - \pgf@xa\pgf@y% - \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/inner xsep}}% - \edef\innerhalfwidth{\the\pgf@xa}% - \addtosavedmacro\innerhalfwidth% - % - \pgf@ya\pgf@y% - \pgfmathaddtolength\pgf@ya{-\pgfkeysvalueof{/pgf/inner ysep}}% - \edef\innerhalfheight{\the\pgf@ya}% - \addtosavedmacro\innerhalfheight% - % - % Take into account the outer sep. - % - \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathaddtolength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% - % - \edef\halfwidth{\the\pgf@x}% - \edef\halfheight{\the\pgf@y}% - \addtosavedmacro\halfwidth% - \addtosavedmacro\halfheight% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + % Adjust for the width of the gate symbol. + % + \setbox\pgf@hbox\hbox{{\pgfkeysvalueof{/pgf/#1 gate IEC symbol}}}% add braces as color-aftergroup-fix TT + \pgf@xa.5\wd\pgf@hbox% + \pgf@ya.5\ht\pgf@hbox% + \advance\pgf@ya.5\dp\pgf@hbox% + \ifdim\pgf@x<\pgf@xa% + \pgf@x\pgf@xa% + \fi% + \ifdim\pgf@y<\pgf@ya% + \pgf@y\pgf@ya% + \fi% + \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + % + % Adjust for minimum height and width. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \ifdim\pgf@y<.5\pgf@ya% + \pgf@y.5\pgf@ya% + \fi% + % + % Adjust the height for the number of inputs. + % + \c@pgf@counta\pgf@lib@sh@logicgate@numinputs% + \advance\c@pgf@counta1\relax% + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \pgf@yb2.0\pgf@yb% + \advance\pgf@yb\pgflinewidth% + \pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/logic gate input sep}}% + \edef\inputsep{\the\pgf@yc}% + \addtosavedmacro\inputsep% + \ifdim\pgf@yb<\pgf@yc% + \pgf@yb\pgf@yc% + \fi% + \multiply\pgf@yb\c@pgf@counta% + \ifdim\pgf@y<.5\pgf@yb% + \pgf@y.5\pgf@yb% + \fi% + % + \pgf@xa\pgf@x% + \pgfmathaddtolength\pgf@xa{-\pgfkeysvalueof{/pgf/inner xsep}}% + \edef\innerhalfwidth{\the\pgf@xa}% + \addtosavedmacro\innerhalfwidth% + % + \pgf@ya\pgf@y% + \pgfmathaddtolength\pgf@ya{-\pgfkeysvalueof{/pgf/inner ysep}}% + \edef\innerhalfheight{\the\pgf@ya}% + \addtosavedmacro\innerhalfheight% + % + % Take into account the outer sep. + % + \pgfmathaddtolength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathaddtolength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + % + \edef\halfwidth{\the\pgf@x}% + \edef\halfheight{\the\pgf@y}% + \addtosavedmacro\halfwidth% + \addtosavedmacro\halfheight% }% \def\pgf@lib@sh@logicgate@IEC@inputanchor#1{% - \dimensions% - \centerpoint% - \advance\pgf@x-\halfwidth% - \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname% - \advance\pgf@x-\invertedradius% - \advance\pgf@x-\outerinvertedradius% - \fi% - % - \pgfutil@tempdima\halfheight% - \multiply\pgfutil@tempdima2\relax% - \c@pgf@counta\numinputs% - \advance\c@pgf@counta1\relax% - \divide\pgfutil@tempdima\c@pgf@counta% - \multiply\pgfutil@tempdima#1\relax% - \advance\pgf@y\halfheight% - \advance\pgf@y-\pgfutil@tempdima% + \dimensions% + \centerpoint% + \advance\pgf@x-\halfwidth% + \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-#1\endcsname% + \advance\pgf@x-\invertedradius% + \advance\pgf@x-\outerinvertedradius% + \fi% + % + \pgfutil@tempdima\halfheight% + \multiply\pgfutil@tempdima2\relax% + \c@pgf@counta\numinputs% + \advance\c@pgf@counta1\relax% + \divide\pgfutil@tempdima\c@pgf@counta% + \multiply\pgfutil@tempdima#1\relax% + \advance\pgf@y\halfheight% + \advance\pgf@y-\pgfutil@tempdima% } @@ -142,117 +142,117 @@ % Shape and gate IEC % \pgfdeclareshape{and gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@and gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@and gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An and gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{and}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \anchor{center}{\centerpoint}% - \anchor{mid}{\midpoint} - \anchor{mid west}{% - \dimensions% - \midpoint% - \advance\pgf@x-\halfwidth}% - \anchor{mid east}{% - \dimensions% - \midpoint% - \advance\pgf@x\halfwidth}% - \anchor{base}{\basepoint} - \anchor{base west}{% - \dimensions% - \basepoint% - \advance\pgf@x-\halfwidth}% - \anchor{base east}{% - \dimensions% - \basepoint% - \advance\pgf@x\halfwidth}% - \anchor{north}{\dimensions\centerpoint\advance\pgf@y\halfheight}% - \anchor{south}{\dimensions\centerpoint\advance\pgf@y-\halfheight}% - \anchor{east}{\dimensions\centerpoint\advance\pgf@x\halfwidth}% - \anchor{west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth}% - \anchor{north east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y\halfheight}% - \anchor{north west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y\halfheight}% - \anchor{south east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y-\halfheight}% - \anchor{south west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y-\halfheight}% - \anchor{output}{\dimensions\centerpoint\advance\pgf@x\halfwidth} - \backgroundpath{% - \dimensions% - \pgf@xc\halfwidth% - \pgf@yc\halfheight% - \pgfmathaddtolength\pgf@xc{-\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathaddtolength\pgf@yc{-\pgfkeysvalueof{/pgf/outer xsep}}% - {% - \pgftransformshift{\centerpoint}% - \pgfpathrectangle{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}% - {% - \pgf@xc2.0\pgf@xc% - \pgf@yc2.0\pgf@yc% - \pgfqpoint{\pgf@xc}{\pgf@yc}% - }% - \pgfpathclose% - % - % Draw inputs. - % - \pgf@xc-\halfwidth% - \advance\pgf@xc-\invertedradius% - \pgf@yc\halfheight% - \pgfutil@tempdima2.0\pgf@yc% - \c@pgf@counta\numinputs% - \advance\c@pgf@counta1\relax% - \divide\pgfutil@tempdima\c@pgf@counta% - \pgfmathloop% - \ifnum\pgfmathcounter>\numinputs% - \else% - \advance\pgf@yc-\pgfutil@tempdima% - \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname% - {% - \pgfpathcircle{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\invertedradius}% - }% - \fi% - \repeatpgfmathloop% - }% - } - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{and}} - \anchorborder{% - \pgfextract@process\externalpoint{}% - \dimensions% - \pgfpointadd{\centerpoint}{\pgfpointborderrectangle{\externalpoint}{\pgfqpoint{\halfwidth}{\halfheight}}}% - }% + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@and gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@and gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@and gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{An and gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{and}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \anchor{center}{\centerpoint}% + \anchor{mid}{\midpoint} + \anchor{mid west}{% + \dimensions% + \midpoint% + \advance\pgf@x-\halfwidth}% + \anchor{mid east}{% + \dimensions% + \midpoint% + \advance\pgf@x\halfwidth}% + \anchor{base}{\basepoint} + \anchor{base west}{% + \dimensions% + \basepoint% + \advance\pgf@x-\halfwidth}% + \anchor{base east}{% + \dimensions% + \basepoint% + \advance\pgf@x\halfwidth}% + \anchor{north}{\dimensions\centerpoint\advance\pgf@y\halfheight}% + \anchor{south}{\dimensions\centerpoint\advance\pgf@y-\halfheight}% + \anchor{east}{\dimensions\centerpoint\advance\pgf@x\halfwidth}% + \anchor{west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth}% + \anchor{north east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y\halfheight}% + \anchor{north west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y\halfheight}% + \anchor{south east}{\dimensions\centerpoint\advance\pgf@x\halfwidth\advance\pgf@y-\halfheight}% + \anchor{south west}{\dimensions\centerpoint\advance\pgf@x-\halfwidth\advance\pgf@y-\halfheight}% + \anchor{output}{\dimensions\centerpoint\advance\pgf@x\halfwidth} + \backgroundpath{% + \dimensions% + \pgf@xc\halfwidth% + \pgf@yc\halfheight% + \pgfmathaddtolength\pgf@xc{-\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathaddtolength\pgf@yc{-\pgfkeysvalueof{/pgf/outer xsep}}% + {% + \pgftransformshift{\centerpoint}% + \pgfpathrectangle{\pgfqpoint{-\pgf@xc}{-\pgf@yc}}% + {% + \pgf@xc2.0\pgf@xc% + \pgf@yc2.0\pgf@yc% + \pgfqpoint{\pgf@xc}{\pgf@yc}% + }% + \pgfpathclose% + % + % Draw inputs. + % + \pgf@xc-\halfwidth% + \advance\pgf@xc-\invertedradius% + \pgf@yc\halfheight% + \pgfutil@tempdima2.0\pgf@yc% + \c@pgf@counta\numinputs% + \advance\c@pgf@counta1\relax% + \divide\pgfutil@tempdima\c@pgf@counta% + \pgfmathloop% + \ifnum\pgfmathcounter>\numinputs% + \else% + \advance\pgf@yc-\pgfutil@tempdima% + \expandafter\ifx\expandafter\pgf@lib@sh@itext\csname input-\pgfmathcounter\endcsname% + {% + \pgfpathcircle{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\invertedradius}% + }% + \fi% + \repeatpgfmathloop% + }% + } + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{and}} + \anchorborder{% + \pgfextract@process\externalpoint{}% + \dimensions% + \pgfpointadd{\centerpoint}{\pgfpointborderrectangle{\externalpoint}{\pgfqpoint{\halfwidth}{\halfheight}}}% + }% } @@ -262,76 +262,76 @@ % Shape nand gate IEC % \pgfdeclareshape{nand gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@nand gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@nand gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nand gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{nand}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \anchor{output}{% - \csname pgf@anchor@and gate IEC@east\endcsname% - \advance\pgf@x\invertedradius% - \advance\pgf@x\outerinvertedradius% - } - \backgroundpath{% - \csname pgf@sh@bg@and gate IEC\endcsname% - \pgfpathcircle{% - \centerpoint% - \advance\pgf@x\halfwidth% - \advance\pgf@x\invertedradius% - }{+\invertedradius}% - } - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nand}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nand gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@nand gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@nand gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{A nand gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{nand}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \anchor{output}{% + \csname pgf@anchor@and gate IEC@east\endcsname% + \advance\pgf@x\invertedradius% + \advance\pgf@x\outerinvertedradius% + } + \backgroundpath{% + \csname pgf@sh@bg@and gate IEC\endcsname% + \pgfpathcircle{% + \centerpoint% + \advance\pgf@x\halfwidth% + \advance\pgf@x\invertedradius% + }{+\invertedradius}% + } + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nand}} + \inheritanchorborder[from=and gate IEC] } @@ -341,65 +341,65 @@ % Shape or gate IEC % \pgfdeclareshape{or gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@or gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@or gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@or gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An or gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{or}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=and gate IEC]{output} - \inheritbackgroundpath[from=and gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{or}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@or gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@or gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@or gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{An or gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{or}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=and gate IEC]{output} + \inheritbackgroundpath[from=and gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{or}} + \inheritanchorborder[from=and gate IEC] } @@ -409,65 +409,65 @@ % Shape nor gate IEC % \pgfdeclareshape{nor gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nor gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@nor gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@nor gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nor gate must have at least two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{nor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=nand gate IEC]{output}% - \inheritbackgroundpath[from=nand gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nor}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@nor gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@nor gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@nor gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{A nor gate must have at least two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{nor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=nand gate IEC]{output}% + \inheritbackgroundpath[from=nand gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{nor}} + \inheritanchorborder[from=and gate IEC] } @@ -477,65 +477,65 @@ % Shape xor gate IEC % \pgfdeclareshape{xor gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xor gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{2}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@xor gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@xor gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An xor gate must have two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{xor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=and gate IEC]{output} - \inheritbackgroundpath[from=and gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xor}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xor gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{2}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@xor gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@xor gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{An xor gate must have two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{xor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=and gate IEC]{output} + \inheritbackgroundpath[from=and gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xor}} + \inheritanchorborder[from=and gate IEC] } @@ -545,65 +545,65 @@ % \pgfdeclareshape{xnor gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xnor gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. - % - \pgfmathloop% - \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% - \else% - \pgfutil@ifundefined{pgf@anchor@xnor gate IEC@input \pgfmathcounter}{% - \expandafter\xdef\csname pgf@anchor@xnor gate IEC@input \pgfmathcounter\endcsname{% - \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% - }% - }{}% - \repeatpgfmathloop% - \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A xnor gate must have two inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{xnor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=nand gate IEC]{output} - \inheritbackgroundpath[from=nand gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xnor}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@xnor gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1024}% Maximum 1024 (!) inputs. + % + \pgfmathloop% + \ifnum\pgfmathcounter>\pgf@lib@sh@logicgate@numinputs% + \else% + \pgfutil@ifundefined{pgf@anchor@xnor gate IEC@input \pgfmathcounter}{% + \expandafter\xdef\csname pgf@anchor@xnor gate IEC@input \pgfmathcounter\endcsname{% + \noexpand\pgf@lib@sh@logicgate@IEC@inputanchor{\pgfmathcounter}% + }% + }{}% + \repeatpgfmathloop% + \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% + \pgferror{A xnor gate must have two inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{xnor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=nand gate IEC]{output} + \inheritbackgroundpath[from=nand gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{xnor}} + \inheritanchorborder[from=and gate IEC] } @@ -612,59 +612,59 @@ % Shape buffer gate IEC % \pgfdeclareshape{buffer gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1}% Maximum 1 input. - % - \expandafter\gdef\csname pgf@anchor@buffer gate IEC@input\endcsname{% - \pgf@lib@sh@logicgate@IEC@inputanchor{1}% - }% - \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A buffer gate must have one inputs}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{xor}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=and gate IEC]{output} - \inheritbackgroundpath[from=and gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{buffer}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1}% Maximum 1 input. + % + \expandafter\gdef\csname pgf@anchor@buffer gate IEC@input\endcsname{% + \pgf@lib@sh@logicgate@IEC@inputanchor{1}% + }% + \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% + \pgferror{A buffer gate must have one inputs}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{xor}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=and gate IEC]{output} + \inheritbackgroundpath[from=and gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{buffer}} + \inheritanchorborder[from=and gate IEC] } @@ -674,60 +674,60 @@ % Shape not gate IEC % \pgfdeclareshape{not gate IEC}{ - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate IEC\endcsname{% - \pgf@lib@sh@logicgate@parseinputs{1}% - % - \pgfutil@ifundefined{pgf@anchor@not gate IEC@input}{% - \expandafter\gdef\csname pgf@anchor@not gate IEC@input\endcsname{% - \pgf@lib@sh@logicgate@IEC@inputanchor{1}% - }}{}% - \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A not gate must have one input}{}% - \fi% - }% - \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% - \saveddimen\invertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - }% - \saveddimen\outerinvertedradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% - \advance\pgf@x.5\pgflinewidth% - } - \savedmacro\dimensions{% - \pgf@lib@sh@logicgates@dimensions@IEC{not}% - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \inheritanchor[from=and gate IEC]{center} - \inheritanchor[from=and gate IEC]{mid} - \inheritanchor[from=and gate IEC]{mid west} - \inheritanchor[from=and gate IEC]{mid east} - \inheritanchor[from=and gate IEC]{base} - \inheritanchor[from=and gate IEC]{base west} - \inheritanchor[from=and gate IEC]{base east} - \inheritanchor[from=and gate IEC]{north} - \inheritanchor[from=and gate IEC]{south} - \inheritanchor[from=and gate IEC]{east} - \inheritanchor[from=and gate IEC]{west} - \inheritanchor[from=and gate IEC]{north east} - \inheritanchor[from=and gate IEC]{north west} - \inheritanchor[from=and gate IEC]{south east} - \inheritanchor[from=and gate IEC]{south west} - \inheritanchor[from=nand gate IEC]{output} - \inheritbackgroundpath[from=nand gate IEC] - \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{not}} - \inheritanchorborder[from=and gate IEC] + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate IEC\endcsname{% + \pgf@lib@sh@logicgate@parseinputs{1}% + % + \pgfutil@ifundefined{pgf@anchor@not gate IEC@input}{% + \expandafter\gdef\csname pgf@anchor@not gate IEC@input\endcsname{% + \pgf@lib@sh@logicgate@IEC@inputanchor{1}% + }}{}% + \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% + \pgferror{A not gate must have one input}% + \fi% + }% + \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% + \saveddimen\invertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + }% + \saveddimen\outerinvertedradius{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/logic gate inverted radius}}% + \advance\pgf@x.5\pgflinewidth% + } + \savedmacro\dimensions{% + \pgf@lib@sh@logicgates@dimensions@IEC{not}% + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \inheritanchor[from=and gate IEC]{center} + \inheritanchor[from=and gate IEC]{mid} + \inheritanchor[from=and gate IEC]{mid west} + \inheritanchor[from=and gate IEC]{mid east} + \inheritanchor[from=and gate IEC]{base} + \inheritanchor[from=and gate IEC]{base west} + \inheritanchor[from=and gate IEC]{base east} + \inheritanchor[from=and gate IEC]{north} + \inheritanchor[from=and gate IEC]{south} + \inheritanchor[from=and gate IEC]{east} + \inheritanchor[from=and gate IEC]{west} + \inheritanchor[from=and gate IEC]{north east} + \inheritanchor[from=and gate IEC]{north west} + \inheritanchor[from=and gate IEC]{south east} + \inheritanchor[from=and gate IEC]{south west} + \inheritanchor[from=nand gate IEC]{output} + \inheritbackgroundpath[from=nand gate IEC] + \foregroundpath{\pgf@lib@sh@logicgates@IEC@foregroundpath{not}} + \inheritanchorborder[from=and gate IEC] } \endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex index ae857c6fd42..f941abd2647 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.US.code.tex @@ -217,7 +217,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An and gate must have at least two inputs}{}% + \pgferror{An and gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -454,7 +454,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nand gate must have at least two inputs}{}% + \pgferror{A nand gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -619,7 +619,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An or gate must have at least two inputs}{}% + \pgferror{An or gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -967,7 +967,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nor gate must have at least two inputs}{}% + \pgferror{A nor gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1166,7 +1166,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An xor gate must have at two inputs}{}% + \pgferror{An xor gate must have at two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1497,7 +1497,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An xnor gate must have two inputs}{}% + \pgferror{An xnor gate must have two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1657,7 +1657,7 @@ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@not gate US\endcsname{% \pgf@lib@sh@logicgate@parseinputs{1}% \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A not gate must have one input}{}% + \pgferror{A not gate must have one input}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -1960,7 +1960,7 @@ \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@buffer gate US\endcsname{% \pgf@lib@sh@logicgate@parseinputs{1}% \ifnum\pgf@lib@sh@logicgate@numinputs=0\relax% - \PackageError{PGF}{A buffer gate must have one input}{}% + \pgferror{A buffer gate must have one input}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -2153,7 +2153,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{An and gate must have at least two inputs}{}% + \pgferror{An and gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% @@ -2405,7 +2405,7 @@ }{}% \repeatpgfmathloop% \ifnum\pgf@lib@sh@logicgate@numinputs<2\relax% - \PackageError{PGF}{A nand gate must have at least two inputs}{}% + \pgferror{A nand gate must have at least two inputs}% \fi% }% \savedmacro\numinputs{\let\numinputs\pgf@lib@sh@logicgate@numinputs}% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex index 440681b7b87..cfa1d80d442 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.callouts.code.tex @@ -247,9 +247,9 @@ \pgf@lib@callouts@shortenpointer% \pgf@lib@ellipsecallout@getpoints% \calloutpointeranchor% - \ifx\pgf@test\pgfutil@empty% + \ifx\pgf@node@name\pgfutil@empty% \else% - \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@test\noexpand\endcsname}% + \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}% \edef\pgf@sh@@@temp{% \noexpand\def\noexpand\calloutpointeranchor{% \noexpand\pgf@x\the\pgf@x% @@ -568,15 +568,15 @@ \pgfmathsetlengthmacro\pointerwidth{\pgfkeysvalueof{/pgf/callout pointer width}}% \pgf@lib@rectanglecallout@pointer% % - % \pgf@test = the shape name (from \pgfmultipartnode) + % \pgf@node@name = the shape name (from \pgfmultipartnode) % - \ifx\pgf@test\pgfutil@empty% + \ifx\pgf@node@name\pgfutil@empty% \else% % % Now hack an extra saved anchor \calloutpointeranchor, % with the new anchor for the callout pointer. % - \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@test\noexpand\endcsname}% + \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}% \edef\pgf@sh@@@temp{% \noexpand\def\noexpand\calloutpointeranchor{% \noexpand\pgf@x\the\pgf@x% @@ -809,7 +809,7 @@ \pgfdeclareshape{cloud callout}{% \savedanchor\calloutpointer{% \pgfutil@ifundefined{pgf@sh@s@cloud}{% - \PackageError{PGF}{I cannot find the cloud shape. Please load the `symbol shapes' library}{}}{}% + \pgferror{I cannot find the cloud shape. Please load the `symbol shapes' library}}{}% \pgf@sh@s@cloud% \pgf@sh@savedmacros% % @@ -862,9 +862,9 @@ \pgfextract@process\calloutpointer{% \pgfpointanchor{pgf@lib@callout@pointer}{center}% }% - \ifx\pgf@test\pgfutil@empty% + \ifx\pgf@node@name\pgfutil@empty% \else% - \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@test\noexpand\endcsname}% + \edef\pgf@sh@@temp{\noexpand\expandafter\noexpand\pgfutil@g@addto@macro\noexpand\csname pgf@sh@np@\pgf@node@name\noexpand\endcsname}% \edef\pgf@sh@@@temp{% \noexpand\def\noexpand\calloutpointeranchor{% \noexpand\pgf@x\the\pgf@x% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex index a57b0cd4511..5466b1a27f2 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex,v 1.3 2008/10/07 18:23:25 vibrovski Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.misc.code.tex,v 1.5 2013/07/18 14:15:25 tantau Exp $ \pgfdeclareshape{cross out} @@ -37,6 +37,8 @@ \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}} \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}} \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } @@ -63,6 +65,8 @@ \foregroundpath{ \pgfpathmoveto{\southwest} \pgfpathlineto{\northeast} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } @@ -1085,7 +1089,7 @@ \pgfmathanglebetweenpoints{\centerpoint}{\after@sw@anchor}% \ifdim\externalangle pt<\pgfmathresult pt\relax% after south west. \pgfpointintersectionoflines{\centerpoint}{\externalpoint}% - {\before@sw@anchor}{\after@sw@anchor}% + {\sw@anchor}{\after@sw@anchor}% \else% \pgfpointintersectionoflines{\centerpoint}{\externalpoint}% {\after@sw@anchor}{\centerpoint\pgf@xa\pgf@x\after@sw@anchor\pgf@x\pgf@xa}% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex index b419a8cb624..efa492cc024 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex,v 1.3 2009/10/27 23:03:12 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/shapes/pgflibraryshapes.symbols.code.tex,v 1.6 2013/09/11 06:15:59 vibrovski Exp $ \pgfdeclareshape{forbidden sign} { @@ -43,6 +43,48 @@ \fi% \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}} \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} + } +} + + +\pgfdeclareshape{correct forbidden sign} +{ + \inheritsavedanchors[from=circle] % this is nearly a circle + \inheritanchorborder[from=circle] + \inheritanchor[from=circle]{north} + \inheritanchor[from=circle]{north west} + \inheritanchor[from=circle]{north east} + \inheritanchor[from=circle]{center} + \inheritanchor[from=circle]{west} + \inheritanchor[from=circle]{east} + \inheritanchor[from=circle]{mid} + \inheritanchor[from=circle]{mid west} + \inheritanchor[from=circle]{mid east} + \inheritanchor[from=circle]{base} + \inheritanchor[from=circle]{base west} + \inheritanchor[from=circle]{base east} + \inheritanchor[from=circle]{south} + \inheritanchor[from=circle]{south west} + \inheritanchor[from=circle]{south east} + \inheritbackgroundpath[from=circle] + \foregroundpath{ + \centerpoint% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgfutil@tempdima=\radius% + \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xb<\pgf@yb% + \advance\pgfutil@tempdima by-\pgf@yb% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \pgfpathmoveto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{0.707107\pgfutil@tempdima}{-0.707107\pgfutil@tempdima}}} + \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}}{\pgfqpoint{-0.707107\pgfutil@tempdima}{0.707107\pgfutil@tempdima}}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } @@ -57,468 +99,468 @@ % /pgf/random starburst : The seed for the random number generator. % \pgfkeys{/pgf/random starburst/% - .code={% - \ifx\pgfkeysnovalue#1% - \pgfmathgeneratepseudorandomnumber% - \else% - \pgfmathtruncatemacro\pgfmathresult{#1}% - \fi% - \pgfkeyslet{/pgf/random starburst}{\pgfmathresult}% - }% + .code={% + \ifx\pgfkeysnovalue#1% + \pgfmathgeneratepseudorandomnumber% + \else% + \pgfmathtruncatemacro\pgfmathresult{#1}% + \fi% + \pgfkeyslet{/pgf/random starburst}{\pgfmathresult}% + }% } \pgfkeys{/pgf/random starburst=100} \pgfkeys{/pgf/starburst point height/.value required} \pgfkeys{/pgf/starburst point height/.code={% - \pgfmathparse{#1}% - \edef\pgfmathresult{\pgfmathresult pt}% - \pgfkeyslet{/pgf/starburst point height}{\pgfmathresult}% - }% + \pgfmathparse{#1}% + \edef\pgfmathresult{\pgfmathresult pt}% + \pgfkeyslet{/pgf/starburst point height}{\pgfmathresult}% + }% }% \pgfkeys{/pgf/starburst point height=.5cm} \pgfkeys{/pgf/starburst points/.value required} \pgfkeys{/pgf/starburst points/.code={% - \pgfmathtruncatemacro\pgfmathresult{#1}% - \pgfkeyslet{/pgf/starburst points}{\pgfmathresult}% - }% + \pgfmathtruncatemacro\pgfmathresult{#1}% + \pgfkeyslet{/pgf/starburst points}{\pgfmathresult}% + }% }% \pgfkeys{/pgf/starburst points=17} \pgfdeclareshape{starburst}{% - \savedmacro\anglestep{% - \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% - \let\anglestep\pgfmathresult% - } - \savedmacro\calculatestarburstpoints{% - % - % Get the angle step. - % - \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% - \let\anglestep\pgfmathresult% - % - % Get the total number of points. - % - \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/starburst points}}% - \multiply\c@pgf@counta2\relax% - \edef\totalpoints{\the\c@pgf@counta}% - \addtosavedmacro{\totalpoints}% - % - % Calculate the centerpoint. - % - \pgfextract@process\centerpoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% - \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% - }% - % - % Get the larger of the outer sep. - % - \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@x<\pgf@y% - \pgf@x\pgf@y% - \fi% - \edef\outersep{\the\pgf@x}% - % - % Get the node dimensions. - % - \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/inner xsep}}% - \pgfmathaddtolength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/inner ysep}}% - \pgfmathaddtolength\pgf@y{+.5\ht\pgfnodeparttextbox}% - \pgfmathaddtolength\pgf@y{+.5\dp\pgfnodeparttextbox}% - % - % Calculate the inner radii. - % - \ifpgfshapeborderusesincircle% - \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% - % - % Use the incircle... - % - \ifdim\pgf@y>\pgf@x% - \pgf@x\pgf@y% - \fi% - \pgf@x1.41421\pgf@x% - \pgf@y\pgf@x% - \else% - % - % Get the rotation (with rounding). - % - \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% - \pgfmathmod@{\rotate}{360}% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% - \advance\c@pgf@counta45\relax% - \divide\c@pgf@counta90\relax% - \multiply\c@pgf@counta90\relax% - \ifnum\c@pgf@counta<0\relax% - \advance\c@pgf@counta360\relax% - \fi% - % - % Calculate the width and height of the node - % contents, according to any border rotation. - % - \ifnum\c@pgf@counta=90\relax% - \pgf@xc\pgf@x% - \pgf@x\pgf@y% - \pgf@y\pgf@xc% - \else% - \ifnum\c@pgf@counta=270\relax% - \pgf@xc\pgf@x% - \pgf@x\pgf@y% - \pgf@y\pgf@xc% - \fi% - \fi% - \edef\rotate{\the\c@pgf@counta}% - % - % ...or not. - % - \pgf@x=1.41421\pgf@x% - \pgf@y=1.41421\pgf@y% - \fi% - \addtosavedmacro{\rotate}% - % - % Adjust innerradius for minimum width and height. - % - \pgf@xa\pgf@x% - \pgfmathsetlength\pgf@xb{+\pgfkeysvalueof{/pgf/starburst point height}}% - \advance\pgf@xa\pgf@xb% - \pgfmathsetlength\pgf@xc{+\pgfkeysvalueof{/pgf/minimum width}}% - \ifdim\pgf@xa<.5\pgf@xc% - \pgf@x.5\pgf@xc% - \advance\pgf@x-\pgf@xb% - \fi% - \pgf@ya\pgf@y% - \pgfmathsetlength\pgf@yb{+\pgfkeysvalueof{/pgf/starburst point height}}% - \advance\pgf@ya\pgf@yb% - \pgfmathsetlength\pgf@yc{+\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@ya<.5\pgf@yc% - \pgf@y.5\pgf@yc% - \advance\pgf@y-\pgf@yb% - \fi% - \edef\xinnerradius{\the\pgf@x}% - \edef\yinnerradius{\the\pgf@y}% - \addtosavedmacro{\xinnerradius}% - \addtosavedmacro{\yinnerradius}% - % - % Calculate a radius outside the starburst. - % - \ifdim\pgf@y>\pgf@x% - \pgf@x\pgf@y% - \fi% - \pgfmathaddtolength\pgf@x{+\pgfkeysvalueof{/pgf/starburst point height}}% - \edef\externalradius{\the\pgf@x}% - \addtosavedmacro{\externalradius}% - % - % Set the seed for the random number generator. - % - \pgfmathsetseed{\pgfkeysvalueof{/pgf/random starburst}}% - % - % Now create the points on the shape and also - % the miter length and angle for each point. - % - \def\angle{90}% Start at the top. - % - % At point a, the miter length and angle are calculated for point b = a - 1. - % - \c@pgf@counta1\relax% - \c@pgf@countb0\relax% - % - % As 3 consecutive points are required to be defined for miter - % calculations, it is necessary to go over the first two points - % again. - % - \c@pgf@countc\totalpoints\relax% - \advance\c@pgf@countc2\relax% - \edef\looppoints{\the\c@pgf@countc}% - \let\secondpoint\pgfutil@empty% - \let\thirdpoint\pgfutil@empty% - \pgfmathloop% - % - % Cycle the point definitions. - % - \let\firstpoint\secondpoint% - \let\secondpoint\thirdpoint% - \ifnum\pgfmathcounter>\looppoints% - \else% - \ifnum\pgfmathcounter>\totalpoints% - \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% - \else% - \ifodd\pgfmathcounter% - % - % An outer point. - % - \ifnum\pgfkeysvalueof{/pgf/random starburst}=0\relax% - \pgf@xa\pgfkeysvalueof{/pgf/starburst point height}\relax% - \else% - \pgf@x\pgfkeysvalueof{/pgf/starburst point height}\relax% - \pgf@xa.75\pgf@x% - \pgf@xb.25\pgf@x% - \pgfmathrnd% - \pgf@xa\pgfmathresult\pgf@xa% - \advance\pgf@xa\pgf@xb% - \fi% - \pgf@x\xinnerradius\relax% - \advance\pgf@x\pgf@xa% - \pgf@y\yinnerradius\relax% - \advance\pgf@y\pgf@xa% - \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% - \pgfpointpolar{\angle}{\the\pgf@x and \the\pgf@y}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \centerpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \else% - % - % An inner point. - % - \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% - \pgfpointpolar{\angle}{\xinnerradius and \yinnerradius}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \centerpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \fi% - % - % Add the points to the saved macro. - % - \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% - \expandafter\addtosavedmacro\expandafter{\csname point@\the\c@pgf@counta @\endcsname}% - \fi% - % - % It is only possible to do the miter calculations if three points are defined. - % - \ifx\firstpoint\pgfutil@empty% - \else% - % - % Calculate the miter length... - % - \pgfmathanglebetweenlines{\secondpoint}{\thirdpoint}{\secondpoint}{\firstpoint}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\defaultmiterangle\pgfmathresult% - \pgfmathcosec@{\pgfmathresult}% - \pgf@x\outersep\relax% - \pgf@x\pgfmathresult\pgf@x% - \edef\miterlength{\the\pgf@x}% - % - % ...the miter angle... - % - \pgfmathanglebetweenlines{\firstpoint}{\secondpoint}{\firstpoint}{\thirdpoint}% - \pgfmathadd@{\pgfmathresult}{\defaultmiterangle}% - \pgfmathsubtract@{180}{\pgfmathresult}% - \let\angletemp\pgfmathresult% - \pgfmathanglebetweenpoints{\firstpoint}{\thirdpoint}% - \pgfmathsubtract@{180}{\pgfmathresult}% - \pgfmathsubtract@{\angletemp}{\pgfmathresult}% - \edef\miterangle{\pgfmathresult}% - % - % ...and thus the border point. - % - \pgfextract@process\borderpoint{% - \secondpoint% - \pgf@xa\pgf@x - \pgf@ya\pgf@y% - \pgfpointpolar{\miterangle}{\miterlength}% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - % - % Get the angle from the centerpoint to the *unrotated* border points. - % - \pgfmathanglebetweenpoints{\centerpoint}{\borderpoint}% - \expandafter\edef\csname angletoborderpoint@\the\c@pgf@countb @\endcsname{\pgfmathresult}% - \expandafter\addtosavedmacro\expandafter{\csname angletoborderpoint@\the\c@pgf@countb @\endcsname}% - % - % Rotatee the border points and save. - % - \expandafter\pgfextract@process\csname borderpoint@\the\c@pgf@countb @\endcsname{% - \pgfmathrotatepointaround{\borderpoint}{\centerpoint}{\rotate}% - }% - \expandafter\addtosavedmacro\expandafter{\csname borderpoint@\the\c@pgf@countb @\endcsname}% - % - % Now create the anchors. - % - \c@pgf@countc\c@pgf@countb% - \advance\c@pgf@countc1\relax% - \divide\c@pgf@countc2\relax% - \ifodd\c@pgf@countb\relax% - \pgfutil@ifundefined{pgf@anchor@starburst@outer point\space\the\c@pgf@countc}{% - \expandafter\xdef\csname pgf@anchor@starburst@outer point\space\the\c@pgf@countc\endcsname{% - \noexpand\calculatestarburstpoints% - \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% - }% - }{}% - \else% - \pgfutil@ifundefined{pgf@anchor@starburst@inner point\space\the\c@pgf@countc}{% - \expandafter\xdef\csname pgf@anchor@starburst@inner point\space\the\c@pgf@countc\endcsname{% - \noexpand\calculatestarburstpoints% - \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% - }% - }{}% - \fi% - \fi% - \pgfmathadd@{\angle}{\anglestep}% - \pgfmathmod@{\pgfmathresult}{360}% - \let\angle\pgfmathresult% - \advance\c@pgf@counta1\relax% - \ifnum\c@pgf@counta>\totalpoints% - \c@pgf@counta1\relax% - \fi% - \advance\c@pgf@countb1\relax% - \ifnum\c@pgf@countb>\totalpoints% - \c@pgf@countb1\relax% - \fi% - \repeatpgfmathloop% - } - \savedanchor\centerpoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% - \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% - }% - \savedanchor\midpoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgfmathsetlength\pgf@y{+.5ex}% - }% - \savedanchor\basepoint{% - \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% - \pgf@y0pt\relax% - }% - \anchor{center}{\centerpoint} - \anchor{base}{\basepoint} - \anchor{mid}{\midpoint} - \anchor{north}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% - } - \anchor{south}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% - } - \anchor{east}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% - } - \anchor{west}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% - } - \anchor{north west}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% - } - \anchor{south west}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% - } - \anchor{north east}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% - } - \anchor{south east}{% - \calculatestarburstpoints% - \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% - } - \backgroundpath{% - \calculatestarburstpoints% - \pgfmathloop% - \ifnum\pgfmathcounter>\totalpoints% - \else% - \ifnum\pgfmathcounter=1\relax% - \let\starburstaction\pgfpathmoveto% - \else% - \let\starburstaction\pgfpathlineto% - \fi% - \starburstaction{% - %\pgfmathrotatepointaround{\csname point@\pgfmathcounter @\endcsname}{\centerpoint}{\rotate}}% - \csname point@\pgfmathcounter @\endcsname} - \repeatpgfmathloop% - \pgfpathclose% - } - \anchorborder{% - % - % Save x and y. - % - \edef\externalx{\the\pgf@x}% - \edef\externaly{\the\pgf@y}% - % - % Adjust the location of the external - % point relative to \centerpoint. - % - \centerpoint% - \pgf@xa\externalx\relax% - \pgf@ya\externaly\relax% - \advance\pgf@xa\pgf@x% - \advance\pgf@ya\pgf@y% - \edef\externalx{\the\pgf@xa}% - \edef\externaly{\the\pgf@ya}% - % - % Get the starburst points. - % - \calculatestarburstpoints% - % - % Get the angle of the external point to the \centerpoint. - % - \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - \pgfmathsubtract@{\pgfmathresult}{\rotate}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\externalangle\pgfmathresult% - % - % Locate the appropriate sides on the starburst border... - % - \ifdim\externalangle pt<90pt\relax% - \c@pgf@counta0\relax% - \c@pgf@countb\totalpoints\relax% - \pgfmathloop% - \ifnum\c@pgf@counta>0\relax% - \else% - \ifdim\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt>90pt\relax% - \c@pgf@counta\c@pgf@countb% - \else% - \ifdim\externalangle pt>\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt\relax% - \c@pgf@counta\c@pgf@countb% - \fi% - \fi% - \advance\c@pgf@countb-1\relax% - \repeatpgfmathloop% - \edef\first{\the\c@pgf@counta}% - \advance\c@pgf@counta1\relax% - \ifnum\c@pgf@counta>\totalpoints\relax% - \c@pgf@counta1\relax% - \fi% - \edef\second{\the\c@pgf@counta}% - \else% - \c@pgf@counta0\relax% - \pgfmathloop% - \ifnum\c@pgf@counta>0\relax% - \else% - \ifdim\csname angletoborderpoint@\pgfmathcounter @\endcsname pt<90pt\relax% - \c@pgf@counta\pgfmathcounter% - \else% - \ifdim\externalangle pt<\csname angletoborderpoint@\pgfmathcounter @\endcsname pt\relax% - \c@pgf@counta\pgfmathcounter% - \fi% - \fi% - \repeatpgfmathloop% - \edef\first{\the\c@pgf@counta}% - \advance\c@pgf@counta-1\relax% - \ifnum\c@pgf@counta=0\relax% - \c@pgf@counta\totalpoints\relax% - \fi% - \edef\second{\the\c@pgf@counta}% - \fi% - % - % ...and thus, the point on the star border. - % - \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - {\csname borderpoint@\first @\endcsname}{\csname borderpoint@\second @\endcsname}% - }% + \savedmacro\anglestep{% + \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% + \let\anglestep\pgfmathresult% + } + \savedmacro\calculatestarburstpoints{% + % + % Get the angle step. + % + \pgfmathdivide@{180}{\pgfkeysvalueof{/pgf/starburst points}}% + \let\anglestep\pgfmathresult% + % + % Get the total number of points. + % + \pgfmathsetcounter{pgf@counta}{\pgfkeysvalueof{/pgf/starburst points}}% + \multiply\c@pgf@counta2\relax% + \edef\totalpoints{\the\c@pgf@counta}% + \addtosavedmacro{\totalpoints}% + % + % Calculate the centerpoint. + % + \pgfextract@process\centerpoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% + }% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + % + % Get the node dimensions. + % + \pgfmathsetlength\pgf@x{+\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfmathaddtolength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+\pgfkeysvalueof{/pgf/inner ysep}}% + \pgfmathaddtolength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{+.5\dp\pgfnodeparttextbox}% + % + % Calculate the inner radii. + % + \ifpgfshapeborderusesincircle% + \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% + % + % Use the incircle... + % + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + \pgf@x1.41421\pgf@x% + \pgf@y\pgf@x% + \else% + % + % Get the rotation (with rounding). + % + \pgfkeysgetvalue{/pgf/shape border rotate}{\rotate}% + \pgfmathmod@{\rotate}{360}% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgf@counta\pgfmathresult\relax\pgfmath@% + \advance\c@pgf@counta45\relax% + \divide\c@pgf@counta90\relax% + \multiply\c@pgf@counta90\relax% + \ifnum\c@pgf@counta<0\relax% + \advance\c@pgf@counta360\relax% + \fi% + % + % Calculate the width and height of the node + % contents, according to any border rotation. + % + \ifnum\c@pgf@counta=90\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \else% + \ifnum\c@pgf@counta=270\relax% + \pgf@xc\pgf@x% + \pgf@x\pgf@y% + \pgf@y\pgf@xc% + \fi% + \fi% + \edef\rotate{\the\c@pgf@counta}% + % + % ...or not. + % + \pgf@x=1.41421\pgf@x% + \pgf@y=1.41421\pgf@y% + \fi% + \addtosavedmacro{\rotate}% + % + % Adjust innerradius for minimum width and height. + % + \pgf@xa\pgf@x% + \pgfmathsetlength\pgf@xb{+\pgfkeysvalueof{/pgf/starburst point height}}% + \advance\pgf@xa\pgf@xb% + \pgfmathsetlength\pgf@xc{+\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@xa<.5\pgf@xc% + \pgf@x.5\pgf@xc% + \advance\pgf@x-\pgf@xb% + \fi% + \pgf@ya\pgf@y% + \pgfmathsetlength\pgf@yb{+\pgfkeysvalueof{/pgf/starburst point height}}% + \advance\pgf@ya\pgf@yb% + \pgfmathsetlength\pgf@yc{+\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@ya<.5\pgf@yc% + \pgf@y.5\pgf@yc% + \advance\pgf@y-\pgf@yb% + \fi% + \edef\xinnerradius{\the\pgf@x}% + \edef\yinnerradius{\the\pgf@y}% + \addtosavedmacro{\xinnerradius}% + \addtosavedmacro{\yinnerradius}% + % + % Calculate a radius outside the starburst. + % + \ifdim\pgf@y>\pgf@x% + \pgf@x\pgf@y% + \fi% + \pgfmathaddtolength\pgf@x{+\pgfkeysvalueof{/pgf/starburst point height}}% + \edef\externalradius{\the\pgf@x}% + \addtosavedmacro{\externalradius}% + % + % Set the seed for the random number generator. + % + \pgfmathsetseed{\pgfkeysvalueof{/pgf/random starburst}}% + % + % Now create the points on the shape and also + % the miter length and angle for each point. + % + \def\angle{90}% Start at the top. + % + % At point a, the miter length and angle are calculated for point b = a - 1. + % + \c@pgf@counta1\relax% + \c@pgf@countb0\relax% + % + % As 3 consecutive points are required to be defined for miter + % calculations, it is necessary to go over the first two points + % again. + % + \c@pgf@countc\totalpoints\relax% + \advance\c@pgf@countc2\relax% + \edef\looppoints{\the\c@pgf@countc}% + \let\secondpoint\pgfutil@empty% + \let\thirdpoint\pgfutil@empty% + \pgfmathloop% + % + % Cycle the point definitions. + % + \let\firstpoint\secondpoint% + \let\secondpoint\thirdpoint% + \ifnum\pgfmathcounter>\looppoints% + \else% + \ifnum\pgfmathcounter>\totalpoints% + \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% + \else% + \ifodd\pgfmathcounter% + % + % An outer point. + % + \ifnum\pgfkeysvalueof{/pgf/random starburst}=0\relax% + \pgf@xa\pgfkeysvalueof{/pgf/starburst point height}\relax% + \else% + \pgf@x\pgfkeysvalueof{/pgf/starburst point height}\relax% + \pgf@xa.75\pgf@x% + \pgf@xb.25\pgf@x% + \pgfmathrnd% + \pgf@xa\pgfmathresult\pgf@xa% + \advance\pgf@xa\pgf@xb% + \fi% + \pgf@x\xinnerradius\relax% + \advance\pgf@x\pgf@xa% + \pgf@y\yinnerradius\relax% + \advance\pgf@y\pgf@xa% + \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% + \pgfpointpolar{\angle}{\the\pgf@x and \the\pgf@y}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \centerpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \else% + % + % An inner point. + % + \expandafter\pgfextract@process\csname point@\the\c@pgf@counta @\endcsname{% + \pgfpointpolar{\angle}{\xinnerradius and \yinnerradius}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \centerpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \fi% + % + % Add the points to the saved macro. + % + \expandafter\let\expandafter\thirdpoint\csname point@\the\c@pgf@counta @\endcsname% + \expandafter\addtosavedmacro\expandafter{\csname point@\the\c@pgf@counta @\endcsname}% + \fi% + % + % It is only possible to do the miter calculations if three points are defined. + % + \ifx\firstpoint\pgfutil@empty% + \else% + % + % Calculate the miter length... + % + \pgfmathanglebetweenlines{\secondpoint}{\thirdpoint}{\secondpoint}{\firstpoint}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\defaultmiterangle\pgfmathresult% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \edef\miterlength{\the\pgf@x}% + % + % ...the miter angle... + % + \pgfmathanglebetweenlines{\firstpoint}{\secondpoint}{\firstpoint}{\thirdpoint}% + \pgfmathadd@{\pgfmathresult}{\defaultmiterangle}% + \pgfmathsubtract@{180}{\pgfmathresult}% + \let\angletemp\pgfmathresult% + \pgfmathanglebetweenpoints{\firstpoint}{\thirdpoint}% + \pgfmathsubtract@{180}{\pgfmathresult}% + \pgfmathsubtract@{\angletemp}{\pgfmathresult}% + \edef\miterangle{\pgfmathresult}% + % + % ...and thus the border point. + % + \pgfextract@process\borderpoint{% + \secondpoint% + \pgf@xa\pgf@x + \pgf@ya\pgf@y% + \pgfpointpolar{\miterangle}{\miterlength}% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Get the angle from the centerpoint to the *unrotated* border points. + % + \pgfmathanglebetweenpoints{\centerpoint}{\borderpoint}% + \expandafter\edef\csname angletoborderpoint@\the\c@pgf@countb @\endcsname{\pgfmathresult}% + \expandafter\addtosavedmacro\expandafter{\csname angletoborderpoint@\the\c@pgf@countb @\endcsname}% + % + % Rotatee the border points and save. + % + \expandafter\pgfextract@process\csname borderpoint@\the\c@pgf@countb @\endcsname{% + \pgfmathrotatepointaround{\borderpoint}{\centerpoint}{\rotate}% + }% + \expandafter\addtosavedmacro\expandafter{\csname borderpoint@\the\c@pgf@countb @\endcsname}% + % + % Now create the anchors. + % + \c@pgf@countc\c@pgf@countb% + \advance\c@pgf@countc1\relax% + \divide\c@pgf@countc2\relax% + \ifodd\c@pgf@countb\relax% + \pgfutil@ifundefined{pgf@anchor@starburst@outer point\space\the\c@pgf@countc}{% + \expandafter\xdef\csname pgf@anchor@starburst@outer point\space\the\c@pgf@countc\endcsname{% + \noexpand\calculatestarburstpoints% + \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% + }% + }{}% + \else% + \pgfutil@ifundefined{pgf@anchor@starburst@inner point\space\the\c@pgf@countc}{% + \expandafter\xdef\csname pgf@anchor@starburst@inner point\space\the\c@pgf@countc\endcsname{% + \noexpand\calculatestarburstpoints% + \noexpand\csname borderpoint@\the\c@pgf@countb @\noexpand\endcsname% + }% + }{}% + \fi% + \fi% + \pgfmathadd@{\angle}{\anglestep}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\angle\pgfmathresult% + \advance\c@pgf@counta1\relax% + \ifnum\c@pgf@counta>\totalpoints% + \c@pgf@counta1\relax% + \fi% + \advance\c@pgf@countb1\relax% + \ifnum\c@pgf@countb>\totalpoints% + \c@pgf@countb1\relax% + \fi% + \repeatpgfmathloop% + } + \savedanchor\centerpoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5\ht\pgfnodeparttextbox}% + \pgfmathaddtolength\pgf@y{+-.5\dp\pgfnodeparttextbox}% + }% + \savedanchor\midpoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \savedanchor\basepoint{% + \pgfmathsetlength\pgf@x{+.5\wd\pgfnodeparttextbox}% + \pgf@y0pt\relax% + }% + \anchor{center}{\centerpoint} + \anchor{base}{\basepoint} + \anchor{mid}{\midpoint} + \anchor{north}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{\externalradius}}% + } + \anchor{south}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{0pt}{-\externalradius}}% + } + \anchor{east}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{0pt}}% + } + \anchor{west}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{0pt}}% + } + \anchor{north west}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{\externalradius}}% + } + \anchor{south west}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{-\externalradius}{-\externalradius}}% + } + \anchor{north east}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{\externalradius}}% + } + \anchor{south east}{% + \calculatestarburstpoints% + \csname pgf@anchor@starburst@border\endcsname{\pgfqpoint{\externalradius}{-\externalradius}}% + } + \backgroundpath{% + \calculatestarburstpoints% + \pgfmathloop% + \ifnum\pgfmathcounter>\totalpoints% + \else% + \ifnum\pgfmathcounter=1\relax% + \let\starburstaction\pgfpathmoveto% + \else% + \let\starburstaction\pgfpathlineto% + \fi% + \starburstaction{% + %\pgfmathrotatepointaround{\csname point@\pgfmathcounter @\endcsname}{\centerpoint}{\rotate}}% + \csname point@\pgfmathcounter @\endcsname} + \repeatpgfmathloop% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external + % point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Get the starburst points. + % + \calculatestarburstpoints% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + \pgfmathsubtract@{\pgfmathresult}{\rotate}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\externalangle\pgfmathresult% + % + % Locate the appropriate sides on the starburst border... + % + \ifdim\externalangle pt<90pt\relax% + \c@pgf@counta0\relax% + \c@pgf@countb\totalpoints\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \else% + \ifdim\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt>90pt\relax% + \c@pgf@counta\c@pgf@countb% + \else% + \ifdim\externalangle pt>\csname angletoborderpoint@\the\c@pgf@countb @\endcsname pt\relax% + \c@pgf@counta\c@pgf@countb% + \fi% + \fi% + \advance\c@pgf@countb-1\relax% + \repeatpgfmathloop% + \edef\first{\the\c@pgf@counta}% + \advance\c@pgf@counta1\relax% + \ifnum\c@pgf@counta>\totalpoints\relax% + \c@pgf@counta1\relax% + \fi% + \edef\second{\the\c@pgf@counta}% + \else% + \c@pgf@counta0\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \else% + \ifdim\csname angletoborderpoint@\pgfmathcounter @\endcsname pt<90pt\relax% + \c@pgf@counta\pgfmathcounter% + \else% + \ifdim\externalangle pt<\csname angletoborderpoint@\pgfmathcounter @\endcsname pt\relax% + \c@pgf@counta\pgfmathcounter% + \fi% + \fi% + \repeatpgfmathloop% + \edef\first{\the\c@pgf@counta}% + \advance\c@pgf@counta-1\relax% + \ifnum\c@pgf@counta=0\relax% + \c@pgf@counta\totalpoints\relax% + \fi% + \edef\second{\the\c@pgf@counta}% + \fi% + % + % ...and thus, the point on the star border. + % + \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + {\csname borderpoint@\first @\endcsname}{\csname borderpoint@\second @\endcsname}% + }% } @@ -533,22 +575,22 @@ \newif\ifpgfcloudignoresaspect% \pgfcloudignoresaspectfalse% \pgfkeys{/pgf/.cd, - cloud puffs/.initial=10, - cloud puff arc/.initial=150, - cloud ignores aspect/.is if=pgfcloudignoresaspect, - cloud anchors use ellipse/.is if=pgfcloudanchorsuseellipse + cloud puffs/.initial=10, + cloud puff arc/.initial=150, + cloud ignores aspect/.is if=pgfcloudignoresaspect, + cloud anchors use ellipse/.is if=pgfcloudanchorsuseellipse }% % If symbol library is loaded separately these need to be defined. % \pgfkeys{/pgf/.cd, - aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz... - shape aspect/.initial=1,% but this is consistent with other pgfset stuff. - shape aspect/.code={% - \pgfkeys{/pgf/aspect=#1}% - \pgfkeyssetvalue{/pgf/shape aspect}{#1} - }% + aspect/.code={\pgfsetshapeaspect{#1}},% this for tikz... + shape aspect/.initial=1,% but this is consistent with other pgfset stuff. + shape aspect/.code={% + \pgfkeys{/pgf/aspect=#1}% + \pgfkeyssetvalue{/pgf/shape aspect}{#1} + }% } \def\pgfsetshapeaspect#1{% @@ -568,717 +610,717 @@ % Shape cloud. % \pgfdeclareshape{cloud}{% - \savedmacro\getradii{% - \pgfmathtruncatemacro\puffs{\pgfkeysvalueof{/pgf/cloud puffs}}% - \addtosavedmacro\puffs% - \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/cloud puffs}}% - \let\anglestep\pgfmathresult% - \addtosavedmacro\anglestep% - \pgfmathsetmacro\arc{\pgfkeysvalueof{/pgf/cloud puff arc}}% - \addtosavedmacro\arc% - % - % x radius. - % - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% - \advance\pgf@x.5\wd\pgfnodeparttextbox% - \pgf@x1.4142135\pgf@x% - % - % y radius. - % - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% - \advance\pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y.5\dp\pgfnodeparttextbox% - \pgf@y1.4142135\pgf@y% - % - % Adjust for shape aspect. - % - \ifpgfcloudignoresaspect% - \pgf@xc\pgf@x% - \pgf@yc\pgf@y% - \else% - \pgf@xc\pgfshapeaspect\pgf@y% - \ifdim\pgf@xc<\pgf@x% - \pgf@xc\pgf@x% - \fi% - \pgf@yc\pgfshapeaspectinverse\pgf@xc% - \ifdim\pgf@yc<\pgf@y% - \pgf@yc\pgf@y% - \pgf@xc\pgfshapeaspect\pgf@y% - \fi% - \fi% - % - \edef\xinnerradius{\the\pgf@xc}% - \edef\yinnerradius{\the\pgf@yc}% - % - % Get the larger of the outer sep. - % - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@x<\pgf@y% - \pgf@x\pgf@y% - \fi% - \edef\outersep{\the\pgf@x}% - \addtosavedmacro\outersep% - % - % For a given cloud, with puff arc length a, the quotient of the - % distance between the start and end point of a puffs circular arc - % and the radius of that arc, is constant: - % - % g = .5 * sec((180-a)/2) - % - \pgfmathsubtract{180}{\arc}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\tempangle\pgfmathresult% - \pgfmathsec@{\pgfmathresult}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\arcradiusquotient\pgfmathresult% - \addtosavedmacro\arcradiusquotient% - % - % In addition, the quotient of the distance between the start and - % end point of a puffs circular arc and the height of that arc - % (ignoring rotation), is also constant: - % - % h = .5 * (1-sin((180-a)/2))/cos((180-a)/2) - % = g * (1 - sin((180-a)/2)) - \pgfmathsin@{\tempangle}% - \pgfmathsubtract@{1}{\pgfmathresult}% - \pgfmathmultiply@{\pgfmathresult}{\arcradiusquotient}% - \let\archeightquotient\pgfmathresult% - \addtosavedmacro\archeightquotient% - % - % Minimum size is applied to the circum-ellipse (i.e. the ellipse - % that passes through the extremeties of each puff). Thus, the - % relationship between the radii of the elliptical incircle ("inellipse"?) - % of the cloud (x and y) and the radii of the circum-ellispe (X and Y), - % is given by - % - % X = 2(x*cos(p/2) + ky) - % Y = 2(y*cos(p/2) + kx) - % - % where: - % k = sin(p/2)*((1-cos(a/2))/sin(a/2)) - % p = the angle between each puff (i.e. 360/) - % a = the length of arc of the puff. - % - \pgfmathdivide{\arc}{2}% - \let\halfarcangle\pgfmathresult% - \pgfmathcos@{\pgfmathresult}% - \pgfmathsubtract@{1}{\pgfmathresult}% - \let\pgf@temp\pgfmathresult% - \pgfmathsin@{\halfarcangle}% - \pgfmathdivide@{\pgf@temp}{\pgfmathresult}% - \let\pgf@temp\pgfmathresult% - \pgfmathdivide@{\anglestep}{2}% - \pgfmathsin@{\pgfmathresult}% - \pgfmathmultiply@{\pgfmathresult}{\pgf@temp}% - \let\k\pgfmathresult% - % - \pgfmathdivide@{\anglestep}{2}% - \pgfmathcos@{\pgfmathresult}% - \let\coshalfanglestep\pgfmathresult% - % - % Calculate the actual radii of the circum-ellipse. - % - \pgf@x\xinnerradius\relax% - \pgf@y\yinnerradius\relax% - \pgf@xa\coshalfanglestep\pgf@x% - \advance\pgf@xa\k\pgf@y% - \pgf@ya\coshalfanglestep\pgf@y% - \advance\pgf@ya\k\pgf@x% - % - % Adjust for minimum height (Y'). - % - \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@ya<.5\pgf@yb% - \pgf@ya.5\pgf@yb% - \fi% - % - % Adjust for minimum width (X'). - % - \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}% - \ifdim\pgf@xa<.5\pgf@xb% - \pgf@xa.5\pgf@xb% - \fi% - % - \edef\xouterradius{\the\pgf@xa}% - \addtosavedmacro\xouterradius% - \edef\youterradius{\the\pgf@ya}% - \addtosavedmacro\youterradius% - % - % Now recalculate `in-ellispe' radii: - % - % x = (X'cos(p/2)-kY')/cos^2(p/2)-k^2, - % y = (Y'cos(p/2)-kX')/cos^2(p/2)-k^2, - % - \pgf@xc\k pt\relax% - \pgf@xc-\k\pgf@xc% - \pgf@yc\coshalfanglestep pt\relax% - \pgf@yc\coshalfanglestep\pgf@yc% - \advance\pgf@xc\pgf@yc\relax% - \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% cos^2(p/2)-k^2 - % - \pgf@x\coshalfanglestep\pgf@xa% - \advance\pgf@x-\k\pgf@ya% - \pgf@x\pgfmathresult\pgf@x% - \pgf@y\coshalfanglestep\pgf@ya% - \advance\pgf@y-\k\pgf@xa% - \pgf@y\pgfmathresult\pgf@y% - % - \edef\xinnerradius{\the\pgf@x}% - \edef\yinnerradius{\the\pgf@y}% - \addtosavedmacro\xinnerradius% - \addtosavedmacro\yinnerradius% - % - % Get some useful trig. constants. - % - \pgfmathdivide@{\arc}{4}% - \let\quarterarc\pgfmathresult% - \pgfmathsubtract@{180}{\arc}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\halfcomplementarc\pgfmathresult% - % - \addtosavedmacro\arc% - \addtosavedmacro\quarterarc% - \addtosavedmacro\halfcomplementarc% - % - \pgfmathsec@{\halfcomplementarc}% 1/cos((180-a)/2) - \let\sechalfcomplementarc\pgfmathresult% - \pgfmathsin@{\halfcomplementarc}% sin((180-a)/2) - \let\sinhalfcomplementarc\pgfmathresult% - % - \addtosavedmacro\sechalfcomplementarc% - \addtosavedmacro\sinhalfcomplementarc% - % - \pgfmathsin@{\quarterarc}% sin(a/4) - \let\sinquarterarc\pgfmathresult% - \pgfmathcos@{\quarterarc}% cos(a/4) - \let\cosquarterarc\pgfmathresult% - \pgfmathreciprocal@{\cosquarterarc}% - \pgfmathmultiply@{\pgfmathresult}{\sinquarterarc}% tan(a/4) - \let\tanquarterarc\pgfmathresult% - % - \addtosavedmacro\sinquarterarc% - \addtosavedmacro\cosquarterarc% - \addtosavedmacro\tanquarterarc% - % - } - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+.5ex}% - } - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \anchor{center}{\centerpoint} - \anchor{mid}{\midpoint} - \anchor{base}{\basepoint} - \anchor{north}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{\youterradius}}% - }% - \anchor{south}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{-\youterradius}}% - }% - \anchor{east}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{\xouterradius}{0pt}}% - }% - \anchor{west}{% - \getradii% - \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{-\xouterradius}{0pt}}% - }% - \anchor{north west}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x-0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - \anchor{north east}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - \anchor{south west}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x-0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y-0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - \anchor{south east}{% - \getradii% - \pgfextract@process\pgf@sh{% - \pgf@x\xouterradius\relax% - \pgf@x0.707106\pgf@x% - \pgf@y\youterradius\relax% - \pgf@y-0.707106\pgf@y% - }% - \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% - }% - % - % Each `puff' is a circular arc of length a, drawn using two a/2 - % arcs (a < 180), approximated by Bezier curves. - % Due to TeX rounding errors, it is sometimes necessary to `force' - % the arc to end at a specific point. So... - % - % @article{riskus2006, - % author = {Aleskus Ri\v{s}kus}, - % title = {Approximation of a cubic Bezier curve by circular arcs and vice versa}, - % journal = {Information Technology and Control}, - % year = {2006}, - % volume = {35}, - % number = {4} - % } - % - \backgroundpath{% - {% - \getradii% - % - % Get the start angle. - % - \pgfmathdivide@{\anglestep}{2}% - \pgfmathsubtract@{90}{\pgfmathresult}% - \let\angle\pgfmathresult% - % - % Calculate the first arc point. - % - \pgfextract@process\arcfirstpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - \pgfpathmoveto{\arcfirstpoint}% - \let\arcendpoint\arcfirstpoint% - % - \pgfmathloop% - \ifnum\pgfmathcounter>\puffs\relax% - \else - \let\arcstartpoint\arcendpoint% - % - % Make sure beginning and end of path are exactly the same. - % - \ifnum\pgfmathcounter=\puffs\relax% - \let\arcendpoint\arcfirstpoint% - \else% - \pgfmathadd@{\angle}{\anglestep}% - \let\angle\pgfmathresult% - \pgfextract@process\arcendpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - \fi% - % - % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. - % - \pgf@sh@getcloudpuffparameters% - % - % Get the rotation for the Bezier curve. - % - \pgfmathsubtract@{90}{\quarterarc}% - \pgfmathadd@{\pgfmathresult}{\arcslope}% - \let\arcrotate\pgfmathresult% - \pgfmathsin@{\arcrotate}% - \let\sinarcrotate\pgfmathresult% - \pgfmathcos@{\arcrotate}% - \let\cosarcrotate\pgfmathresult% - % - % Calculate the amount by which to scale the control - % points, in order to approximate an a/2 arc with radius x. - % - \pgf@x\arcradius\relax% - \pgf@x\tanquarterarc\pgf@x% tan(a/4) - \edef\controlscale{\pgfmath@tonumber{\pgf@x}}% - % - % Get the first control point for the first arc (length a/2)... - % - \pgfextract@process\controlone{% - % - % k = 0.552284745 (a `magic' number)... - % - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) - % - % ...scale the control points up... - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - % ...rotate... - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - % ...and shift. - % - \arcstartpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - % - % Get the midpoint of the 150° arc. - % - \pgfextract@process\arcmidpoint{% - \pgfextract@process\arcmidpoint{% - \pgf@x-\halfchordlength\relax% - \pgf@y\segmentheight\relax% - }% - \pgfpointadd{\arcstartpoint}{% - \pgfmathrotatepointaround{\arcmidpoint}{\pgfpointorigin}{\arcslope}% - }% - }% - % - % Get the second control point for the first arc (length a/2)... - % - \pgfextract@process\controltwo{% - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y-0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) - % - % ...scale, rotate and shift. - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - \arcmidpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - {% - \pgfsetcornersarced{\pgfpointorigin}% - \pgfpathcurveto{\controlone}{\controltwo}{\arcmidpoint}% - }% - % - % Do the same for the second arc... - % - \pgfmathadd@{\quarterarc}{90}% - \pgfmathadd@{\pgfmathresult}{\arcslope}% - \let\arcrotate\pgfmathresult% - \pgfmathsin@{\arcrotate}% - \let\sinarcrotate\pgfmathresult% - \pgfmathcos@{\arcrotate}% - \let\cosarcrotate\pgfmathresult% - % - % First control point for the second arc... - % - \pgfextract@process\controlone{% - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) - % - % ...scale, rotate and shift. - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - \arcmidpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - % - % Second control point for the second arc. - % - \pgfextract@process\controltwo{% - \pgf@x0.55228475pt\relax% - \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) - \pgf@y-0.55228475pt\relax% - \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) - % - % ...scale, rotate and shift. - % - \pgf@x\controlscale\pgf@x% - \pgf@y\controlscale\pgf@y% - % - \pgf@xa\cosarcrotate\pgf@x% - \advance\pgf@xa-\sinarcrotate\pgf@y% - \pgf@ya\cosarcrotate\pgf@y% - \advance\pgf@ya\sinarcrotate\pgf@x% - % - \arcendpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \pgfpathcurveto{\controlone}{\controltwo}{\arcendpoint}% - \repeatpgfmathloop% - \pgfpathclose% Phew! - }% - }% - % - % Calculate a point on the border of the cloud. This is a two-stage process: - % - % 1. Locate the correct puff. - % 2. Locate the angle on the circular arc which forms the puff. - % - \anchorborder{% - % - % Save x and y. - % - \edef\externalx{\the\pgf@x}% - \edef\externaly{\the\pgf@y}% - % - % Get the inner radii and trig. constants. - % - \getradii% - % - % - % - \ifpgfcloudanchorsuseellipse% - \pgfpointadd{\centerpoint}{% - \pgfpointborderellipse{% - \pgfpoint{\externalx}{\externaly} - }{% - \pgfpoint{\xouterradius}{\youterradius} - }% - }% - \else% - \pgfextract@process\externalpoint{% - \centerpoint% - \advance\pgf@x\externalx\relax% - \advance\pgf@y\externaly\relax% - }% - \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% - \let\externalangle\pgfmathresult% - % - % 1. Locate the correct puff: - % - % Get end angle of the relavent puff arc. - % - \pgfmathdivide@{\anglestep}{2}% - \let\halfanglestep\pgfmathresult% - \pgfmathsubtract@{90}{\halfanglestep}% - \let\endangle\pgfmathresult% - \pgfmathloop% - \pgfmathsubtract@{\endangle}{\anglestep}% - \ifdim\pgfmathresult pt<-\anglestep pt\relax% - \else% - \let\endangle\pgfmathresult% - \repeatpgfmathloop% - \def\angle{0}% - \let\lastangle\angle% - \pgfmathloop% - \pgfmathadd@{\endangle}{\anglestep}% - \let\endangle\pgfmathresult% - % - % Calculate the `miter point'. This is the point between - % each puff, and takes into account the outer sep. - % - \pgfextract@process\miterpoint{% - % - \pgfextract@process\secondpoint{% - \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% - }% - % - \pgfmathadd@{\endangle}{\anglestep}% - \let\angletemp\pgfmathresult% - \pgfextract@process\thirdpoint{% - \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% - }% - % - \pgfmathsubtract@{\endangle}{\anglestep}% - \let\angletemp\pgfmathresult% - \pgfextract@process\firstpoint{% - \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% - }% - % - \pgfmathanglebetweenpoints{\firstpoint}{\secondpoint}% - \let\anglealpha\pgfmathresult% - \pgfmathanglebetweenpoints{\secondpoint}{\thirdpoint}% - \let\anglebeta\pgfmathresult% - % - \pgfmathsubtract@{\anglebeta}{\anglealpha}% - \pgfmathdivide@{\pgfmathresult}{2}% - \pgfmathadd@{\pgfmathresult}{\halfcomplementarc}% - \pgfmathcosec@{\pgfmathresult}% - \pgf@x\outersep\relax% - \pgf@x\pgfmathresult\pgf@x% - \edef\miterradius{\the\pgf@x}% - % - \pgfmathadd@{\anglealpha}{\anglebeta}% - \pgfmathsubtract@{\pgfmathresult}{180}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\miterangle\pgfmathresult% - \pgfpointadd{\secondpoint}{% - \pgfqpointpolar{\miterangle}{\miterradius}% - }% - }% - % - % Get the angle of the miter point... - % - \pgfmathanglebetweenpoints{\pgfpointorigin}{\miterpoint}% - \let\angle\pgfmathresult% - \ifdim\angle pt<\lastangle pt\relax% Guard against 360° = 0° - \pgfmathadd@{\angle}{360}% - \let\angle\pgfmathresult% - \fi% - \let\lastangle\angle% - % - % ...and see if it is greater than the external point. - % - \ifdim\externalangle pt>\angle pt\relax% - \repeatpgfmathloop% - % - % Get the start angle of the relevant arc and ensure angles are in the range. - % - \pgfmathmod@{\endangle}{360}% - \let\endangle\pgfmathresult% - \pgfmathsubtract@{\endangle}{\anglestep}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\startangle\pgfmathresult% - % - % Now, get the start and end points of the arc. - % - \pgfextract@process\arcstartpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\startangle}{+\xinnerradius and +\yinnerradius}% - }% - }% - \pgfextract@process\arcendpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% - }% - }% - % - % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. - % - \pgf@sh@getcloudpuffparameters% - % - % Hackery, for when an arc straddles 0°. - % - \ifdim\endangle pt<\startangle pt\relax% - \pgfmathadd@{\externalangle}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \let\x\pgfmathresult% - \else% - \let\x\externalangle% - \fi% - % - % 2. Locate the angle on the circular arc which forms the puff. - % - % Essentially a binary search to find the angle on the circular - % arc, which provides the nearset estimate to the border point. - % - \let\s\halfcomplementarc% The start of the arc. - \pgfmathadd@{\s}{\arc}% - \let\e\pgfmathresult% The end of the arc. - \pgfmathadd@{\e}{\s}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\n\pgfmathresult% The nearest estimate (default to middle of arc). - \def\m{360}% Measure of `nearness'. - \pgfmathloop% - \pgfmathadd@{\e}{\s}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\p\pgfmathresult% The point halfway between \s and \e. - \ifdim\p pt=\s pt\relax% - \else% - % - % Get the point on the circular arc. - % - \pgfmathadd@{\p}{\arcslope}% - \let\a\pgfmathresult% - \pgfextract@process\arcpoint{% - \pgfpointadd{\circlecenterpoint}{% - \pgfqpointpolar{\a}{\outerarcradius}% - }% - }% - % - % Find the angle between the node centre and the point on the arc. - % - \pgfmathanglebetweenpoints{\centerpoint}{\arcpoint}% - % - % Hackery, for when an arc straddles 0°. - % - \ifdim\endangle pt<\startangle pt\relax% - \pgfmathadd@{\pgfmathresult}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \fi% - \let\q\pgfmathresult% - \ifdim\x pt=\q pt% Found it! - \pgfmathbreakloop% Breaks after current iteration is complete. - \else - \ifdim\x pt<\q pt\relax% - \let\e\p% - \else% - \let\s\p% - \fi% - \fi% - \pgfmathsubtract@{\x}{\q}% - \pgfmathabs@{\pgfmathresult}% - % - % Save the estimate if it is better than any previous estimate. - % - \ifdim\pgfmathresult pt<\m pt\relax% - \let\m\pgfmathresult% - \let\n\p% - \fi% - \repeatpgfmathloop% - % - % Use the nearest estimate as the anchor angle. - % - \pgfmathadd@{\n}{\arcslope}% - \let\anchorangle\pgfmathresult% - % - % Finally, the required point. - % - \pgfpointadd{\circlecenterpoint}{% - \pgfqpointpolar{\anchorangle}{\outerarcradius}% - }% - \fi% - }% Again, Phew! - % - % Now, a sneaky hack. This means an arbitrary `puff' anchors - % can be used for positiong the cloud shape. This is needed - % if a cloud is positioned using the `puff ' anchor, where - % n is the number of puffs of any previously drawn cloud. - % - \pgfutil@g@addto@macro\pgf@sh@s@cloud{% - \c@pgf@counta\puffs\relax% - \pgfmathloop% - \ifnum\c@pgf@counta>0\relax% - \pgfutil@ifundefined{pgf@anchor@cloud@puff\space\the\c@pgf@counta}{% - \expandafter\xdef\csname pgf@anchor@cloud@puff\space\the\c@pgf@counta\endcsname{% - \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}% - }% - }{\c@pgf@counta0\relax}% - \advance\c@pgf@counta-1\relax% - \repeatpgfmathloop% - }% + \savedmacro\getradii{% + \pgfmathtruncatemacro\puffs{\pgfkeysvalueof{/pgf/cloud puffs}}% + \addtosavedmacro\puffs% + \pgfmathdivide{360}{\pgfkeysvalueof{/pgf/cloud puffs}}% + \let\anglestep\pgfmathresult% + \addtosavedmacro\anglestep% + \pgfmathsetmacro\arc{\pgfkeysvalueof{/pgf/cloud puff arc}}% + \addtosavedmacro\arc% + % + % x radius. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgf@x1.4142135\pgf@x% + % + % y radius. + % + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + \pgf@y1.4142135\pgf@y% + % + % Adjust for shape aspect. + % + \ifpgfcloudignoresaspect% + \pgf@xc\pgf@x% + \pgf@yc\pgf@y% + \else% + \pgf@xc\pgfshapeaspect\pgf@y% + \ifdim\pgf@xc<\pgf@x% + \pgf@xc\pgf@x% + \fi% + \pgf@yc\pgfshapeaspectinverse\pgf@xc% + \ifdim\pgf@yc<\pgf@y% + \pgf@yc\pgf@y% + \pgf@xc\pgfshapeaspect\pgf@y% + \fi% + \fi% + % + \edef\xinnerradius{\the\pgf@xc}% + \edef\yinnerradius{\the\pgf@yc}% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x<\pgf@y% + \pgf@x\pgf@y% + \fi% + \edef\outersep{\the\pgf@x}% + \addtosavedmacro\outersep% + % + % For a given cloud, with puff arc length a, the quotient of the + % distance between the start and end point of a puffs circular arc + % and the radius of that arc, is constant: + % + % g = .5 * sec((180-a)/2) + % + \pgfmathsubtract{180}{\arc}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\tempangle\pgfmathresult% + \pgfmathsec@{\pgfmathresult}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\arcradiusquotient\pgfmathresult% + \addtosavedmacro\arcradiusquotient% + % + % In addition, the quotient of the distance between the start and + % end point of a puffs circular arc and the height of that arc + % (ignoring rotation), is also constant: + % + % h = .5 * (1-sin((180-a)/2))/cos((180-a)/2) + % = g * (1 - sin((180-a)/2)) + \pgfmathsin@{\tempangle}% + \pgfmathsubtract@{1}{\pgfmathresult}% + \pgfmathmultiply@{\pgfmathresult}{\arcradiusquotient}% + \let\archeightquotient\pgfmathresult% + \addtosavedmacro\archeightquotient% + % + % Minimum size is applied to the circum-ellipse (i.e. the ellipse + % that passes through the extremeties of each puff). Thus, the + % relationship between the radii of the elliptical incircle ("inellipse"?) + % of the cloud (x and y) and the radii of the circum-ellispe (X and Y), + % is given by + % + % X = 2(x*cos(p/2) + ky) + % Y = 2(y*cos(p/2) + kx) + % + % where: + % k = sin(p/2)*((1-cos(a/2))/sin(a/2)) + % p = the angle between each puff (i.e. 360/) + % a = the length of arc of the puff. + % + \pgfmathdivide{\arc}{2}% + \let\halfarcangle\pgfmathresult% + \pgfmathcos@{\pgfmathresult}% + \pgfmathsubtract@{1}{\pgfmathresult}% + \let\pgf@temp\pgfmathresult% + \pgfmathsin@{\halfarcangle}% + \pgfmathdivide@{\pgf@temp}{\pgfmathresult}% + \let\pgf@temp\pgfmathresult% + \pgfmathdivide@{\anglestep}{2}% + \pgfmathsin@{\pgfmathresult}% + \pgfmathmultiply@{\pgfmathresult}{\pgf@temp}% + \let\k\pgfmathresult% + % + \pgfmathdivide@{\anglestep}{2}% + \pgfmathcos@{\pgfmathresult}% + \let\coshalfanglestep\pgfmathresult% + % + % Calculate the actual radii of the circum-ellipse. + % + \pgf@x\xinnerradius\relax% + \pgf@y\yinnerradius\relax% + \pgf@xa\coshalfanglestep\pgf@x% + \advance\pgf@xa\k\pgf@y% + \pgf@ya\coshalfanglestep\pgf@y% + \advance\pgf@ya\k\pgf@x% + % + % Adjust for minimum height (Y'). + % + \pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@ya<.5\pgf@yb% + \pgf@ya.5\pgf@yb% + \fi% + % + % Adjust for minimum width (X'). + % + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgf@xa<.5\pgf@xb% + \pgf@xa.5\pgf@xb% + \fi% + % + \edef\xouterradius{\the\pgf@xa}% + \addtosavedmacro\xouterradius% + \edef\youterradius{\the\pgf@ya}% + \addtosavedmacro\youterradius% + % + % Now recalculate `in-ellispe' radii: + % + % x = (X'cos(p/2)-kY')/cos^2(p/2)-k^2, + % y = (Y'cos(p/2)-kX')/cos^2(p/2)-k^2, + % + \pgf@xc\k pt\relax% + \pgf@xc-\k\pgf@xc% + \pgf@yc\coshalfanglestep pt\relax% + \pgf@yc\coshalfanglestep\pgf@yc% + \advance\pgf@xc\pgf@yc\relax% + \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@xc}}% cos^2(p/2)-k^2 + % + \pgf@x\coshalfanglestep\pgf@xa% + \advance\pgf@x-\k\pgf@ya% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\coshalfanglestep\pgf@ya% + \advance\pgf@y-\k\pgf@xa% + \pgf@y\pgfmathresult\pgf@y% + % + \edef\xinnerradius{\the\pgf@x}% + \edef\yinnerradius{\the\pgf@y}% + \addtosavedmacro\xinnerradius% + \addtosavedmacro\yinnerradius% + % + % Get some useful trig. constants. + % + \pgfmathdivide@{\arc}{4}% + \let\quarterarc\pgfmathresult% + \pgfmathsubtract@{180}{\arc}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\halfcomplementarc\pgfmathresult% + % + \addtosavedmacro\arc% + \addtosavedmacro\quarterarc% + \addtosavedmacro\halfcomplementarc% + % + \pgfmathsec@{\halfcomplementarc}% 1/cos((180-a)/2) + \let\sechalfcomplementarc\pgfmathresult% + \pgfmathsin@{\halfcomplementarc}% sin((180-a)/2) + \let\sinhalfcomplementarc\pgfmathresult% + % + \addtosavedmacro\sechalfcomplementarc% + \addtosavedmacro\sinhalfcomplementarc% + % + \pgfmathsin@{\quarterarc}% sin(a/4) + \let\sinquarterarc\pgfmathresult% + \pgfmathcos@{\quarterarc}% cos(a/4) + \let\cosquarterarc\pgfmathresult% + \pgfmathreciprocal@{\cosquarterarc}% + \pgfmathmultiply@{\pgfmathresult}{\sinquarterarc}% tan(a/4) + \let\tanquarterarc\pgfmathresult% + % + \addtosavedmacro\sinquarterarc% + \addtosavedmacro\cosquarterarc% + \addtosavedmacro\tanquarterarc% + % + } + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + } + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \anchor{center}{\centerpoint} + \anchor{mid}{\midpoint} + \anchor{base}{\basepoint} + \anchor{north}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{\youterradius}}% + }% + \anchor{south}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{0pt}{-\youterradius}}% + }% + \anchor{east}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{\xouterradius}{0pt}}% + }% + \anchor{west}{% + \getradii% + \csname pgf@anchor@cloud@border\endcsname{\pgfqpoint{-\xouterradius}{0pt}}% + }% + \anchor{north west}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x-0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + \anchor{north east}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + \anchor{south west}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x-0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y-0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + \anchor{south east}{% + \getradii% + \pgfextract@process\pgf@sh{% + \pgf@x\xouterradius\relax% + \pgf@x0.707106\pgf@x% + \pgf@y\youterradius\relax% + \pgf@y-0.707106\pgf@y% + }% + \csname pgf@anchor@cloud@border\endcsname{\pgf@sh}% + }% + % + % Each `puff' is a circular arc of length a, drawn using two a/2 + % arcs (a < 180), approximated by Bezier curves. + % Due to TeX rounding errors, it is sometimes necessary to `force' + % the arc to end at a specific point. So... + % + % @article{riskus2006, + % author = {Aleskus Ri\v{s}kus}, + % title = {Approximation of a cubic Bezier curve by circular arcs and vice versa}, + % journal = {Information Technology and Control}, + % year = {2006}, + % volume = {35}, + % number = {4} + % } + % + \backgroundpath{% + {% + \getradii% + % + % Get the start angle. + % + \pgfmathdivide@{\anglestep}{2}% + \pgfmathsubtract@{90}{\pgfmathresult}% + \let\angle\pgfmathresult% + % + % Calculate the first arc point. + % + \pgfextract@process\arcfirstpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + \pgfpathmoveto{\arcfirstpoint}% + \let\arcendpoint\arcfirstpoint% + % + \pgfmathloop% + \ifnum\pgfmathcounter>\puffs\relax% + \else + \let\arcstartpoint\arcendpoint% + % + % Make sure beginning and end of path are exactly the same. + % + \ifnum\pgfmathcounter=\puffs\relax% + \let\arcendpoint\arcfirstpoint% + \else% + \pgfmathadd@{\angle}{\anglestep}% + \let\angle\pgfmathresult% + \pgfextract@process\arcendpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + \fi% + % + % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. + % + \pgf@sh@getcloudpuffparameters% + % + % Get the rotation for the Bezier curve. + % + \pgfmathsubtract@{90}{\quarterarc}% + \pgfmathadd@{\pgfmathresult}{\arcslope}% + \let\arcrotate\pgfmathresult% + \pgfmathsin@{\arcrotate}% + \let\sinarcrotate\pgfmathresult% + \pgfmathcos@{\arcrotate}% + \let\cosarcrotate\pgfmathresult% + % + % Calculate the amount by which to scale the control + % points, in order to approximate an a/2 arc with radius x. + % + \pgf@x\arcradius\relax% + \pgf@x\tanquarterarc\pgf@x% tan(a/4) + \edef\controlscale{\pgfmath@tonumber{\pgf@x}}% + % + % Get the first control point for the first arc (length a/2)... + % + \pgfextract@process\controlone{% + % + % k = 0.552284745 (a `magic' number)... + % + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) + % + % ...scale the control points up... + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + % ...rotate... + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + % ...and shift. + % + \arcstartpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Get the midpoint of the 150� arc. + % + \pgfextract@process\arcmidpoint{% + \pgfextract@process\arcmidpoint{% + \pgf@x-\halfchordlength\relax% + \pgf@y\segmentheight\relax% + }% + \pgfpointadd{\arcstartpoint}{% + \pgfmathrotatepointaround{\arcmidpoint}{\pgfpointorigin}{\arcslope}% + }% + }% + % + % Get the second control point for the first arc (length a/2)... + % + \pgfextract@process\controltwo{% + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y-0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) + % + % ...scale, rotate and shift. + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + \arcmidpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + {% + \pgfsetcornersarced{\pgfpointorigin}% + \pgfpathcurveto{\controlone}{\controltwo}{\arcmidpoint}% + }% + % + % Do the same for the second arc... + % + \pgfmathadd@{\quarterarc}{90}% + \pgfmathadd@{\pgfmathresult}{\arcslope}% + \let\arcrotate\pgfmathresult% + \pgfmathsin@{\arcrotate}% + \let\sinarcrotate\pgfmathresult% + \pgfmathcos@{\arcrotate}% + \let\cosarcrotate\pgfmathresult% + % + % First control point for the second arc... + % + \pgfextract@process\controlone{% + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% k * cos(a/2) + % + % ...scale, rotate and shift. + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + \arcmidpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + % + % Second control point for the second arc. + % + \pgfextract@process\controltwo{% + \pgf@x0.55228475pt\relax% + \pgf@x\sinquarterarc\pgf@x% k * sin(a/2) + \pgf@y-0.55228475pt\relax% + \pgf@y\cosquarterarc\pgf@y% -k * cos(a/2) + % + % ...scale, rotate and shift. + % + \pgf@x\controlscale\pgf@x% + \pgf@y\controlscale\pgf@y% + % + \pgf@xa\cosarcrotate\pgf@x% + \advance\pgf@xa-\sinarcrotate\pgf@y% + \pgf@ya\cosarcrotate\pgf@y% + \advance\pgf@ya\sinarcrotate\pgf@x% + % + \arcendpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfpathcurveto{\controlone}{\controltwo}{\arcendpoint}% + \repeatpgfmathloop% + \pgfpathclose% Phew! + }% + }% + % + % Calculate a point on the border of the cloud. This is a two-stage process: + % + % 1. Locate the correct puff. + % 2. Locate the angle on the circular arc which forms the puff. + % + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Get the inner radii and trig. constants. + % + \getradii% + % + % + % + \ifpgfcloudanchorsuseellipse% + \pgfpointadd{\centerpoint}{% + \pgfpointborderellipse{% + \pgfpoint{\externalx}{\externaly} + }{% + \pgfpoint{\xouterradius}{\youterradius} + }% + }% + \else% + \pgfextract@process\externalpoint{% + \centerpoint% + \advance\pgf@x\externalx\relax% + \advance\pgf@y\externaly\relax% + }% + \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% + \let\externalangle\pgfmathresult% + % + % 1. Locate the correct puff: + % + % Get end angle of the relavent puff arc. + % + \pgfmathdivide@{\anglestep}{2}% + \let\halfanglestep\pgfmathresult% + \pgfmathsubtract@{90}{\halfanglestep}% + \let\endangle\pgfmathresult% + \pgfmathloop% + \pgfmathsubtract@{\endangle}{\anglestep}% + \ifdim\pgfmathresult pt<-\anglestep pt\relax% + \else% + \let\endangle\pgfmathresult% + \repeatpgfmathloop% + \def\angle{0}% + \let\lastangle\angle% + \pgfmathloop% + \pgfmathadd@{\endangle}{\anglestep}% + \let\endangle\pgfmathresult% + % + % Calculate the `miter point'. This is the point between + % each puff, and takes into account the outer sep. + % + \pgfextract@process\miterpoint{% + % + \pgfextract@process\secondpoint{% + \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% + }% + % + \pgfmathadd@{\endangle}{\anglestep}% + \let\angletemp\pgfmathresult% + \pgfextract@process\thirdpoint{% + \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% + }% + % + \pgfmathsubtract@{\endangle}{\anglestep}% + \let\angletemp\pgfmathresult% + \pgfextract@process\firstpoint{% + \pgfpointpolar{+\angletemp}{+\xinnerradius and +\yinnerradius}% + }% + % + \pgfmathanglebetweenpoints{\firstpoint}{\secondpoint}% + \let\anglealpha\pgfmathresult% + \pgfmathanglebetweenpoints{\secondpoint}{\thirdpoint}% + \let\anglebeta\pgfmathresult% + % + \pgfmathsubtract@{\anglebeta}{\anglealpha}% + \pgfmathdivide@{\pgfmathresult}{2}% + \pgfmathadd@{\pgfmathresult}{\halfcomplementarc}% + \pgfmathcosec@{\pgfmathresult}% + \pgf@x\outersep\relax% + \pgf@x\pgfmathresult\pgf@x% + \edef\miterradius{\the\pgf@x}% + % + \pgfmathadd@{\anglealpha}{\anglebeta}% + \pgfmathsubtract@{\pgfmathresult}{180}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\miterangle\pgfmathresult% + \pgfpointadd{\secondpoint}{% + \pgfqpointpolar{\miterangle}{\miterradius}% + }% + }% + % + % Get the angle of the miter point... + % + \pgfmathanglebetweenpoints{\pgfpointorigin}{\miterpoint}% + \let\angle\pgfmathresult% + \ifdim\angle pt<\lastangle pt\relax% Guard against 360� = 0� + \pgfmathadd@{\angle}{360}% + \let\angle\pgfmathresult% + \fi% + \let\lastangle\angle% + % + % ...and see if it is greater than the external point. + % + \ifdim\externalangle pt>\angle pt\relax% + \repeatpgfmathloop% + % + % Get the start angle of the relevant arc and ensure angles are in the range. + % + \pgfmathmod@{\endangle}{360}% + \let\endangle\pgfmathresult% + \pgfmathsubtract@{\endangle}{\anglestep}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\startangle\pgfmathresult% + % + % Now, get the start and end points of the arc. + % + \pgfextract@process\arcstartpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\startangle}{+\xinnerradius and +\yinnerradius}% + }% + }% + \pgfextract@process\arcendpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\endangle}{+\xinnerradius and +\yinnerradius}% + }% + }% + % + % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. + % + \pgf@sh@getcloudpuffparameters% + % + % Hackery, for when an arc straddles 0�. + % + \ifdim\endangle pt<\startangle pt\relax% + \pgfmathadd@{\externalangle}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\x\pgfmathresult% + \else% + \let\x\externalangle% + \fi% + % + % 2. Locate the angle on the circular arc which forms the puff. + % + % Essentially a binary search to find the angle on the circular + % arc, which provides the nearset estimate to the border point. + % + \let\s\halfcomplementarc% The start of the arc. + \pgfmathadd@{\s}{\arc}% + \let\e\pgfmathresult% The end of the arc. + \pgfmathadd@{\e}{\s}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\n\pgfmathresult% The nearest estimate (default to middle of arc). + \def\m{360}% Measure of `nearness'. + \pgfmathloop% + \pgfmathadd@{\e}{\s}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\p\pgfmathresult% The point halfway between \s and \e. + \ifdim\p pt=\s pt\relax% + \else% + % + % Get the point on the circular arc. + % + \pgfmathadd@{\p}{\arcslope}% + \let\a\pgfmathresult% + \pgfextract@process\arcpoint{% + \pgfpointadd{\circlecenterpoint}{% + \pgfqpointpolar{\a}{\outerarcradius}% + }% + }% + % + % Find the angle between the node centre and the point on the arc. + % + \pgfmathanglebetweenpoints{\centerpoint}{\arcpoint}% + % + % Hackery, for when an arc straddles 0�. + % + \ifdim\endangle pt<\startangle pt\relax% + \pgfmathadd@{\pgfmathresult}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \fi% + \let\q\pgfmathresult% + \ifdim\x pt=\q pt% Found it! + \pgfmathbreakloop% Breaks after current iteration is complete. + \else + \ifdim\x pt<\q pt\relax% + \let\e\p% + \else% + \let\s\p% + \fi% + \fi% + \pgfmathsubtract@{\x}{\q}% + \pgfmathabs@{\pgfmathresult}% + % + % Save the estimate if it is better than any previous estimate. + % + \ifdim\pgfmathresult pt<\m pt\relax% + \let\m\pgfmathresult% + \let\n\p% + \fi% + \repeatpgfmathloop% + % + % Use the nearest estimate as the anchor angle. + % + \pgfmathadd@{\n}{\arcslope}% + \let\anchorangle\pgfmathresult% + % + % Finally, the required point. + % + \pgfpointadd{\circlecenterpoint}{% + \pgfqpointpolar{\anchorangle}{\outerarcradius}% + }% + \fi% + }% Again, Phew! + % + % Now, a sneaky hack. This means an arbitrary `puff' anchors + % can be used for positiong the cloud shape. This is needed + % if a cloud is positioned using the `puff ' anchor, where + % n is the number of puffs of any previously drawn cloud. + % + \pgfutil@g@addto@macro\pgf@sh@s@cloud{% + \c@pgf@counta\puffs\relax% + \pgfmathloop% + \ifnum\c@pgf@counta>0\relax% + \pgfutil@ifundefined{pgf@anchor@cloud@puff\space\the\c@pgf@counta}{% + \expandafter\xdef\csname pgf@anchor@cloud@puff\space\the\c@pgf@counta\endcsname{% + \noexpand\pgf@sh@@cloudpuffanchor{\the\c@pgf@counta}% + }% + }{\c@pgf@counta0\relax}% + \advance\c@pgf@counta-1\relax% + \repeatpgfmathloop% + }% } % \pgf@sh@@cloudpuffanchor @@ -1286,43 +1328,43 @@ % Internal macro for calculating the anchors puff 1, puff 2, ... etc. % \def\pgf@sh@@cloudpuffanchor#1{% - \getradii% - \pgfmathdivide@{\anglestep}{2}% - \let\halfanglestep\pgfmathresult% - \c@pgf@counta#1\relax% - \advance\c@pgf@counta-1\relax% - \pgfmathmultiply@{\anglestep}{\the\c@pgf@counta}% - \pgfmathadd@{\pgfmathresult}{90}% - \pgfmathsubtract@{\pgfmathresult}{\halfanglestep}% - \let\angle\pgfmathresult% - % - % Calculate the first arc point. - % - \pgfextract@process\arcstartpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - % - \pgfmathadd@{\angle}{\anglestep}% - \let\angle\pgfmathresult% - \pgfextract@process\arcendpoint{% - \pgfpointadd{\centerpoint}{% - \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% - }% - }% - % - % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. - % - \pgf@sh@getcloudpuffparameters% - % - % Calculate the point. - % - \pgfmathadd@{\arcslope}{90}% - \let\anchorangle\pgfmathresult% - \pgfpointadd{\circlecenterpoint}{% - \pgfqpointpolar{\anchorangle}{\outerarcradius}% - }% + \getradii% + \pgfmathdivide@{\anglestep}{2}% + \let\halfanglestep\pgfmathresult% + \c@pgf@counta#1\relax% + \advance\c@pgf@counta-1\relax% + \pgfmathmultiply@{\anglestep}{\the\c@pgf@counta}% + \pgfmathadd@{\pgfmathresult}{90}% + \pgfmathsubtract@{\pgfmathresult}{\halfanglestep}% + \let\angle\pgfmathresult% + % + % Calculate the first arc point. + % + \pgfextract@process\arcstartpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + % + \pgfmathadd@{\angle}{\anglestep}% + \let\angle\pgfmathresult% + \pgfextract@process\arcendpoint{% + \pgfpointadd{\centerpoint}{% + \pgfpointpolar{+\angle}{+\xinnerradius and +\yinnerradius}% + }% + }% + % + % Get some useful cloud parameters from \arcstartpoint and \arcendpoint. + % + \pgf@sh@getcloudpuffparameters% + % + % Calculate the point. + % + \pgfmathadd@{\arcslope}{90}% + \let\anchorangle\pgfmathresult% + \pgfpointadd{\circlecenterpoint}{% + \pgfqpointpolar{\anchorangle}{\outerarcradius}% + }% } % \pgf@sh@cloudpuffparameters @@ -1333,11 +1375,11 @@ % \def\pgf@sh@getcloudpuffparameters{% % - % Calculate the angle to which the entire arc is sloped. - % - \pgfmathanglebetweenpoints{\arcendpoint}{\arcstartpoint}% - \let\arcslope\pgfmathresult% - % + % Calculate the angle to which the entire arc is sloped. + % + \pgfmathanglebetweenpoints{\arcendpoint}{\arcstartpoint}% + \let\arcslope\pgfmathresult% + % % Calculate the chord length and arc radius. % \pgfpointdiff{\arcendpoint}{\arcstartpoint}% @@ -1345,7 +1387,7 @@ \pgf@x\pgfmathresult pt\relax% \pgf@xa.5\pgf@x% \edef\halfchordlength{\the\pgf@xa}% - \pgf@x\arcradiusquotient\pgf@x% + \pgf@x\arcradiusquotient\pgf@x% \edef\arcradius{\the\pgf@x}% \pgf@xa\outersep\relax% \advance\pgf@xa\pgf@x% @@ -1382,671 +1424,671 @@ \def\pgf@lib@sh@signal@to{to}% \def\pgf@lib@sh@signal@parsedirection#1#2{% - % - \let\pgf@lib@sh@signal@direction=#2% - \edef\pgf@lib@sh@temp{#1}% - \expandafter\pgf@lib@sh@signal@@parsedirection\pgf@lib@sh@temp\pgf@stop} + % + \let\pgf@lib@sh@signal@direction=#2% + \edef\pgf@lib@sh@temp{#1}% + \expandafter\pgf@lib@sh@signal@@parsedirection\pgf@lib@sh@temp\pgf@stop} \def\pgf@lib@sh@signal@@parsedirection#1\pgf@stop{% - \pgfutil@in@{and}{#1}% - \ifpgfutil@in@% - \pgf@lib@sh@signal@@@parsedirection#1\pgf@lib% - \else% - \pgf@lib@sh@signal@@@parsedirection#1 and #1\pgf@lib% - \fi + \pgfutil@in@{and}{#1}% + \ifpgfutil@in@% + \pgf@lib@sh@signal@@@parsedirection#1\pgf@lib% + \else% + \pgf@lib@sh@signal@@@parsedirection#1 and #1\pgf@lib% + \fi } \def\pgf@lib@sh@signal@@@parsedirection#1 and #2\pgf@lib{% - \pgfutil@in@{nowhere}{#1}% - \ifpgfutil@in@ - \else% - \pgf@lib@sh@signal@@@@parsedirection{#1}% - \pgf@lib@sh@signal@@@@parsedirection{#2}% - \fi% + \pgfutil@in@{nowhere}{#1}% + \ifpgfutil@in@ + \else% + \pgf@lib@sh@signal@@@@parsedirection{#1}% + \pgf@lib@sh@signal@@@@parsedirection{#2}% + \fi% } \def\pgf@lib@sh@signal@@@@parsedirection#1{% - \pgfutil@in@{ #1 }{ east right }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% - \fi% - \pgfutil@in@{ #1 }{ left west }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% - \fi% - \pgfutil@in@{ #1 }{ above up north }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% - \fi% - \pgfutil@in@{ #1 }{ below down south }% - \ifpgfutil@in@% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@direction% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% - \fi% + \pgfutil@in@{ #1 }{ east right }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% + \fi% + \pgfutil@in@{ #1 }{ left west }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% + \fi% + \pgfutil@in@{ #1 }{ above up north }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% + \fi% + \pgfutil@in@{ #1 }{ below down south }% + \ifpgfutil@in@% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@direction% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% + \fi% } % Keys for signal shape: % \pgfkeys{/pgf/.cd, - signal pointer angle/.initial=90, - signal to/.initial=east, - signal from/.initial=nowhere + signal pointer angle/.initial=90, + signal to/.initial=east, + signal from/.initial=nowhere } \pgfdeclareshape{signal}{% - \savedmacro\installsignalparameters{% - % - \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% - \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% - % - \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal from}}{\pgf@lib@sh@signal@from}% - \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal to}}{\pgf@lib@sh@signal@to}% - % - % Define a centerpoint. - % - \pgfextract@process\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - }% - % - % Get some useful trig. stuff - % - \pgfmathsetmacro\pointerangle{\pgfkeysvalueof{/pgf/signal pointer angle}}% - % - \pgfmathdivide@{\pointerangle}{2}% - \let\halfpointerangle=\pgfmathresult% - % - \pgfmathcosec@{\halfpointerangle}% - \let\cosechalfpointerangle=\pgfmathresult% - % - \pgfmathdivide@{\halfpointerangle}{2}% - \let\quarterpointerangle=\pgfmathresult% - % - \pgfmathcosec@{\quarterpointerangle}% - \let\cosecquarterpointerangle=\pgfmathresult% - % - \pgfmathsec@{\quarterpointerangle}% - \let\secquarterpointerangle=\pgfmathresult% - % - \pgfmathsubtract@{90}{\quarterpointerangle}% - \let\complementquarterpointerangle\pgfmathresult% - % - % Get the larger of the outer sep. - % - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@x>\pgf@y% - \pgf@y\pgf@x% - \fi% - \pgf@yc=\pgf@y% - % - % Calculate the miter due to the line width, at the pointer apex... - % - \pgf@x=\cosechalfpointerangle\pgf@y% - \edef\pointerapexmiter{\the\pgf@x}% - % - % ...at a corner by a `to' pointer (i.e. sticks out)... - % - \pgf@x=\secquarterpointerangle\pgf@y% - \edef\tocornermiter{\the\pgf@x}% - % - % ...at a corner by a `from' pointer (i.e. sticks in). - % - \pgf@x=\cosecquarterpointerangle\pgf@y - \edef\fromcornermiter{\the\pgf@x}% - % - % Get the (half) dimensions of the node. - % - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \advance\pgf@xa.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}% - \advance\pgf@ya.5\ht\pgfnodeparttextbox% - \advance\pgf@ya.5\dp\pgfnodeparttextbox% - % - % Get the distance a pointer sticks out to the side... - % - \pgfmathsubtract@{90}{\halfpointerangle}% - \pgfmathtan@{\pgfmathresult}% - \pgf@xb=\pgfmathresult\pgf@ya% - % - % ...and up. - % - \pgf@yb=\pgfmathresult\pgf@xa% - % - % Adjust for minimum height. - % - \pgfutil@tempdima=2.0\pgf@ya% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@yb% - \fi% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgfutil@tempdima<\pgf@y% - \pgfutil@tempdima=\pgf@y% - % - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@yb% - \fi% - \pgf@ya=0.5\pgfutil@tempdima% - \pgfmathsubtract@{90}{\halfpointerangle}% - \pgfmathtan@{\pgfmathresult}% - \pgf@xb=\pgfmathresult\pgf@ya% - \fi% - % - % Adjust for minimum width. - % - \pgfutil@tempdima=2.0\pgf@xa% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@xb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by\pgf@xb% - \fi% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}% - \ifdim\pgfutil@tempdima<\pgf@x% - \pgfutil@tempdima=\pgf@x% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@xb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \else% - \advance\pgfutil@tempdima by-\pgf@xb% - \fi% - \pgf@xa=0.5\pgfutil@tempdima% - \pgfmathsubtract@{90}{\halfpointerangle}% - \pgfmathtan@{\pgfmathresult}% - \pgf@yb=\pgfmathresult\pgf@xa% - \fi% - % - % So, define the points for the background path. - % - \pgfextract@process\north{% - \centerpoint% - \advance\pgf@y\pgf@ya% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% - \advance\pgf@y\pgf@yb% - \fi% - }% - \pgfextract@process\south{% - \centerpoint% - \advance\pgf@y-\pgf@ya% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% - \advance\pgf@y-\pgf@yb% - \fi% - }% - \pgfextract@process\east{% - \centerpoint% - \advance\pgf@x\pgf@xa% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% - \advance\pgf@x\pgf@xb% - \fi% - }% - \pgfextract@process\west{% - \centerpoint% - \advance\pgf@x-\pgf@xa% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \advance\pgf@x-\pgf@xb% - \fi% - }% - \pgfextract@process\northeast{% - \centerpoint% - \advance\pgf@y\pgf@ya% - \advance\pgf@x\pgf@xa% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \advance\pgf@y\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \advance\pgf@x\pgf@xb% - \fi% - }% - \pgfextract@process\southeast{% - \centerpoint% - \advance\pgf@y-\pgf@ya% - \advance\pgf@x\pgf@xa% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \advance\pgf@y-\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \advance\pgf@x\pgf@xb% - \fi% - }% - \pgfextract@process\southwest{% - \centerpoint% - \advance\pgf@y-\pgf@ya% - \advance\pgf@x-\pgf@xa% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \advance\pgf@y-\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \advance\pgf@x-\pgf@xb% - \fi% - }% - \pgfextract@process\northwest{% - \centerpoint% - \advance\pgf@y\pgf@ya% - \advance\pgf@x-\pgf@xa% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \advance\pgf@y\pgf@yb% - \fi% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \advance\pgf@x-\pgf@xb% - \fi% - }% - \addtosavedmacro{\north}% - \addtosavedmacro{\south}% - \addtosavedmacro{\east}% - \addtosavedmacro{\west}% - \addtosavedmacro{\northeast}% - \addtosavedmacro{\southwest}% - \addtosavedmacro{\southeast}% - \addtosavedmacro{\northwest}% - % - % Calculate the `miter vectors' (i.e. +outer sep). - % - \pgfextract@process\northmiter{% - \pgf@x0pt% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% - \pgf@y\pgf@yc% - \else% - \pgf@y\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\southmiter{% - \pgf@x0pt% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% - \pgf@y-\pgf@yc% - \else% - \pgf@y-\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\eastmiter{% - \pgf@y0pt% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \pgf@x\pgf@yc% - \else% - \pgf@x\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\westmiter{% - \pgf@y0pt% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \pgf@x-\pgf@yc% - \else% - \pgf@x-\pointerapexmiter\relax% - \fi% - }% - \pgfextract@process\northeastmiter{% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \pgf@x\pgf@yc - \pgf@y\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \pgfqpointpolar{\quarterpointerangle}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% - \pgfqpointpolar{\complementquarterpointerangle}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \pgfqpointpolar{\complementquarterpointerangle}{\fromcornermiter}% - \else% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% - \pgfqpointpolar{\quarterpointerangle}{\tocornermiter}% - \fi% - \fi% - }% - \pgfextract@process\southeastmiter{% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% - \pgf@x\pgf@yc% - \pgf@y\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% - \pgfqpointpolar{-\quarterpointerangle}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% - \pgfqpointpolar{-\complementquarterpointerangle}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \pgfqpointpolar{-\complementquarterpointerangle}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% - \pgfqpointpolar{-\quarterpointerangle}{\tocornermiter}% - \fi% - \fi% - }% - \pgfextract@process\southwestmiter{% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \pgf@x-\pgf@yc - \pgf@y-\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \pgfmathadd@{\quarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \pgfmathadd@{\complementquarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% - \pgfmathadd@{\complementquarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% - \else% - \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% - \pgfmathadd@{\quarterpointerangle}{180}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - }% - \pgfextract@process\northwestmiter{% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% - \pgf@x-\pgf@yc% - \pgf@y\pgf@yc% - \else - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% - \pgfmathsubtract@{180}{\quarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} - \else% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \pgfmathsubtract@{180}{\complementquarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - \fi% - \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% - \pgfmathsubtract@{180}{\complementquarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% - \else% - \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% - \pgfmathsubtract@{180}{\quarterpointerangle}% - \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% - \fi% - \fi% - }% - \addtosavedmacro{\northmiter}% - \addtosavedmacro{\southmiter}% - \addtosavedmacro{\eastmiter}% - \addtosavedmacro{\westmiter}% - \addtosavedmacro{\northeastmiter}% - \addtosavedmacro{\southeastmiter}% - \addtosavedmacro{\southwestmiter}% - \addtosavedmacro{\northwestmiter}% - % - % Now calculate the anchor points - % - \pgfextract@process\anchornorth{% - \pgfpointadd{\north}{\northmiter}% - }% - \pgfextract@process\anchorsouth{% - \pgfpointadd{\south}{\southmiter}% - }% - \pgfextract@process\anchoreast{% - \pgfpointadd{\east}{\eastmiter}% - }% - \pgfextract@process\anchorwest{% - \pgfpointadd{\west}{\westmiter}% - }% - \pgfextract@process\anchornortheast{% - \pgfpointadd{\northeast}{\northeastmiter}% - }% - \pgfextract@process\anchorsoutheast{% - \pgfpointadd{\southeast}{\southeastmiter}% - }% - \pgfextract@process\anchorsouthwest{% - \pgfpointadd{\southwest}{\southwestmiter}% - }% - \pgfextract@process\anchornorthwest{% - \pgfpointadd{\northwest}{\northwestmiter}% - }% - \addtosavedmacro{\anchornorth}% - \addtosavedmacro{\anchorsouth}% - \addtosavedmacro{\anchoreast}% - \addtosavedmacro{\anchorwest}% - \addtosavedmacro{\anchornortheast}% - \addtosavedmacro{\anchorsouthwest}% - \addtosavedmacro{\anchorsoutheast}% - \addtosavedmacro{\anchornorthwest}% - }% - \savedanchor\centerpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - }% - \savedanchor\basepoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - }% - \savedanchor\midpoint{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+.5ex}% - }% - \anchor{center}{\centerpoint}% - \anchor{base}{\basepoint}% - \anchor{base east}{% - \installsignalparameters% - \anchoreast% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsoutheast% - \ifdim\pgf@xa>\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \basepoint% - \pgf@x\pgfutil@tempdima% - } - \basepoint% - \let\firstpoint\anchoreast% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsoutheast% - \else% - \let\secondpoint\anchornortheast% - \fi% - \pgfpointintersectionoflines{\basepoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{base west}{% - \installsignalparameters% - \anchorwest% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsouthwest% - \ifdim\pgf@xa<\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \basepoint% - \pgf@x\pgfutil@tempdima% - } - \basepoint% - \let\firstpoint\anchorwest% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsouthwest% - \else% - \let\secondpoint\anchornorthwest% - \fi% - \pgfpointintersectionoflines{\basepoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{mid}{\midpoint}% - \anchor{mid east}{% - \installsignalparameters% - \anchoreast% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsoutheast% - \ifdim\pgf@xa>\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \midpoint% - \pgf@x\pgfutil@tempdima% - } - \midpoint% - \let\firstpoint\anchoreast% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsoutheast% - \else% - \let\secondpoint\anchornortheast% - \fi% - \pgfpointintersectionoflines{\midpoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{mid west}{% - \installsignalparameters% - \anchorwest% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \anchorsouthwest% - \ifdim\pgf@xa<\pgf@x% - \pgfutil@tempdima\pgf@xa% - \else% - \pgfutil@tempdima\pgf@x% - \fi% - \pgfextract@process\externalpoint{% - \midpoint% - \pgf@x\pgfutil@tempdima% - } - \midpoint% - \let\firstpoint\anchorwest% - \ifdim\pgf@y<\pgf@ya% - \let\secondpoint\anchorsouthwest% - \else% - \let\secondpoint\anchornorthwest% - \fi% - \pgfpointintersectionoflines{\midpoint}{\externalpoint}% - {\firstpoint}{\secondpoint}% - }% - \anchor{north}{\installsignalparameters\anchornorth}% - \anchor{south}{\installsignalparameters\anchorsouth}% - \anchor{east}{\installsignalparameters\anchoreast}% - \anchor{west}{\installsignalparameters\anchorwest}% - \anchor{north east}{\installsignalparameters\anchornortheast}% - \anchor{south east}{\installsignalparameters\anchorsoutheast}% - \anchor{south west}{\installsignalparameters\anchorsouthwest}% - \anchor{north west}{\installsignalparameters\anchornorthwest}% - \backgroundpath{% - \installsignalparameters% - \pgfpathmoveto{\north}% - \pgfpathlineto{\northeast}% - \pgfpathlineto{\east}% - \pgfpathlineto{\southeast}% - \pgfpathlineto{\south}% - \pgfpathlineto{\southwest}% - \pgfpathlineto{\west}% - \pgfpathlineto{\northwest}% - \pgfpathclose% - } - \anchorborder{% - % - % Save x and y. - % - \edef\externalx{\the\pgf@x}% - \edef\externaly{\the\pgf@y}% - % - % Adjust the location of the external - % point relative to \centerpoint. - % - \centerpoint% - \pgf@xa\externalx\relax% - \pgf@ya\externaly\relax% - \advance\pgf@xa\pgf@x% - \advance\pgf@ya\pgf@y% - \edef\externalx{\the\pgf@xa}% - \edef\externaly{\the\pgf@ya}% - % - % Get the shape parameters. - % - \installsignalparameters% - % - % Get the angle of the external point to the \centerpoint. - % - \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - \let\externalangle\pgfmathresult% - % - % - % - \pgfmathanglebetweenpoints{\centerpoint}{\anchorwest}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \pgfmathanglebetweenpoints{\centerpoint}{\anchornorth}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \pgfmathanglebetweenpoints{\centerpoint}{\anchornortheast}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchoreast% - \let\secondpoint\anchornortheast% - \else% - \let\secondpoint\anchornortheast% - \let\firstpoint\anchornorth% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\anchornorthwest}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchornorth% - \let\secondpoint\anchornorthwest% - \else% - \let\secondpoint\anchornorthwest% - \let\firstpoint\anchorwest% - \fi% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouth}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouthwest}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchorwest% - \let\secondpoint\anchorsouthwest% - \else% - \let\secondpoint\anchorsouthwest% - \let\firstpoint\anchorsouth% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\anchorsoutheast}% - \ifdim\externalangle pt<\pgfmathresult pt\relax% - \let\firstpoint\anchorsouth% - \let\secondpoint\anchorsoutheast% - \else% - \let\secondpoint\anchorsoutheast% - \let\firstpoint\anchoreast% - \fi% - \fi% - \fi% - % - % Now locate the point. - % - \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% - {\firstpoint}{\secondpoint}% - }% + \savedmacro\installsignalparameters{% + % + \let\pgf@lib@sh@signal@north=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@south=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@east=\pgf@lib@sh@signal@nowhere% + \let\pgf@lib@sh@signal@west=\pgf@lib@sh@signal@nowhere% + % + \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal from}}{\pgf@lib@sh@signal@from}% + \pgf@lib@sh@signal@parsedirection{\pgfkeysvalueof{/pgf/signal to}}{\pgf@lib@sh@signal@to}% + % + % Define a centerpoint. + % + \pgfextract@process\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + % + % Get some useful trig. stuff + % + \pgfmathsetmacro\pointerangle{\pgfkeysvalueof{/pgf/signal pointer angle}}% + % + \pgfmathdivide@{\pointerangle}{2}% + \let\halfpointerangle=\pgfmathresult% + % + \pgfmathcosec@{\halfpointerangle}% + \let\cosechalfpointerangle=\pgfmathresult% + % + \pgfmathdivide@{\halfpointerangle}{2}% + \let\quarterpointerangle=\pgfmathresult% + % + \pgfmathcosec@{\quarterpointerangle}% + \let\cosecquarterpointerangle=\pgfmathresult% + % + \pgfmathsec@{\quarterpointerangle}% + \let\secquarterpointerangle=\pgfmathresult% + % + \pgfmathsubtract@{90}{\quarterpointerangle}% + \let\complementquarterpointerangle\pgfmathresult% + % + % Get the larger of the outer sep. + % + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@x>\pgf@y% + \pgf@y\pgf@x% + \fi% + \pgf@yc=\pgf@y% + % + % Calculate the miter due to the line width, at the pointer apex... + % + \pgf@x=\cosechalfpointerangle\pgf@y% + \edef\pointerapexmiter{\the\pgf@x}% + % + % ...at a corner by a `to' pointer (i.e. sticks out)... + % + \pgf@x=\secquarterpointerangle\pgf@y% + \edef\tocornermiter{\the\pgf@x}% + % + % ...at a corner by a `from' pointer (i.e. sticks in). + % + \pgf@x=\cosecquarterpointerangle\pgf@y + \edef\fromcornermiter{\the\pgf@x}% + % + % Get the (half) dimensions of the node. + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@xa.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@ya.5\ht\pgfnodeparttextbox% + \advance\pgf@ya.5\dp\pgfnodeparttextbox% + % + % Get the distance a pointer sticks out to the side... + % + \pgfmathsubtract@{90}{\halfpointerangle}% + \pgfmathtan@{\pgfmathresult}% + \pgf@xb=\pgfmathresult\pgf@ya% + % + % ...and up. + % + \pgf@yb=\pgfmathresult\pgf@xa% + % + % Adjust for minimum height. + % + \pgfutil@tempdima=2.0\pgf@ya% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@yb% + \fi% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgfutil@tempdima<\pgf@y% + \pgfutil@tempdima=\pgf@y% + % + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@yb% + \fi% + \pgf@ya=0.5\pgfutil@tempdima% + \pgfmathsubtract@{90}{\halfpointerangle}% + \pgfmathtan@{\pgfmathresult}% + \pgf@xb=\pgfmathresult\pgf@ya% + \fi% + % + % Adjust for minimum width. + % + \pgfutil@tempdima=2.0\pgf@xa% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@xb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by\pgf@xb% + \fi% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/minimum width}}% + \ifdim\pgfutil@tempdima<\pgf@x% + \pgfutil@tempdima=\pgf@x% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \else% + \advance\pgfutil@tempdima by-\pgf@xb% + \fi% + \pgf@xa=0.5\pgfutil@tempdima% + \pgfmathsubtract@{90}{\halfpointerangle}% + \pgfmathtan@{\pgfmathresult}% + \pgf@yb=\pgfmathresult\pgf@xa% + \fi% + % + % So, define the points for the background path. + % + \pgfextract@process\north{% + \centerpoint% + \advance\pgf@y\pgf@ya% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% + \advance\pgf@y\pgf@yb% + \fi% + }% + \pgfextract@process\south{% + \centerpoint% + \advance\pgf@y-\pgf@ya% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% + \advance\pgf@y-\pgf@yb% + \fi% + }% + \pgfextract@process\east{% + \centerpoint% + \advance\pgf@x\pgf@xa% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% + \advance\pgf@x\pgf@xb% + \fi% + }% + \pgfextract@process\west{% + \centerpoint% + \advance\pgf@x-\pgf@xa% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \advance\pgf@x-\pgf@xb% + \fi% + }% + \pgfextract@process\northeast{% + \centerpoint% + \advance\pgf@y\pgf@ya% + \advance\pgf@x\pgf@xa% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \advance\pgf@y\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \advance\pgf@x\pgf@xb% + \fi% + }% + \pgfextract@process\southeast{% + \centerpoint% + \advance\pgf@y-\pgf@ya% + \advance\pgf@x\pgf@xa% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \advance\pgf@y-\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \advance\pgf@x\pgf@xb% + \fi% + }% + \pgfextract@process\southwest{% + \centerpoint% + \advance\pgf@y-\pgf@ya% + \advance\pgf@x-\pgf@xa% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \advance\pgf@y-\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \advance\pgf@x-\pgf@xb% + \fi% + }% + \pgfextract@process\northwest{% + \centerpoint% + \advance\pgf@y\pgf@ya% + \advance\pgf@x-\pgf@xa% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \advance\pgf@y\pgf@yb% + \fi% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \advance\pgf@x-\pgf@xb% + \fi% + }% + \addtosavedmacro{\north}% + \addtosavedmacro{\south}% + \addtosavedmacro{\east}% + \addtosavedmacro{\west}% + \addtosavedmacro{\northeast}% + \addtosavedmacro{\southwest}% + \addtosavedmacro{\southeast}% + \addtosavedmacro{\northwest}% + % + % Calculate the `miter vectors' (i.e. +outer sep). + % + \pgfextract@process\northmiter{% + \pgf@x0pt% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@nowhere% + \pgf@y\pgf@yc% + \else% + \pgf@y\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\southmiter{% + \pgf@x0pt% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@nowhere% + \pgf@y-\pgf@yc% + \else% + \pgf@y-\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\eastmiter{% + \pgf@y0pt% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \pgf@x\pgf@yc% + \else% + \pgf@x\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\westmiter{% + \pgf@y0pt% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \pgf@x-\pgf@yc% + \else% + \pgf@x-\pointerapexmiter\relax% + \fi% + }% + \pgfextract@process\northeastmiter{% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \pgf@x\pgf@yc + \pgf@y\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \pgfqpointpolar{\quarterpointerangle}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% + \pgfqpointpolar{\complementquarterpointerangle}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \pgfqpointpolar{\complementquarterpointerangle}{\fromcornermiter}% + \else% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@to% + \pgfqpointpolar{\quarterpointerangle}{\tocornermiter}% + \fi% + \fi% + }% + \pgfextract@process\southeastmiter{% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@nowhere% + \pgf@x\pgf@yc% + \pgf@y\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@from% + \pgfqpointpolar{-\quarterpointerangle}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@east\pgf@lib@sh@signal@to% + \pgfqpointpolar{-\complementquarterpointerangle}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \pgfqpointpolar{-\complementquarterpointerangle}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% + \pgfqpointpolar{-\quarterpointerangle}{\tocornermiter}% + \fi% + \fi% + }% + \pgfextract@process\southwestmiter{% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \pgf@x-\pgf@yc + \pgf@y-\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \pgfmathadd@{\quarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \pgfmathadd@{\complementquarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@from% + \pgfmathadd@{\complementquarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% + \else% + \ifx\pgf@lib@sh@signal@south\pgf@lib@sh@signal@to% + \pgfmathadd@{\quarterpointerangle}{180}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + }% + \pgfextract@process\northwestmiter{% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@nowhere% + \pgf@x-\pgf@yc% + \pgf@y\pgf@yc% + \else + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@from% + \pgfmathsubtract@{180}{\quarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter} + \else% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \pgfmathsubtract@{180}{\complementquarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + \fi% + \ifx\pgf@lib@sh@signal@north\pgf@lib@sh@signal@from% + \pgfmathsubtract@{180}{\complementquarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\fromcornermiter}% + \else% + \ifx\pgf@lib@sh@signal@west\pgf@lib@sh@signal@to% + \pgfmathsubtract@{180}{\quarterpointerangle}% + \expandafter\pgfqpointpolar\expandafter{\pgfmathresult}{\tocornermiter}% + \fi% + \fi% + }% + \addtosavedmacro{\northmiter}% + \addtosavedmacro{\southmiter}% + \addtosavedmacro{\eastmiter}% + \addtosavedmacro{\westmiter}% + \addtosavedmacro{\northeastmiter}% + \addtosavedmacro{\southeastmiter}% + \addtosavedmacro{\southwestmiter}% + \addtosavedmacro{\northwestmiter}% + % + % Now calculate the anchor points + % + \pgfextract@process\anchornorth{% + \pgfpointadd{\north}{\northmiter}% + }% + \pgfextract@process\anchorsouth{% + \pgfpointadd{\south}{\southmiter}% + }% + \pgfextract@process\anchoreast{% + \pgfpointadd{\east}{\eastmiter}% + }% + \pgfextract@process\anchorwest{% + \pgfpointadd{\west}{\westmiter}% + }% + \pgfextract@process\anchornortheast{% + \pgfpointadd{\northeast}{\northeastmiter}% + }% + \pgfextract@process\anchorsoutheast{% + \pgfpointadd{\southeast}{\southeastmiter}% + }% + \pgfextract@process\anchorsouthwest{% + \pgfpointadd{\southwest}{\southwestmiter}% + }% + \pgfextract@process\anchornorthwest{% + \pgfpointadd{\northwest}{\northwestmiter}% + }% + \addtosavedmacro{\anchornorth}% + \addtosavedmacro{\anchorsouth}% + \addtosavedmacro{\anchoreast}% + \addtosavedmacro{\anchorwest}% + \addtosavedmacro{\anchornortheast}% + \addtosavedmacro{\anchorsouthwest}% + \addtosavedmacro{\anchorsoutheast}% + \addtosavedmacro{\anchornorthwest}% + }% + \savedanchor\centerpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + }% + \savedanchor\basepoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + }% + \savedanchor\midpoint{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+.5ex}% + }% + \anchor{center}{\centerpoint}% + \anchor{base}{\basepoint}% + \anchor{base east}{% + \installsignalparameters% + \anchoreast% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsoutheast% + \ifdim\pgf@xa>\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \basepoint% + \pgf@x\pgfutil@tempdima% + } + \basepoint% + \let\firstpoint\anchoreast% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsoutheast% + \else% + \let\secondpoint\anchornortheast% + \fi% + \pgfpointintersectionoflines{\basepoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{base west}{% + \installsignalparameters% + \anchorwest% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsouthwest% + \ifdim\pgf@xa<\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \basepoint% + \pgf@x\pgfutil@tempdima% + } + \basepoint% + \let\firstpoint\anchorwest% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsouthwest% + \else% + \let\secondpoint\anchornorthwest% + \fi% + \pgfpointintersectionoflines{\basepoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{mid}{\midpoint}% + \anchor{mid east}{% + \installsignalparameters% + \anchoreast% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsoutheast% + \ifdim\pgf@xa>\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \midpoint% + \pgf@x\pgfutil@tempdima% + } + \midpoint% + \let\firstpoint\anchoreast% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsoutheast% + \else% + \let\secondpoint\anchornortheast% + \fi% + \pgfpointintersectionoflines{\midpoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{mid west}{% + \installsignalparameters% + \anchorwest% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \anchorsouthwest% + \ifdim\pgf@xa<\pgf@x% + \pgfutil@tempdima\pgf@xa% + \else% + \pgfutil@tempdima\pgf@x% + \fi% + \pgfextract@process\externalpoint{% + \midpoint% + \pgf@x\pgfutil@tempdima% + } + \midpoint% + \let\firstpoint\anchorwest% + \ifdim\pgf@y<\pgf@ya% + \let\secondpoint\anchorsouthwest% + \else% + \let\secondpoint\anchornorthwest% + \fi% + \pgfpointintersectionoflines{\midpoint}{\externalpoint}% + {\firstpoint}{\secondpoint}% + }% + \anchor{north}{\installsignalparameters\anchornorth}% + \anchor{south}{\installsignalparameters\anchorsouth}% + \anchor{east}{\installsignalparameters\anchoreast}% + \anchor{west}{\installsignalparameters\anchorwest}% + \anchor{north east}{\installsignalparameters\anchornortheast}% + \anchor{south east}{\installsignalparameters\anchorsoutheast}% + \anchor{south west}{\installsignalparameters\anchorsouthwest}% + \anchor{north west}{\installsignalparameters\anchornorthwest}% + \backgroundpath{% + \installsignalparameters% + \pgfpathmoveto{\north}% + \pgfpathlineto{\northeast}% + \pgfpathlineto{\east}% + \pgfpathlineto{\southeast}% + \pgfpathlineto{\south}% + \pgfpathlineto{\southwest}% + \pgfpathlineto{\west}% + \pgfpathlineto{\northwest}% + \pgfpathclose% + } + \anchorborder{% + % + % Save x and y. + % + \edef\externalx{\the\pgf@x}% + \edef\externaly{\the\pgf@y}% + % + % Adjust the location of the external + % point relative to \centerpoint. + % + \centerpoint% + \pgf@xa\externalx\relax% + \pgf@ya\externaly\relax% + \advance\pgf@xa\pgf@x% + \advance\pgf@ya\pgf@y% + \edef\externalx{\the\pgf@xa}% + \edef\externaly{\the\pgf@ya}% + % + % Get the shape parameters. + % + \installsignalparameters% + % + % Get the angle of the external point to the \centerpoint. + % + \pgfmathanglebetweenpoints{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + \let\externalangle\pgfmathresult% + % + % + % + \pgfmathanglebetweenpoints{\centerpoint}{\anchorwest}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\centerpoint}{\anchornorth}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\centerpoint}{\anchornortheast}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchoreast% + \let\secondpoint\anchornortheast% + \else% + \let\secondpoint\anchornortheast% + \let\firstpoint\anchornorth% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\anchornorthwest}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchornorth% + \let\secondpoint\anchornorthwest% + \else% + \let\secondpoint\anchornorthwest% + \let\firstpoint\anchorwest% + \fi% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouth}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \pgfmathanglebetweenpoints{\centerpoint}{\anchorsouthwest}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchorwest% + \let\secondpoint\anchorsouthwest% + \else% + \let\secondpoint\anchorsouthwest% + \let\firstpoint\anchorsouth% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\anchorsoutheast}% + \ifdim\externalangle pt<\pgfmathresult pt\relax% + \let\firstpoint\anchorsouth% + \let\secondpoint\anchorsoutheast% + \else% + \let\secondpoint\anchorsoutheast% + \let\firstpoint\anchoreast% + \fi% + \fi% + \fi% + % + % Now locate the point. + % + \pgfpointintersectionoflines{\centerpoint}{\pgfqpoint{\externalx}{\externaly}}% + {\firstpoint}{\secondpoint}% + }% }% @@ -2060,10 +2102,10 @@ % /pgf/tape bend bottom : Type of bend for south side. % /pgf/tape bend height : The height of the bends. \pgfkeys{/pgf/.cd, - tape bend top/.initial=in and out, - tape bend bottom/.initial=in and out, - tape bend/.style={/pgf/tape bend top=#1, /pgf/tape bend bottom=#1}, - tape bend height/.initial=5pt + tape bend top/.initial=in and out, + tape bend bottom/.initial=in and out, + tape bend/.style={/pgf/tape bend top=#1, /pgf/tape bend bottom=#1}, + tape bend height/.initial=5pt } \def\pgf@lib@sh@inandouttext{in and out} @@ -2071,447 +2113,447 @@ \def\pgf@lib@sh@nonetext{none} \pgfdeclareshape{tape}{ - \savedmacro\tapedimensions{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% - \advance\pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% - \advance\pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y.5\dp\pgfnodeparttextbox% - % - \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}% - \addtosavedmacro\outerxsep% - \addtosavedmacro\outerysep% - % - \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/tape bend height}}% - \pgfutil@tempdima.5\pgfutil@tempdima% - \edef\halfbendheight{\the\pgfutil@tempdima}% - \addtosavedmacro\halfbendheight% - % - \pgfkeysgetvalue{/pgf/tape bend top}{\topbendstyle}% - \pgfkeysgetvalue{/pgf/tape bend bottom}{\bottombendstyle}% - \addtosavedmacro\topbendstyle% - \addtosavedmacro\bottombendstyle% - % - \ifx\topbendstyle\pgf@lib@sh@nonetext% - \else% - \advance\pgf@y\pgfutil@tempdima% - \fi% - \ifx\bottombendstyle\pgf@lib@sh@none% - \else% - \advance\pgf@y\pgfutil@tempdima% - \fi% - % - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% - \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% - \ifdim\pgf@x<.5\pgf@xa% - \pgf@x.5\pgf@xa% - \fi% - \ifdim\pgf@y<.5\pgf@ya% - \pgf@y.5\pgf@ya% - \fi% - \ifx\topbendstyle\pgf@lib@sh@nonetext% - \else% - \advance\pgf@y-\pgfutil@tempdima% - \fi% - \ifx\bottombendstyle\pgf@lib@sh@nonetext% - \else% - \advance\pgf@y-\pgfutil@tempdima% - \fi% - % - \pgfutil@tempdima3.414213\pgfutil@tempdima% 1 / (1-sin(45)) - \edef\bendyradius{\the\pgfutil@tempdima}% - \addtosavedmacro\bendyradius% - \advance\pgfutil@tempdima\outerysep% - \edef\outerbendyradius{\the\pgfutil@tempdima}% - \addtosavedmacro\outerbendyradius% - \advance\pgfutil@tempdima-\outerysep% - \advance\pgfutil@tempdima-\outerysep% - \edef\innerbendyradius{\the\pgfutil@tempdima}% - \addtosavedmacro\innerbendyradius% - % - \pgfutil@tempdima0.707106\pgf@x% cos(45) - \edef\bendxradius{\the\pgfutil@tempdima}% - \addtosavedmacro\bendxradius% - \advance\pgfutil@tempdima\outerxsep% - \edef\outerbendxradius{\the\pgfutil@tempdima}% - \addtosavedmacro\outerbendxradius% - \advance\pgfutil@tempdima-\outerxsep% - \advance\pgfutil@tempdima-\outerxsep% - \edef\innerbendxradius{\the\pgfutil@tempdima}% - \addtosavedmacro\innerbendxradius% - % - \edef\halfwidth{\the\pgf@x}% - \edef\halfheight{\the\pgf@y}% - \addtosavedmacro\halfwidth% - \addtosavedmacro\halfheight% - % - \advance\pgf@x\outerxsep% - \edef\outerhalfwidth{\the\pgf@x}% - \addtosavedmacro\outerhalfwidth% - % - \pgf@xc\bendxradius% - \pgf@yc\bendyradius% - \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@xc}}% - \pgfmathatan{\pgfmathresult}% - \pgf@xc\pgfmathresult pt\relax% - \pgf@xc.5\pgf@xc% - \edef\halfangle{\pgfmath@tonumber{\pgf@xc}}% - \addtosavedmacro\halfangle% - % - \pgf@xc45pt\relax% - \advance\pgf@xc-\halfangle pt% - \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% - \let\cothalfanglein\pgfmathresult% - \addtosavedmacro\cothalfanglein% - % - \pgf@xc90pt\relax% - \advance\pgf@xc-\halfangle pt% - \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% - \let\cothalfangleout\pgfmathresult% - \addtosavedmacro\cothalfangleout% - % - } - \savedanchor{\centerpoint}{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y.5\ht\pgfnodeparttextbox% - \advance\pgf@y-.5\dp\pgfnodeparttextbox% - } - \savedanchor{\midpoint}{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgfmathsetlength\pgf@y{+0.5ex}% - } - \savedanchor{\basepoint}{% - \pgf@x.5\wd\pgfnodeparttextbox% - \pgf@y0pt% - } - \anchor{center}{\centerpoint}% - \anchor{mid}{\midpoint}% - \anchor{mid east}{\tapedimensions\midpoint\advance\pgf@x\outerhalfwidth}% - \anchor{mid west}{\tapedimensions\midpoint\advance\pgf@x-\outerhalfwidth}% - \anchor{base}{\basepoint}% - \anchor{base east}{\tapedimensions\basepoint\advance\pgf@x\outerhalfwidth}% - \anchor{base west}{\tapedimensions\basepoint\advance\pgf@x-\outerhalfwidth}% - \anchor{north}{% - \csname pgf@anchor@tape@north east\endcsname% - \pgf@ya\pgf@y% - \csname pgf@anchor@tape@north west\endcsname% - \advance\pgf@ya\pgf@y% - \centerpoint% - \pgf@y.5\pgf@ya% - } - \anchor{south}{% - \csname pgf@anchor@tape@south east\endcsname% - \pgf@ya\pgf@y% - \csname pgf@anchor@tape@south west\endcsname% - \advance\pgf@ya\pgf@y% - \centerpoint% - \pgf@y.5\pgf@ya% - } - \anchor{east}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x\outerhalfwidth% - } - \anchor{west}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x-\outerhalfwidth% - } - \anchor{north east}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x\outerhalfwidth% - \advance\pgf@y\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfangleout\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfanglein\pgf@yc% - \else% - \advance\pgf@y\pgf@yc% - \fi% - \fi% - }% - \anchor{north west}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x-\outerhalfwidth% - \advance\pgf@y\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfanglein\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y\halfbendheight% - \advance\pgf@y\cothalfangleout\pgf@yc% - \else% - \advance\pgf@y\pgf@yc% - \fi% - \fi% - }% - \anchor{south east}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x\outerhalfwidth% - \advance\pgf@y-\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfangleout\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfanglein\pgf@yc% - \else% - \advance\pgf@y-\pgf@yc% - \fi% - \fi% - }% - \anchor{south west}{% - \tapedimensions% - \centerpoint% - \advance\pgf@x-\outerhalfwidth% - \advance\pgf@y-\halfheight% - \pgf@yc\outerysep% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfanglein\pgf@yc% - \else% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \advance\pgf@y-\halfbendheight% - \advance\pgf@y-\cothalfangleout\pgf@yc% - \else% - \advance\pgf@y-\pgf@yc% - \fi% - \fi% - }% - \backgroundpath{% - \tapedimensions% - % - \pgf@xc\halfwidth% - \pgf@yc\halfheight% - % - \pgf@xc\bendxradius% - \pgf@yc\bendyradius% - {% - \pgftransformshift{\centerpoint}% - \pgfpathmoveto{\pgfqpoint{-\halfwidth}{0pt}}% - \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}% - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% - \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% - \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% - \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% - \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% - \else% - \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}% - \fi% - \fi% - \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}% - \ifx\bottombendstyle\pgf@lib@sh@inandouttext% - \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% - \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% - \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% - \else% - \ifx\bottombendstyle\pgf@lib@sh@outandintext% - \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% - \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% - \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% - \else% - \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}% - \fi% - \fi% - \pgfpathclose% - }% - } - \anchorborder{% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\externalpoint{% - \centerpoint% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% - \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% - \let\externalangle\pgfmathresult% - \tapedimensions% - % - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north west\endcsname}% - \ifdim\externalangle pt<\pgfmathresult pt% - \ifdim\externalangle pt<90pt% - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north east\endcsname}% - \ifdim\externalangle pt<\pgfmathresult pt% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@south east\endcsname}% - \else% - % Between north and north east. - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\outerbendxradius and \outerbendyradius}% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\innerbendxradius and \innerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@north west\endcsname}% - \fi% - \fi% - \fi% - \else% - % Between north and north west. - \ifx\topbendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\innerbendxradius and \innerbendyradius}% - \else% - \ifx\topbendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y\halfheight% - \advance\pgf@y\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\outerbendxradius and \outerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@north west\endcsname}% - \fi% - \fi% - \fi% - \else% - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south west\endcsname}% - \ifdim\externalangle pt>\pgfmathresult pt% - \ifdim\externalangle pt>270pt% - \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south east\endcsname}% - \ifdim\externalangle pt>\pgfmathresult pt% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north east\endcsname}% - {\csname pgf@anchor@tape@south east\endcsname}% - \else% - % Between south and south east. - \ifx\bottombendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\innerbendxradius and \innerbendyradius}% - \else% - \ifx\bottombendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\outerbendxradius and \outerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@south east\endcsname}% - {\csname pgf@anchor@tape@south west\endcsname}% - \fi% - \fi% - \fi% - \else% - % Between south and south west. - \ifx\bottombendstyle\pgf@lib@sh@inandouttext% - % in and out. - \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y.707106\pgf@yc% - }% - {185}{355}{\outerbendxradius and \outerbendyradius}% - \else% - \ifx\bottombendstyle\pgf@lib@sh@outandintext% - % out and in. - \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% - {% - \centerpoint% - \pgf@xc\halfwidth% - \advance\pgf@x-.5\pgf@xc% - \advance\pgf@y-\halfheight% - \advance\pgf@y-\halfbendheight% - \pgf@yc\bendyradius% - \advance\pgf@y-.707106\pgf@yc% - }% - {5}{175}{\innerbendxradius and \innerbendyradius}% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@south east\endcsname}% - {\csname pgf@anchor@tape@south west\endcsname}% - \fi% - \fi% - \fi% - \else% - \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% - {\csname pgf@anchor@tape@north west\endcsname}% - {\csname pgf@anchor@tape@south west\endcsname}% - \fi% - \fi% - }% + \savedmacro\tapedimensions{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}% + \advance\pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y.5\dp\pgfnodeparttextbox% + % + \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}% + \addtosavedmacro\outerxsep% + \addtosavedmacro\outerysep% + % + \pgfmathsetlength\pgfutil@tempdima{\pgfkeysvalueof{/pgf/tape bend height}}% + \pgfutil@tempdima.5\pgfutil@tempdima% + \edef\halfbendheight{\the\pgfutil@tempdima}% + \addtosavedmacro\halfbendheight% + % + \pgfkeysgetvalue{/pgf/tape bend top}{\topbendstyle}% + \pgfkeysgetvalue{/pgf/tape bend bottom}{\bottombendstyle}% + \addtosavedmacro\topbendstyle% + \addtosavedmacro\bottombendstyle% + % + \ifx\topbendstyle\pgf@lib@sh@nonetext% + \else% + \advance\pgf@y\pgfutil@tempdima% + \fi% + \ifx\bottombendstyle\pgf@lib@sh@none% + \else% + \advance\pgf@y\pgfutil@tempdima% + \fi% + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<.5\pgf@xa% + \pgf@x.5\pgf@xa% + \fi% + \ifdim\pgf@y<.5\pgf@ya% + \pgf@y.5\pgf@ya% + \fi% + \ifx\topbendstyle\pgf@lib@sh@nonetext% + \else% + \advance\pgf@y-\pgfutil@tempdima% + \fi% + \ifx\bottombendstyle\pgf@lib@sh@nonetext% + \else% + \advance\pgf@y-\pgfutil@tempdima% + \fi% + % + \pgfutil@tempdima3.414213\pgfutil@tempdima% 1 / (1-sin(45)) + \edef\bendyradius{\the\pgfutil@tempdima}% + \addtosavedmacro\bendyradius% + \advance\pgfutil@tempdima\outerysep% + \edef\outerbendyradius{\the\pgfutil@tempdima}% + \addtosavedmacro\outerbendyradius% + \advance\pgfutil@tempdima-\outerysep% + \advance\pgfutil@tempdima-\outerysep% + \edef\innerbendyradius{\the\pgfutil@tempdima}% + \addtosavedmacro\innerbendyradius% + % + \pgfutil@tempdima0.707106\pgf@x% cos(45) + \edef\bendxradius{\the\pgfutil@tempdima}% + \addtosavedmacro\bendxradius% + \advance\pgfutil@tempdima\outerxsep% + \edef\outerbendxradius{\the\pgfutil@tempdima}% + \addtosavedmacro\outerbendxradius% + \advance\pgfutil@tempdima-\outerxsep% + \advance\pgfutil@tempdima-\outerxsep% + \edef\innerbendxradius{\the\pgfutil@tempdima}% + \addtosavedmacro\innerbendxradius% + % + \edef\halfwidth{\the\pgf@x}% + \edef\halfheight{\the\pgf@y}% + \addtosavedmacro\halfwidth% + \addtosavedmacro\halfheight% + % + \advance\pgf@x\outerxsep% + \edef\outerhalfwidth{\the\pgf@x}% + \addtosavedmacro\outerhalfwidth% + % + \pgf@xc\bendxradius% + \pgf@yc\bendyradius% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@yc}}{\pgfmath@tonumber{\pgf@xc}}% + \pgfmathatan{\pgfmathresult}% + \pgf@xc\pgfmathresult pt\relax% + \pgf@xc.5\pgf@xc% + \edef\halfangle{\pgfmath@tonumber{\pgf@xc}}% + \addtosavedmacro\halfangle% + % + \pgf@xc45pt\relax% + \advance\pgf@xc-\halfangle pt% + \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% + \let\cothalfanglein\pgfmathresult% + \addtosavedmacro\cothalfanglein% + % + \pgf@xc90pt\relax% + \advance\pgf@xc-\halfangle pt% + \pgfmathcot@{\pgfmath@tonumber{\pgf@xc}}% + \let\cothalfangleout\pgfmathresult% + \addtosavedmacro\cothalfangleout% + % + } + \savedanchor{\centerpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y.5\ht\pgfnodeparttextbox% + \advance\pgf@y-.5\dp\pgfnodeparttextbox% + } + \savedanchor{\midpoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgfmathsetlength\pgf@y{+0.5ex}% + } + \savedanchor{\basepoint}{% + \pgf@x.5\wd\pgfnodeparttextbox% + \pgf@y0pt% + } + \anchor{center}{\centerpoint}% + \anchor{mid}{\midpoint}% + \anchor{mid east}{\tapedimensions\midpoint\advance\pgf@x\outerhalfwidth}% + \anchor{mid west}{\tapedimensions\midpoint\advance\pgf@x-\outerhalfwidth}% + \anchor{base}{\basepoint}% + \anchor{base east}{\tapedimensions\basepoint\advance\pgf@x\outerhalfwidth}% + \anchor{base west}{\tapedimensions\basepoint\advance\pgf@x-\outerhalfwidth}% + \anchor{north}{% + \csname pgf@anchor@tape@north east\endcsname% + \pgf@ya\pgf@y% + \csname pgf@anchor@tape@north west\endcsname% + \advance\pgf@ya\pgf@y% + \centerpoint% + \pgf@y.5\pgf@ya% + } + \anchor{south}{% + \csname pgf@anchor@tape@south east\endcsname% + \pgf@ya\pgf@y% + \csname pgf@anchor@tape@south west\endcsname% + \advance\pgf@ya\pgf@y% + \centerpoint% + \pgf@y.5\pgf@ya% + } + \anchor{east}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x\outerhalfwidth% + } + \anchor{west}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x-\outerhalfwidth% + } + \anchor{north east}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x\outerhalfwidth% + \advance\pgf@y\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfangleout\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfanglein\pgf@yc% + \else% + \advance\pgf@y\pgf@yc% + \fi% + \fi% + }% + \anchor{north west}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x-\outerhalfwidth% + \advance\pgf@y\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfanglein\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y\halfbendheight% + \advance\pgf@y\cothalfangleout\pgf@yc% + \else% + \advance\pgf@y\pgf@yc% + \fi% + \fi% + }% + \anchor{south east}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x\outerhalfwidth% + \advance\pgf@y-\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfangleout\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfanglein\pgf@yc% + \else% + \advance\pgf@y-\pgf@yc% + \fi% + \fi% + }% + \anchor{south west}{% + \tapedimensions% + \centerpoint% + \advance\pgf@x-\outerhalfwidth% + \advance\pgf@y-\halfheight% + \pgf@yc\outerysep% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfanglein\pgf@yc% + \else% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \advance\pgf@y-\halfbendheight% + \advance\pgf@y-\cothalfangleout\pgf@yc% + \else% + \advance\pgf@y-\pgf@yc% + \fi% + \fi% + }% + \backgroundpath{% + \tapedimensions% + % + \pgf@xc\halfwidth% + \pgf@yc\halfheight% + % + \pgf@xc\bendxradius% + \pgf@yc\bendyradius% + {% + \pgftransformshift{\centerpoint}% + \pgfpathmoveto{\pgfqpoint{-\halfwidth}{0pt}}% + \pgfpathlineto{\pgfqpoint{-\halfwidth}{\halfheight}}% + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% + \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% + \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + \pgfpathlineto{\pgf@x-\halfwidth\pgf@y\halfheight\advance\pgf@y\halfbendheight}% + \pgfpatharc{135}{45}{\bendxradius and \bendyradius}% + \pgfpatharc{225}{315}{\bendxradius and \bendyradius}% + \else% + \pgfpathlineto{\pgfqpoint{\halfwidth}{\halfheight}}% + \fi% + \fi% + \pgfpathlineto{\pgfqpoint{\halfwidth}{-\halfheight}}% + \ifx\bottombendstyle\pgf@lib@sh@inandouttext% + \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% + \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% + \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% + \else% + \ifx\bottombendstyle\pgf@lib@sh@outandintext% + \pgfpathlineto{\pgf@x\halfwidth\pgf@y-\halfheight\advance\pgf@y-\halfbendheight}% + \pgfpatharc{315}{225}{\bendxradius and \bendyradius}% + \pgfpatharc{45}{135}{\bendxradius and \bendyradius}% + \else% + \pgfpathlineto{\pgfqpoint{-\halfwidth}{-\halfheight}}% + \fi% + \fi% + \pgfpathclose% + }% + } + \anchorborder{% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\externalpoint{% + \centerpoint% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% + \pgfmathanglebetweenpoints{\centerpoint}{\externalpoint}% + \let\externalangle\pgfmathresult% + \tapedimensions% + % + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north west\endcsname}% + \ifdim\externalangle pt<\pgfmathresult pt% + \ifdim\externalangle pt<90pt% + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@north east\endcsname}% + \ifdim\externalangle pt<\pgfmathresult pt% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@south east\endcsname}% + \else% + % Between north and north east. + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\outerbendxradius and \outerbendyradius}% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\innerbendxradius and \innerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@north west\endcsname}% + \fi% + \fi% + \fi% + \else% + % Between north and north west. + \ifx\topbendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\innerbendxradius and \innerbendyradius}% + \else% + \ifx\topbendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y\halfheight% + \advance\pgf@y\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\outerbendxradius and \outerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@north west\endcsname}% + \fi% + \fi% + \fi% + \else% + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south west\endcsname}% + \ifdim\externalangle pt>\pgfmathresult pt% + \ifdim\externalangle pt>270pt% + \pgfmathanglebetweenpoints{\centerpoint}{\csname pgf@anchor@tape@south east\endcsname}% + \ifdim\externalangle pt>\pgfmathresult pt% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north east\endcsname}% + {\csname pgf@anchor@tape@south east\endcsname}% + \else% + % Between south and south east. + \ifx\bottombendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\innerbendxradius and \innerbendyradius}% + \else% + \ifx\bottombendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\outerbendxradius and \outerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@south east\endcsname}% + {\csname pgf@anchor@tape@south west\endcsname}% + \fi% + \fi% + \fi% + \else% + % Between south and south west. + \ifx\bottombendstyle\pgf@lib@sh@inandouttext% + % in and out. + \pgfmathpointintersectionoflineandarc{\externalpoint}{\centerpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y.707106\pgf@yc% + }% + {185}{355}{\outerbendxradius and \outerbendyradius}% + \else% + \ifx\bottombendstyle\pgf@lib@sh@outandintext% + % out and in. + \pgfmathpointintersectionoflineandarc{\centerpoint}{\externalpoint}% + {% + \centerpoint% + \pgf@xc\halfwidth% + \advance\pgf@x-.5\pgf@xc% + \advance\pgf@y-\halfheight% + \advance\pgf@y-\halfbendheight% + \pgf@yc\bendyradius% + \advance\pgf@y-.707106\pgf@yc% + }% + {5}{175}{\innerbendxradius and \innerbendyradius}% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@south east\endcsname}% + {\csname pgf@anchor@tape@south west\endcsname}% + \fi% + \fi% + \fi% + \else% + \pgfpointintersectionoflines{\externalpoint}{\centerpoint}% + {\csname pgf@anchor@tape@north west\endcsname}% + {\csname pgf@anchor@tape@south west\endcsname}% + \fi% + \fi% + }% } @@ -2565,7 +2607,169 @@ {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima}}} \pgfpathlineto{\pgfpointadd{\pgfqpoint{\pgf@xc}{\pgf@yc}} {\pgfpointpolar{\pgfkeysvalueof{/pgf/magnifying glass handle angle}}{\pgfutil@tempdima+\pgfutil@tempdima*(\pgfkeysvalueof{/pgf/magnifying glass handle aspect})}}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} } } +\pgfkeys{% + /pgf/magnetic tape tail/.initial=0.15, + /pgf/magnetic tape tail extend/.initial=0cm, +} +\pgfdeclareshape{magnetic tape}{ + \nodeparts{text} + \savedmacro\installparameters{% + % + \pgf@x=0.5\wd\pgfnodeparttextbox% + \pgf@y=0.5\ht\pgfnodeparttextbox% + \advance\pgf@y by-0.5\dp\pgfnodeparttextbox% + \edef\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + % + \pgf@x=\wd\pgfnodeparttextbox% + \pgf@y=\ht\pgfnodeparttextbox% + \advance\pgf@y by\dp\pgfnodeparttextbox% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/inner ysep}}% + \advance\pgf@x by2.0\pgf@xa% + \advance\pgf@y by2.0\pgf@ya% + \ifdim\pgf@y>\pgf@x% + \pgf@x=\pgf@y% + \fi% + \pgf@x=1.414213\pgf@x% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}% + \ifdim\pgf@x<\pgf@xa% + \pgf@x=\pgf@xa% + \fi% + \ifdim\pgf@x<\pgf@ya% + \pgf@x=\pgf@ya% + \fi% + \pgf@x=0.5\pgf@x% + \edef\radius{\the\pgf@x}% + % + \pgfmathparse{max(\pgfkeysvalueof{/pgf/magnetic tape tail extend},0)}% + \edef\tailextend{\pgfmathresult pt}% + % + \pgfmathparse{min(max(\pgfkeysvalueof{/pgf/magnetic tape tail},0),1)}% + \pgf@xa=\pgfmathresult\pgf@x% + \edef\tailheight{\the\pgf@xa}% + % + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}% + \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}% + \ifdim\pgf@xa<\pgf@ya% + \pgf@xa=\pgf@ya% + \fi% + \edef\outersep{\the\pgf@xa}% + % + \pgfmathparse{\outersep+\radius}% + \edef\outerradius{\pgfmathresult pt}% + % + \pgfmathparse{(\radius-\tailheight)/\radius}% + \pgfmathasin@{\pgfmathresult}% + \pgfmathadd@{-\pgfmathresult}{360}% + \let\tailangle=\pgfmathresult% + % + \pgfmathparse{\outerradius/(\outerradius+\tailextend)}% + \pgfmathatan@{\pgfmathresult}% + \pgfmathadd@{-\pgfmathresult}{360}% + \let\tailbottomangle=\pgfmathresult% + % + \pgfmathparse{(\outerradius-\outersep-\tailheight-\outersep)/(\outerradius+\tailextend)}% + \pgfmathatan@{\pgfmathresult}% + \pgfmathadd@{-\pgfmathresult}{360}% + \let\tailtopangle=\pgfmathresult% + % + \addtosavedmacro\radius% + \addtosavedmacro\outerradius% + \addtosavedmacro\outersep% + \addtosavedmacro\tailheight% + \addtosavedmacro\tailextend + \addtosavedmacro\tailangle% + \addtosavedmacro\tailtopangle% + \addtosavedmacro\tailbottomangle% + \addtosavedmacro\centerpoint% + } + \savedanchor{\base}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}} + \savedanchor{\mid}{\pgfqpoint{0.5\wd\pgfnodeparttextbox}{0pt}\pgfmathsetlength\pgf@y{.5ex}} + \anchor{center}{\installparameters\centerpoint}% \addtosavedmacro\outerradius% + \anchor{base}{\base} + \anchor{mid}{\mid} + \anchor{base west}{\installparameters\pgfpointadd{\base}{\pgfqpoint{-\outerradius}{0pt}}} + \anchor{base east}{\installparameters\pgfpointadd{\base}{\pgfqpoint{\outerradius}{0pt}}} + \anchor{mid west}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{-\outerradius}{0pt}}} + \anchor{mid east}{\installparameters\pgfpointadd{\mid}{\pgfqpoint{\outerradius}{0pt}}} + \anchor{north}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{\outerradius}}} + \anchor{north east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{45}{\outerradius}}} + \anchor{south}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{0pt}{-\outerradius}}} + \anchor{south east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{-\outerradius}}} + \anchor{east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{\outerradius}{0pt}}} + \anchor{south west}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{225}{\outerradius}}} + \anchor{west}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpoint{-\outerradius}{0pt}}} + \anchor{north west}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfqpointpolar{135}{\outerradius}}} + \anchor{tail east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight/2}}} + \anchor{tail south east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius}}} + \anchor{tail north east}{\installparameters% + \pgfpointadd{\centerpoint}{\pgfpoint{\radius+\tailextend+\outersep}{-\outerradius+\outersep+\tailheight+\outersep}}} + \backgroundpath{ + % + \installparameters% + {% + \pgftransformshift{\centerpoint}% + \pgfpathmoveto{\pgfpointpolar{\tailangle}{\radius}}% + \pgfpatharc{\tailangle}{360}{\radius}% + \pgfpatharc{0}{270}{\radius}% + \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius}}% + \pgfpathlineto{\pgfpoint{\radius+\tailextend}{-\radius+\tailheight}}% + \pgfpathclose% + }% + } + \anchorborder{% + \pgfextract@process\externalpoint{}% + \installparameters% + \pgfmathanglebetweenpoints{\pgfpointorigin}{\externalpoint} + \ifdim\pgfmathresult pt<270pt\relax% + \pgfpointadd{\centerpoint}{% + \pgfpointborderellipse% + {\externalpoint}% + {\pgfqpoint{\outerradius}{\outerradius}}% + }% + \else% + \ifdim\pgfmathresult pt<\tailbottomangle pt\relax% + \pgfpointadd{\centerpoint}{% + \pgfpointintersectionoflines% + {\externalpoint}{\pgfpointorigin}% + {\pgfqpoint{0pt}{-\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}% + }% + \else% + \ifdim\pgfmathresult pt<\tailtopangle pt\relax% + \pgfpointadd{\centerpoint}{% + \pgfpointintersectionoflines% + {\externalpoint}{\pgfpointorigin}% + {\pgfqpoint{\outerradius}{\outerradius}}{\pgfqpoint{\outerradius}{-\outerradius}}% + }% + \else% + \pgfpointadd{\centerpoint}{% + \pgfpointborderellipse% + {\externalpoint}% + {\pgfqpoint{\outerradius}{\outerradius}}% + }% + \fi% + \fi% + \fi% + } +} + +% Local Variables: +% tab-width: 2 +% End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua new file mode 100644 index 00000000000..583777075df --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual.lua @@ -0,0 +1,18 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/lua/pgf/manual.lua,v 1.1 2013/05/23 20:01:29 tantau Exp $ + + + +local manual = {} + +require 'pgf'.manual = manual + +return manual diff --git a/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua new file mode 100644 index 00000000000..3905f348358 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/lua/pgf/manual/DocumentParser.lua @@ -0,0 +1,596 @@ +-- Copyright 2013 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/lua/pgf/manual/DocumentParser.lua,v 1.2 2013/08/01 16:02:22 tantau Exp $ + + + +--- +-- This class offers functions for converting the documentation of Lua +-- and other code into \TeX. +-- +-- @field renderers This array must consist of tables having two +-- fields: |test| and |renderer|. The first must be set to a function +-- that is called with an information table as parameter and must +-- return |true| if the funciton stored in the |renderer| should be +-- called. (Typically, the |test| will test whether the ``head line'' +-- following a documentation block has a special form.) + +local DocumentParser = { + renderers = {} +} + +-- Namespace: +require 'pgf.manual'.DocumentParser = DocumentParser + +-- Imports +local keys = require 'pgf.gd.interface.InterfaceCore'.keys + +-- Forwards: + +local collect_infos, render_infos + + +--- +-- Includes the documentation stored in some file in the manual. +-- +-- @param filename The file from which the documentation is to be read +-- @param type The type of the file. + +function DocumentParser.include(filename, typ) + + local fullname = assert(kpse.find_file(filename:gsub("%.", "/"), typ or "lua") + or kpse.find_file(filename:gsub("%.", "\\"), typ or "lua"), + "file " .. filename .. " not found") + + local file, error = io.open(fullname) + + -- First, let us read the file into a table to make handling easier: + local lines = {} + + for line in file:lines() do + lines [#lines + 1] = line + end + + -- A table storing the current output. The array part contains TeX + -- lines, the table part contains information about special table.s + local output = {} + + -- Now, start the main parser loop. + local i = 1 + while i <= #lines do + + if lines[i]:match("^%-%-%-") then + local infos = collect_infos (lines, i) + + infos.filename = filename + + render_infos(infos, output) + + i = infos.last_line + end + + i = i + 1 + end + + -- Render output: + for _,l in ipairs(output) do + if type(l) == "string" then + tex.print(l) + else + l() + end + end + +end + + + +--- +-- Add a test and a renderer to the array of renderers. +-- +-- @param test A test function (see |DocumentParser.renderers|). +-- @param renderer A rendering function. + +function DocumentParser.addRenderer (test, renderer) + DocumentParser.renderers [#DocumentParser.renderers + 1] = + { test = test, renderer = renderer } +end + + +-- Forwards: +local print_on_output, print_on_output_escape, print_docline_on_output, open_mode, close_mode, print_lines_on_output + + + +local function strip_quotes(s) + if s then return string.gsub(s, '^"(.*)"$', "%1") end +end + +local function split(s) + local t = {} + for line in string.gmatch(s, ".-\n") do + t[#t+1] = line + end + for i=#t,1,-1 do + if t[i]:match("^%s*$") then + t[i] = nil + else + return t + end + end + return t +end + + +local function process_string(s) + if s then + local t = split(s.."\n") + -- Compute min spaces + local min = math.huge + for _,l in ipairs(t) do + min = math.min(min, string.find(l, "%S") or math.huge) + end + if min < math.huge then + -- Now, trim 'em all! + for i=1,#t do + t[i] = string.sub(t[i],min,-2) + end + end + return t + end +end + + +local function process_examples(t) + if not t then + return nil + end + + if type(t) == "string" then + t = {t} + end + + local n = {} + for i=1,#t do + n[i] = process_string(strip_quotes(t[i])) + end + return n +end + + + +-- The standard renderers: + + +-- The function renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return + infos.keywords["function"] or + infos.head_line:match("^%s*function%s+") or + infos.head_line:match("^%s*local%s+function%s+") + end, + function (infos, output) + -- The renderer + + if infos.keywords["function"] then + local k = infos.keywords["function"][1] + infos.head_line = k:match("^%s*@(.*)") + end + + local rest = infos.head_line:match("function%s+(.*)") + local tab = rest:match("([^(]*[%.%:]).*") + local fun = rest:match("[^(]*[%.%:](.-)%s*%(") or rest:match("(.-)%s*%(") + local pars = rest:match(".-%((.*)%)") + + -- Render the head + print_on_output_escape(output, [[\begin{luacommand}]]) + output[#output+1] = "{" .. (tab or "") .. fun .. "}" + print_on_output_escape(output, + "{", tab or "", "}", + "{", fun, "}", + "{", pars, "}") + + if tab then + local table_name = tab:sub(1,-2) + local t = output[table_name] or {} + t[#t+1] = { + link = "pgf/lua/" .. tab .. fun, + text = "function " .. tab .. "\\declare{" .. fun .. "} (" .. pars .. ")" + } + output[table_name] = t + end + + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + if mode ~= "done" then + mode = print_docline_on_output(output, l, mode) + end + end + close_mode(output, mode) + + print_on_output(output, [[\end{luacommand}]]) + + end +) + + +-- The table renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return + infos.keywords["table"] or + infos.head_line:match("=%s*{") + end, + function (infos, output) + -- The renderer + + if infos.keywords["table"] then + local k = infos.keywords["table"][1] + infos.head_line = k:match("^%s*@table(.*)") .. "=" + end + + local name = + infos.head_line:match("^%s*local%s+(.-)%s*=") or + infos.head_line:match("^%s*(.*)%s*=") + + -- Render the head + print_on_output_escape(output, + [[\begin{luatable}]], + "{", name:match("(.*[%.%:]).*") or "", "}", + "{", name:match(".*[%.%:](*-)") or name,"}", + "{", infos.filename, "}") + + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + + output[#output+1] = + function () + if output[name] then + tex.print("\\par\\emph{Alphabetical method summary:}\\par{\\small") + table.sort(output[name], function (a,b) return a.text < b.text end) + for _,l in ipairs(output[name]) do + tex.print("\\texttt{\\hyperlink{" .. l.link .. "}{" .. l.text:gsub("_", "\\_") .. "}}\\par") + end + tex.print("}") + end + end + + print_on_output(output, [[\end{luatable}]]) + + end +) + + + +-- The library renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return infos.keywords["library"] + end, + function (infos, output) + -- The renderer + + local name = infos.filename:gsub("%.library$",""):gsub("^pgf%.gd%.","") + + -- Render the head + print_on_output_escape(output, "\\begin{lualibrary}{", name, "}") + + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + + print_on_output(output, "\\end{lualibrary}") + + end +) + + +-- The section renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return infos.keywords["section"] + end, + function (infos, output) + -- The renderer + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + end +) + + +-- The documentation (plain text) renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return infos.keywords["documentation"] + end, + function (infos, output) + -- The renderer + local mode = "text" + for _,l in ipairs(infos.doc_lines) do + mode = print_docline_on_output(output, l, mode) + end + close_mode(output, mode) + end +) + + +-- The declare renderer +DocumentParser.addRenderer ( + function (infos) + -- The test + return + infos.keywords["declare"] or + infos.head_line:match("declare%s*{") or + infos.head_line:match("^%s*key%s*") + end, + function (infos, output) + -- The renderer + + local key_name + + if infos.keywords["declare"] then + local k = infos.keywords["declare"][1] + key_name = k:match("^%s*@declare%s*(.*)") + elseif infos.head_line:match("^%s*key%s*") then + key_name = infos.head_line:match('^%s*key%s*"(.*)"') or + infos.head_line:match("^%s*key%s*'(.*)'") + else + local l = infos.lines [infos.last_line + 1] + key_name = l:match('key%s*=%s*"(.*)"') or l:match("key%s*=%s*'(.*)'") + end + + assert (key_name, "could not determine key") + local key = assert (keys[key_name], "unknown key '" .. key_name .. "'") + + -- Render the head + if key.type then + print_on_output_escape(output, + "\\begin{luadeclare}", + "{", key.key, "}", + "{\\meta{", key.type, "}}", + "{", key.default or "", "}", + "{", key.initial or "", "}") + else + print_on_output_escape(output, + "\\begin{luadeclarestyle}", + "{", key.key, "}", + "{}", + "{", key.default or "", "}", + "{", key.initial or "", "}") + end + + + local mode = "text" + + print_lines_on_output(output, process_string(strip_quotes(key.summary))) + print_lines_on_output(output, process_string(strip_quotes(key.documentation))) + + if key.examples then + local e = process_examples(key.examples) + print_on_output(output, + "\\par\\smallskip\\emph{Example" .. (((#e>1) and "s") or "") .. "}\\par") + for _,example in ipairs(e) do + print_on_output(output, "\\begin{codeexample}[]") + print_lines_on_output(output, example) + print_on_output(output, "\\end{codeexample}") + end + end + + print_on_output(output, key.type and "\\end{luadeclare}" or "\\end{luadeclarestyle}") + end +) + + + +-- The empty line +DocumentParser.addRenderer ( + function (infos) + -- The test + return + #infos.doc_lines == 1 and + infos.doc_lines[1]:match("^%-*%s*$") + end, + function (infos, output) + end +) + + +function print_lines_on_output(output, lines) + for _,l in ipairs(lines or {}) do + output[#output+1] = l + end +end + +function print_on_output(output, ...) + local args = {...} + if #args > 0 then + for i = 1, #args do + args[i] = tostring(args[i]) + end + output[#output+1] = table.concat(args) + end +end + +function print_on_output_escape(output, ...) + local args = {...} + if #args > 0 then + for i = 1, #args do + args[i] = tostring(args[i]):gsub("_", "\\_") + end + output[#output+1] = table.concat(args) + end +end + + +function print_docline_on_output(output, l, mode) + + if l:match("^%s*@section") then + print_on_output(output, "\\", l:match("%s*@section%s*(.*)")) + elseif l:match("^%s*@param%s+") then + if mode ~= "param" then + close_mode (output, mode) + mode = open_mode (output, "param") + end + print_on_output(output, "\\item[\\texttt{", + l:match("%s@param%s+(.-)%s"):gsub("_", "\\_"), + "}] ", + l:match("%s@param%s+.-%s+(.*)")) + elseif l:match("^%s*@return%s+") then + if mode ~= "return" then + close_mode (output, mode) + mode = open_mode (output, "returns") + end + print_on_output(output, "\\item[]", l:match("%s@return%s+(.*)")) + elseif l:match("^%s*@see%s+") then + if mode ~= "text" then + close_mode (output, mode) + mode = open_mode (output, "text") + end + print_on_output(output, "\\par\\emph{See also:} \\texttt{", + l:match("%s@see%s+(.*)"):gsub("_", "\\_"), + "}") + elseif l:match("^%s*@usage%s+") then + if mode ~= "text" then + close_mode (output, mode) + mode = open_mode (output, "text") + end + print_on_output(output, "\\par\\emph{Usage:} ", + l:match("%s@usage%s+(.*)")) + elseif l:match("^%s*@field+") then + close_mode (output, mode) + mode = open_mode (output, "field") + print_on_output(output, "{", + (l:match("%s@field%s+(.-)%s") or l:match("%s@field%s+(.*)")):gsub("_", "\\_"), + "}", + l:match("%s@field%s+.-%s+(.*)")) + elseif l:match("^%s*@done") or l:match("^%s*@text") then + close_mode(output, mode) + print_on_output(output, l) + + mode = "text" + elseif l:match("^%s*@library") then + -- do nothing + elseif l:match("^%s*@end") then + close_mode(output, mode) + mode = "done" + elseif l:match("^%s*@") then + error("Unknown mark " .. l) + else + print_on_output(output, l) + end + + return mode +end + +function open_mode (output, mode) + if mode == "param" then + print_on_output(output, "\\begin{luaparameters}") + elseif mode == "field" then + print_on_output(output, "\\begin{luafield}") + elseif mode == "returns" then + print_on_output(output, "\\begin{luareturns}") + end + return mode +end + +function close_mode (output, mode) + if mode == "param" then + print_on_output(output, "\\end{luaparameters}") + elseif mode == "field" then + print_on_output(output, "\\end{luafield}") + elseif mode == "returns" then + print_on_output(output, "\\end{luareturns}") + end + return mode +end + + +function collect_infos (lines, i, state) + + local doc_lines = {} + + local keywords = {} + + local function find_keywords(line) + local keyword = line:match("^%s*@([^%s]*)") + if keyword then + local t = keywords[keyword] or {} + t[#t+1] = line + keywords[keyword] = t + end + return line + end + + -- Copy triple matches: + while lines[i] and lines[i]:match("^%-%-%-") do + doc_lines [#doc_lines + 1] = find_keywords(lines[i]:sub(4)) + i = i + 1 + end + + -- Continue with double matches: + while lines[i] and lines[i]:match("^%-%-") do + doc_lines [#doc_lines + 1] = find_keywords(lines[i]:sub(3)) + i = i + 1 + end + + local head_line = "" + + if not keywords["end"] then + -- Skip empty lines + while lines[i] and lines[i]:match("^%s*$") do + i = i + 1 + end + head_line = lines[i] or "" + if lines[i] and lines[i]:match("^%-%-%-") then + i = i - 1 + end + end + + return { + lines = lines, + last_line = i, + doc_lines = doc_lines, + keywords = keywords, + head_line = head_line + } + +end + + + +function render_infos(infos, state) + + for _,renderer in ipairs(DocumentParser.renderers) do + if renderer.test (infos, state) then + renderer.renderer (infos, state) + return + end + end + + pgf.debug(infos) + error("Unkown documentation type") +end + + +return DocumentParser diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex index 9c51dc46117..0c11f544594 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmath.code.tex @@ -7,6 +7,11 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\ifx\pgfmathsetlength\undefined +\else + \expandafter\endinput +\fi + \input pgfmathcalc.code.tex \ifx\pgfkeysloaded\undefined @@ -15,3 +20,4 @@ \expandafter\input pgfmathfloat.code.tex \fi +\endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex index c1f099ce160..5cc58e62e5d 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathcalc.code.tex @@ -33,21 +33,24 @@ % parsed assignment. \def\pgfmathsetlength#1#2{% - \expandafter\pgfmath@onquick#2\pgfmath@% - {% - % Ok, quick version: - \begingroup% - \pgfmath@selectfont% - \pgfmath@x#2\unskip% - \pgfmath@returnone\pgfmath@x% - \endgroup% - #1\pgfmathresult pt\relax% - }% - {% - \pgfmathparse{#2}% - #1\pgfmathresult pt\relax% - }% - \ignorespaces% + \expandafter\pgfmath@onquick#2\pgfmath@% + {% + % Ok, quick version: + \begingroup% + \pgfmath@selectfont% + #1#2\unskip% + \expandafter\endgroup% + \expandafter#1\the#1\relax% + }% + {% + \pgfmathparse{#2}% + \ifpgfmathmathunitsdeclared% + #1\pgfmathresult mu\relax% + \else% + #1\pgfmathresult pt\relax% + \fi% + }% + \ignorespaces% } % \pgfmathaddtolength @@ -58,19 +61,22 @@ % #2 - an expression % \def\pgfmathaddtolength#1#2{% - \expandafter\pgfmath@onquick#2\pgfmath@% + \expandafter\pgfmath@onquick#2\pgfmath@% {% - \begingroup% - \pgfmath@selectfont% - \pgfmath@x#1\relax% - \advance\pgfmath@x#2\unskip% - \pgfmath@returnone\pgfmath@x% + \begingroup% + \pgfmath@selectfont% + \advance#1#2\unskip% + \expandafter% \endgroup% - #1\pgfmathresult pt\relax% + \expandafter#1\the#1\relax% }% {% - \pgfmathparse{#2}% - \advance#1\pgfmathresult pt\relax% + \pgfmathparse{#2}% + \ifpgfmathmathunitsdeclared% + \advance#1\pgfmathresult mu\relax% + \else% + \advance#1\pgfmathresult pt\relax% + \fi% }% \ignorespaces% } @@ -135,11 +141,11 @@ % \thecounter (same as \the\c@counter) % \def\pgfmathnewcounter#1{% - \expandafter\ifx\csname c@#1\endcsname\relax% - \def\pgfmath@marshal{\csname newcount\endcsname}% Ha! Who cares about \outer? - \expandafter\pgfmath@marshal\csname c@#1\endcsname% - \expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}% - \fi% + \expandafter\ifx\csname c@#1\endcsname\relax% + \def\pgfmath@marshal{\csname newcount\endcsname}% Ha! Who cares about \outer? + \expandafter\pgfmath@marshal\csname c@#1\endcsname% + \expandafter\def\csname the#1\endcsname{\expandafter\the\csname c@#1\endcsname}% + \fi% } % \pgfmathsetcounter @@ -150,7 +156,7 @@ % #2 - an expression % \def\pgfmathsetcounter#1#2{% - \expandafter\pgfmathsetcount\csname c@#1\endcsname{#2}% + \expandafter\pgfmathsetcount\csname c@#1\endcsname{#2}% } % \pgfmathaddtocounter @@ -173,17 +179,17 @@ \def\pgfmath@pgftext{pgf} \def\pgfmath@tikztext{tikz} \def\pgfmathmakecounterglobal#1{% - \pgfmath@ifundefined{c@#1}{}{% - \expandafter\pgfmath@in@\expandafter{\pgfmath@pgftext}{#1}% - \ifpgfmath@in@% - \else% - \expandafter\pgfmath@in@\expandafter{\pgfmath@tikztext}{#1}% - \ifpgfmath@in@% - \else% - \expandafter\global\csname c@#1\endcsname\csname c@#1\endcsname\relax% - \fi% - \fi% - }% + \pgfmath@ifundefined{c@#1}{}{% + \expandafter\pgfmath@in@\expandafter{\pgfmath@pgftext}{#1}% + \ifpgfmath@in@% + \else% + \expandafter\pgfmath@in@\expandafter{\pgfmath@tikztext}{#1}% + \ifpgfmath@in@% + \else% + \expandafter\global\csname c@#1\endcsname\csname c@#1\endcsname\relax% + \fi% + \fi% + }% } % \pgfmathsetmacro @@ -194,11 +200,11 @@ % #2 - an expression % \def\pgfmathsetmacro#1#2{% - \begingroup% - \pgfmathsetlength\pgfmath@x{#2}% - \edef#1{\pgfmath@tonumber{\pgfmath@x}}% - \pgfmath@smuggleone{#1}% - \endgroup% + \begingroup% + \pgfmathparse{#2}% + \let#1=\pgfmathresult + \pgfmath@smuggleone{#1}% + \endgroup% } % \pgfmathsetlengthmacro @@ -209,11 +215,11 @@ % #2 - an expression % \def\pgfmathsetlengthmacro#1#2{% - \begingroup% - \pgfmathsetlength\pgfmath@x{#2}% - \edef#1{\the\pgfmath@x}% - \pgfmath@smuggleone{#1}% - \endgroup% + \begingroup% + \pgfmathsetlength\pgfmath@x{#2}% + \edef#1{\the\pgfmath@x}% + \pgfmath@smuggleone{#1}% + \endgroup% } % \pgfmathtruncatemacro @@ -224,11 +230,11 @@ % #2 - an expression % \def\pgfmathtruncatemacro#1#2{% - \begingroup% - \pgfmathsetcount\c@pgfmath@counta{#2}% - \edef#1{\the\c@pgfmath@counta}% - \pgfmath@smuggleone{#1}% - \endgroup% + \begingroup% + \pgfmathsetcount\c@pgfmath@counta{#2}% + \edef#1{\the\c@pgfmath@counta}% + \pgfmath@smuggleone{#1}% + \endgroup% } % Check whether a given parameter starts with quick. @@ -247,72 +253,33 @@ \futurelet\pgfmath@next% \pgfmath@@onquick} \def\pgfmath@@onquick#1\pgfmath@{% - \ifx\pgfmath@next+% - \let\pgfmath@next=\pgfmath@firstoftwo% - \else% - \let\pgfmath@next=\pgfmath@secondoftwo% - \fi% - \pgfmath@next% + \ifx\pgfmath@next+% + \let\pgfmath@next=\pgfmath@firstoftwo% + \else% + \let\pgfmath@next=\pgfmath@secondoftwo% + \fi% + \pgfmath@next% } % *** The following commands DO NOT WORK without the rest of PGF *** % % (a dumping ground for stuff that doesn't really belong anywhere else) - + % \pgfmathanglebetweenpoints % % Define \pgfmathresult as the angle between points #1 and #2 % Should get the quadrants right as well. % \def\pgfmathanglebetweenpoints#1#2{% - \begingroup% - \pgf@process{\pgfpointdiff{#1}{#2}}% - % - % First approximate the angle of the external point... - % - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@x% - \pgf@yb\pgf@y% - \ifdim\pgf@xa<0pt\relax% - \pgf@xa-\pgf@xa% - \fi% - \ifdim\pgf@ya<0pt\relax% - \pgf@ya-\pgf@ya% - \fi% - \ifdim\pgf@ya>\pgf@xa% - \pgf@x\pgf@xa% - \pgf@y\pgf@ya% - \else% - \pgf@x\pgf@ya% - \pgf@y\pgf@xa% - \fi% - \ifdim\pgf@y=0pt\relax% - \pgf@x0pt% - \else% - \pgfmathreciprocal@{\pgfmath@tonumber{\pgf@y}}% - \pgf@x\pgfmathresult\pgf@x% - \fi% - \multiply\pgf@x1000\relax% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgf@counta\the\pgf@x\relax\pgfmath@% - \expandafter\pgf@x\csname pgfmath@atan@\the\c@pgf@counta\endcsname pt\relax% - \ifdim\pgfmath@ya>\pgfmath@xa\relax% - \pgf@x-\pgf@x% - \advance\pgf@x90pt% - \fi% - \ifdim\pgf@xb<0pt% - \ifdim\pgf@yb>0pt% - \pgf@x-\pgf@x% - \fi% - \advance\pgf@x180pt\relax% - \else% - \ifdim\pgf@yb<0pt% - \pgf@x-\pgf@x% - \advance\pgf@x360pt\relax% - \fi\fi% - \pgfmath@returnone\pgf@x% - \endgroup% + \begingroup% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \edef\pgf@marshall{\expandafter\noexpand\csname pgfmathatan2@\endcsname{\expandafter\Pgf@geT\the\pgf@y}{\expandafter\Pgf@geT\the\pgf@x}}% + \pgf@marshall% + \ifdim\pgfmathresult pt<0pt% + \pgfmathparse{\pgfmathresult+360}% + \fi% + \expandafter% + \endgroup\expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult}% } % @@ -321,33 +288,33 @@ % Rotate point #1 about point #2 by #3 degrees. % \def\pgfmathrotatepointaround#1#2#3{% - \pgf@process{% - \pgf@process{#1}% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \pgf@process{#2}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@x% - \pgf@yb\pgf@y% - \pgf@x=\pgf@xc% - \pgf@y=\pgf@yc% - \advance\pgf@x-\pgf@xa% - \advance\pgf@y-\pgf@ya% - \pgfmathsetmacro\angle{#3}% - \pgfmathsin@{\angle}% - \let\sineangle\pgfmathresult% - \pgfmathcos@{\angle}% - \let\cosineangle\pgfmathresult% - \pgf@xa\cosineangle\pgf@x% - \advance\pgf@xa-\sineangle\pgf@y% - \pgf@ya\sineangle\pgf@x% - \advance\pgf@ya\cosineangle\pgf@y% - \pgf@x\pgf@xb% - \pgf@y\pgf@yb% - \advance\pgf@x\pgf@xa% - \advance\pgf@y\pgf@ya% - }% + \pgf@process{% + \pgf@process{#1}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{#2}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@x% + \pgf@yb\pgf@y% + \pgf@x=\pgf@xc% + \pgf@y=\pgf@yc% + \advance\pgf@x-\pgf@xa% + \advance\pgf@y-\pgf@ya% + \pgfmathsetmacro\angle{#3}% + \pgfmathsin@{\angle}% + \let\sineangle\pgfmathresult% + \pgfmathcos@{\angle}% + \let\cosineangle\pgfmathresult% + \pgf@xa\cosineangle\pgf@x% + \advance\pgf@xa-\sineangle\pgf@y% + \pgf@ya\sineangle\pgf@x% + \advance\pgf@ya\cosineangle\pgf@y% + \pgf@x\pgf@xb% + \pgf@y\pgf@yb% + \advance\pgf@x\pgf@xa% + \advance\pgf@y\pgf@ya% + }% } % \pgfmathanglebetweenlines @@ -356,18 +323,18 @@ % to point #2 and a line from #3 to point #4. % \def\pgfmathanglebetweenlines#1#2#3#4{% - \begingroup% - \pgfmathanglebetweenpoints{#1}{#2}% - \let\firstangle\pgfmathresult% - \pgfmathanglebetweenpoints{#3}{#4}% - \let\secondangle\pgfmathresult% - \ifdim\firstangle pt>\secondangle pt\relax% - \pgfmathadd@{\secondangle}{360}% - \let\secondangle\pgfmathresult% - \fi% - \pgfmathsubtract@{\secondangle}{\firstangle}% - \pgfmath@smuggleone\pgfmathresult% - \endgroup% + \begingroup% + \pgfmathanglebetweenpoints{#1}{#2}% + \let\firstangle\pgfmathresult% + \pgfmathanglebetweenpoints{#3}{#4}% + \let\secondangle\pgfmathresult% + \ifdim\firstangle pt>\secondangle pt\relax% + \pgfmathadd@{\secondangle}{360}% + \let\secondangle\pgfmathresult% + \fi% + \pgfmathsubtract@{\secondangle}{\firstangle}% + \pgfmath@smuggleone\pgfmathresult% + \endgroup% } % \pgfmathpointreflectalongaxis @@ -375,14 +342,14 @@ % Reflects point #2 around an axis centered on #2 at an angle #3. % \def\pgfmathreflectpointalongaxis#1#2#3{% - \pgf@process{% - \pgfmathanglebetweenpoints{#2}{#1}% - \pgfmath@tempdima\pgfmathresult pt\relax% - \pgfmathparse{#3}% - \advance\pgfmath@tempdima-\pgfmathresult pt\relax% - \pgfmath@tempdima-2.0\pgfmath@tempdima% - \pgfmathrotatepointaround{#1}{#2}{\pgfmath@tonumber{\pgfmath@tempdima}}% - }% + \pgf@process{% + \pgfmathanglebetweenpoints{#2}{#1}% + \pgfmath@tempdima\pgfmathresult pt\relax% + \pgfmathparse{#3}% + \advance\pgfmath@tempdima-\pgfmathresult pt\relax% + \pgfmath@tempdima-2.0\pgfmath@tempdima% + \pgfmathrotatepointaround{#1}{#2}{\pgfmath@tonumber{\pgfmath@tempdima}}% + }% } @@ -402,107 +369,107 @@ % #6 radii of the arc. % \def\pgfmathpointintersectionoflineandarc#1#2#3#4#5#6{% - \pgf@process{% - % - % Get the required angle. - % - \pgfmathanglebetweenpoints{#2}{#1}% - \let\x\pgfmathresult% - % - % Get the radii of the arc. - % - \pgfmath@in@{and }{#6}% - \ifpgfmath@in@% - \pgf@polar@#6\@@% - \else% - \pgf@polar@#6 and #6\@@% - \fi% - \edef\xarcradius{\the\pgf@x}% - \edef\yarcradius{\the\pgf@y}% - % - % Get the start and end angles of the arc... - % - \pgfmathsetmacro\s{#4}% - \pgfmathsetmacro\e{#5}% - % - % ...and also with rounding. - % - \pgfmathmod@{\s}{360}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\ss\pgfmathresult% - \pgfmathmod@{\e}{360}% - \ifdim\pgfmathresult pt<0pt\relax% - \pgfmathadd@{\pgfmathresult}{360}% - \fi% - \let\ee\pgfmathresult% - % - % Hackery for when arc straddles zero. - % - \ifdim\ee pt<\ss pt\relax% - \pgfmathadd@{\x}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \let\x\pgfmathresult% - \fi% - \def\m{360}% Measure of nearness. - \pgfmathadd@{\s}{\e}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\n\pgfmathresult% The best estimate (default to middle of arc). - \pgfmathloop% - \pgfmathadd@{\s}{\e}% - \pgfmathdivide@{\pgfmathresult}{2}% - \let\p\pgfmathresult% - \ifdim\p pt=\s pt\relax% - \else% - \pgfmathanglebetweenpoints{#2}{% - \pgfpointadd{#3}{% - \pgf@x\xarcradius\relax% - \pgfmathcos@{\p}% - \pgf@x\pgfmathresult\pgf@x% - \pgf@y\yarcradius\relax% - \pgfmathsin@{\p}% - \pgf@y\pgfmathresult\pgf@y% - }% - }% - % - % Hackery for when arc straddles zero. - % - \ifdim\ee pt<\ss pt\relax% - \pgfmathadd@{\pgfmathresult}{180}% - \pgfmathmod@{\pgfmathresult}{360}% - \fi% - \let\q\pgfmathresult% - % - % More hackery... - % - \ifdim\x pt>335pt\relax% - \ifdim\q pt<45pt\relax% - \pgfmathadd@{\q}{360}% - \let\q\pgfmathresult% - \fi% - \fi% - \ifdim\x pt=\q pt% Found it! - \pgfmathbreakloop% Breaks after current iteration is complete. - \else - \ifdim\x pt<\q pt\relax% - \let\e\p% - \else% - \let\s\p% - \fi% - \fi% - \pgfmathsubtract@{\x}{\q}% - \pgfmathabs@{\pgfmathresult}% - % - % Save the estimate if it is better than any previous estimate. - % - \ifdim\pgfmathresult pt<\m pt\relax% - \let\m\pgfmathresult% - \let\n\p% - \fi% - \repeatpgfmathloop% - \pgfpointadd{#3}{\pgfpointpolar{\n}{\xarcradius and \yarcradius}}% - }% + \pgf@process{% + % + % Get the required angle. + % + \pgfmathanglebetweenpoints{#2}{#1}% + \let\x\pgfmathresult% + % + % Get the radii of the arc. + % + \pgfmath@in@{and }{#6}% + \ifpgfmath@in@% + \pgf@polar@#6\@@% + \else% + \pgf@polar@#6 and #6\@@% + \fi% + \edef\xarcradius{\the\pgf@x}% + \edef\yarcradius{\the\pgf@y}% + % + % Get the start and end angles of the arc... + % + \pgfmathsetmacro\s{#4}% + \pgfmathsetmacro\e{#5}% + % + % ...and also with rounding. + % + \pgfmathmod@{\s}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\ss\pgfmathresult% + \pgfmathmod@{\e}{360}% + \ifdim\pgfmathresult pt<0pt\relax% + \pgfmathadd@{\pgfmathresult}{360}% + \fi% + \let\ee\pgfmathresult% + % + % Hackery for when arc straddles zero. + % + \ifdim\ee pt<\ss pt\relax% + \pgfmathadd@{\x}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \let\x\pgfmathresult% + \fi% + \def\m{360}% Measure of nearness. + \pgfmathadd@{\s}{\e}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\n\pgfmathresult% The best estimate (default to middle of arc). + \pgfmathloop% + \pgfmathadd@{\s}{\e}% + \pgfmathdivide@{\pgfmathresult}{2}% + \let\p\pgfmathresult% + \ifdim\p pt=\s pt\relax% + \else% + \pgfmathanglebetweenpoints{#2}{% + \pgfpointadd{#3}{% + \pgf@x\xarcradius\relax% + \pgfmathcos@{\p}% + \pgf@x\pgfmathresult\pgf@x% + \pgf@y\yarcradius\relax% + \pgfmathsin@{\p}% + \pgf@y\pgfmathresult\pgf@y% + }% + }% + % + % Hackery for when arc straddles zero. + % + \ifdim\ee pt<\ss pt\relax% + \pgfmathadd@{\pgfmathresult}{180}% + \pgfmathmod@{\pgfmathresult}{360}% + \fi% + \let\q\pgfmathresult% + % + % More hackery... + % + \ifdim\x pt>335pt\relax% + \ifdim\q pt<45pt\relax% + \pgfmathadd@{\q}{360}% + \let\q\pgfmathresult% + \fi% + \fi% + \ifdim\x pt=\q pt% Found it! + \pgfmathbreakloop% Breaks after current iteration is complete. + \else + \ifdim\x pt<\q pt\relax% + \let\e\p% + \else% + \let\s\p% + \fi% + \fi% + \pgfmathsubtract@{\x}{\q}% + \pgfmathabs@{\pgfmathresult}% + % + % Save the estimate if it is better than any previous estimate. + % + \ifdim\pgfmathresult pt<\m pt\relax% + \let\m\pgfmathresult% + \let\n\p% + \fi% + \repeatpgfmathloop% + \pgfpointadd{#3}{\pgfpointpolar{\n}{\xarcradius and \yarcradius}}% + }% } % \pgfmathangleonellipse @@ -513,58 +480,63 @@ % #2 - the radii of the ellipse. % \def\pgfmathangleonellipse#1#2{% - \begingroup% - \pgfmath@in@{and }{#2}% - \ifpgfmath@in@% - \pgf@polar@#2\@@% - \else% - \pgf@polar@#2 and #2\@@% - \fi% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@process{#1}% - \ifdim\pgf@x=0pt\relax% - \pgfutil@tempdima1pt\relax% - \else% - \pgfutil@tempdima\pgf@x% - \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgfutil@tempdima}}% - \pgfutil@tempdima\pgfmathresult pt\relax% - \fi% - \ifdim\pgf@y=0pt\relax% - \pgfutil@tempdima1pt\relax% - \else% - \pgfmathdivide@{\pgfmath@tonumber{\pgf@y}}{\pgfmath@tonumber{\pgf@ya}}% - \pgfutil@tempdima\pgfmathresult\pgfutil@tempdima% - \pgfmathatan@{\pgfmath@tonumber{\pgfutil@tempdima}}% - \fi% - % - \pgfutil@tempdima\pgfmathresult pt\relax% - \ifdim\pgfutil@tempdima<0pt\relax% - \advance\pgfutil@tempdima360pt\relax% - \fi% - \ifdim\pgf@x<0pt\relax% - \ifdim\pgf@y=0pt\relax% - \pgfutil@tempdima180pt\relax% - \else% - \ifdim\pgf@y<0pt\relax% - \advance\pgfutil@tempdima180pt\relax% - \else% - \advance\pgfutil@tempdima-180pt\relax% - \fi% - \fi% - \else% - \ifdim\pgf@x=0pt\relax% - \ifdim\pgf@y<0pt\relax% - \pgfutil@tempdima270pt\relax% - \else% - \pgfutil@tempdima90pt\relax% - \fi% - \else% - \ifdim\pgf@y=0pt\relax% - \pgfutil@tempdima0pt\relax% - \fi% - \fi% - \fi% - \pgfmath@returnone\pgfutil@tempdima% - \endgroup% + \begingroup% + \pgfmath@in@{and }{#2}% + \ifpgfmath@in@% + \pgf@polar@#2\@@% + \else% + \pgf@polar@#2 and #2\@@% + \fi% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@process{#1}% + \ifdim\pgf@x=0pt\relax% + \pgfutil@tempdima1pt\relax% + \else% + \pgfutil@tempdima\pgf@x% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgfutil@tempdima}}% + \pgfutil@tempdima\pgfmathresult pt\relax% + \fi% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima1pt\relax% + \else% + \pgfmathdivide@{\pgfmath@tonumber{\pgf@y}}{\pgfmath@tonumber{\pgf@ya}}% + \pgfutil@tempdima\pgfmathresult\pgfutil@tempdima% + \pgfmathatan@{\pgfmath@tonumber{\pgfutil@tempdima}}% + \fi% + % + \pgfutil@tempdima\pgfmathresult pt\relax% + \ifdim\pgfutil@tempdima<0pt\relax% + \advance\pgfutil@tempdima360pt\relax% + \fi% + \ifdim\pgf@x<0pt\relax% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima180pt\relax% + \else% + \ifdim\pgf@y<0pt\relax% + \advance\pgfutil@tempdima180pt\relax% + \else% + \advance\pgfutil@tempdima-180pt\relax% + \fi% + \fi% + \else% + \ifdim\pgf@x=0pt\relax% + \ifdim\pgf@y<0pt\relax% + \pgfutil@tempdima270pt\relax% + \else% + \pgfutil@tempdima90pt\relax% + \fi% + \else% + \ifdim\pgf@y=0pt\relax% + \pgfutil@tempdima0pt\relax% + \fi% + \fi% + \fi% + \pgfmath@returnone\pgfutil@tempdima% + \endgroup% } + + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex index 722856f3628..727af976f8d 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfloat.code.tex @@ -10,7 +10,28 @@ % This file contains methods for basic floating point arithmetics, rounding % to arbitrary precision and number pretty printing. % -% Version 1.0 2008/09/17 + + +\pgfkeys{ + % The bug 3430171 (wrong minus sign spacing in pgfmathprintnumber) + % has been fixed in 2.10 CVS. Since it changes the spacing, its + % effects can be undone with this compatibility switch. + /pgf/compat/number printer/.is choice, + /pgf/compat/number printer/2.10/.code={% + \def\pgfmathprintnumber@begingroup{\bgroup}% + \def\pgfmathprintnumber@endgroup{\egroup}% + }, + % I do not know the version number of the next release at this + % time. Please be so kind and KEEP THIS NAME INTACT. Add an alias + % if needed. + /pgf/compat/number printer/next after 2.10/.code={% + \def\pgfmathprintnumber@begingroup{\begingroup}% + \def\pgfmathprintnumber@endgroup{\endgroup}% + }, + % activate the fix by default. + /pgf/compat/number printer/next after 2.10,% +} + \global\newif\ifpgfmathfloatcomparison \newif\ifpgfmathfloatroundhasperiod @@ -34,6 +55,13 @@ % can be changed with options. \def\pgfmathfloat@round@precision{2} +% I introduced this to acces the "original" precision in case a +% formatted changes it locally... in this case, the formatter may +% overwrite \pgfmathfloat@round@precision@orig to provide the original +% one. +% The default implementation here does nothing: +\def\pgfmathfloat@round@precision@orig{\pgfmathfloat@round@precision}% + \gdef\pgfmathfloat@glob@TMP{} @@ -472,7 +500,7 @@ \pgfkeysgetvalue{/pgf/number format/set decimal separator}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK \pgfkeysgetvalue{/pgf/number format/set thousands separator}\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP - \c@pgf@counta=#4\relax + \c@pgf@counta=#4\relax % it is the exponent here. \ifnum#2=0 \c@pgf@counta=0 \fi @@ -511,20 +539,30 @@ \else \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod#1\pgfmathfloat@EOI\pgfmathfloat@EOI\pgfmathfloat@EOI \fi + \ifpgfmathprintnumber@thousand@sep@in@fractional + \let\pgfmathresultfractional\pgfutil@empty% + \pgfmathprintnumber@thousand@sep@in@fractional#2MMMM\@@ + \else + \def\pgfmathresultfractional{#2}% + \fi \begingroup \toks0=\expandafter{\pgfmathresult}% \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}% - \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP #2}% - \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% + \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP}% + \toks3=\expandafter{\pgfmathresultfractional}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 \the\toks3 }% \endgroup \let\pgfmathresult=\pgfmathfloat@glob@TMP }% + +% assigns \pgfmathresult such that it contains the formatted result. +% It assumes that none of the following tokens contains a period. \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod{% \ifx\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP\pgfutil@empty \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}% \else - \ifnum\c@pgf@counta<0\relax + \ifnum\c@pgf@counta<0\relax % exponent of the number in this context \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall}% \else @@ -561,7 +599,7 @@ \fi \fi \fi - \ifnum\c@pgf@counta>0 + \ifnum\c@pgf@counta>0 % \c@pgf@counta = N MOD 3 in this context \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% \expandafter\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits\pgfmathfloat@loc@TMPb }% @@ -573,7 +611,8 @@ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT } \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printtrailingdigits#1#2{% - \ifcase\c@pgf@counta + \ifcase\c@pgf@counta % = N MOD 3 in this context + % does not happen per construction \or \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult #1}% \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT{% @@ -585,7 +624,7 @@ \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@counteverythird% }% \fi - \ifnum\c@pgf@countb>0\relax + \ifnum\c@pgf@countb>0\relax % \c@pgf@countb = N DIV 3 in this context \begingroup \toks0=\expandafter{\pgfmathresult}% \toks1=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}% @@ -625,6 +664,32 @@ \fi \pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@NEXT } + +% \pgfmathprintnumber@thousand@sep@in@fractional 01234525MMMM\@@ +% -> +% 01234525 +\def\pgfmathprintnumber@thousand@sep@in@fractional#1#2#3#4{% + \if#4M% + % Ok, no further separator + \def\pgfmathprint@next{\pgfmathprintnumber@thousand@sep@in@fractional@finish#1#2#3#4}% + \else + \begingroup + \toks0=\expandafter{\pgfmathresultfractional}% + \toks1={#1#2#3}% + \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@THOUSAND@SEP}% + \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% + \endgroup + \let\pgfmathresultfractional=\pgfmathfloat@glob@TMP + \def\pgfmathprint@next{\pgfmathprintnumber@thousand@sep@in@fractional#4}% + \fi + \pgfmathprint@next +}% +\def\pgfmathprintnumber@thousand@sep@in@fractional@finish#1M{% + \expandafter\def\expandafter\pgfmathresultfractional\expandafter{\pgfmathresultfractional #1}% + \pgfmathprintnumber@thousand@sep@in@fractional@finish@ +}% +\def\pgfmathprintnumber@thousand@sep@in@fractional@finish@#1\@@{}% + \def\pgfmathprintnumber@fixed@styleDEFAULT@impl@noperiod@printall#1{% \def\pgfmathfloat@loc@TMPb{#1}% \let\pgfmathfloat@loc@TMPc=\pgfutil@empty @@ -662,7 +727,7 @@ % The default style to display fixed point numbers. % -% It does not apply numerics, but it is responsable to typeset the +% It does not apply numerics, but it is responsable for typesetting the % rounded number. % It can access the \ifpgfmathfloatroundhasperiod boolean. % @@ -753,21 +818,23 @@ % #1: the part before the exponent code % #2: the part for the exponent code. \def\pgfmathfloatrounddisplaystyle@shared@impl@#1#2{% - {\toks0={#1}% + \pgfmathprintnumber@begingroup + \toks0={#1}% \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}% \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 }% - }% + \pgfmathprintnumber@endgroup \let\pgfmathresult=\pgfmathfloat@glob@TMP }% % Same as \pgfmathfloatrounddisplaystyle@shared@impl@, but it also % inserts the '@dec sep mark' at the end. \def\pgfmathfloatrounddisplaystyle@shared@impl@@#1#2{% - {\toks0={#1}% + \pgfmathprintnumber@begingroup + \toks0={#1}% \toks1=\expandafter{\pgfmathfloatrounddisplaystyle@e@mark #2}% \pgfkeysgetvalue{/pgf/number format/@dec sep mark}\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK \toks2=\expandafter{\pgfmathprintnumber@fixed@styleDEFAULT@DEC@SEP@MARK}% \xdef\pgfmathfloat@glob@TMP{\the\toks0 \the\toks1 \the\toks2 }% - }% + \pgfmathprintnumber@endgroup \let\pgfmathresult=\pgfmathfloat@glob@TMP } @@ -782,10 +849,11 @@ } \def\pgfmathfloatrounddisplaystyle@e#1#2e#3\relax{% \ifnum#3<0\relax - {\count0=#3\relax + \pgfmathprintnumber@begingroup + \count0=#3\relax \multiply\count0 by-1 \xdef\pgfmathfloat@glob@TMP{e{-}\the\count0}% - }% + \pgfmathprintnumber@endgroup% \let\pgfmathresult=\pgfmathfloat@glob@TMP \else \def\pgfmathresult{e{+}#3}% @@ -795,10 +863,11 @@ } \def\pgfmathfloatrounddisplaystyle@E#1#2e#3\relax{% \ifnum#3<0\relax - {\count0=#3\relax + \pgfmathprintnumber@begingroup + \count0=#3\relax \multiply\count0 by-1 \xdef\pgfmathfloat@glob@TMP{E{-}\the\count0}% - }% + \pgfmathprintnumber@endgroup% \let\pgfmathresult=\pgfmathfloat@glob@TMP \else \def\pgfmathresult{E{+}#3}% @@ -841,6 +910,14 @@ \long\def\pgfmathfloatfrac@verbatim#1#2{#1/#2}% +\let\pgfmathround@@orig=\pgfmathround@ + +% 2 = compatible +% 0 = no +% 1 = yes +\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{2}% + +\newif\ifpgfmathprintnumber@thousand@sep@in@fractional \pgfkeys{% /pgf/number format/.is family, /pgf/number format, @@ -848,6 +925,22 @@ sci/.code= \pgfmath@set@number@printer{pgfmathprintnumber@SCI}, std/.code= {\pgfmath@set@number@printer{pgfmathprintnumber@STD}\pgfmathprintnumber@STD@setparam{#1}}, std/.default=,% + relative round mode/.is choice, + relative round mode/fixed/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{1}}, + relative round mode/mantissa/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{0}}, + relative round mode/compatible/.code={\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed{2}}, + % relative={} + relative/.code= {% + \pgfmath@set@number@printer{pgfmathprintnumber@RELATIVE}% + \pgfmathround@@orig{#1}% + \expandafter\pgfmathfloattoint@@\pgfmathresult\relax + \let\pgfmathprintnumber@RELATIVE@param=\pgfmathresult + },% + relative/.value required, + relative*/.style={/pgf/number format/relative={#1},/pgf/number format/relative round mode=fixed}, + every relative/.style=std, + relative style/.style={/pgf/number format/every relative/.append style={#1}}, + fixed relative/.code= \pgfmath@set@number@printer{pgfmathprintnumber@FIXED@RELATIVE}, int detect/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@DETECT}, int trunc/.code= \pgfmath@set@number@printer{pgfmathprintnumber@INT@TRUNC}, frac/.code= \pgfmath@set@number@printer{pgfmathprintnumber@frac},% @@ -880,11 +973,13 @@ sci precision=, fixed default/.code= {\let\pgfmathprintnumber@fixed@style=\pgfmathprintnumber@fixed@styleDEFAULT}, set decimal separator/.initial=, - dec sep/.style={/pgf/number format/set decimal separator=#1}, + dec sep/.style={/pgf/number format/set decimal separator={#1}}, @dec sep mark/.initial=, @sci exponent mark/.initial=, set thousands separator/.initial=, - 1000 sep/.style={/pgf/number format/set thousands separator=#1}, + 1000 sep in fractionals/.is if=pgfmathprintnumber@thousand@sep@in@fractional, + 1000 sep in fractionals/.default=true, + 1000 sep/.style={/pgf/number format/set thousands separator={#1}}, min exponent for 1000 sep/.initial=0, use period/.style= {/pgf/number format/set decimal separator={.},/pgf/number format/set thousands separator={{{,}}}}, use comma/.style= {/pgf/number format/set decimal separator={{{,}}},/pgf/number format/set thousands separator={.}}, @@ -946,7 +1041,7 @@ \ifx\pgfmathfloat@loc@TMPb\pgfutil@empty % DEFAULT for lower and upper bound. \def\pgfmathprintnumber@STD@getlowerbound{% - \c@pgf@counta=\pgfmathfloat@round@precision\relax + \c@pgf@counta=\pgfmathfloat@round@precision@orig\relax \divide\c@pgf@counta by-2\relax }% \def\pgfmathprintnumber@STD@upperbound{4}% @@ -992,6 +1087,114 @@ \fi } +\def\pgfmathprintnumber@RELATIVE#1{% + % parse the input: + \pgfmathfloatparsenumber{#1}% + \pgfmathfloat@to@FMeE@style\pgfmathresult + \expandafter\pgfmathprintnumber@RELATIVE@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn{% + \immediate\write16{! Package pgf warning: the use of /pgf/number format/relative is discouraged (buggy). Please use 'relative*' instead or type \string\pgfkeys{/pgf/number format/relative round mode=fixed} into your preamble.}% + \global\let\pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn=\relax +} + +\def\pgfmathprintnumber@RELATIVE@issci#1#2e#3\relax{% + \begingroup + % format X / 10^{relative}: + \c@pgf@counta=#3\relax + \advance\c@pgf@counta by-\pgfmathprintnumber@RELATIVE@param\relax + \pgfmathfloatcreate{#1}{#2}{\the\c@pgf@counta}% + % OK, round it to the desired precision: + \if0\pgfmathprintnumber@RELATIVE@choice@roundtofixed + % relative round mode=mantissa + \def\b@round@fixed{0}% + \else + \if1\pgfmathprintnumber@RELATIVE@choice@roundtofixed + % relative round mode=fixed + \def\b@round@fixed{1}% + \else + \pgfmathprintnumber@RELATIVE@choice@roundtofixed@warn + % relative round mode=compatible + \ifnum\c@pgf@counta>0 + % hm. for positive exponents, we should round the + % mantissa rather than only the fractional part. + \def\b@round@fixed{0}% + \else + % negative exponent -> round fixed representation: + \def\b@round@fixed{1}% + \fi + \fi + \fi + \if1\b@round@fixed + % round fixed representation: + \pgfmathfloattofixed\pgfmathresult + \expandafter\pgfmathroundto\expandafter{\pgfmathresult}% + \pgfmathfloatparsenumber{\pgfmathresult}% + \pgfmathfloatroundhasperiodtrue% make sure the code below works: + \else + % round the mantissa: + \expandafter\pgfmathfloatround\expandafter{\pgfmathresult}% + \fi + % Now, compute result * 10^{relative} and format the result: + \pgfmathfloattoregisterstok\pgfmathresult\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifnum\pgfmathfloat@a@S=0 + \pgfmathfloat@a@E=\pgfmathfloat@a@S % avoid 0 * 10^8 + \else + \advance\pgfmathfloat@a@E by+\pgfmathprintnumber@RELATIVE@param\relax + \fi + \edef\pgfmathresultX{% + \the\pgfmathfloat@a@S + \the\pgfmathfloat@a@Mtok + \ifpgfmathfloatroundhasperiod\else.0\fi + e\the\pgfmathfloat@a@E}% + % call another formatter for the result (but avoid rounding inside of it): + \pgfqkeys{/pgf/number format}{/pgf/number format/every relative, + fixed zerofill=false,% useless here! + sci zerofill=false}% + \ifx\pgfmathprintnumber@issci\pgfmathprintnumber@RELATIVE@issci + \pgfmath@error{The '/pgf/number format/every relative' style should set a valid display style}% + \fi + \let\pgfmathfloat@round@precision@orig=\pgfmathfloat@round@precision + \def\pgfmathfloat@round@precision{9999}% + \expandafter\pgfmathprintnumber@issci\pgfmathresultX\relax% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + +\def\pgfmathprintnumber@FIXED@RELATIVE#1{% + % parse the input: + \pgfmathfloatparsenumber{#1}% + \pgfmathfloat@to@FMeE@style\pgfmathresult + \expandafter\pgfmathprintnumber@FIXED@RELATIVE@issci\pgfmathresult\relax +} + +\def\pgfmathprintnumber@FIXED@RELATIVE@issci#1#2e#3\relax{% + \begingroup + \pgfmathfloatcreate{#1}{#2}{#3}% + % we want the first digits - not the first + % +1 digits: + \c@pgf@counta=\pgfmathfloat@round@precision\relax + \advance\c@pgf@counta by-1 + \edef\pgfmathfloat@round@precision{\the\c@pgf@counta}% + \pgfmathfloatround{\pgfmathresult}% + \pgfmathfloattoregisterstok\pgfmathresult\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifnum\pgfmathfloat@a@S=0 + \pgfmathfloat@a@E=\pgfmathfloat@a@S % avoid 0 * 10^8 + \fi + \edef\pgfmathresultX{% + \the\pgfmathfloat@a@S + \the\pgfmathfloat@a@Mtok + \ifpgfmathfloatroundhasperiod\else.0\fi + e\the\pgfmathfloat@a@E}% + \let\pgfmathfloat@round@precision@orig=\pgfmathfloat@round@precision + \pgfmathfloat@usezerofill@fixedfalse + \def\pgfmathfloat@round@precision{9999}% typeset all remaining digits! + \expandafter\pgfmathprintnumber@FIXED@issci\pgfmathresultX\relax% + \pgfmath@smuggleone\pgfmathresult + \endgroup +} + \def\pgfmathprintnumber@frac#1{% % parse the input: \pgfmathfloatparsenumber{#1}% @@ -1048,7 +1251,7 @@ % The numerator and denominator is always a number (not empty) \def\pgfmathfloatgetfrac#1{% \pgfutil@ifundefined{pgfmathfloatmultiply@}{% - \PackageError{tikz}{Sorry, the number format 'frac' requires '\string\usetikzlibrary{fpu}' (and, optionally, \string\usepackage{fp}) in order to work correctly}{}% + \pgfmath@PackageError{Sorry, the number format 'frac' requires '\string\usetikzlibrary{fpu}' (and, optionally, \string\usepackage{fp}) in order to work correctly}% \edef\pgfmathresult{{#1}{0}{1}}% }{% \pgfmathfloatgetfrac@{#1}% diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex index a4e510d4dc8..581cdaade5f 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.base.code.tex @@ -301,3 +301,31 @@ \def\pgfmathsetbasenumberlength#1{\def\pgfmath@basenumberlength{#1}} \pgfmathsetbasenumberlength{1}% + +% \pgfmathtodigitlist\marg{macro}\marg{number}} +% +% This command converts \meta{number} into a comma-separated +% list of digits and stores the result in \meta{macro}. +% The \marg{number} is \emph{not} parsed before processing. +% +\def\pgfmathtodigitlist#1#2{% + \def\pgfmath@temp{#1}% + \let\pgfmath@digitlist=\pgfutil@empty% + \edef\pgfmath@@tmp{#2}% + \expandafter\pgfmath@todigitlist\pgfmath@@tmp @% +} +\def\pgfmath@base@atchar{@} +\def\pgfmath@todigitlist#1{% + \def\pgfmath@digit{#1}% + \ifx\pgfmath@digit\pgfmath@base@atchar% + \expandafter\let\pgfmath@temp=\pgfmath@digitlist% + \else% + \ifx\pgfmath@digitlist\pgfutil@empty% + \edef\pgfmath@digitlist{#1}% + \else% + \edef\pgfmath@digitlist{\pgfmath@digitlist,#1}% + \fi% + \expandafter\pgfmath@todigitlist% + \fi% +} + diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex index ca741fa7adc..99f8ccbb2c0 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.basic.code.tex @@ -121,9 +121,24 @@ \divide\c@pgfmath@counta by\c@pgfmath@countb% \pgfmath@ya=\c@pgfmath@counta\pgfmath@y% \advance\pgfmath@x by-\pgfmath@ya% - \expandafter\expandafter\expandafter\def% - \expandafter\expandafter\expandafter\pgfmathresult - \expandafter\expandafter\expandafter{\expandafter\pgfmathresult\the\c@pgfmath@counta}% + \def\pgfmath@next{% + \toks0=\expandafter{\pgfmathresult}% + \edef\pgfmathresult{\the\toks0 \the\c@pgfmath@counta}% + }% + \ifpgfmath@divide@period + \else + % we are behind the period. It may happen that the + % result is more than one digit - in that case, + % introduce special handling: + \ifnum\c@pgfmath@counta>9 % + \expandafter\pgfmathdivide@advance@last@digit\pgfmathresult CCCCC\@@ + \advance\c@pgfmath@counta by-10 % + \ifnum\c@pgfmath@counta=0 + \let\pgfmath@next=\relax + \fi + \fi + \fi + \pgfmath@next \fi% \let\pgfmath@next=\pgfmathdivide@@% \fi% @@ -131,6 +146,46 @@ \pgfmath@next% } +% advances the last digit found in the number. Any missing digits are +% supposed to be filled with 'C'. +\def\pgfmathdivide@advance@last@digit#1.#2#3#4#5#6#7\@@{% + \pgfmath@ya=\pgfmathresult pt % + \if#2C% + \pgfmath@xa=1pt % + \else + \if#3C% + \pgfmath@xa=0.1pt % + \else + \if#4C% + \pgfmath@xa=0.01pt % + \else + \if#5C% + \pgfmath@xa=0.001pt % + \else + \if#6C% + \pgfmath@xa=0.0001pt % + \else + \pgfmath@xa=0.00001pt % + \fi + \fi + \fi + \fi + \fi + \advance\pgfmath@ya by\pgfmath@xa + \edef\pgfmathresult{\pgfmath@tonumber@notrailingzero\pgfmath@ya}% +}% + +{ +\catcode`\p=12 +\catcode`\t=12 +\gdef\Pgf@geT@NO@TRAILING@ZERO#1.#2pt{% + #1.% + \ifnum#2=0 \else #2\fi +} +} +\def\pgfmath@tonumber@notrailingzero#1{\expandafter\Pgf@geT@NO@TRAILING@ZERO\the#1} + + \def\pgfmathdivide@dimenbyten#1{% \edef\pgfmath@temp{\pgfmath@tonumber{#1}}% \expandafter\pgfmathdivide@@dimenbyten\pgfmath@temp\@@#1\@@} @@ -451,32 +506,33 @@ % exp function. % \pgfmathdeclarefunction{exp}{1}{% - \begingroup% - \pgfmath@xc=#1pt\relax% - \ifdim\pgfmath@xc<-9pt% - \pgfmath@x=1sp\relax% - \else% - \ifdim\pgfmath@xc<0pt% - \pgfmath@xc=-\pgfmath@xc% - \fi% - \pgfmath@x=1pt\relax% - \pgfmath@xa=1pt\relax% - \pgfmath@xb=\pgfmath@x% + \begingroup + \pgfmath@xc=#1pt\relax + \pgfmath@yc=#1pt\relax + \ifdim\pgfmath@xc<-9pt + \pgfmath@x=1sp\relax + \else + \ifdim\pgfmath@xc<0pt + \pgfmath@xc=-\pgfmath@xc + \fi + \pgfmath@x=1pt\relax + \pgfmath@xa=1pt\relax + \pgfmath@xb=\pgfmath@x \pgfmathloop% - \divide\pgfmath@xa by\pgfmathcounter% + \divide\pgfmath@xa by\pgfmathcounter \pgfmath@xa=\pgfmath@tonumber\pgfmath@xc\pgfmath@xa% - \advance\pgfmath@x by\pgfmath@xa% - \ifdim\pgfmath@x=\pgfmath@xb% - \else% - \pgfmath@xb=\pgfmath@x% + \advance\pgfmath@x by\pgfmath@xa + \ifdim\pgfmath@x=\pgfmath@xb + \else + \pgfmath@xb=\pgfmath@x \repeatpgfmathloop% - \ifdim#1pt<0pt% + \ifdim\pgfmath@yc<0pt \pgfmathreciprocal@{\pgfmath@tonumber\pgfmath@x}% - \pgfmath@x=\pgfmathresult pt\relax% - \fi% - \fi% + \pgfmath@x=\pgfmathresult pt\relax + \fi + \fi \pgfmath@returnone\pgfmath@x% - \endgroup% + \endgroup } % sqrt function. @@ -664,34 +720,42 @@ \begingroup% \pgfmath@xa=#1pt% \pgfmath@xb=#2pt% - \afterassignment\pgfmath@x% - \expandafter\c@pgfmath@counta\the\pgfmath@xb\relax% - \ifnum\c@pgfmath@counta<0\relax% - \c@pgfmath@counta=-\c@pgfmath@counta% - \pgfmathreciprocal@{#1}% - \pgfmath@xa=\pgfmathresult pt\relax% - \fi - \ifdim\pgfmath@x=0pt\relax% - \pgfmath@x=1pt\relax% - \pgfmathloop% - \ifnum\c@pgfmath@counta>0\relax% - \ifodd\c@pgfmath@counta% - \pgfmath@x=\pgfmath@tonumber{\pgfmath@x}\pgfmath@xa% - \fi - \ifnum\c@pgfmath@counta>1\relax% - \pgfmath@xa=\pgfmath@tonumber{\pgfmath@xa}\pgfmath@xa% - \fi% - \divide\c@pgfmath@counta by2\relax% - \repeatpgfmathloop% - \else% - \pgfmathln@{#1}% - \pgfmath@x=\pgfmathresult pt\relax% - \pgfmath@x=\pgfmath@tonumber{\pgfmath@xb}\pgfmath@x% - \pgfmathexp@{\pgfmath@tonumber{\pgfmath@x}}% - \pgfmath@x=\pgfmathresult pt\relax% - \fi% - \pgfmath@returnone\pgf@x% - \endgroup% + \ifdim\pgfmath@xa=0pt\relax% + \ifdim\pgfmath@xb=0pt\relax% + \pgfmath@x=1pt\relax% + \else% + \pgfmath@x=0pt\relax% + \fi% + \else% + \afterassignment\pgfmath@x% + \expandafter\c@pgfmath@counta\the\pgfmath@xb\relax% + \ifnum\c@pgfmath@counta<0\relax% + \c@pgfmath@counta=-\c@pgfmath@counta% + \pgfmathreciprocal@{#1}% + \pgfmath@xa=\pgfmathresult pt\relax% + \fi + \ifdim\pgfmath@x=0pt\relax% + \pgfmath@x=1pt\relax% + \pgfmathloop% + \ifnum\c@pgfmath@counta>0\relax% + \ifodd\c@pgfmath@counta% + \pgfmath@x=\pgfmath@tonumber{\pgfmath@x}\pgfmath@xa% + \fi + \ifnum\c@pgfmath@counta>1\relax% + \pgfmath@xa=\pgfmath@tonumber{\pgfmath@xa}\pgfmath@xa% + \fi% + \divide\c@pgfmath@counta by2\relax% + \repeatpgfmathloop% + \else% + \pgfmathln@{#1}% + \pgfmath@x=\pgfmathresult pt\relax% + \pgfmath@x=\pgfmath@tonumber{\pgfmath@xb}\pgfmath@x% + \pgfmathexp@{\pgfmath@tonumber{\pgfmath@x}}% + \pgfmath@x=\pgfmathresult pt\relax% + \fi% + \fi + \pgfmath@returnone\pgf@x% + \endgroup% } % factorial function. @@ -711,3 +775,7 @@ \pgfmath@smuggleone\pgfmathresult% \endgroup% } + +% Local Variables: +% coding: undecided-unix +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex index a493b6c6b62..55ef700c14d 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.code.tex @@ -238,3 +238,10 @@ \input pgfmathfunctions.base.code.tex \input pgfmathfunctions.round.code.tex \input pgfmathfunctions.misc.code.tex +\input pgfmathfunctions.integerarithmetics.code.tex + + + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex new file mode 100644 index 00000000000..f11704c94c2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.integerarithmetics.code.tex @@ -0,0 +1,124 @@ +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +% Macros contributed by Alain Matthes and adapted by CJ +\pgfmathdeclarefunction{gcd}{2}{% + \begingroup + \pgfmathcontinuelooptrue + \pgfmath@xa=#1pt + \pgfmath@xb=#2pt + \ifdim\pgfmath@xa=0pt + \pgfmathcontinueloopfalse + \pgfmath@xa=\pgfmath@xb + \fi + \ifdim\pgfmath@xb=0pt + \pgfmathcontinueloopfalse + \pgfmath@xb=\pgfmath@xa + \fi + \ifdim\pgfmath@xa<0pt + \pgfmath@xa=-\pgfmath@xa + \fi + \ifdim\pgfmath@xb<0pt + \pgfmath@xb=-\pgfmath@xb + \fi + \loop + \ifpgfmathcontinueloop + \ifdim\pgfmath@xa=\pgfmath@xb + \pgfmathcontinueloopfalse + \else + \ifdim\pgfmath@xa>\pgfmath@xb + \advance\pgfmath@xa by-\pgfmath@xb + \else + \advance\pgfmath@xb by-\pgfmath@xa + \fi + \fi + \repeat + \pgfmathparse{int(\pgfmath@xa)}% + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\newif\ifpgfmath@isprime@unknown +\newif\ifpgfmath@isprime + +\pgfmathdeclarefunction{isprime}{1}{% + \begingroup + \pgfmath@isprime@unknowntrue + \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}% + \ifcase\c@pgfmath@counta\relax + % |#1| = 0 + \pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \or + % |#1| = 1 + \pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \or + % |#1| = 2 + \pgfmath@isprimetrue + \pgfmath@isprime@unknownfalse + \or + % |#1| = 3 + \pgfmath@isprimetrue + \pgfmath@isprime@unknownfalse + \else + % |#1| > 3 + \ifodd\c@pgfmath@counta\relax + \else + \pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \fi + \fi + \ifpgfmath@isprime@unknown + \c@pgfmath@countd=3 + \pgfmath@isprimetrue + \pgfmathloop + \c@pgfmath@countb=\c@pgfmath@counta + \divide\c@pgfmath@countb by\c@pgfmath@countd + \ifnum\c@pgfmath@countb>\c@pgfmath@countd + \pgfmath@isprime@unknowntrue + \else + \pgfmath@isprime@unknownfalse + \fi + \multiply\c@pgfmath@countb by\c@pgfmath@countd + \ifnum\c@pgfmath@countb=\c@pgfmath@counta + \global\pgfmath@isprimefalse + \pgfmath@isprime@unknownfalse + \fi + \ifpgfmath@isprime@unknown\advance\c@pgfmath@countd by 2 + \repeatpgfmathloop + \fi + \ifpgfmath@isprime + \def\pgfmathresult{1}% + \else + \def\pgfmathresult{0}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\pgfmathdeclarefunction{isodd}{1}{% + \begingroup + \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}% + \ifodd\c@pgfmath@counta + \def\pgfmathresult{1}% + \else + \def\pgfmathresult{0}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\pgfmathdeclarefunction{iseven}{1}{% + \begingroup + \pgfmathsetcount\c@pgfmath@counta{abs(int(#1))}% + \ifodd\c@pgfmath@counta + \def\pgfmathresult{0}% + \else + \def\pgfmathresult{1}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup} + +\endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex index 65460e4b3cc..e00786d7a37 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.misc.code.tex @@ -160,6 +160,9 @@ \def\pgfmath@scientific@@@#1#2#3#4#5#6\pgfmath@{% \edef\pgfmath@sci@mantissaB{#1#2#3#4#5}% \c@pgfmath@counta\pgfmath@sci@exponent\relax% + \ifnum\c@pgfmath@counta<-4\relax% + \pgfmath@x0pt\relax% + \else% \c@pgfmath@countb\c@pgfmath@counta% \ifnum\c@pgfmath@counta<0\relax% \c@pgfmath@counta-\c@pgfmath@counta% @@ -191,7 +194,7 @@ \advance\c@pgfmath@countc100000\relax% \edef\pgfmath@sci@result{\pgfmath@sci@sign\the\c@pgfmath@counta.\expandafter\pgfmath@gobbleone\the\c@pgfmath@countc pt}% \pgfmath@x\pgfmath@sci@result\relax% - \fi% + \fi\fi% \pgfmath@returnone\pgfmath@x% \endgroup} @@ -263,6 +266,24 @@ \pgfmath@smuggleone\pgfmathresult\endgroup% } +% dim function: return dimension of an array +% dim({1,2,3}) return 3 +% dim({{1,2,3},{4,5,6}}) return 2 +\pgfmathdeclarefunction{dim}{1}{% + \begingroup + \pgfmath@count=0\relax + \expandafter\pgfmath@dim@i\pgfutil@firstofone#1\pgfmath@token@stop + \edef\pgfmathresult{\the\pgfmath@count}% + \pgfmath@smuggleone\pgfmathresult% + \endgroup} + +\def\pgfmath@dim@i#1{% + \ifx\pgfmath@token@stop#1% + \else + \advance\pgfmath@count by 1\relax + \expandafter\pgfmath@dim@i + \fi} + % max function. % @@ -287,7 +308,7 @@ % For compatability with old code. \def\pgfmathmax#1#2{% - \pgfmathparse{getargs(#1,#2)}% + \pgfmathparse{#1,#2}% \expandafter\pgfmathmax@\expandafter{\pgfmathresult}% } @@ -314,7 +335,7 @@ % For compatability with old code. \def\pgfmathmin#1#2{% - \pgfmathparse{getargs(#1,#2)}% + \pgfmathparse{#1,#2}% \expandafter\pgfmathmin@\expandafter{\pgfmathresult}% } diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex index 6b60eb7ec16..02726731357 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathfunctions.trigonometric.code.tex @@ -24,36 +24,36 @@ % Convert #1 from radians to degrees (accurate to 1 deg). % \pgfmathdeclarefunction{radians}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) + \pgfmath@returnone\pgfmath@x% + \endgroup% }% % \pgfmathdeg % % Convert #1 from radians to degrees. % -\pgfmathdeclarefunction{deg}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) - \pgfmath@returnone\pgfmath@x% - \endgroup% +\pgfmathdeclarefunction{deg}{1}{% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@x57.29577\pgfmath@x\relax% 57.29577 = 360/(2*pi) + \pgfmath@returnone\pgfmath@x% + \endgroup% }% % \pgfmathrad % % Convert #1 from degrees to radians. % -\pgfmathdeclarefunction{rad}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@x3.14159\pgfmath@x% - \divide\pgfmath@x180\relax% - \pgfmath@returnone\pgfmath@x% - \endgroup% +\pgfmathdeclarefunction{rad}{1}{% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@x3.14159\pgfmath@x% + \divide\pgfmath@x180\relax% + \pgfmath@returnone\pgfmath@x% + \endgroup% }% % \pgfmathsin @@ -61,40 +61,41 @@ % Calculate the sine of #1 (in degrees). % \pgfmathdeclarefunction{sin}{1}{% - % Let #1 = a.b - % Then sin(#1) \approx (1-b)*sin(a) + b*sin(a+1) - % - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \advance\pgfmath@x-90pt\relax% - \afterassignment\pgfmath@gobbletilpgfmath@ - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@ - \divide\c@pgfmath@counta360\relax% - \multiply\c@pgfmath@counta-360\relax% - \advance\pgfmath@x\c@pgfmath@counta pt\relax% - \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% - \ifdim\pgfmath@x<180pt\relax% - \else - \pgfmath@x-\pgfmath@x% - \advance\pgfmath@x360pt\relax% - \fi% - % Now 0 <= x < 179. So split x into integer and decimal... - % - \afterassignment\pgfmath@xa% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% - % - % ...if #1 is an integer, don't do anything fancy. - \ifdim\pgfmath@xa=0pt% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt\relax% - \else% - \pgfmath@x-\pgfmath@xa% - \advance\pgfmath@x1pt\relax% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% - \advance\c@pgfmath@counta1\relax% - \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup + % Let #1 = a.b + % Then sin(#1) \approx (1-b)*sin(a) + b*sin(a+1) + % + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \advance\pgfmath@x-90pt\relax% + \afterassignment\pgfmath@gobbletilpgfmath@ + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@ + \divide\c@pgfmath@counta360\relax% + \multiply\c@pgfmath@counta-360\relax% + \advance\pgfmath@x\c@pgfmath@counta pt\relax% + \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% + \ifdim\pgfmath@x<180pt\relax% + \else + \pgfmath@x-\pgfmath@x% + \advance\pgfmath@x360pt\relax% + \fi% + % Now 0 <= x < 179. So split x into integer and decimal... + % + \afterassignment\pgfmath@xa% + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% + % + % ...if #1 is an integer, don't do anything fancy. + \ifdim\pgfmath@xa=0pt% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt\relax% + \else% + \pgfmath@x-\pgfmath@xa% + \advance\pgfmath@x1pt\relax% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% + \advance\c@pgfmath@counta1\relax% + \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi% + \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup } % \pgfmathcos @@ -102,40 +103,40 @@ % Calculate the cosine of #1 (in degrees). % \pgfmathdeclarefunction{cos}{1}{% - % Let x = a.b - % Then cos(x) \approx (1-b)*cos(a) + b*cos(a+1) - % - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \divide\c@pgfmath@counta360\relax% - \multiply\c@pgfmath@counta-360\relax% - \advance\pgfmath@x\c@pgfmath@counta pt\relax% - \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% - \ifdim\pgfmath@x<180pt\relax% - \else% - \pgfmath@x-\pgfmath@x% - \advance\pgfmath@x360pt\relax% - \fi% - % Now 0 <= x < 179. So split x into integer and decimal... - % - \afterassignment\pgfmath@xa% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% - % - % ...if #1 is an integer, don't do anything fancy. - \ifdim\pgfmath@xa=0pt% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt% - \else% - \pgfmath@x-\pgfmath@xa% - \advance\pgfmath@x1pt\relax% - \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% - \advance\c@pgfmath@counta1\relax% - \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi% - \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + % Let x = a.b + % Then cos(x) \approx (1-b)*cos(a) + b*cos(a+1) + % + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \afterassignment\pgfmath@gobbletilpgfmath@% + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% + \divide\c@pgfmath@counta360\relax% + \multiply\c@pgfmath@counta-360\relax% + \advance\pgfmath@x\c@pgfmath@counta pt\relax% + \ifdim\pgfmath@x<0pt\relax\pgfmath@x-\pgfmath@x\fi% + \ifdim\pgfmath@x<180pt\relax% + \else% + \pgfmath@x-\pgfmath@x% + \advance\pgfmath@x360pt\relax% + \fi% + % Now 0 <= x < 179. So split x into integer and decimal... + % + \afterassignment\pgfmath@xa% + \expandafter\c@pgfmath@counta\the\pgfmath@x\relax% + % + % ...if #1 is an integer, don't do anything fancy. + \ifdim\pgfmath@xa=0pt% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname pt% + \else% + \pgfmath@x-\pgfmath@xa% + \advance\pgfmath@x1pt\relax% + \expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@x% + \advance\c@pgfmath@counta1\relax% + \ifnum\c@pgfmath@counta=181\relax\c@pgfmath@counta179\relax\fi% + \expandafter\advance\expandafter\pgfmath@x\csname pgfmath@cos@\the\c@pgfmath@counta\endcsname\pgfmath@xa% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } % \pgfmathsincos @@ -143,12 +144,12 @@ % Calculate the sin and cosine of #1 (in degrees). % \def\pgfmathsincos#1{% - \pgfmathparse{#1}% - \expandafter\pgfmathsincos@\expandafter{\pgfmathresult}} + \pgfmathparse{#1}% + \expandafter\pgfmathsincos@\expandafter{\pgfmathresult}} \def\pgfmathsincos@#1{% - \edef\pgfmath@temparg{#1}% - \pgfmathsin@{\pgfmath@temparg}\edef\pgfmathresulty{\pgfmathresult}% - \pgfmathcos@{\pgfmath@temparg}\edef\pgfmathresultx{\pgfmathresult}% + \edef\pgfmath@temparg{#1}% + \pgfmathsin@{\pgfmath@temparg}\edef\pgfmathresulty{\pgfmathresult}% + \pgfmathcos@{\pgfmath@temparg}\edef\pgfmathresultx{\pgfmathresult}% } % \pgfmathtan @@ -156,25 +157,25 @@ % Calculate the tangent of #1 (in degrees). % \pgfmathdeclarefunction{tan}{1}{% - \begingroup% - \edef\pgfmath@temparg{#1}% - \pgfmathcos@{\pgfmath@temparg}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% - \edef\pgfmath@tantemp{\pgfmathresult}% - \pgfmathsin@{\pgfmath@temparg}% - \pgfmath@x\pgfmathresult pt\relax% - \pgfmath@x\pgfmath@tantemp\pgfmath@x% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \edef\pgfmath@temparg{#1}% + \pgfmathcos@{\pgfmath@temparg}% + \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% + \edef\pgfmath@tantemp{\pgfmathresult}% + \pgfmathsin@{\pgfmath@temparg}% + \pgfmath@x\pgfmathresult pt\relax% + \pgfmath@x\pgfmath@tantemp\pgfmath@x% + \pgfmath@returnone\pgfmath@x% + \endgroup% } % \pgfmathcosec % % Calculate the cosec of #1 (in degrees). % -\pgfmathdeclarefunction{cosec}{1}{% - \expandafter\pgfmathsin@\expandafter{#1}% - \pgfmathreciprocal@{\pgfmathresult}% +\pgfmathdeclarefunction{cosec}{1}{% + \expandafter\pgfmathsin@\expandafter{#1}% + \pgfmathreciprocal@{\pgfmathresult}% } % \pgfmathsec @@ -182,1282 +183,1338 @@ % Calculate the sec of #1 (in degrees). % \pgfmathdeclarefunction{sec}{1}{% - \expandafter\pgfmathcos@\expandafter{#1}% - \pgfmathreciprocal@{\pgfmathresult}% + \expandafter\pgfmathcos@\expandafter{#1}% + \pgfmathreciprocal@{\pgfmathresult}% } % \pgfmathcot % % Calculate the cotangent of #1 (in degrees). % -\pgfmathdeclarefunction{cot}{1}{% - \begingroup% - \edef\pgfmath@temparg{#1}% - \pgfmathsin@{\pgfmath@temparg}% - \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% - \edef\pgfmath@tantemp{\pgfmathresult}% - \pgfmathcos@{\pgfmath@temparg}% - \pgfmath@x\pgfmathresult pt\relax% - \pgfmath@x\pgfmath@tantemp\pgfmath@x% - \pgfmath@returnone\pgfmath@x% - \endgroup% +\pgfmathdeclarefunction{cot}{1}{% + \begingroup% + \edef\pgfmath@temparg{#1}% + \pgfmathsin@{\pgfmath@temparg}% + \expandafter\pgfmathreciprocal@\expandafter{\pgfmathresult}% + \edef\pgfmath@tantemp{\pgfmathresult}% + \pgfmathcos@{\pgfmath@temparg}% + \pgfmath@x\pgfmathresult pt\relax% + \pgfmath@x\pgfmath@tantemp\pgfmath@x% + \pgfmath@returnone\pgfmath@x% + \endgroup% } +\def\pgfmath@multiply@thousand#1.#2#3#4#5\relax{% + \edef\pgfmathresult{#1#2#3#4.#5}% +}% + % \pgfmathasin % % The asin of #1 % \pgfmathdeclarefunction{asin}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@xa\pgfmath@x% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@x1000\pgfmath@x% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \pgfmath@x-\csname pgfmath@acos@\the\c@pgfmath@counta\endcsname pt\relax% - \advance\pgfmath@x90pt\relax% - \ifdim\pgfmath@xa<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \pgfmath@x=#1pt % + \pgfmath@xa\pgfmath@x% + \edef\pgf@temp{\pgf@sys@tonumber\pgfmath@x}% + % compute lossless '*1000' operation: + \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax + \pgfmath@x=\pgfmathresult pt % + \ifdim\pgfmath@x<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@table@lookup{\pgfmath@x}{pgfmath@acos@}{1001}% + \pgfmath@x=-\pgfmath@x + \advance\pgfmath@x90pt\relax% + \ifdim\pgfmath@xa<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% +} + +% Defines \pgfmath@x to be the result of the table lookup for value +% '#1' in table '#2' +% +% #1: a value for which lookup should be performed +% #2: the table's prefix name +% #3: the table's size +\def\pgfmath@table@lookup#1#2#3{% + \pgfmath@x=#1\relax + \expandafter\pgfmath@table@lookup@\the\pgfmath@x\relax{#2}{#3}% } +\def\pgfmath@table@lookup@#1.#2\relax#3#4{% + \edef\pgf@temp{\Pgf@geT#2}% strip 'pt' suffix. + % + % prepare constant interpolant (i.e. the value at node '#1'): + \pgfmath@x=\csname #3#1\endcsname pt % + % + \c@pgfmath@countc=#1 % + \advance\c@pgfmath@countc by1 % + \ifnum\c@pgfmath@countc<#4 % + % Ah - we have enough elements in the table. + % + % perform linear interpolation: + \pgfmath@ya=\csname #3\the\c@pgfmath@countc\endcsname pt % + \advance\pgfmath@ya by-\pgfmath@x % + \advance\pgfmath@x by0.\pgf@temp\pgfmath@ya + \fi +}% % \pgfmathacos % % The acos of #1 -% +% \pgfmathdeclarefunction{acos}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@xa\pgfmath@x% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@x1000\pgfmath@x% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \expandafter\pgfmath@x\csname pgfmath@acos@\the\c@pgfmath@counta\endcsname pt\relax% - \ifdim\pgfmath@xa<0pt\relax% - \pgfmath@x-\pgfmath@x% - \advance\pgfmath@x by180pt\relax% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \pgfmath@x#1pt\relax% + \pgfmath@xa\pgfmath@x% + \edef\pgf@temp{\pgf@sys@tonumber\pgfmath@x}% + % compute lossless '*1000' operation: + \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax + \pgfmath@x=\pgfmathresult pt % + \ifdim\pgfmath@x<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@table@lookup{\pgfmath@x}{pgfmath@acos@}{1001}% + \ifdim\pgfmath@xa<0pt\relax% + \pgfmath@x-\pgfmath@x% + \advance\pgfmath@x by180pt\relax% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } \pgfmathdeclarefunction{atan}{1}{% - \begingroup% - \expandafter\pgfmath@x#1pt\relax% - \pgfmath@xa\pgfmath@x% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@xb\pgfmath@x% - \ifdim\pgfmath@x>1pt\relax% - \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}% - \pgfmathreciprocal@{\pgfmath@temp}% - \pgfmath@x\pgfmathresult pt\relax% - \fi% - \pgfmath@x1000\pgfmath@x% - \afterassignment\pgfmath@gobbletilpgfmath@% - \expandafter\c@pgfmath@counta\the\pgfmath@x\relax\pgfmath@% - \ifdim\pgfmath@xb>1pt\relax% - \expandafter\pgfmath@x\expandafter-\csname pgfmath@atan@\the\c@pgfmath@counta\endcsname pt\relax% - \advance\pgfmath@x90pt% - \else% - \expandafter\pgfmath@x\csname pgfmath@atan@\the\c@pgfmath@counta\endcsname pt\relax% - \fi% - \ifdim\pgfmath@xa<0pt\relax% - \pgfmath@x-\pgfmath@x% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + \begingroup% + \expandafter\pgfmath@x#1pt\relax% + \pgfmath@xa\pgfmath@x% + \ifdim\pgfmath@x<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@xb\pgfmath@x% + \ifdim\pgfmath@x>1pt\relax% + \edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@x}}% + \pgfmathreciprocal@{\pgfmath@temp}% + \pgfmath@x\pgfmathresult pt\relax% + \fi% + % compute lossless '*1000' operation: + \edef\pgf@temp{\pgf@sys@tonumber\pgfmath@x}% + \expandafter\pgfmath@multiply@thousand\pgf@temp 000\relax + \pgfmath@x=\pgfmathresult pt % + \pgfmath@table@lookup{\pgfmath@x}{pgfmath@atan@}{1001}%xxx + \ifdim\pgfmath@xb>1pt\relax% + \pgfmath@x=-\pgfmath@x% + \advance\pgfmath@x90pt% + \fi% + \ifdim\pgfmath@xa<0pt\relax% + \pgfmath@x-\pgfmath@x% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } \pgfmathdeclarefunction{atan2}{2}{% - \begingroup% - \pgfmath@x=#1pt\relax% - \ifdim\pgfmath@x<0pt\relax% - \pgfmath@x=-\pgfmath@x% - \fi% - \ifdim\pgfmath@x<0.001pt\relax% - \ifdim#2pt<0pt\relax% - \pgfmath@x=-90pt\relax% - \else% - \ifdim#2pt>0pt\relax% - \pgfmath@x=90pt\relax% - \else% - \pgfmath@x=0pt\relax% - \fi% - \fi% - \else% - \pgfmathdivide@{#2}{#1}% - \expandafter\pgfmathatan@\expandafter{\pgfmathresult}% - \pgfmath@x=\pgfmathresult pt\relax% - \ifdim#2pt<0pt\relax% - \ifdim#1pt<0pt\relax% - \advance\pgfmath@x by-180pt\relax% - \fi% - \else% - \ifdim#1pt<0pt\relax% - \advance\pgfmath@x by180pt\relax% - \fi% - \fi% - \fi% - \pgfmath@returnone\pgfmath@x% - \endgroup% + % Note: first parameter is y (!), second is x (!) + \begingroup% + \pgfmath@y=#1pt\relax% + \ifdim\pgfmath@y<0pt\relax% + \pgfmath@y=-\pgfmath@y% + \fi% + \ifdim\pgfmath@y<0.001pt\relax% + \ifdim#2pt<0pt\relax% + \pgfmath@x=-180pt\relax% + \else% + \ifdim#2pt>0pt\relax% + \pgfmath@x=0pt\relax% + \else% + \ifdim#1pt<0pt% + \pgfmath@x=-90pt\relax% + \else% + \pgfmath@x=90pt\relax% + \fi% + \fi% + \fi% + \else% + \pgfmathabs@{#1}\let\pgfmath@tempa\pgfmathresult% + \pgfmathabs@{#2}\let\pgfmath@tempb\pgfmathresult% + \ifdim\pgfmath@tempa pt>\pgfmath@tempb pt% + \pgfmathdivide@{#2}{\pgfmath@tempa}% + \expandafter\pgfmathatan@\expandafter{\pgfmathresult}% + \pgfmath@x=90pt% + \advance\pgfmath@x by-\pgfmathresult pt\relax% + \else% + \pgfmathdivide@{\pgfmath@tempa}{#2}% + \expandafter\pgfmathatan@\expandafter{\pgfmathresult}% + \pgfmath@x=\pgfmathresult pt\relax% + \ifdim#2pt<0pt% + \advance\pgfmath@x by180pt\relax% + \fi% + \fi% + \ifdim#1pt<0pt\relax% + \pgfmath@x=-\pgfmath@x% + \fi% + \fi% + \pgfmath@returnone\pgfmath@x% + \endgroup% } +% This is needed since \pgfmathatan2 is not a legal macro name +\expandafter\let\expandafter\pgfmathatantwo\csname pgfmathatan2\endcsname +\expandafter\let\expandafter\pgfmathatantwo@\csname pgfmathatan2@\endcsname + \def\pgfmath@def#1#2#3{\expandafter\def\csname pgfmath@#1@#2\endcsname{#3}} -\pgfmath@def{cos}{0}{1.00000} \pgfmath@def{cos}{1}{0.99985} -\pgfmath@def{cos}{2}{0.99939} \pgfmath@def{cos}{3}{0.99863} -\pgfmath@def{cos}{4}{0.99756} \pgfmath@def{cos}{5}{0.99619} -\pgfmath@def{cos}{6}{0.99452} \pgfmath@def{cos}{7}{0.99255} -\pgfmath@def{cos}{8}{0.99027} \pgfmath@def{cos}{9}{0.98769} -\pgfmath@def{cos}{10}{0.98481} \pgfmath@def{cos}{11}{0.98163} -\pgfmath@def{cos}{12}{0.97815} \pgfmath@def{cos}{13}{0.97437} -\pgfmath@def{cos}{14}{0.97030} \pgfmath@def{cos}{15}{0.96593} -\pgfmath@def{cos}{16}{0.96126} \pgfmath@def{cos}{17}{0.95630} -\pgfmath@def{cos}{18}{0.95106} \pgfmath@def{cos}{19}{0.94552} -\pgfmath@def{cos}{20}{0.93969} \pgfmath@def{cos}{21}{0.93358} -\pgfmath@def{cos}{22}{0.92718} \pgfmath@def{cos}{23}{0.92050} -\pgfmath@def{cos}{24}{0.91355} \pgfmath@def{cos}{25}{0.90631} -\pgfmath@def{cos}{26}{0.89879} \pgfmath@def{cos}{27}{0.89101} -\pgfmath@def{cos}{28}{0.88295} \pgfmath@def{cos}{29}{0.87462} -\pgfmath@def{cos}{30}{0.86603} \pgfmath@def{cos}{31}{0.85717} -\pgfmath@def{cos}{32}{0.84805} \pgfmath@def{cos}{33}{0.83867} -\pgfmath@def{cos}{34}{0.82904} \pgfmath@def{cos}{35}{0.81915} -\pgfmath@def{cos}{36}{0.80902} \pgfmath@def{cos}{37}{0.79864} -\pgfmath@def{cos}{38}{0.78801} \pgfmath@def{cos}{39}{0.77715} -\pgfmath@def{cos}{40}{0.76604} \pgfmath@def{cos}{41}{0.75471} -\pgfmath@def{cos}{42}{0.74314} \pgfmath@def{cos}{43}{0.73135} -\pgfmath@def{cos}{44}{0.71934} \pgfmath@def{cos}{45}{0.70711} -\pgfmath@def{cos}{46}{0.69466} \pgfmath@def{cos}{47}{0.68200} -\pgfmath@def{cos}{48}{0.66913} \pgfmath@def{cos}{49}{0.65606} -\pgfmath@def{cos}{50}{0.64279} \pgfmath@def{cos}{51}{0.62932} -\pgfmath@def{cos}{52}{0.61566} \pgfmath@def{cos}{53}{0.60182} -\pgfmath@def{cos}{54}{0.58779} \pgfmath@def{cos}{55}{0.57358} -\pgfmath@def{cos}{56}{0.55919} \pgfmath@def{cos}{57}{0.54464} -\pgfmath@def{cos}{58}{0.52992} \pgfmath@def{cos}{59}{0.51504} -\pgfmath@def{cos}{60}{0.50000} \pgfmath@def{cos}{61}{0.48481} -\pgfmath@def{cos}{62}{0.46947} \pgfmath@def{cos}{63}{0.45399} -\pgfmath@def{cos}{64}{0.43837} \pgfmath@def{cos}{65}{0.42262} -\pgfmath@def{cos}{66}{0.40674} \pgfmath@def{cos}{67}{0.39073} -\pgfmath@def{cos}{68}{0.37461} \pgfmath@def{cos}{69}{0.35837} -\pgfmath@def{cos}{70}{0.34202} \pgfmath@def{cos}{71}{0.32557} -\pgfmath@def{cos}{72}{0.30902} \pgfmath@def{cos}{73}{0.29237} -\pgfmath@def{cos}{74}{0.27564} \pgfmath@def{cos}{75}{0.25882} -\pgfmath@def{cos}{76}{0.24192} \pgfmath@def{cos}{77}{0.22495} -\pgfmath@def{cos}{78}{0.20791} \pgfmath@def{cos}{79}{0.19081} -\pgfmath@def{cos}{80}{0.17365} \pgfmath@def{cos}{81}{0.15643} -\pgfmath@def{cos}{82}{0.13917} \pgfmath@def{cos}{83}{0.12187} -\pgfmath@def{cos}{84}{0.10453} \pgfmath@def{cos}{85}{0.08716} -\pgfmath@def{cos}{86}{0.06976} \pgfmath@def{cos}{87}{0.05234} -\pgfmath@def{cos}{88}{0.03490} \pgfmath@def{cos}{89}{0.01745} -\pgfmath@def{cos}{90}{0.00000} \pgfmath@def{cos}{91}{-0.01745} -\pgfmath@def{cos}{92}{-0.03490} \pgfmath@def{cos}{93}{-0.05234} -\pgfmath@def{cos}{94}{-0.06976} \pgfmath@def{cos}{95}{-0.08716} -\pgfmath@def{cos}{96}{-0.10453} \pgfmath@def{cos}{97}{-0.12187} -\pgfmath@def{cos}{98}{-0.13917} \pgfmath@def{cos}{99}{-0.15643} -\pgfmath@def{cos}{100}{-0.17365} \pgfmath@def{cos}{101}{-0.19081} -\pgfmath@def{cos}{102}{-0.20791} \pgfmath@def{cos}{103}{-0.22495} -\pgfmath@def{cos}{104}{-0.24192} \pgfmath@def{cos}{105}{-0.25882} -\pgfmath@def{cos}{106}{-0.27564} \pgfmath@def{cos}{107}{-0.29237} -\pgfmath@def{cos}{108}{-0.30902} \pgfmath@def{cos}{109}{-0.32557} -\pgfmath@def{cos}{110}{-0.34202} \pgfmath@def{cos}{111}{-0.35837} -\pgfmath@def{cos}{112}{-0.37461} \pgfmath@def{cos}{113}{-0.39073} -\pgfmath@def{cos}{114}{-0.40674} \pgfmath@def{cos}{115}{-0.42262} -\pgfmath@def{cos}{116}{-0.43837} \pgfmath@def{cos}{117}{-0.45399} -\pgfmath@def{cos}{118}{-0.46947} \pgfmath@def{cos}{119}{-0.48481} -\pgfmath@def{cos}{120}{-0.50000} \pgfmath@def{cos}{121}{-0.51504} -\pgfmath@def{cos}{122}{-0.52992} \pgfmath@def{cos}{123}{-0.54464} -\pgfmath@def{cos}{124}{-0.55919} \pgfmath@def{cos}{125}{-0.57358} -\pgfmath@def{cos}{126}{-0.58779} \pgfmath@def{cos}{127}{-0.60182} -\pgfmath@def{cos}{128}{-0.61566} \pgfmath@def{cos}{129}{-0.62932} -\pgfmath@def{cos}{130}{-0.64279} \pgfmath@def{cos}{131}{-0.65606} -\pgfmath@def{cos}{132}{-0.66913} \pgfmath@def{cos}{133}{-0.68200} -\pgfmath@def{cos}{134}{-0.69466} \pgfmath@def{cos}{135}{-0.70711} -\pgfmath@def{cos}{136}{-0.71934} \pgfmath@def{cos}{137}{-0.73135} -\pgfmath@def{cos}{138}{-0.74314} \pgfmath@def{cos}{139}{-0.75471} -\pgfmath@def{cos}{140}{-0.76604} \pgfmath@def{cos}{141}{-0.77715} -\pgfmath@def{cos}{142}{-0.78801} \pgfmath@def{cos}{143}{-0.79864} -\pgfmath@def{cos}{144}{-0.80902} \pgfmath@def{cos}{145}{-0.81915} -\pgfmath@def{cos}{146}{-0.82904} \pgfmath@def{cos}{147}{-0.83867} -\pgfmath@def{cos}{148}{-0.84805} \pgfmath@def{cos}{149}{-0.85717} -\pgfmath@def{cos}{150}{-0.86603} \pgfmath@def{cos}{151}{-0.87462} -\pgfmath@def{cos}{152}{-0.88295} \pgfmath@def{cos}{153}{-0.89101} -\pgfmath@def{cos}{154}{-0.89879} \pgfmath@def{cos}{155}{-0.90631} -\pgfmath@def{cos}{156}{-0.91355} \pgfmath@def{cos}{157}{-0.92050} -\pgfmath@def{cos}{158}{-0.92718} \pgfmath@def{cos}{159}{-0.93358} -\pgfmath@def{cos}{160}{-0.93969} \pgfmath@def{cos}{161}{-0.94552} -\pgfmath@def{cos}{162}{-0.95106} \pgfmath@def{cos}{163}{-0.95630} -\pgfmath@def{cos}{164}{-0.96126} \pgfmath@def{cos}{165}{-0.96593} -\pgfmath@def{cos}{166}{-0.97030} \pgfmath@def{cos}{167}{-0.97437} -\pgfmath@def{cos}{168}{-0.97815} \pgfmath@def{cos}{169}{-0.98163} -\pgfmath@def{cos}{170}{-0.98481} \pgfmath@def{cos}{171}{-0.98769} -\pgfmath@def{cos}{172}{-0.99027} \pgfmath@def{cos}{173}{-0.99255} -\pgfmath@def{cos}{174}{-0.99452} \pgfmath@def{cos}{175}{-0.99619} -\pgfmath@def{cos}{176}{-0.99756} \pgfmath@def{cos}{177}{-0.99863} -\pgfmath@def{cos}{178}{-0.99939} \pgfmath@def{cos}{179}{-0.99985} -\pgfmath@def{cos}{180}{-1.00000} \pgfmath@def{cos}{181}{-0.99985} +\pgfmath@def{cos}{0}{1.00000} \pgfmath@def{cos}{1}{0.99985} +\pgfmath@def{cos}{2}{0.99939} \pgfmath@def{cos}{3}{0.99863} +\pgfmath@def{cos}{4}{0.99756} \pgfmath@def{cos}{5}{0.99619} +\pgfmath@def{cos}{6}{0.99452} \pgfmath@def{cos}{7}{0.99255} +\pgfmath@def{cos}{8}{0.99027} \pgfmath@def{cos}{9}{0.98769} +\pgfmath@def{cos}{10}{0.98481} \pgfmath@def{cos}{11}{0.98163} +\pgfmath@def{cos}{12}{0.97815} \pgfmath@def{cos}{13}{0.97437} +\pgfmath@def{cos}{14}{0.97030} \pgfmath@def{cos}{15}{0.96593} +\pgfmath@def{cos}{16}{0.96126} \pgfmath@def{cos}{17}{0.95630} +\pgfmath@def{cos}{18}{0.95106} \pgfmath@def{cos}{19}{0.94552} +\pgfmath@def{cos}{20}{0.93969} \pgfmath@def{cos}{21}{0.93358} +\pgfmath@def{cos}{22}{0.92718} \pgfmath@def{cos}{23}{0.92050} +\pgfmath@def{cos}{24}{0.91355} \pgfmath@def{cos}{25}{0.90631} +\pgfmath@def{cos}{26}{0.89879} \pgfmath@def{cos}{27}{0.89101} +\pgfmath@def{cos}{28}{0.88295} \pgfmath@def{cos}{29}{0.87462} +\pgfmath@def{cos}{30}{0.86603} \pgfmath@def{cos}{31}{0.85717} +\pgfmath@def{cos}{32}{0.84805} \pgfmath@def{cos}{33}{0.83867} +\pgfmath@def{cos}{34}{0.82904} \pgfmath@def{cos}{35}{0.81915} +\pgfmath@def{cos}{36}{0.80902} \pgfmath@def{cos}{37}{0.79864} +\pgfmath@def{cos}{38}{0.78801} \pgfmath@def{cos}{39}{0.77715} +\pgfmath@def{cos}{40}{0.76604} \pgfmath@def{cos}{41}{0.75471} +\pgfmath@def{cos}{42}{0.74314} \pgfmath@def{cos}{43}{0.73135} +\pgfmath@def{cos}{44}{0.71934} \pgfmath@def{cos}{45}{0.70711} +\pgfmath@def{cos}{46}{0.69466} \pgfmath@def{cos}{47}{0.68200} +\pgfmath@def{cos}{48}{0.66913} \pgfmath@def{cos}{49}{0.65606} +\pgfmath@def{cos}{50}{0.64279} \pgfmath@def{cos}{51}{0.62932} +\pgfmath@def{cos}{52}{0.61566} \pgfmath@def{cos}{53}{0.60182} +\pgfmath@def{cos}{54}{0.58779} \pgfmath@def{cos}{55}{0.57358} +\pgfmath@def{cos}{56}{0.55919} \pgfmath@def{cos}{57}{0.54464} +\pgfmath@def{cos}{58}{0.52992} \pgfmath@def{cos}{59}{0.51504} +\pgfmath@def{cos}{60}{0.50000} \pgfmath@def{cos}{61}{0.48481} +\pgfmath@def{cos}{62}{0.46947} \pgfmath@def{cos}{63}{0.45399} +\pgfmath@def{cos}{64}{0.43837} \pgfmath@def{cos}{65}{0.42262} +\pgfmath@def{cos}{66}{0.40674} \pgfmath@def{cos}{67}{0.39073} +\pgfmath@def{cos}{68}{0.37461} \pgfmath@def{cos}{69}{0.35837} +\pgfmath@def{cos}{70}{0.34202} \pgfmath@def{cos}{71}{0.32557} +\pgfmath@def{cos}{72}{0.30902} \pgfmath@def{cos}{73}{0.29237} +\pgfmath@def{cos}{74}{0.27564} \pgfmath@def{cos}{75}{0.25882} +\pgfmath@def{cos}{76}{0.24192} \pgfmath@def{cos}{77}{0.22495} +\pgfmath@def{cos}{78}{0.20791} \pgfmath@def{cos}{79}{0.19081} +\pgfmath@def{cos}{80}{0.17365} \pgfmath@def{cos}{81}{0.15643} +\pgfmath@def{cos}{82}{0.13917} \pgfmath@def{cos}{83}{0.12187} +\pgfmath@def{cos}{84}{0.10453} \pgfmath@def{cos}{85}{0.08716} +\pgfmath@def{cos}{86}{0.06976} \pgfmath@def{cos}{87}{0.05234} +\pgfmath@def{cos}{88}{0.03490} \pgfmath@def{cos}{89}{0.01745} +\pgfmath@def{cos}{90}{0.00000} \pgfmath@def{cos}{91}{-0.01745} +\pgfmath@def{cos}{92}{-0.03490} \pgfmath@def{cos}{93}{-0.05234} +\pgfmath@def{cos}{94}{-0.06976} \pgfmath@def{cos}{95}{-0.08716} +\pgfmath@def{cos}{96}{-0.10453} \pgfmath@def{cos}{97}{-0.12187} +\pgfmath@def{cos}{98}{-0.13917} \pgfmath@def{cos}{99}{-0.15643} +\pgfmath@def{cos}{100}{-0.17365} \pgfmath@def{cos}{101}{-0.19081} +\pgfmath@def{cos}{102}{-0.20791} \pgfmath@def{cos}{103}{-0.22495} +\pgfmath@def{cos}{104}{-0.24192} \pgfmath@def{cos}{105}{-0.25882} +\pgfmath@def{cos}{106}{-0.27564} \pgfmath@def{cos}{107}{-0.29237} +\pgfmath@def{cos}{108}{-0.30902} \pgfmath@def{cos}{109}{-0.32557} +\pgfmath@def{cos}{110}{-0.34202} \pgfmath@def{cos}{111}{-0.35837} +\pgfmath@def{cos}{112}{-0.37461} \pgfmath@def{cos}{113}{-0.39073} +\pgfmath@def{cos}{114}{-0.40674} \pgfmath@def{cos}{115}{-0.42262} +\pgfmath@def{cos}{116}{-0.43837} \pgfmath@def{cos}{117}{-0.45399} +\pgfmath@def{cos}{118}{-0.46947} \pgfmath@def{cos}{119}{-0.48481} +\pgfmath@def{cos}{120}{-0.50000} \pgfmath@def{cos}{121}{-0.51504} +\pgfmath@def{cos}{122}{-0.52992} \pgfmath@def{cos}{123}{-0.54464} +\pgfmath@def{cos}{124}{-0.55919} \pgfmath@def{cos}{125}{-0.57358} +\pgfmath@def{cos}{126}{-0.58779} \pgfmath@def{cos}{127}{-0.60182} +\pgfmath@def{cos}{128}{-0.61566} \pgfmath@def{cos}{129}{-0.62932} +\pgfmath@def{cos}{130}{-0.64279} \pgfmath@def{cos}{131}{-0.65606} +\pgfmath@def{cos}{132}{-0.66913} \pgfmath@def{cos}{133}{-0.68200} +\pgfmath@def{cos}{134}{-0.69466} \pgfmath@def{cos}{135}{-0.70711} +\pgfmath@def{cos}{136}{-0.71934} \pgfmath@def{cos}{137}{-0.73135} +\pgfmath@def{cos}{138}{-0.74314} \pgfmath@def{cos}{139}{-0.75471} +\pgfmath@def{cos}{140}{-0.76604} \pgfmath@def{cos}{141}{-0.77715} +\pgfmath@def{cos}{142}{-0.78801} \pgfmath@def{cos}{143}{-0.79864} +\pgfmath@def{cos}{144}{-0.80902} \pgfmath@def{cos}{145}{-0.81915} +\pgfmath@def{cos}{146}{-0.82904} \pgfmath@def{cos}{147}{-0.83867} +\pgfmath@def{cos}{148}{-0.84805} \pgfmath@def{cos}{149}{-0.85717} +\pgfmath@def{cos}{150}{-0.86603} \pgfmath@def{cos}{151}{-0.87462} +\pgfmath@def{cos}{152}{-0.88295} \pgfmath@def{cos}{153}{-0.89101} +\pgfmath@def{cos}{154}{-0.89879} \pgfmath@def{cos}{155}{-0.90631} +\pgfmath@def{cos}{156}{-0.91355} \pgfmath@def{cos}{157}{-0.92050} +\pgfmath@def{cos}{158}{-0.92718} \pgfmath@def{cos}{159}{-0.93358} +\pgfmath@def{cos}{160}{-0.93969} \pgfmath@def{cos}{161}{-0.94552} +\pgfmath@def{cos}{162}{-0.95106} \pgfmath@def{cos}{163}{-0.95630} +\pgfmath@def{cos}{164}{-0.96126} \pgfmath@def{cos}{165}{-0.96593} +\pgfmath@def{cos}{166}{-0.97030} \pgfmath@def{cos}{167}{-0.97437} +\pgfmath@def{cos}{168}{-0.97815} \pgfmath@def{cos}{169}{-0.98163} +\pgfmath@def{cos}{170}{-0.98481} \pgfmath@def{cos}{171}{-0.98769} +\pgfmath@def{cos}{172}{-0.99027} \pgfmath@def{cos}{173}{-0.99255} +\pgfmath@def{cos}{174}{-0.99452} \pgfmath@def{cos}{175}{-0.99619} +\pgfmath@def{cos}{176}{-0.99756} \pgfmath@def{cos}{177}{-0.99863} +\pgfmath@def{cos}{178}{-0.99939} \pgfmath@def{cos}{179}{-0.99985} +\pgfmath@def{cos}{180}{-1.00000} \pgfmath@def{cos}{181}{-0.99985} -\pgfmath@def{cosfrac}{0}{1.00000} \pgfmath@def{cosfrac}{1}{0.99995} -\pgfmath@def{cosfrac}{2}{0.99980} \pgfmath@def{cosfrac}{3}{0.99955} -\pgfmath@def{cosfrac}{4}{0.99920} \pgfmath@def{cosfrac}{5}{0.99875} -\pgfmath@def{cosfrac}{6}{0.99820} \pgfmath@def{cosfrac}{7}{0.99755} -\pgfmath@def{cosfrac}{8}{0.99681} \pgfmath@def{cosfrac}{9}{0.99597} -\pgfmath@def{cosfrac}{10}{0.99503} \pgfmath@def{cosfrac}{11}{0.99400} -\pgfmath@def{cosfrac}{12}{0.99287} \pgfmath@def{cosfrac}{13}{0.99165} -\pgfmath@def{cosfrac}{14}{0.99034} \pgfmath@def{cosfrac}{15}{0.98893} -\pgfmath@def{cosfrac}{16}{0.98744} \pgfmath@def{cosfrac}{17}{0.98585} -\pgfmath@def{cosfrac}{18}{0.98418} \pgfmath@def{cosfrac}{19}{0.98242} -\pgfmath@def{cosfrac}{20}{0.98058} \pgfmath@def{cosfrac}{21}{0.97865} -\pgfmath@def{cosfrac}{22}{0.97664} \pgfmath@def{cosfrac}{23}{0.97455} -\pgfmath@def{cosfrac}{24}{0.97238} \pgfmath@def{cosfrac}{25}{0.97014} -\pgfmath@def{cosfrac}{26}{0.96782} \pgfmath@def{cosfrac}{27}{0.96542} -\pgfmath@def{cosfrac}{28}{0.96296} \pgfmath@def{cosfrac}{29}{0.96042} -\pgfmath@def{cosfrac}{30}{0.95782} \pgfmath@def{cosfrac}{31}{0.95515} -\pgfmath@def{cosfrac}{32}{0.95242} \pgfmath@def{cosfrac}{33}{0.94962} -\pgfmath@def{cosfrac}{34}{0.94677} \pgfmath@def{cosfrac}{35}{0.94385} -\pgfmath@def{cosfrac}{36}{0.94088} \pgfmath@def{cosfrac}{37}{0.93786} -\pgfmath@def{cosfrac}{38}{0.93478} \pgfmath@def{cosfrac}{39}{0.93165} -\pgfmath@def{cosfrac}{40}{0.92847} \pgfmath@def{cosfrac}{41}{0.92525} -\pgfmath@def{cosfrac}{42}{0.92198} \pgfmath@def{cosfrac}{43}{0.91866} -\pgfmath@def{cosfrac}{44}{0.91531} \pgfmath@def{cosfrac}{45}{0.91192} -\pgfmath@def{cosfrac}{46}{0.90849} \pgfmath@def{cosfrac}{47}{0.90502} -\pgfmath@def{cosfrac}{48}{0.90152} \pgfmath@def{cosfrac}{49}{0.89799} -\pgfmath@def{cosfrac}{50}{0.89442} \pgfmath@def{cosfrac}{51}{0.89083} -\pgfmath@def{cosfrac}{52}{0.88721} \pgfmath@def{cosfrac}{53}{0.88357} -\pgfmath@def{cosfrac}{54}{0.87990} \pgfmath@def{cosfrac}{55}{0.87621} -\pgfmath@def{cosfrac}{56}{0.87250} \pgfmath@def{cosfrac}{57}{0.86877} -\pgfmath@def{cosfrac}{58}{0.86503} \pgfmath@def{cosfrac}{59}{0.86126} -\pgfmath@def{cosfrac}{60}{0.85749} \pgfmath@def{cosfrac}{61}{0.85370} -\pgfmath@def{cosfrac}{62}{0.84990} \pgfmath@def{cosfrac}{63}{0.84609} -\pgfmath@def{cosfrac}{64}{0.84227} \pgfmath@def{cosfrac}{65}{0.83844} -\pgfmath@def{cosfrac}{66}{0.83460} \pgfmath@def{cosfrac}{67}{0.83077} -\pgfmath@def{cosfrac}{68}{0.82692} \pgfmath@def{cosfrac}{69}{0.82308} -\pgfmath@def{cosfrac}{70}{0.81923} \pgfmath@def{cosfrac}{71}{0.81538} -\pgfmath@def{cosfrac}{72}{0.81153} \pgfmath@def{cosfrac}{73}{0.80768} -\pgfmath@def{cosfrac}{74}{0.80384} \pgfmath@def{cosfrac}{75}{0.80000} -\pgfmath@def{cosfrac}{76}{0.79616} \pgfmath@def{cosfrac}{77}{0.79232} -\pgfmath@def{cosfrac}{78}{0.78850} \pgfmath@def{cosfrac}{79}{0.78468} -\pgfmath@def{cosfrac}{80}{0.78086} \pgfmath@def{cosfrac}{81}{0.77706} -\pgfmath@def{cosfrac}{82}{0.77326} \pgfmath@def{cosfrac}{83}{0.76948} -\pgfmath@def{cosfrac}{84}{0.76570} \pgfmath@def{cosfrac}{85}{0.76193} -\pgfmath@def{cosfrac}{86}{0.75818} \pgfmath@def{cosfrac}{87}{0.75444} -\pgfmath@def{cosfrac}{88}{0.75071} \pgfmath@def{cosfrac}{89}{0.74699} -\pgfmath@def{cosfrac}{90}{0.74329} \pgfmath@def{cosfrac}{91}{0.73960} -\pgfmath@def{cosfrac}{92}{0.73593} \pgfmath@def{cosfrac}{93}{0.73227} -\pgfmath@def{cosfrac}{94}{0.72862} \pgfmath@def{cosfrac}{95}{0.72499} -\pgfmath@def{cosfrac}{96}{0.72138} \pgfmath@def{cosfrac}{97}{0.71779} -\pgfmath@def{cosfrac}{98}{0.71421} \pgfmath@def{cosfrac}{99}{0.71065} -\pgfmath@def{cosfrac}{100}{0.70710} +\pgfmath@def{cosfrac}{0}{1.00000} \pgfmath@def{cosfrac}{1}{0.99995} +\pgfmath@def{cosfrac}{2}{0.99980} \pgfmath@def{cosfrac}{3}{0.99955} +\pgfmath@def{cosfrac}{4}{0.99920} \pgfmath@def{cosfrac}{5}{0.99875} +\pgfmath@def{cosfrac}{6}{0.99820} \pgfmath@def{cosfrac}{7}{0.99755} +\pgfmath@def{cosfrac}{8}{0.99681} \pgfmath@def{cosfrac}{9}{0.99597} +\pgfmath@def{cosfrac}{10}{0.99503} \pgfmath@def{cosfrac}{11}{0.99400} +\pgfmath@def{cosfrac}{12}{0.99287} \pgfmath@def{cosfrac}{13}{0.99165} +\pgfmath@def{cosfrac}{14}{0.99034} \pgfmath@def{cosfrac}{15}{0.98893} +\pgfmath@def{cosfrac}{16}{0.98744} \pgfmath@def{cosfrac}{17}{0.98585} +\pgfmath@def{cosfrac}{18}{0.98418} \pgfmath@def{cosfrac}{19}{0.98242} +\pgfmath@def{cosfrac}{20}{0.98058} \pgfmath@def{cosfrac}{21}{0.97865} +\pgfmath@def{cosfrac}{22}{0.97664} \pgfmath@def{cosfrac}{23}{0.97455} +\pgfmath@def{cosfrac}{24}{0.97238} \pgfmath@def{cosfrac}{25}{0.97014} +\pgfmath@def{cosfrac}{26}{0.96782} \pgfmath@def{cosfrac}{27}{0.96542} +\pgfmath@def{cosfrac}{28}{0.96296} \pgfmath@def{cosfrac}{29}{0.96042} +\pgfmath@def{cosfrac}{30}{0.95782} \pgfmath@def{cosfrac}{31}{0.95515} +\pgfmath@def{cosfrac}{32}{0.95242} \pgfmath@def{cosfrac}{33}{0.94962} +\pgfmath@def{cosfrac}{34}{0.94677} \pgfmath@def{cosfrac}{35}{0.94385} +\pgfmath@def{cosfrac}{36}{0.94088} \pgfmath@def{cosfrac}{37}{0.93786} +\pgfmath@def{cosfrac}{38}{0.93478} \pgfmath@def{cosfrac}{39}{0.93165} +\pgfmath@def{cosfrac}{40}{0.92847} \pgfmath@def{cosfrac}{41}{0.92525} +\pgfmath@def{cosfrac}{42}{0.92198} \pgfmath@def{cosfrac}{43}{0.91866} +\pgfmath@def{cosfrac}{44}{0.91531} \pgfmath@def{cosfrac}{45}{0.91192} +\pgfmath@def{cosfrac}{46}{0.90849} \pgfmath@def{cosfrac}{47}{0.90502} +\pgfmath@def{cosfrac}{48}{0.90152} \pgfmath@def{cosfrac}{49}{0.89799} +\pgfmath@def{cosfrac}{50}{0.89442} \pgfmath@def{cosfrac}{51}{0.89083} +\pgfmath@def{cosfrac}{52}{0.88721} \pgfmath@def{cosfrac}{53}{0.88357} +\pgfmath@def{cosfrac}{54}{0.87990} \pgfmath@def{cosfrac}{55}{0.87621} +\pgfmath@def{cosfrac}{56}{0.87250} \pgfmath@def{cosfrac}{57}{0.86877} +\pgfmath@def{cosfrac}{58}{0.86503} \pgfmath@def{cosfrac}{59}{0.86126} +\pgfmath@def{cosfrac}{60}{0.85749} \pgfmath@def{cosfrac}{61}{0.85370} +\pgfmath@def{cosfrac}{62}{0.84990} \pgfmath@def{cosfrac}{63}{0.84609} +\pgfmath@def{cosfrac}{64}{0.84227} \pgfmath@def{cosfrac}{65}{0.83844} +\pgfmath@def{cosfrac}{66}{0.83460} \pgfmath@def{cosfrac}{67}{0.83077} +\pgfmath@def{cosfrac}{68}{0.82692} \pgfmath@def{cosfrac}{69}{0.82308} +\pgfmath@def{cosfrac}{70}{0.81923} \pgfmath@def{cosfrac}{71}{0.81538} +\pgfmath@def{cosfrac}{72}{0.81153} \pgfmath@def{cosfrac}{73}{0.80768} +\pgfmath@def{cosfrac}{74}{0.80384} \pgfmath@def{cosfrac}{75}{0.80000} +\pgfmath@def{cosfrac}{76}{0.79616} \pgfmath@def{cosfrac}{77}{0.79232} +\pgfmath@def{cosfrac}{78}{0.78850} \pgfmath@def{cosfrac}{79}{0.78468} +\pgfmath@def{cosfrac}{80}{0.78086} \pgfmath@def{cosfrac}{81}{0.77706} +\pgfmath@def{cosfrac}{82}{0.77326} \pgfmath@def{cosfrac}{83}{0.76948} +\pgfmath@def{cosfrac}{84}{0.76570} \pgfmath@def{cosfrac}{85}{0.76193} +\pgfmath@def{cosfrac}{86}{0.75818} \pgfmath@def{cosfrac}{87}{0.75444} +\pgfmath@def{cosfrac}{88}{0.75071} \pgfmath@def{cosfrac}{89}{0.74699} +\pgfmath@def{cosfrac}{90}{0.74329} \pgfmath@def{cosfrac}{91}{0.73960} +\pgfmath@def{cosfrac}{92}{0.73593} \pgfmath@def{cosfrac}{93}{0.73227} +\pgfmath@def{cosfrac}{94}{0.72862} \pgfmath@def{cosfrac}{95}{0.72499} +\pgfmath@def{cosfrac}{96}{0.72138} \pgfmath@def{cosfrac}{97}{0.71779} +\pgfmath@def{cosfrac}{98}{0.71421} \pgfmath@def{cosfrac}{99}{0.71065} +\pgfmath@def{cosfrac}{100}{0.70710} % Oh No! Some really loooooong tables. -\pgfmath@def{atan}{0}{0.00000} \pgfmath@def{atan}{1}{0.05729} -\pgfmath@def{atan}{2}{0.11459} \pgfmath@def{atan}{3}{0.17188} -\pgfmath@def{atan}{4}{0.22918} \pgfmath@def{atan}{5}{0.28647} -\pgfmath@def{atan}{6}{0.34377} \pgfmath@def{atan}{7}{0.40106} -\pgfmath@def{atan}{8}{0.45835} \pgfmath@def{atan}{9}{0.51564} -\pgfmath@def{atan}{10}{0.57293} \pgfmath@def{atan}{11}{0.63022} -\pgfmath@def{atan}{12}{0.68751} \pgfmath@def{atan}{13}{0.74480} -\pgfmath@def{atan}{14}{0.80208} \pgfmath@def{atan}{15}{0.85937} -\pgfmath@def{atan}{16}{0.91665} \pgfmath@def{atan}{17}{0.97393} -\pgfmath@def{atan}{18}{1.03121} \pgfmath@def{atan}{19}{1.08848} -\pgfmath@def{atan}{20}{1.14576} \pgfmath@def{atan}{21}{1.20303} -\pgfmath@def{atan}{22}{1.26030} \pgfmath@def{atan}{23}{1.31757} -\pgfmath@def{atan}{24}{1.37483} \pgfmath@def{atan}{25}{1.43209} -\pgfmath@def{atan}{26}{1.48935} \pgfmath@def{atan}{27}{1.54661} -\pgfmath@def{atan}{28}{1.60386} \pgfmath@def{atan}{29}{1.66111} -\pgfmath@def{atan}{30}{1.71835} \pgfmath@def{atan}{31}{1.77560} -\pgfmath@def{atan}{32}{1.83284} \pgfmath@def{atan}{33}{1.89007} -\pgfmath@def{atan}{34}{1.94730} \pgfmath@def{atan}{35}{2.00453} -\pgfmath@def{atan}{36}{2.06175} \pgfmath@def{atan}{37}{2.11897} -\pgfmath@def{atan}{38}{2.17619} \pgfmath@def{atan}{39}{2.23340} -\pgfmath@def{atan}{40}{2.29061} \pgfmath@def{atan}{41}{2.34781} -\pgfmath@def{atan}{42}{2.40500} \pgfmath@def{atan}{43}{2.46220} -\pgfmath@def{atan}{44}{2.51938} \pgfmath@def{atan}{45}{2.57657} -\pgfmath@def{atan}{46}{2.63374} \pgfmath@def{atan}{47}{2.69092} -\pgfmath@def{atan}{48}{2.74808} \pgfmath@def{atan}{49}{2.80524} -\pgfmath@def{atan}{50}{2.86240} \pgfmath@def{atan}{51}{2.91955} -\pgfmath@def{atan}{52}{2.97669} \pgfmath@def{atan}{53}{3.03383} -\pgfmath@def{atan}{54}{3.09097} \pgfmath@def{atan}{55}{3.14809} -\pgfmath@def{atan}{56}{3.20521} \pgfmath@def{atan}{57}{3.26232} -\pgfmath@def{atan}{58}{3.31943} \pgfmath@def{atan}{59}{3.37653} -\pgfmath@def{atan}{60}{3.43363} \pgfmath@def{atan}{61}{3.49071} -\pgfmath@def{atan}{62}{3.54779} \pgfmath@def{atan}{63}{3.60487} -\pgfmath@def{atan}{64}{3.66193} \pgfmath@def{atan}{65}{3.71899} -\pgfmath@def{atan}{66}{3.77604} \pgfmath@def{atan}{67}{3.83308} -\pgfmath@def{atan}{68}{3.89012} \pgfmath@def{atan}{69}{3.94715} -\pgfmath@def{atan}{70}{4.00417} \pgfmath@def{atan}{71}{4.06118} -\pgfmath@def{atan}{72}{4.11819} \pgfmath@def{atan}{73}{4.17518} -\pgfmath@def{atan}{74}{4.23217} \pgfmath@def{atan}{75}{4.28915} -\pgfmath@def{atan}{76}{4.34612} \pgfmath@def{atan}{77}{4.40308} -\pgfmath@def{atan}{78}{4.46004} \pgfmath@def{atan}{79}{4.51698} -\pgfmath@def{atan}{80}{4.57392} \pgfmath@def{atan}{81}{4.63084} -\pgfmath@def{atan}{82}{4.68776} \pgfmath@def{atan}{83}{4.74467} -\pgfmath@def{atan}{84}{4.80157} \pgfmath@def{atan}{85}{4.85846} -\pgfmath@def{atan}{86}{4.91534} \pgfmath@def{atan}{87}{4.97221} -\pgfmath@def{atan}{88}{5.02907} \pgfmath@def{atan}{89}{5.08592} -\pgfmath@def{atan}{90}{5.14276} \pgfmath@def{atan}{91}{5.19959} -\pgfmath@def{atan}{92}{5.25641} \pgfmath@def{atan}{93}{5.31322} -\pgfmath@def{atan}{94}{5.37002} \pgfmath@def{atan}{95}{5.42681} -\pgfmath@def{atan}{96}{5.48359} \pgfmath@def{atan}{97}{5.54035} -\pgfmath@def{atan}{98}{5.59711} \pgfmath@def{atan}{99}{5.65385} -\pgfmath@def{atan}{100}{5.71059} \pgfmath@def{atan}{101}{5.76731} -\pgfmath@def{atan}{102}{5.82402} \pgfmath@def{atan}{103}{5.88072} -\pgfmath@def{atan}{104}{5.93741} \pgfmath@def{atan}{105}{5.99409} -\pgfmath@def{atan}{106}{6.05075} \pgfmath@def{atan}{107}{6.10741} -\pgfmath@def{atan}{108}{6.16405} \pgfmath@def{atan}{109}{6.22068} -\pgfmath@def{atan}{110}{6.27729} \pgfmath@def{atan}{111}{6.33390} -\pgfmath@def{atan}{112}{6.39049} \pgfmath@def{atan}{113}{6.44707} -\pgfmath@def{atan}{114}{6.50364} \pgfmath@def{atan}{115}{6.56019} -\pgfmath@def{atan}{116}{6.61673} \pgfmath@def{atan}{117}{6.67326} -\pgfmath@def{atan}{118}{6.72978} \pgfmath@def{atan}{119}{6.78628} -\pgfmath@def{atan}{120}{6.84277} \pgfmath@def{atan}{121}{6.89924} -\pgfmath@def{atan}{122}{6.95571} \pgfmath@def{atan}{123}{7.01216} -\pgfmath@def{atan}{124}{7.06859} \pgfmath@def{atan}{125}{7.12501} -\pgfmath@def{atan}{126}{7.18142} \pgfmath@def{atan}{127}{7.23781} -\pgfmath@def{atan}{128}{7.29419} \pgfmath@def{atan}{129}{7.35056} -\pgfmath@def{atan}{130}{7.40691} \pgfmath@def{atan}{131}{7.46324} -\pgfmath@def{atan}{132}{7.51957} \pgfmath@def{atan}{133}{7.57587} -\pgfmath@def{atan}{134}{7.63217} \pgfmath@def{atan}{135}{7.68844} -\pgfmath@def{atan}{136}{7.74471} \pgfmath@def{atan}{137}{7.80095} -\pgfmath@def{atan}{138}{7.85719} \pgfmath@def{atan}{139}{7.91340} -\pgfmath@def{atan}{140}{7.96961} \pgfmath@def{atan}{141}{8.02579} -\pgfmath@def{atan}{142}{8.08196} \pgfmath@def{atan}{143}{8.13812} -\pgfmath@def{atan}{144}{8.19426} \pgfmath@def{atan}{145}{8.25038} -\pgfmath@def{atan}{146}{8.30649} \pgfmath@def{atan}{147}{8.36258} -\pgfmath@def{atan}{148}{8.41866} \pgfmath@def{atan}{149}{8.47472} -\pgfmath@def{atan}{150}{8.53076} \pgfmath@def{atan}{151}{8.58679} -\pgfmath@def{atan}{152}{8.64280} \pgfmath@def{atan}{153}{8.69879} -\pgfmath@def{atan}{154}{8.75477} \pgfmath@def{atan}{155}{8.81073} -\pgfmath@def{atan}{156}{8.86667} \pgfmath@def{atan}{157}{8.92260} -\pgfmath@def{atan}{158}{8.97851} \pgfmath@def{atan}{159}{9.03440} -\pgfmath@def{atan}{160}{9.09027} \pgfmath@def{atan}{161}{9.14613} -\pgfmath@def{atan}{162}{9.20197} \pgfmath@def{atan}{163}{9.25779} -\pgfmath@def{atan}{164}{9.31359} \pgfmath@def{atan}{165}{9.36938} -\pgfmath@def{atan}{166}{9.42515} \pgfmath@def{atan}{167}{9.48090} -\pgfmath@def{atan}{168}{9.53663} \pgfmath@def{atan}{169}{9.59235} -\pgfmath@def{atan}{170}{9.64804} \pgfmath@def{atan}{171}{9.70372} -\pgfmath@def{atan}{172}{9.75938} \pgfmath@def{atan}{173}{9.81502} -\pgfmath@def{atan}{174}{9.87064} \pgfmath@def{atan}{175}{9.92624} -\pgfmath@def{atan}{176}{9.98182} \pgfmath@def{atan}{177}{10.03739} -\pgfmath@def{atan}{178}{10.09294} \pgfmath@def{atan}{179}{10.14846} -\pgfmath@def{atan}{180}{10.20397} \pgfmath@def{atan}{181}{10.25946} -\pgfmath@def{atan}{182}{10.31493} \pgfmath@def{atan}{183}{10.37037} -\pgfmath@def{atan}{184}{10.42580} \pgfmath@def{atan}{185}{10.48121} -\pgfmath@def{atan}{186}{10.53660} \pgfmath@def{atan}{187}{10.59197} -\pgfmath@def{atan}{188}{10.64732} \pgfmath@def{atan}{189}{10.70265} -\pgfmath@def{atan}{190}{10.75796} \pgfmath@def{atan}{191}{10.81325} -\pgfmath@def{atan}{192}{10.86852} \pgfmath@def{atan}{193}{10.92377} -\pgfmath@def{atan}{194}{10.97900} \pgfmath@def{atan}{195}{11.03420} -\pgfmath@def{atan}{196}{11.08939} \pgfmath@def{atan}{197}{11.14456} -\pgfmath@def{atan}{198}{11.19970} \pgfmath@def{atan}{199}{11.25483} -\pgfmath@def{atan}{200}{11.30993} \pgfmath@def{atan}{201}{11.36501} -\pgfmath@def{atan}{202}{11.42007} \pgfmath@def{atan}{203}{11.47511} -\pgfmath@def{atan}{204}{11.53013} \pgfmath@def{atan}{205}{11.58512} -\pgfmath@def{atan}{206}{11.64010} \pgfmath@def{atan}{207}{11.69505} -\pgfmath@def{atan}{208}{11.74998} \pgfmath@def{atan}{209}{11.80489} -\pgfmath@def{atan}{210}{11.85977} \pgfmath@def{atan}{211}{11.91464} -\pgfmath@def{atan}{212}{11.96948} \pgfmath@def{atan}{213}{12.02430} -\pgfmath@def{atan}{214}{12.07910} \pgfmath@def{atan}{215}{12.13388} -\pgfmath@def{atan}{216}{12.18863} \pgfmath@def{atan}{217}{12.24336} -\pgfmath@def{atan}{218}{12.29807} \pgfmath@def{atan}{219}{12.35275} -\pgfmath@def{atan}{220}{12.40741} \pgfmath@def{atan}{221}{12.46205} -\pgfmath@def{atan}{222}{12.51667} \pgfmath@def{atan}{223}{12.57126} -\pgfmath@def{atan}{224}{12.62583} \pgfmath@def{atan}{225}{12.68038} -\pgfmath@def{atan}{226}{12.73490} \pgfmath@def{atan}{227}{12.78940} -\pgfmath@def{atan}{228}{12.84388} \pgfmath@def{atan}{229}{12.89833} -\pgfmath@def{atan}{230}{12.95276} \pgfmath@def{atan}{231}{13.00717} -\pgfmath@def{atan}{232}{13.06155} \pgfmath@def{atan}{233}{13.11590} -\pgfmath@def{atan}{234}{13.17024} \pgfmath@def{atan}{235}{13.22455} -\pgfmath@def{atan}{236}{13.27883} \pgfmath@def{atan}{237}{13.33309} -\pgfmath@def{atan}{238}{13.38733} \pgfmath@def{atan}{239}{13.44154} -\pgfmath@def{atan}{240}{13.49573} \pgfmath@def{atan}{241}{13.54989} -\pgfmath@def{atan}{242}{13.60403} \pgfmath@def{atan}{243}{13.65814} -\pgfmath@def{atan}{244}{13.71223} \pgfmath@def{atan}{245}{13.76630} -\pgfmath@def{atan}{246}{13.82034} \pgfmath@def{atan}{247}{13.87435} -\pgfmath@def{atan}{248}{13.92834} \pgfmath@def{atan}{249}{13.98230} -\pgfmath@def{atan}{250}{14.03624} \pgfmath@def{atan}{251}{14.09015} -\pgfmath@def{atan}{252}{14.14404} \pgfmath@def{atan}{253}{14.19790} -\pgfmath@def{atan}{254}{14.25174} \pgfmath@def{atan}{255}{14.30555} -\pgfmath@def{atan}{256}{14.35933} \pgfmath@def{atan}{257}{14.41309} -\pgfmath@def{atan}{258}{14.46682} \pgfmath@def{atan}{259}{14.52053} -\pgfmath@def{atan}{260}{14.57421} \pgfmath@def{atan}{261}{14.62787} -\pgfmath@def{atan}{262}{14.68149} \pgfmath@def{atan}{263}{14.73510} -\pgfmath@def{atan}{264}{14.78867} \pgfmath@def{atan}{265}{14.84222} -\pgfmath@def{atan}{266}{14.89575} \pgfmath@def{atan}{267}{14.94924} -\pgfmath@def{atan}{268}{15.00271} \pgfmath@def{atan}{269}{15.05615} -\pgfmath@def{atan}{270}{15.10957} \pgfmath@def{atan}{271}{15.16296} -\pgfmath@def{atan}{272}{15.21632} \pgfmath@def{atan}{273}{15.26966} -\pgfmath@def{atan}{274}{15.32297} \pgfmath@def{atan}{275}{15.37625} -\pgfmath@def{atan}{276}{15.42950} \pgfmath@def{atan}{277}{15.48273} -\pgfmath@def{atan}{278}{15.53593} \pgfmath@def{atan}{279}{15.58910} -\pgfmath@def{atan}{280}{15.64224} \pgfmath@def{atan}{281}{15.69536} -\pgfmath@def{atan}{282}{15.74845} \pgfmath@def{atan}{283}{15.80151} -\pgfmath@def{atan}{284}{15.85454} \pgfmath@def{atan}{285}{15.90755} -\pgfmath@def{atan}{286}{15.96052} \pgfmath@def{atan}{287}{16.01347} -\pgfmath@def{atan}{288}{16.06640} \pgfmath@def{atan}{289}{16.11929} -\pgfmath@def{atan}{290}{16.17215} \pgfmath@def{atan}{291}{16.22499} -\pgfmath@def{atan}{292}{16.27780} \pgfmath@def{atan}{293}{16.33058} -\pgfmath@def{atan}{294}{16.38333} \pgfmath@def{atan}{295}{16.43605} -\pgfmath@def{atan}{296}{16.48875} \pgfmath@def{atan}{297}{16.54142} -\pgfmath@def{atan}{298}{16.59405} \pgfmath@def{atan}{299}{16.64666} -\pgfmath@def{atan}{300}{16.69924} \pgfmath@def{atan}{301}{16.75179} -\pgfmath@def{atan}{302}{16.80431} \pgfmath@def{atan}{303}{16.85680} -\pgfmath@def{atan}{304}{16.90927} \pgfmath@def{atan}{305}{16.96170} -\pgfmath@def{atan}{306}{17.01411} \pgfmath@def{atan}{307}{17.06648} -\pgfmath@def{atan}{308}{17.11883} \pgfmath@def{atan}{309}{17.17114} -\pgfmath@def{atan}{310}{17.22343} \pgfmath@def{atan}{311}{17.27569} -\pgfmath@def{atan}{312}{17.32792} \pgfmath@def{atan}{313}{17.38012} -\pgfmath@def{atan}{314}{17.43228} \pgfmath@def{atan}{315}{17.48442} -\pgfmath@def{atan}{316}{17.53653} \pgfmath@def{atan}{317}{17.58861} -\pgfmath@def{atan}{318}{17.64066} \pgfmath@def{atan}{319}{17.69268} -\pgfmath@def{atan}{320}{17.74467} \pgfmath@def{atan}{321}{17.79663} -\pgfmath@def{atan}{322}{17.84855} \pgfmath@def{atan}{323}{17.90045} -\pgfmath@def{atan}{324}{17.95232} \pgfmath@def{atan}{325}{18.00416} -\pgfmath@def{atan}{326}{18.05596} \pgfmath@def{atan}{327}{18.10774} -\pgfmath@def{atan}{328}{18.15949} \pgfmath@def{atan}{329}{18.21120} -\pgfmath@def{atan}{330}{18.26289} \pgfmath@def{atan}{331}{18.31454} -\pgfmath@def{atan}{332}{18.36616} \pgfmath@def{atan}{333}{18.41775} -\pgfmath@def{atan}{334}{18.46931} \pgfmath@def{atan}{335}{18.52084} -\pgfmath@def{atan}{336}{18.57234} \pgfmath@def{atan}{337}{18.62381} -\pgfmath@def{atan}{338}{18.67525} \pgfmath@def{atan}{339}{18.72665} -\pgfmath@def{atan}{340}{18.77803} \pgfmath@def{atan}{341}{18.82937} -\pgfmath@def{atan}{342}{18.88068} \pgfmath@def{atan}{343}{18.93196} -\pgfmath@def{atan}{344}{18.98321} \pgfmath@def{atan}{345}{19.03443} -\pgfmath@def{atan}{346}{19.08562} \pgfmath@def{atan}{347}{19.13677} -\pgfmath@def{atan}{348}{19.18789} \pgfmath@def{atan}{349}{19.23898} -\pgfmath@def{atan}{350}{19.29004} \pgfmath@def{atan}{351}{19.34107} -\pgfmath@def{atan}{352}{19.39206} \pgfmath@def{atan}{353}{19.44303} -\pgfmath@def{atan}{354}{19.49396} \pgfmath@def{atan}{355}{19.54486} -\pgfmath@def{atan}{356}{19.59572} \pgfmath@def{atan}{357}{19.64656} -\pgfmath@def{atan}{358}{19.69736} \pgfmath@def{atan}{359}{19.74813} -\pgfmath@def{atan}{360}{19.79887} \pgfmath@def{atan}{361}{19.84958} -\pgfmath@def{atan}{362}{19.90025} \pgfmath@def{atan}{363}{19.95089} -\pgfmath@def{atan}{364}{20.00150} \pgfmath@def{atan}{365}{20.05208} -\pgfmath@def{atan}{366}{20.10262} \pgfmath@def{atan}{367}{20.15313} -\pgfmath@def{atan}{368}{20.20361} \pgfmath@def{atan}{369}{20.25406} -\pgfmath@def{atan}{370}{20.30447} \pgfmath@def{atan}{371}{20.35485} -\pgfmath@def{atan}{372}{20.40520} \pgfmath@def{atan}{373}{20.45551} -\pgfmath@def{atan}{374}{20.50579} \pgfmath@def{atan}{375}{20.55604} -\pgfmath@def{atan}{376}{20.60626} \pgfmath@def{atan}{377}{20.65644} -\pgfmath@def{atan}{378}{20.70659} \pgfmath@def{atan}{379}{20.75670} -\pgfmath@def{atan}{380}{20.80679} \pgfmath@def{atan}{381}{20.85684} -\pgfmath@def{atan}{382}{20.90685} \pgfmath@def{atan}{383}{20.95684} -\pgfmath@def{atan}{384}{21.00678} \pgfmath@def{atan}{385}{21.05670} -\pgfmath@def{atan}{386}{21.10658} \pgfmath@def{atan}{387}{21.15643} -\pgfmath@def{atan}{388}{21.20625} \pgfmath@def{atan}{389}{21.25603} -\pgfmath@def{atan}{390}{21.30578} \pgfmath@def{atan}{391}{21.35549} -\pgfmath@def{atan}{392}{21.40517} \pgfmath@def{atan}{393}{21.45482} -\pgfmath@def{atan}{394}{21.50444} \pgfmath@def{atan}{395}{21.55402} -\pgfmath@def{atan}{396}{21.60356} \pgfmath@def{atan}{397}{21.65307} -\pgfmath@def{atan}{398}{21.70255} \pgfmath@def{atan}{399}{21.75200} -\pgfmath@def{atan}{400}{21.80140} \pgfmath@def{atan}{401}{21.85078} -\pgfmath@def{atan}{402}{21.90012} \pgfmath@def{atan}{403}{21.94943} -\pgfmath@def{atan}{404}{21.99870} \pgfmath@def{atan}{405}{22.04794} -\pgfmath@def{atan}{406}{22.09715} \pgfmath@def{atan}{407}{22.14632} -\pgfmath@def{atan}{408}{22.19546} \pgfmath@def{atan}{409}{22.24456} -\pgfmath@def{atan}{410}{22.29362} \pgfmath@def{atan}{411}{22.34266} -\pgfmath@def{atan}{412}{22.39166} \pgfmath@def{atan}{413}{22.44062} -\pgfmath@def{atan}{414}{22.48955} \pgfmath@def{atan}{415}{22.53845} -\pgfmath@def{atan}{416}{22.58731} \pgfmath@def{atan}{417}{22.63613} -\pgfmath@def{atan}{418}{22.68492} \pgfmath@def{atan}{419}{22.73368} -\pgfmath@def{atan}{420}{22.78240} \pgfmath@def{atan}{421}{22.83109} -\pgfmath@def{atan}{422}{22.87974} \pgfmath@def{atan}{423}{22.92836} -\pgfmath@def{atan}{424}{22.97694} \pgfmath@def{atan}{425}{23.02549} -\pgfmath@def{atan}{426}{23.07400} \pgfmath@def{atan}{427}{23.12248} -\pgfmath@def{atan}{428}{23.17092} \pgfmath@def{atan}{429}{23.21933} -\pgfmath@def{atan}{430}{23.26770} \pgfmath@def{atan}{431}{23.31604} -\pgfmath@def{atan}{432}{23.36434} \pgfmath@def{atan}{433}{23.41261} -\pgfmath@def{atan}{434}{23.46084} \pgfmath@def{atan}{435}{23.50904} -\pgfmath@def{atan}{436}{23.55720} \pgfmath@def{atan}{437}{23.60532} -\pgfmath@def{atan}{438}{23.65341} \pgfmath@def{atan}{439}{23.70147} -\pgfmath@def{atan}{440}{23.74949} \pgfmath@def{atan}{441}{23.79747} -\pgfmath@def{atan}{442}{23.84542} \pgfmath@def{atan}{443}{23.89334} -\pgfmath@def{atan}{444}{23.94122} \pgfmath@def{atan}{445}{23.98906} -\pgfmath@def{atan}{446}{24.03687} \pgfmath@def{atan}{447}{24.08464} -\pgfmath@def{atan}{448}{24.13238} \pgfmath@def{atan}{449}{24.18008} -\pgfmath@def{atan}{450}{24.22774} \pgfmath@def{atan}{451}{24.27537} -\pgfmath@def{atan}{452}{24.32296} \pgfmath@def{atan}{453}{24.37052} -\pgfmath@def{atan}{454}{24.41804} \pgfmath@def{atan}{455}{24.46553} -\pgfmath@def{atan}{456}{24.51298} \pgfmath@def{atan}{457}{24.56040} -\pgfmath@def{atan}{458}{24.60778} \pgfmath@def{atan}{459}{24.65512} -\pgfmath@def{atan}{460}{24.70243} \pgfmath@def{atan}{461}{24.74970} -\pgfmath@def{atan}{462}{24.79693} \pgfmath@def{atan}{463}{24.84413} -\pgfmath@def{atan}{464}{24.89130} \pgfmath@def{atan}{465}{24.93842} -\pgfmath@def{atan}{466}{24.98551} \pgfmath@def{atan}{467}{25.03257} -\pgfmath@def{atan}{468}{25.07959} \pgfmath@def{atan}{469}{25.12657} -\pgfmath@def{atan}{470}{25.17352} \pgfmath@def{atan}{471}{25.22043} -\pgfmath@def{atan}{472}{25.26731} \pgfmath@def{atan}{473}{25.31414} -\pgfmath@def{atan}{474}{25.36095} \pgfmath@def{atan}{475}{25.40771} -\pgfmath@def{atan}{476}{25.45444} \pgfmath@def{atan}{477}{25.50114} -\pgfmath@def{atan}{478}{25.54780} \pgfmath@def{atan}{479}{25.59442} -\pgfmath@def{atan}{480}{25.64100} \pgfmath@def{atan}{481}{25.68755} -\pgfmath@def{atan}{482}{25.73406} \pgfmath@def{atan}{483}{25.78054} -\pgfmath@def{atan}{484}{25.82698} \pgfmath@def{atan}{485}{25.87338} -\pgfmath@def{atan}{486}{25.91975} \pgfmath@def{atan}{487}{25.96608} -\pgfmath@def{atan}{488}{26.01237} \pgfmath@def{atan}{489}{26.05863} -\pgfmath@def{atan}{490}{26.10485} \pgfmath@def{atan}{491}{26.15103} -\pgfmath@def{atan}{492}{26.19718} \pgfmath@def{atan}{493}{26.24329} -\pgfmath@def{atan}{494}{26.28937} \pgfmath@def{atan}{495}{26.33541} -\pgfmath@def{atan}{496}{26.38141} \pgfmath@def{atan}{497}{26.42737} -\pgfmath@def{atan}{498}{26.47330} \pgfmath@def{atan}{499}{26.51919} -\pgfmath@def{atan}{500}{26.56505} \pgfmath@def{atan}{501}{26.61086} -\pgfmath@def{atan}{502}{26.65665} \pgfmath@def{atan}{503}{26.70239} -\pgfmath@def{atan}{504}{26.74810} \pgfmath@def{atan}{505}{26.79377} -\pgfmath@def{atan}{506}{26.83941} \pgfmath@def{atan}{507}{26.88500} -\pgfmath@def{atan}{508}{26.93057} \pgfmath@def{atan}{509}{26.97609} -\pgfmath@def{atan}{510}{27.02158} \pgfmath@def{atan}{511}{27.06703} -\pgfmath@def{atan}{512}{27.11244} \pgfmath@def{atan}{513}{27.15782} -\pgfmath@def{atan}{514}{27.20316} \pgfmath@def{atan}{515}{27.24846} -\pgfmath@def{atan}{516}{27.29373} \pgfmath@def{atan}{517}{27.33896} -\pgfmath@def{atan}{518}{27.38415} \pgfmath@def{atan}{519}{27.42931} -\pgfmath@def{atan}{520}{27.47443} \pgfmath@def{atan}{521}{27.51951} -\pgfmath@def{atan}{522}{27.56455} \pgfmath@def{atan}{523}{27.60956} -\pgfmath@def{atan}{524}{27.65453} \pgfmath@def{atan}{525}{27.69947} -\pgfmath@def{atan}{526}{27.74437} \pgfmath@def{atan}{527}{27.78923} -\pgfmath@def{atan}{528}{27.83405} \pgfmath@def{atan}{529}{27.87884} -\pgfmath@def{atan}{530}{27.92359} \pgfmath@def{atan}{531}{27.96830} -\pgfmath@def{atan}{532}{28.01297} \pgfmath@def{atan}{533}{28.05761} -\pgfmath@def{atan}{534}{28.10221} \pgfmath@def{atan}{535}{28.14678} -\pgfmath@def{atan}{536}{28.19130} \pgfmath@def{atan}{537}{28.23579} -\pgfmath@def{atan}{538}{28.28025} \pgfmath@def{atan}{539}{28.32466} -\pgfmath@def{atan}{540}{28.36904} \pgfmath@def{atan}{541}{28.41338} -\pgfmath@def{atan}{542}{28.45769} \pgfmath@def{atan}{543}{28.50196} -\pgfmath@def{atan}{544}{28.54619} \pgfmath@def{atan}{545}{28.59038} -\pgfmath@def{atan}{546}{28.63454} \pgfmath@def{atan}{547}{28.67865} -\pgfmath@def{atan}{548}{28.72274} \pgfmath@def{atan}{549}{28.76678} -\pgfmath@def{atan}{550}{28.81079} \pgfmath@def{atan}{551}{28.85476} -\pgfmath@def{atan}{552}{28.89869} \pgfmath@def{atan}{553}{28.94259} -\pgfmath@def{atan}{554}{28.98645} \pgfmath@def{atan}{555}{29.03027} -\pgfmath@def{atan}{556}{29.07405} \pgfmath@def{atan}{557}{29.11780} -\pgfmath@def{atan}{558}{29.16151} \pgfmath@def{atan}{559}{29.20519} -\pgfmath@def{atan}{560}{29.24882} \pgfmath@def{atan}{561}{29.29242} -\pgfmath@def{atan}{562}{29.33598} \pgfmath@def{atan}{563}{29.37951} -\pgfmath@def{atan}{564}{29.42299} \pgfmath@def{atan}{565}{29.46644} -\pgfmath@def{atan}{566}{29.50986} \pgfmath@def{atan}{567}{29.55323} -\pgfmath@def{atan}{568}{29.59657} \pgfmath@def{atan}{569}{29.63987} -\pgfmath@def{atan}{570}{29.68314} \pgfmath@def{atan}{571}{29.72636} -\pgfmath@def{atan}{572}{29.76955} \pgfmath@def{atan}{573}{29.81270} -\pgfmath@def{atan}{574}{29.85582} \pgfmath@def{atan}{575}{29.89890} -\pgfmath@def{atan}{576}{29.94194} \pgfmath@def{atan}{577}{29.98494} -\pgfmath@def{atan}{578}{30.02791} \pgfmath@def{atan}{579}{30.07084} -\pgfmath@def{atan}{580}{30.11373} \pgfmath@def{atan}{581}{30.15658} -\pgfmath@def{atan}{582}{30.19940} \pgfmath@def{atan}{583}{30.24218} -\pgfmath@def{atan}{584}{30.28492} \pgfmath@def{atan}{585}{30.32763} -\pgfmath@def{atan}{586}{30.37030} \pgfmath@def{atan}{587}{30.41293} -\pgfmath@def{atan}{588}{30.45552} \pgfmath@def{atan}{589}{30.49808} -\pgfmath@def{atan}{590}{30.54060} \pgfmath@def{atan}{591}{30.58308} -\pgfmath@def{atan}{592}{30.62553} \pgfmath@def{atan}{593}{30.66794} -\pgfmath@def{atan}{594}{30.71031} \pgfmath@def{atan}{595}{30.75264} -\pgfmath@def{atan}{596}{30.79494} \pgfmath@def{atan}{597}{30.83720} -\pgfmath@def{atan}{598}{30.87942} \pgfmath@def{atan}{599}{30.92160} -\pgfmath@def{atan}{600}{30.96375} \pgfmath@def{atan}{601}{31.00586} -\pgfmath@def{atan}{602}{31.04794} \pgfmath@def{atan}{603}{31.08997} -\pgfmath@def{atan}{604}{31.13197} \pgfmath@def{atan}{605}{31.17393} -\pgfmath@def{atan}{606}{31.21586} \pgfmath@def{atan}{607}{31.25775} -\pgfmath@def{atan}{608}{31.29960} \pgfmath@def{atan}{609}{31.34141} -\pgfmath@def{atan}{610}{31.38319} \pgfmath@def{atan}{611}{31.42493} -\pgfmath@def{atan}{612}{31.46663} \pgfmath@def{atan}{613}{31.50829} -\pgfmath@def{atan}{614}{31.54992} \pgfmath@def{atan}{615}{31.59151} -\pgfmath@def{atan}{616}{31.63306} \pgfmath@def{atan}{617}{31.67458} -\pgfmath@def{atan}{618}{31.71606} \pgfmath@def{atan}{619}{31.75750} -\pgfmath@def{atan}{620}{31.79891} \pgfmath@def{atan}{621}{31.84028} -\pgfmath@def{atan}{622}{31.88161} \pgfmath@def{atan}{623}{31.92290} -\pgfmath@def{atan}{624}{31.96416} \pgfmath@def{atan}{625}{32.00538} -\pgfmath@def{atan}{626}{32.04656} \pgfmath@def{atan}{627}{32.08771} -\pgfmath@def{atan}{628}{32.12882} \pgfmath@def{atan}{629}{32.16989} -\pgfmath@def{atan}{630}{32.21092} \pgfmath@def{atan}{631}{32.25192} -\pgfmath@def{atan}{632}{32.29288} \pgfmath@def{atan}{633}{32.33381} -\pgfmath@def{atan}{634}{32.37469} \pgfmath@def{atan}{635}{32.41554} -\pgfmath@def{atan}{636}{32.45636} \pgfmath@def{atan}{637}{32.49713} -\pgfmath@def{atan}{638}{32.53787} \pgfmath@def{atan}{639}{32.57857} -\pgfmath@def{atan}{640}{32.61924} \pgfmath@def{atan}{641}{32.65987} -\pgfmath@def{atan}{642}{32.70046} \pgfmath@def{atan}{643}{32.74101} -\pgfmath@def{atan}{644}{32.78153} \pgfmath@def{atan}{645}{32.82201} -\pgfmath@def{atan}{646}{32.86246} \pgfmath@def{atan}{647}{32.90286} -\pgfmath@def{atan}{648}{32.94323} \pgfmath@def{atan}{649}{32.98357} -\pgfmath@def{atan}{650}{33.02386} \pgfmath@def{atan}{651}{33.06412} -\pgfmath@def{atan}{652}{33.10435} \pgfmath@def{atan}{653}{33.14453} -\pgfmath@def{atan}{654}{33.18468} \pgfmath@def{atan}{655}{33.22479} -\pgfmath@def{atan}{656}{33.26487} \pgfmath@def{atan}{657}{33.30491} -\pgfmath@def{atan}{658}{33.34491} \pgfmath@def{atan}{659}{33.38488} -\pgfmath@def{atan}{660}{33.42481} \pgfmath@def{atan}{661}{33.46470} -\pgfmath@def{atan}{662}{33.50455} \pgfmath@def{atan}{663}{33.54437} -\pgfmath@def{atan}{664}{33.58416} \pgfmath@def{atan}{665}{33.62390} -\pgfmath@def{atan}{666}{33.66361} \pgfmath@def{atan}{667}{33.70328} -\pgfmath@def{atan}{668}{33.74292} \pgfmath@def{atan}{669}{33.78252} -\pgfmath@def{atan}{670}{33.82208} \pgfmath@def{atan}{671}{33.86161} -\pgfmath@def{atan}{672}{33.90110} \pgfmath@def{atan}{673}{33.94055} -\pgfmath@def{atan}{674}{33.97997} \pgfmath@def{atan}{675}{34.01935} -\pgfmath@def{atan}{676}{34.05869} \pgfmath@def{atan}{677}{34.09800} -\pgfmath@def{atan}{678}{34.13727} \pgfmath@def{atan}{679}{34.17650} -\pgfmath@def{atan}{680}{34.21570} \pgfmath@def{atan}{681}{34.25486} -\pgfmath@def{atan}{682}{34.29398} \pgfmath@def{atan}{683}{34.33307} -\pgfmath@def{atan}{684}{34.37212} \pgfmath@def{atan}{685}{34.41114} -\pgfmath@def{atan}{686}{34.45012} \pgfmath@def{atan}{687}{34.48906} -\pgfmath@def{atan}{688}{34.52797} \pgfmath@def{atan}{689}{34.56684} -\pgfmath@def{atan}{690}{34.60567} \pgfmath@def{atan}{691}{34.64447} -\pgfmath@def{atan}{692}{34.68323} \pgfmath@def{atan}{693}{34.72195} -\pgfmath@def{atan}{694}{34.76064} \pgfmath@def{atan}{695}{34.79930} -\pgfmath@def{atan}{696}{34.83791} \pgfmath@def{atan}{697}{34.87649} -\pgfmath@def{atan}{698}{34.91504} \pgfmath@def{atan}{699}{34.95354} -\pgfmath@def{atan}{700}{34.99202} \pgfmath@def{atan}{701}{35.03045} -\pgfmath@def{atan}{702}{35.06885} \pgfmath@def{atan}{703}{35.10721} -\pgfmath@def{atan}{704}{35.14554} \pgfmath@def{atan}{705}{35.18383} -\pgfmath@def{atan}{706}{35.22209} \pgfmath@def{atan}{707}{35.26031} -\pgfmath@def{atan}{708}{35.29849} \pgfmath@def{atan}{709}{35.33664} -\pgfmath@def{atan}{710}{35.37475} \pgfmath@def{atan}{711}{35.41282} -\pgfmath@def{atan}{712}{35.45086} \pgfmath@def{atan}{713}{35.48886} -\pgfmath@def{atan}{714}{35.52683} \pgfmath@def{atan}{715}{35.56476} -\pgfmath@def{atan}{716}{35.60266} \pgfmath@def{atan}{717}{35.64052} -\pgfmath@def{atan}{718}{35.67834} \pgfmath@def{atan}{719}{35.71613} -\pgfmath@def{atan}{720}{35.75388} \pgfmath@def{atan}{721}{35.79160} -\pgfmath@def{atan}{722}{35.82928} \pgfmath@def{atan}{723}{35.86692} -\pgfmath@def{atan}{724}{35.90453} \pgfmath@def{atan}{725}{35.94211} -\pgfmath@def{atan}{726}{35.97965} \pgfmath@def{atan}{727}{36.01715} -\pgfmath@def{atan}{728}{36.05461} \pgfmath@def{atan}{729}{36.09204} -\pgfmath@def{atan}{730}{36.12944} \pgfmath@def{atan}{731}{36.16680} -\pgfmath@def{atan}{732}{36.20412} \pgfmath@def{atan}{733}{36.24141} -\pgfmath@def{atan}{734}{36.27866} \pgfmath@def{atan}{735}{36.31588} -\pgfmath@def{atan}{736}{36.35306} \pgfmath@def{atan}{737}{36.39021} -\pgfmath@def{atan}{738}{36.42732} \pgfmath@def{atan}{739}{36.46440} -\pgfmath@def{atan}{740}{36.50144} \pgfmath@def{atan}{741}{36.53844} -\pgfmath@def{atan}{742}{36.57541} \pgfmath@def{atan}{743}{36.61234} -\pgfmath@def{atan}{744}{36.64924} \pgfmath@def{atan}{745}{36.68611} -\pgfmath@def{atan}{746}{36.72293} \pgfmath@def{atan}{747}{36.75973} -\pgfmath@def{atan}{748}{36.79648} \pgfmath@def{atan}{749}{36.83321} -\pgfmath@def{atan}{750}{36.86989} \pgfmath@def{atan}{751}{36.90654} -\pgfmath@def{atan}{752}{36.94316} \pgfmath@def{atan}{753}{36.97974} -\pgfmath@def{atan}{754}{37.01629} \pgfmath@def{atan}{755}{37.05280} -\pgfmath@def{atan}{756}{37.08928} \pgfmath@def{atan}{757}{37.12572} -\pgfmath@def{atan}{758}{37.16212} \pgfmath@def{atan}{759}{37.19849} -\pgfmath@def{atan}{760}{37.23483} \pgfmath@def{atan}{761}{37.27113} -\pgfmath@def{atan}{762}{37.30740} \pgfmath@def{atan}{763}{37.34363} -\pgfmath@def{atan}{764}{37.37982} \pgfmath@def{atan}{765}{37.41598} -\pgfmath@def{atan}{766}{37.45211} \pgfmath@def{atan}{767}{37.48820} -\pgfmath@def{atan}{768}{37.52426} \pgfmath@def{atan}{769}{37.56028} -\pgfmath@def{atan}{770}{37.59627} \pgfmath@def{atan}{771}{37.63222} -\pgfmath@def{atan}{772}{37.66814} \pgfmath@def{atan}{773}{37.70402} -\pgfmath@def{atan}{774}{37.73987} \pgfmath@def{atan}{775}{37.77568} -\pgfmath@def{atan}{776}{37.81146} \pgfmath@def{atan}{777}{37.84720} -\pgfmath@def{atan}{778}{37.88291} \pgfmath@def{atan}{779}{37.91859} -\pgfmath@def{atan}{780}{37.95423} \pgfmath@def{atan}{781}{37.98983} -\pgfmath@def{atan}{782}{38.02540} \pgfmath@def{atan}{783}{38.06094} -\pgfmath@def{atan}{784}{38.09644} \pgfmath@def{atan}{785}{38.13191} -\pgfmath@def{atan}{786}{38.16734} \pgfmath@def{atan}{787}{38.20274} -\pgfmath@def{atan}{788}{38.23811} \pgfmath@def{atan}{789}{38.27344} -\pgfmath@def{atan}{790}{38.30873} \pgfmath@def{atan}{791}{38.34399} -\pgfmath@def{atan}{792}{38.37922} \pgfmath@def{atan}{793}{38.41441} -\pgfmath@def{atan}{794}{38.44957} \pgfmath@def{atan}{795}{38.48469} -\pgfmath@def{atan}{796}{38.51979} \pgfmath@def{atan}{797}{38.55484} -\pgfmath@def{atan}{798}{38.58986} \pgfmath@def{atan}{799}{38.62485} -\pgfmath@def{atan}{800}{38.65980} \pgfmath@def{atan}{801}{38.69472} -\pgfmath@def{atan}{802}{38.72961} \pgfmath@def{atan}{803}{38.76446} -\pgfmath@def{atan}{804}{38.79928} \pgfmath@def{atan}{805}{38.83406} -\pgfmath@def{atan}{806}{38.86881} \pgfmath@def{atan}{807}{38.90353} -\pgfmath@def{atan}{808}{38.93821} \pgfmath@def{atan}{809}{38.97285} -\pgfmath@def{atan}{810}{39.00747} \pgfmath@def{atan}{811}{39.04205} -\pgfmath@def{atan}{812}{39.07659} \pgfmath@def{atan}{813}{39.11111} -\pgfmath@def{atan}{814}{39.14558} \pgfmath@def{atan}{815}{39.18003} -\pgfmath@def{atan}{816}{39.21444} \pgfmath@def{atan}{817}{39.24882} -\pgfmath@def{atan}{818}{39.28316} \pgfmath@def{atan}{819}{39.31747} -\pgfmath@def{atan}{820}{39.35175} \pgfmath@def{atan}{821}{39.38599} -\pgfmath@def{atan}{822}{39.42020} \pgfmath@def{atan}{823}{39.45438} -\pgfmath@def{atan}{824}{39.48852} \pgfmath@def{atan}{825}{39.52263} -\pgfmath@def{atan}{826}{39.55670} \pgfmath@def{atan}{827}{39.59074} -\pgfmath@def{atan}{828}{39.62475} \pgfmath@def{atan}{829}{39.65873} -\pgfmath@def{atan}{830}{39.69267} \pgfmath@def{atan}{831}{39.72658} -\pgfmath@def{atan}{832}{39.76045} \pgfmath@def{atan}{833}{39.79429} -\pgfmath@def{atan}{834}{39.82810} \pgfmath@def{atan}{835}{39.86188} -\pgfmath@def{atan}{836}{39.89562} \pgfmath@def{atan}{837}{39.92933} -\pgfmath@def{atan}{838}{39.96300} \pgfmath@def{atan}{839}{39.99665} -\pgfmath@def{atan}{840}{40.03025} \pgfmath@def{atan}{841}{40.06383} -\pgfmath@def{atan}{842}{40.09737} \pgfmath@def{atan}{843}{40.13088} -\pgfmath@def{atan}{844}{40.16436} \pgfmath@def{atan}{845}{40.19781} -\pgfmath@def{atan}{846}{40.23122} \pgfmath@def{atan}{847}{40.26459} -\pgfmath@def{atan}{848}{40.29794} \pgfmath@def{atan}{849}{40.33125} -\pgfmath@def{atan}{850}{40.36453} \pgfmath@def{atan}{851}{40.39778} -\pgfmath@def{atan}{852}{40.43099} \pgfmath@def{atan}{853}{40.46417} -\pgfmath@def{atan}{854}{40.49732} \pgfmath@def{atan}{855}{40.53044} -\pgfmath@def{atan}{856}{40.56352} \pgfmath@def{atan}{857}{40.59657} -\pgfmath@def{atan}{858}{40.62959} \pgfmath@def{atan}{859}{40.66257} -\pgfmath@def{atan}{860}{40.69553} \pgfmath@def{atan}{861}{40.72845} -\pgfmath@def{atan}{862}{40.76133} \pgfmath@def{atan}{863}{40.79419} -\pgfmath@def{atan}{864}{40.82701} \pgfmath@def{atan}{865}{40.85980} -\pgfmath@def{atan}{866}{40.89256} \pgfmath@def{atan}{867}{40.92528} -\pgfmath@def{atan}{868}{40.95798} \pgfmath@def{atan}{869}{40.99064} -\pgfmath@def{atan}{870}{41.02326} \pgfmath@def{atan}{871}{41.05586} -\pgfmath@def{atan}{872}{41.08842} \pgfmath@def{atan}{873}{41.12095} -\pgfmath@def{atan}{874}{41.15345} \pgfmath@def{atan}{875}{41.18592} -\pgfmath@def{atan}{876}{41.21836} \pgfmath@def{atan}{877}{41.25076} -\pgfmath@def{atan}{878}{41.28313} \pgfmath@def{atan}{879}{41.31547} -\pgfmath@def{atan}{880}{41.34777} \pgfmath@def{atan}{881}{41.38005} -\pgfmath@def{atan}{882}{41.41229} \pgfmath@def{atan}{883}{41.44450} -\pgfmath@def{atan}{884}{41.47668} \pgfmath@def{atan}{885}{41.50882} -\pgfmath@def{atan}{886}{41.54094} \pgfmath@def{atan}{887}{41.57302} -\pgfmath@def{atan}{888}{41.60507} \pgfmath@def{atan}{889}{41.63709} -\pgfmath@def{atan}{890}{41.66908} \pgfmath@def{atan}{891}{41.70103} -\pgfmath@def{atan}{892}{41.73296} \pgfmath@def{atan}{893}{41.76485} -\pgfmath@def{atan}{894}{41.79671} \pgfmath@def{atan}{895}{41.82854} -\pgfmath@def{atan}{896}{41.86034} \pgfmath@def{atan}{897}{41.89210} -\pgfmath@def{atan}{898}{41.92383} \pgfmath@def{atan}{899}{41.95554} -\pgfmath@def{atan}{900}{41.98721} \pgfmath@def{atan}{901}{42.01885} -\pgfmath@def{atan}{902}{42.05046} \pgfmath@def{atan}{903}{42.08203} -\pgfmath@def{atan}{904}{42.11358} \pgfmath@def{atan}{905}{42.14509} -\pgfmath@def{atan}{906}{42.17657} \pgfmath@def{atan}{907}{42.20802} -\pgfmath@def{atan}{908}{42.23944} \pgfmath@def{atan}{909}{42.27083} -\pgfmath@def{atan}{910}{42.30219} \pgfmath@def{atan}{911}{42.33352} -\pgfmath@def{atan}{912}{42.36481} \pgfmath@def{atan}{913}{42.39607} -\pgfmath@def{atan}{914}{42.42731} \pgfmath@def{atan}{915}{42.45851} -\pgfmath@def{atan}{916}{42.48968} \pgfmath@def{atan}{917}{42.52082} -\pgfmath@def{atan}{918}{42.55193} \pgfmath@def{atan}{919}{42.58300} -\pgfmath@def{atan}{920}{42.61405} \pgfmath@def{atan}{921}{42.64507} -\pgfmath@def{atan}{922}{42.67605} \pgfmath@def{atan}{923}{42.70701} -\pgfmath@def{atan}{924}{42.73793} \pgfmath@def{atan}{925}{42.76882} -\pgfmath@def{atan}{926}{42.79968} \pgfmath@def{atan}{927}{42.83051} -\pgfmath@def{atan}{928}{42.86131} \pgfmath@def{atan}{929}{42.89208} -\pgfmath@def{atan}{930}{42.92282} \pgfmath@def{atan}{931}{42.95353} -\pgfmath@def{atan}{932}{42.98421} \pgfmath@def{atan}{933}{43.01485} -\pgfmath@def{atan}{934}{43.04547} \pgfmath@def{atan}{935}{43.07605} -\pgfmath@def{atan}{936}{43.10661} \pgfmath@def{atan}{937}{43.13713} -\pgfmath@def{atan}{938}{43.16763} \pgfmath@def{atan}{939}{43.19809} -\pgfmath@def{atan}{940}{43.22853} \pgfmath@def{atan}{941}{43.25893} -\pgfmath@def{atan}{942}{43.28930} \pgfmath@def{atan}{943}{43.31964} -\pgfmath@def{atan}{944}{43.34996} \pgfmath@def{atan}{945}{43.38024} -\pgfmath@def{atan}{946}{43.41049} \pgfmath@def{atan}{947}{43.44071} -\pgfmath@def{atan}{948}{43.47090} \pgfmath@def{atan}{949}{43.50106} -\pgfmath@def{atan}{950}{43.53119} \pgfmath@def{atan}{951}{43.56130} -\pgfmath@def{atan}{952}{43.59137} \pgfmath@def{atan}{953}{43.62141} -\pgfmath@def{atan}{954}{43.65142} \pgfmath@def{atan}{955}{43.68140} -\pgfmath@def{atan}{956}{43.71135} \pgfmath@def{atan}{957}{43.74127} -\pgfmath@def{atan}{958}{43.77116} \pgfmath@def{atan}{959}{43.80102} -\pgfmath@def{atan}{960}{43.83086} \pgfmath@def{atan}{961}{43.86066} -\pgfmath@def{atan}{962}{43.89043} \pgfmath@def{atan}{963}{43.92017} -\pgfmath@def{atan}{964}{43.94988} \pgfmath@def{atan}{965}{43.97957} -\pgfmath@def{atan}{966}{44.00922} \pgfmath@def{atan}{967}{44.03884} -\pgfmath@def{atan}{968}{44.06844} \pgfmath@def{atan}{969}{44.09800} -\pgfmath@def{atan}{970}{44.12754} \pgfmath@def{atan}{971}{44.15704} -\pgfmath@def{atan}{972}{44.18652} \pgfmath@def{atan}{973}{44.21597} -\pgfmath@def{atan}{974}{44.24538} \pgfmath@def{atan}{975}{44.27477} -\pgfmath@def{atan}{976}{44.30413} \pgfmath@def{atan}{977}{44.33346} -\pgfmath@def{atan}{978}{44.36276} \pgfmath@def{atan}{979}{44.39203} -\pgfmath@def{atan}{980}{44.42127} \pgfmath@def{atan}{981}{44.45048} -\pgfmath@def{atan}{982}{44.47966} \pgfmath@def{atan}{983}{44.50882} -\pgfmath@def{atan}{984}{44.53794} \pgfmath@def{atan}{985}{44.56704} -\pgfmath@def{atan}{986}{44.59610} \pgfmath@def{atan}{987}{44.62514} -\pgfmath@def{atan}{988}{44.65415} \pgfmath@def{atan}{989}{44.68313} -\pgfmath@def{atan}{990}{44.71208} \pgfmath@def{atan}{991}{44.74100} -\pgfmath@def{atan}{992}{44.76989} \pgfmath@def{atan}{993}{44.79876} -\pgfmath@def{atan}{994}{44.82759} \pgfmath@def{atan}{995}{44.85640} -\pgfmath@def{atan}{996}{44.88517} \pgfmath@def{atan}{997}{44.91392} -\pgfmath@def{atan}{998}{44.94264} \pgfmath@def{atan}{999}{44.97133} -\pgfmath@def{atan}{1000}{45.00000} - -\pgfmath@def{acos}{0}{90.00000} \pgfmath@def{acos}{1}{89.94270} -\pgfmath@def{acos}{2}{89.88540} \pgfmath@def{acos}{3}{89.82811} -\pgfmath@def{acos}{4}{89.77081} \pgfmath@def{acos}{5}{89.71352} -\pgfmath@def{acos}{6}{89.65622} \pgfmath@def{acos}{7}{89.59892} -\pgfmath@def{acos}{8}{89.54162} \pgfmath@def{acos}{9}{89.48433} -\pgfmath@def{acos}{10}{89.42703} \pgfmath@def{acos}{11}{89.36973} -\pgfmath@def{acos}{12}{89.31243} \pgfmath@def{acos}{13}{89.25513} -\pgfmath@def{acos}{14}{89.19783} \pgfmath@def{acos}{15}{89.14053} -\pgfmath@def{acos}{16}{89.08322} \pgfmath@def{acos}{17}{89.02592} -\pgfmath@def{acos}{18}{88.96862} \pgfmath@def{acos}{19}{88.91131} -\pgfmath@def{acos}{20}{88.85400} \pgfmath@def{acos}{21}{88.79670} -\pgfmath@def{acos}{22}{88.73939} \pgfmath@def{acos}{23}{88.68208} -\pgfmath@def{acos}{24}{88.62476} \pgfmath@def{acos}{25}{88.56745} -\pgfmath@def{acos}{26}{88.51014} \pgfmath@def{acos}{27}{88.45282} -\pgfmath@def{acos}{28}{88.39550} \pgfmath@def{acos}{29}{88.33818} -\pgfmath@def{acos}{30}{88.28086} \pgfmath@def{acos}{31}{88.22354} -\pgfmath@def{acos}{32}{88.16622} \pgfmath@def{acos}{33}{88.10889} -\pgfmath@def{acos}{34}{88.05156} \pgfmath@def{acos}{35}{87.99423} -\pgfmath@def{acos}{36}{87.93690} \pgfmath@def{acos}{37}{87.87957} -\pgfmath@def{acos}{38}{87.82223} \pgfmath@def{acos}{39}{87.76489} -\pgfmath@def{acos}{40}{87.70755} \pgfmath@def{acos}{41}{87.65021} -\pgfmath@def{acos}{42}{87.59286} \pgfmath@def{acos}{43}{87.53552} -\pgfmath@def{acos}{44}{87.47817} \pgfmath@def{acos}{45}{87.42081} -\pgfmath@def{acos}{46}{87.36346} \pgfmath@def{acos}{47}{87.30610} -\pgfmath@def{acos}{48}{87.24874} \pgfmath@def{acos}{49}{87.19138} -\pgfmath@def{acos}{50}{87.13401} \pgfmath@def{acos}{51}{87.07664} -\pgfmath@def{acos}{52}{87.01927} \pgfmath@def{acos}{53}{86.96190} -\pgfmath@def{acos}{54}{86.90452} \pgfmath@def{acos}{55}{86.84714} -\pgfmath@def{acos}{56}{86.78975} \pgfmath@def{acos}{57}{86.73237} -\pgfmath@def{acos}{58}{86.67497} \pgfmath@def{acos}{59}{86.61758} -\pgfmath@def{acos}{60}{86.56018} \pgfmath@def{acos}{61}{86.50278} -\pgfmath@def{acos}{62}{86.44538} \pgfmath@def{acos}{63}{86.38797} -\pgfmath@def{acos}{64}{86.33056} \pgfmath@def{acos}{65}{86.27314} -\pgfmath@def{acos}{66}{86.21572} \pgfmath@def{acos}{67}{86.15830} -\pgfmath@def{acos}{68}{86.10087} \pgfmath@def{acos}{69}{86.04344} -\pgfmath@def{acos}{70}{85.98601} \pgfmath@def{acos}{71}{85.92857} -\pgfmath@def{acos}{72}{85.87113} \pgfmath@def{acos}{73}{85.81368} -\pgfmath@def{acos}{74}{85.75623} \pgfmath@def{acos}{75}{85.69877} -\pgfmath@def{acos}{76}{85.64131} \pgfmath@def{acos}{77}{85.58385} -\pgfmath@def{acos}{78}{85.52638} \pgfmath@def{acos}{79}{85.46891} -\pgfmath@def{acos}{80}{85.41143} \pgfmath@def{acos}{81}{85.35395} -\pgfmath@def{acos}{82}{85.29646} \pgfmath@def{acos}{83}{85.23897} -\pgfmath@def{acos}{84}{85.18147} \pgfmath@def{acos}{85}{85.12397} -\pgfmath@def{acos}{86}{85.06646} \pgfmath@def{acos}{87}{85.00895} -\pgfmath@def{acos}{88}{84.95144} \pgfmath@def{acos}{89}{84.89392} -\pgfmath@def{acos}{90}{84.83639} \pgfmath@def{acos}{91}{84.77886} -\pgfmath@def{acos}{92}{84.72132} \pgfmath@def{acos}{93}{84.66378} -\pgfmath@def{acos}{94}{84.60623} \pgfmath@def{acos}{95}{84.54868} -\pgfmath@def{acos}{96}{84.49112} \pgfmath@def{acos}{97}{84.43355} -\pgfmath@def{acos}{98}{84.37598} \pgfmath@def{acos}{99}{84.31841} -\pgfmath@def{acos}{100}{84.26083} \pgfmath@def{acos}{101}{84.20324} -\pgfmath@def{acos}{102}{84.14564} \pgfmath@def{acos}{103}{84.08805} -\pgfmath@def{acos}{104}{84.03044} \pgfmath@def{acos}{105}{83.97283} -\pgfmath@def{acos}{106}{83.91521} \pgfmath@def{acos}{107}{83.85759} -\pgfmath@def{acos}{108}{83.79996} \pgfmath@def{acos}{109}{83.74232} -\pgfmath@def{acos}{110}{83.68468} \pgfmath@def{acos}{111}{83.62703} -\pgfmath@def{acos}{112}{83.56938} \pgfmath@def{acos}{113}{83.51171} -\pgfmath@def{acos}{114}{83.45405} \pgfmath@def{acos}{115}{83.39637} -\pgfmath@def{acos}{116}{83.33869} \pgfmath@def{acos}{117}{83.28100} -\pgfmath@def{acos}{118}{83.22330} \pgfmath@def{acos}{119}{83.16560} -\pgfmath@def{acos}{120}{83.10789} \pgfmath@def{acos}{121}{83.05018} -\pgfmath@def{acos}{122}{82.99245} \pgfmath@def{acos}{123}{82.93472} -\pgfmath@def{acos}{124}{82.87698} \pgfmath@def{acos}{125}{82.81924} -\pgfmath@def{acos}{126}{82.76149} \pgfmath@def{acos}{127}{82.70373} -\pgfmath@def{acos}{128}{82.64596} \pgfmath@def{acos}{129}{82.58819} -\pgfmath@def{acos}{130}{82.53040} \pgfmath@def{acos}{131}{82.47261} -\pgfmath@def{acos}{132}{82.41482} \pgfmath@def{acos}{133}{82.35701} -\pgfmath@def{acos}{134}{82.29920} \pgfmath@def{acos}{135}{82.24138} -\pgfmath@def{acos}{136}{82.18355} \pgfmath@def{acos}{137}{82.12571} -\pgfmath@def{acos}{138}{82.06786} \pgfmath@def{acos}{139}{82.01001} -\pgfmath@def{acos}{140}{81.95215} \pgfmath@def{acos}{141}{81.89428} -\pgfmath@def{acos}{142}{81.83640} \pgfmath@def{acos}{143}{81.77851} -\pgfmath@def{acos}{144}{81.72062} \pgfmath@def{acos}{145}{81.66272} -\pgfmath@def{acos}{146}{81.60480} \pgfmath@def{acos}{147}{81.54688} -\pgfmath@def{acos}{148}{81.48895} \pgfmath@def{acos}{149}{81.43102} -\pgfmath@def{acos}{150}{81.37307} \pgfmath@def{acos}{151}{81.31511} -\pgfmath@def{acos}{152}{81.25715} \pgfmath@def{acos}{153}{81.19917} -\pgfmath@def{acos}{154}{81.14119} \pgfmath@def{acos}{155}{81.08320} -\pgfmath@def{acos}{156}{81.02520} \pgfmath@def{acos}{157}{80.96719} -\pgfmath@def{acos}{158}{80.90917} \pgfmath@def{acos}{159}{80.85114} -\pgfmath@def{acos}{160}{80.79310} \pgfmath@def{acos}{161}{80.73505} -\pgfmath@def{acos}{162}{80.67699} \pgfmath@def{acos}{163}{80.61893} -\pgfmath@def{acos}{164}{80.56085} \pgfmath@def{acos}{165}{80.50276} -\pgfmath@def{acos}{166}{80.44466} \pgfmath@def{acos}{167}{80.38656} -\pgfmath@def{acos}{168}{80.32844} \pgfmath@def{acos}{169}{80.27031} -\pgfmath@def{acos}{170}{80.21218} \pgfmath@def{acos}{171}{80.15403} -\pgfmath@def{acos}{172}{80.09587} \pgfmath@def{acos}{173}{80.03770} -\pgfmath@def{acos}{174}{79.97953} \pgfmath@def{acos}{175}{79.92134} -\pgfmath@def{acos}{176}{79.86314} \pgfmath@def{acos}{177}{79.80493} -\pgfmath@def{acos}{178}{79.74671} \pgfmath@def{acos}{179}{79.68848} -\pgfmath@def{acos}{180}{79.63024} \pgfmath@def{acos}{181}{79.57198} -\pgfmath@def{acos}{182}{79.51372} \pgfmath@def{acos}{183}{79.45545} -\pgfmath@def{acos}{184}{79.39716} \pgfmath@def{acos}{185}{79.33886} -\pgfmath@def{acos}{186}{79.28056} \pgfmath@def{acos}{187}{79.22224} -\pgfmath@def{acos}{188}{79.16391} \pgfmath@def{acos}{189}{79.10556} -\pgfmath@def{acos}{190}{79.04721} \pgfmath@def{acos}{191}{78.98885} -\pgfmath@def{acos}{192}{78.93047} \pgfmath@def{acos}{193}{78.87208} -\pgfmath@def{acos}{194}{78.81368} \pgfmath@def{acos}{195}{78.75527} -\pgfmath@def{acos}{196}{78.69685} \pgfmath@def{acos}{197}{78.63841} -\pgfmath@def{acos}{198}{78.57997} \pgfmath@def{acos}{199}{78.52151} -\pgfmath@def{acos}{200}{78.46304} \pgfmath@def{acos}{201}{78.40455} -\pgfmath@def{acos}{202}{78.34606} \pgfmath@def{acos}{203}{78.28755} -\pgfmath@def{acos}{204}{78.22903} \pgfmath@def{acos}{205}{78.17050} -\pgfmath@def{acos}{206}{78.11195} \pgfmath@def{acos}{207}{78.05339} -\pgfmath@def{acos}{208}{77.99482} \pgfmath@def{acos}{209}{77.93624} -\pgfmath@def{acos}{210}{77.87764} \pgfmath@def{acos}{211}{77.81903} -\pgfmath@def{acos}{212}{77.76041} \pgfmath@def{acos}{213}{77.70178} -\pgfmath@def{acos}{214}{77.64313} \pgfmath@def{acos}{215}{77.58447} -\pgfmath@def{acos}{216}{77.52579} \pgfmath@def{acos}{217}{77.46711} -\pgfmath@def{acos}{218}{77.40841} \pgfmath@def{acos}{219}{77.34969} -\pgfmath@def{acos}{220}{77.29096} \pgfmath@def{acos}{221}{77.23222} -\pgfmath@def{acos}{222}{77.17347} \pgfmath@def{acos}{223}{77.11470} -\pgfmath@def{acos}{224}{77.05591} \pgfmath@def{acos}{225}{76.99712} -\pgfmath@def{acos}{226}{76.93831} \pgfmath@def{acos}{227}{76.87948} -\pgfmath@def{acos}{228}{76.82064} \pgfmath@def{acos}{229}{76.76179} -\pgfmath@def{acos}{230}{76.70292} \pgfmath@def{acos}{231}{76.64404} -\pgfmath@def{acos}{232}{76.58515} \pgfmath@def{acos}{233}{76.52624} -\pgfmath@def{acos}{234}{76.46731} \pgfmath@def{acos}{235}{76.40837} -\pgfmath@def{acos}{236}{76.34942} \pgfmath@def{acos}{237}{76.29045} -\pgfmath@def{acos}{238}{76.23147} \pgfmath@def{acos}{239}{76.17247} -\pgfmath@def{acos}{240}{76.11346} \pgfmath@def{acos}{241}{76.05443} -\pgfmath@def{acos}{242}{75.99538} \pgfmath@def{acos}{243}{75.93632} -\pgfmath@def{acos}{244}{75.87725} \pgfmath@def{acos}{245}{75.81816} -\pgfmath@def{acos}{246}{75.75906} \pgfmath@def{acos}{247}{75.69994} -\pgfmath@def{acos}{248}{75.64080} \pgfmath@def{acos}{249}{75.58165} -\pgfmath@def{acos}{250}{75.52248} \pgfmath@def{acos}{251}{75.46330} -\pgfmath@def{acos}{252}{75.40410} \pgfmath@def{acos}{253}{75.34489} -\pgfmath@def{acos}{254}{75.28566} \pgfmath@def{acos}{255}{75.22641} -\pgfmath@def{acos}{256}{75.16715} \pgfmath@def{acos}{257}{75.10787} -\pgfmath@def{acos}{258}{75.04857} \pgfmath@def{acos}{259}{74.98926} -\pgfmath@def{acos}{260}{74.92993} \pgfmath@def{acos}{261}{74.87059} -\pgfmath@def{acos}{262}{74.81123} \pgfmath@def{acos}{263}{74.75185} -\pgfmath@def{acos}{264}{74.69245} \pgfmath@def{acos}{265}{74.63304} -\pgfmath@def{acos}{266}{74.57361} \pgfmath@def{acos}{267}{74.51417} -\pgfmath@def{acos}{268}{74.45471} \pgfmath@def{acos}{269}{74.39523} -\pgfmath@def{acos}{270}{74.33573} \pgfmath@def{acos}{271}{74.27621} -\pgfmath@def{acos}{272}{74.21668} \pgfmath@def{acos}{273}{74.15713} -\pgfmath@def{acos}{274}{74.09757} \pgfmath@def{acos}{275}{74.03798} -\pgfmath@def{acos}{276}{73.97838} \pgfmath@def{acos}{277}{73.91876} -\pgfmath@def{acos}{278}{73.85912} \pgfmath@def{acos}{279}{73.79946} -\pgfmath@def{acos}{280}{73.73979} \pgfmath@def{acos}{281}{73.68010} -\pgfmath@def{acos}{282}{73.62039} \pgfmath@def{acos}{283}{73.56066} -\pgfmath@def{acos}{284}{73.50091} \pgfmath@def{acos}{285}{73.44115} -\pgfmath@def{acos}{286}{73.38136} \pgfmath@def{acos}{287}{73.32156} -\pgfmath@def{acos}{288}{73.26174} \pgfmath@def{acos}{289}{73.20190} -\pgfmath@def{acos}{290}{73.14204} \pgfmath@def{acos}{291}{73.08216} -\pgfmath@def{acos}{292}{73.02226} \pgfmath@def{acos}{293}{72.96235} -\pgfmath@def{acos}{294}{72.90241} \pgfmath@def{acos}{295}{72.84246} -\pgfmath@def{acos}{296}{72.78248} \pgfmath@def{acos}{297}{72.72249} -\pgfmath@def{acos}{298}{72.66248} \pgfmath@def{acos}{299}{72.60244} -\pgfmath@def{acos}{300}{72.54239} \pgfmath@def{acos}{301}{72.48232} -\pgfmath@def{acos}{302}{72.42223} \pgfmath@def{acos}{303}{72.36212} -\pgfmath@def{acos}{304}{72.30198} \pgfmath@def{acos}{305}{72.24183} -\pgfmath@def{acos}{306}{72.18166} \pgfmath@def{acos}{307}{72.12147} -\pgfmath@def{acos}{308}{72.06125} \pgfmath@def{acos}{309}{72.00102} -\pgfmath@def{acos}{310}{71.94077} \pgfmath@def{acos}{311}{71.88049} -\pgfmath@def{acos}{312}{71.82019} \pgfmath@def{acos}{313}{71.75988} -\pgfmath@def{acos}{314}{71.69954} \pgfmath@def{acos}{315}{71.63918} -\pgfmath@def{acos}{316}{71.57880} \pgfmath@def{acos}{317}{71.51840} -\pgfmath@def{acos}{318}{71.45798} \pgfmath@def{acos}{319}{71.39754} -\pgfmath@def{acos}{320}{71.33707} \pgfmath@def{acos}{321}{71.27658} -\pgfmath@def{acos}{322}{71.21608} \pgfmath@def{acos}{323}{71.15555} -\pgfmath@def{acos}{324}{71.09499} \pgfmath@def{acos}{325}{71.03442} -\pgfmath@def{acos}{326}{70.97382} \pgfmath@def{acos}{327}{70.91321} -\pgfmath@def{acos}{328}{70.85257} \pgfmath@def{acos}{329}{70.79190} -\pgfmath@def{acos}{330}{70.73122} \pgfmath@def{acos}{331}{70.67051} -\pgfmath@def{acos}{332}{70.60978} \pgfmath@def{acos}{333}{70.54903} -\pgfmath@def{acos}{334}{70.48826} \pgfmath@def{acos}{335}{70.42746} -\pgfmath@def{acos}{336}{70.36664} \pgfmath@def{acos}{337}{70.30579} -\pgfmath@def{acos}{338}{70.24493} \pgfmath@def{acos}{339}{70.18404} -\pgfmath@def{acos}{340}{70.12312} \pgfmath@def{acos}{341}{70.06218} -\pgfmath@def{acos}{342}{70.00122} \pgfmath@def{acos}{343}{69.94024} -\pgfmath@def{acos}{344}{69.87923} \pgfmath@def{acos}{345}{69.81820} -\pgfmath@def{acos}{346}{69.75714} \pgfmath@def{acos}{347}{69.69606} -\pgfmath@def{acos}{348}{69.63496} \pgfmath@def{acos}{349}{69.57383} -\pgfmath@def{acos}{350}{69.51268} \pgfmath@def{acos}{351}{69.45150} -\pgfmath@def{acos}{352}{69.39030} \pgfmath@def{acos}{353}{69.32908} -\pgfmath@def{acos}{354}{69.26783} \pgfmath@def{acos}{355}{69.20655} -\pgfmath@def{acos}{356}{69.14525} \pgfmath@def{acos}{357}{69.08393} -\pgfmath@def{acos}{358}{69.02258} \pgfmath@def{acos}{359}{68.96120} -\pgfmath@def{acos}{360}{68.89980} \pgfmath@def{acos}{361}{68.83837} -\pgfmath@def{acos}{362}{68.77692} \pgfmath@def{acos}{363}{68.71544} -\pgfmath@def{acos}{364}{68.65394} \pgfmath@def{acos}{365}{68.59241} -\pgfmath@def{acos}{366}{68.53086} \pgfmath@def{acos}{367}{68.46928} -\pgfmath@def{acos}{368}{68.40767} \pgfmath@def{acos}{369}{68.34604} -\pgfmath@def{acos}{370}{68.28438} \pgfmath@def{acos}{371}{68.22269} -\pgfmath@def{acos}{372}{68.16098} \pgfmath@def{acos}{373}{68.09924} -\pgfmath@def{acos}{374}{68.03748} \pgfmath@def{acos}{375}{67.97568} -\pgfmath@def{acos}{376}{67.91386} \pgfmath@def{acos}{377}{67.85202} -\pgfmath@def{acos}{378}{67.79014} \pgfmath@def{acos}{379}{67.72824} -\pgfmath@def{acos}{380}{67.66631} \pgfmath@def{acos}{381}{67.60436} -\pgfmath@def{acos}{382}{67.54237} \pgfmath@def{acos}{383}{67.48036} -\pgfmath@def{acos}{384}{67.41832} \pgfmath@def{acos}{385}{67.35626} -\pgfmath@def{acos}{386}{67.29416} \pgfmath@def{acos}{387}{67.23204} -\pgfmath@def{acos}{388}{67.16988} \pgfmath@def{acos}{389}{67.10770} -\pgfmath@def{acos}{390}{67.04550} \pgfmath@def{acos}{391}{66.98326} -\pgfmath@def{acos}{392}{66.92099} \pgfmath@def{acos}{393}{66.85870} -\pgfmath@def{acos}{394}{66.79637} \pgfmath@def{acos}{395}{66.73402} -\pgfmath@def{acos}{396}{66.67164} \pgfmath@def{acos}{397}{66.60923} -\pgfmath@def{acos}{398}{66.54679} \pgfmath@def{acos}{399}{66.48432} -\pgfmath@def{acos}{400}{66.42182} \pgfmath@def{acos}{401}{66.35929} -\pgfmath@def{acos}{402}{66.29673} \pgfmath@def{acos}{403}{66.23414} -\pgfmath@def{acos}{404}{66.17152} \pgfmath@def{acos}{405}{66.10887} -\pgfmath@def{acos}{406}{66.04619} \pgfmath@def{acos}{407}{65.98348} -\pgfmath@def{acos}{408}{65.92074} \pgfmath@def{acos}{409}{65.85796} -\pgfmath@def{acos}{410}{65.79516} \pgfmath@def{acos}{411}{65.73233} -\pgfmath@def{acos}{412}{65.66946} \pgfmath@def{acos}{413}{65.60657} -\pgfmath@def{acos}{414}{65.54364} \pgfmath@def{acos}{415}{65.48068} -\pgfmath@def{acos}{416}{65.41769} \pgfmath@def{acos}{417}{65.35467} -\pgfmath@def{acos}{418}{65.29161} \pgfmath@def{acos}{419}{65.22853} -\pgfmath@def{acos}{420}{65.16541} \pgfmath@def{acos}{421}{65.10226} -\pgfmath@def{acos}{422}{65.03908} \pgfmath@def{acos}{423}{64.97586} -\pgfmath@def{acos}{424}{64.91261} \pgfmath@def{acos}{425}{64.84933} -\pgfmath@def{acos}{426}{64.78602} \pgfmath@def{acos}{427}{64.72267} -\pgfmath@def{acos}{428}{64.65929} \pgfmath@def{acos}{429}{64.59588} -\pgfmath@def{acos}{430}{64.53244} \pgfmath@def{acos}{431}{64.46896} -\pgfmath@def{acos}{432}{64.40544} \pgfmath@def{acos}{433}{64.34190} -\pgfmath@def{acos}{434}{64.27832} \pgfmath@def{acos}{435}{64.21470} -\pgfmath@def{acos}{436}{64.15105} \pgfmath@def{acos}{437}{64.08737} -\pgfmath@def{acos}{438}{64.02365} \pgfmath@def{acos}{439}{63.95990} -\pgfmath@def{acos}{440}{63.89611} \pgfmath@def{acos}{441}{63.83229} -\pgfmath@def{acos}{442}{63.76844} \pgfmath@def{acos}{443}{63.70455} -\pgfmath@def{acos}{444}{63.64062} \pgfmath@def{acos}{445}{63.57666} -\pgfmath@def{acos}{446}{63.51266} \pgfmath@def{acos}{447}{63.44863} -\pgfmath@def{acos}{448}{63.38456} \pgfmath@def{acos}{449}{63.32045} -\pgfmath@def{acos}{450}{63.25631} \pgfmath@def{acos}{451}{63.19213} -\pgfmath@def{acos}{452}{63.12792} \pgfmath@def{acos}{453}{63.06367} -\pgfmath@def{acos}{454}{62.99938} \pgfmath@def{acos}{455}{62.93506} -\pgfmath@def{acos}{456}{62.87070} \pgfmath@def{acos}{457}{62.80630} -\pgfmath@def{acos}{458}{62.74187} \pgfmath@def{acos}{459}{62.67740} -\pgfmath@def{acos}{460}{62.61289} \pgfmath@def{acos}{461}{62.54834} -\pgfmath@def{acos}{462}{62.48376} \pgfmath@def{acos}{463}{62.41913} -\pgfmath@def{acos}{464}{62.35447} \pgfmath@def{acos}{465}{62.28977} -\pgfmath@def{acos}{466}{62.22504} \pgfmath@def{acos}{467}{62.16026} -\pgfmath@def{acos}{468}{62.09545} \pgfmath@def{acos}{469}{62.03059} -\pgfmath@def{acos}{470}{61.96570} \pgfmath@def{acos}{471}{61.90077} -\pgfmath@def{acos}{472}{61.83580} \pgfmath@def{acos}{473}{61.77079} -\pgfmath@def{acos}{474}{61.70574} \pgfmath@def{acos}{475}{61.64065} -\pgfmath@def{acos}{476}{61.57552} \pgfmath@def{acos}{477}{61.51035} -\pgfmath@def{acos}{478}{61.44514} \pgfmath@def{acos}{479}{61.37988} -\pgfmath@def{acos}{480}{61.31459} \pgfmath@def{acos}{481}{61.24926} -\pgfmath@def{acos}{482}{61.18389} \pgfmath@def{acos}{483}{61.11847} -\pgfmath@def{acos}{484}{61.05302} \pgfmath@def{acos}{485}{60.98752} -\pgfmath@def{acos}{486}{60.92199} \pgfmath@def{acos}{487}{60.85641} -\pgfmath@def{acos}{488}{60.79078} \pgfmath@def{acos}{489}{60.72512} -\pgfmath@def{acos}{490}{60.65941} \pgfmath@def{acos}{491}{60.59367} -\pgfmath@def{acos}{492}{60.52787} \pgfmath@def{acos}{493}{60.46204} -\pgfmath@def{acos}{494}{60.39616} \pgfmath@def{acos}{495}{60.33025} -\pgfmath@def{acos}{496}{60.26428} \pgfmath@def{acos}{497}{60.19828} -\pgfmath@def{acos}{498}{60.13223} \pgfmath@def{acos}{499}{60.06613} -\pgfmath@def{acos}{500}{60.00000} \pgfmath@def{acos}{501}{59.93381} -\pgfmath@def{acos}{502}{59.86759} \pgfmath@def{acos}{503}{59.80132} -\pgfmath@def{acos}{504}{59.73500} \pgfmath@def{acos}{505}{59.66864} -\pgfmath@def{acos}{506}{59.60224} \pgfmath@def{acos}{507}{59.53579} -\pgfmath@def{acos}{508}{59.46929} \pgfmath@def{acos}{509}{59.40275} -\pgfmath@def{acos}{510}{59.33617} \pgfmath@def{acos}{511}{59.26953} -\pgfmath@def{acos}{512}{59.20285} \pgfmath@def{acos}{513}{59.13613} -\pgfmath@def{acos}{514}{59.06936} \pgfmath@def{acos}{515}{59.00254} -\pgfmath@def{acos}{516}{58.93568} \pgfmath@def{acos}{517}{58.86876} -\pgfmath@def{acos}{518}{58.80180} \pgfmath@def{acos}{519}{58.73480} -\pgfmath@def{acos}{520}{58.66774} \pgfmath@def{acos}{521}{58.60064} -\pgfmath@def{acos}{522}{58.53349} \pgfmath@def{acos}{523}{58.46629} -\pgfmath@def{acos}{524}{58.39905} \pgfmath@def{acos}{525}{58.33175} -\pgfmath@def{acos}{526}{58.26441} \pgfmath@def{acos}{527}{58.19702} -\pgfmath@def{acos}{528}{58.12957} \pgfmath@def{acos}{529}{58.06208} -\pgfmath@def{acos}{530}{57.99454} \pgfmath@def{acos}{531}{57.92695} -\pgfmath@def{acos}{532}{57.85931} \pgfmath@def{acos}{533}{57.79162} -\pgfmath@def{acos}{534}{57.72388} \pgfmath@def{acos}{535}{57.65608} -\pgfmath@def{acos}{536}{57.58824} \pgfmath@def{acos}{537}{57.52035} -\pgfmath@def{acos}{538}{57.45240} \pgfmath@def{acos}{539}{57.38441} -\pgfmath@def{acos}{540}{57.31636} \pgfmath@def{acos}{541}{57.24826} -\pgfmath@def{acos}{542}{57.18010} \pgfmath@def{acos}{543}{57.11190} -\pgfmath@def{acos}{544}{57.04364} \pgfmath@def{acos}{545}{56.97533} -\pgfmath@def{acos}{546}{56.90697} \pgfmath@def{acos}{547}{56.83855} -\pgfmath@def{acos}{548}{56.77008} \pgfmath@def{acos}{549}{56.70156} -\pgfmath@def{acos}{550}{56.63298} \pgfmath@def{acos}{551}{56.56435} -\pgfmath@def{acos}{552}{56.49567} \pgfmath@def{acos}{553}{56.42693} -\pgfmath@def{acos}{554}{56.35813} \pgfmath@def{acos}{555}{56.28928} -\pgfmath@def{acos}{556}{56.22038} \pgfmath@def{acos}{557}{56.15141} -\pgfmath@def{acos}{558}{56.08240} \pgfmath@def{acos}{559}{56.01333} -\pgfmath@def{acos}{560}{55.94420} \pgfmath@def{acos}{561}{55.87501} -\pgfmath@def{acos}{562}{55.80577} \pgfmath@def{acos}{563}{55.73647} -\pgfmath@def{acos}{564}{55.66712} \pgfmath@def{acos}{565}{55.59770} -\pgfmath@def{acos}{566}{55.52823} \pgfmath@def{acos}{567}{55.45871} -\pgfmath@def{acos}{568}{55.38912} \pgfmath@def{acos}{569}{55.31947} -\pgfmath@def{acos}{570}{55.24977} \pgfmath@def{acos}{571}{55.18001} -\pgfmath@def{acos}{572}{55.11019} \pgfmath@def{acos}{573}{55.04030} -\pgfmath@def{acos}{574}{54.97036} \pgfmath@def{acos}{575}{54.90036} -\pgfmath@def{acos}{576}{54.83030} \pgfmath@def{acos}{577}{54.76018} -\pgfmath@def{acos}{578}{54.69000} \pgfmath@def{acos}{579}{54.61976} -\pgfmath@def{acos}{580}{54.54945} \pgfmath@def{acos}{581}{54.47909} -\pgfmath@def{acos}{582}{54.40866} \pgfmath@def{acos}{583}{54.33817} -\pgfmath@def{acos}{584}{54.26762} \pgfmath@def{acos}{585}{54.19701} -\pgfmath@def{acos}{586}{54.12633} \pgfmath@def{acos}{587}{54.05559} -\pgfmath@def{acos}{588}{53.98479} \pgfmath@def{acos}{589}{53.91392} -\pgfmath@def{acos}{590}{53.84299} \pgfmath@def{acos}{591}{53.77199} -\pgfmath@def{acos}{592}{53.70093} \pgfmath@def{acos}{593}{53.62981} -\pgfmath@def{acos}{594}{53.55862} \pgfmath@def{acos}{595}{53.48736} -\pgfmath@def{acos}{596}{53.41604} \pgfmath@def{acos}{597}{53.34466} -\pgfmath@def{acos}{598}{53.27320} \pgfmath@def{acos}{599}{53.20168} -\pgfmath@def{acos}{600}{53.13010} \pgfmath@def{acos}{601}{53.05844} -\pgfmath@def{acos}{602}{52.98672} \pgfmath@def{acos}{603}{52.91494} -\pgfmath@def{acos}{604}{52.84308} \pgfmath@def{acos}{605}{52.77115} -\pgfmath@def{acos}{606}{52.69916} \pgfmath@def{acos}{607}{52.62710} -\pgfmath@def{acos}{608}{52.55497} \pgfmath@def{acos}{609}{52.48276} -\pgfmath@def{acos}{610}{52.41049} \pgfmath@def{acos}{611}{52.33815} -\pgfmath@def{acos}{612}{52.26574} \pgfmath@def{acos}{613}{52.19326} -\pgfmath@def{acos}{614}{52.12070} \pgfmath@def{acos}{615}{52.04808} -\pgfmath@def{acos}{616}{51.97538} \pgfmath@def{acos}{617}{51.90261} -\pgfmath@def{acos}{618}{51.82976} \pgfmath@def{acos}{619}{51.75685} -\pgfmath@def{acos}{620}{51.68386} \pgfmath@def{acos}{621}{51.61080} -\pgfmath@def{acos}{622}{51.53766} \pgfmath@def{acos}{623}{51.46445} -\pgfmath@def{acos}{624}{51.39117} \pgfmath@def{acos}{625}{51.31781} -\pgfmath@def{acos}{626}{51.24437} \pgfmath@def{acos}{627}{51.17086} -\pgfmath@def{acos}{628}{51.09728} \pgfmath@def{acos}{629}{51.02361} -\pgfmath@def{acos}{630}{50.94987} \pgfmath@def{acos}{631}{50.87606} -\pgfmath@def{acos}{632}{50.80216} \pgfmath@def{acos}{633}{50.72819} -\pgfmath@def{acos}{634}{50.65414} \pgfmath@def{acos}{635}{50.58001} -\pgfmath@def{acos}{636}{50.50580} \pgfmath@def{acos}{637}{50.43152} -\pgfmath@def{acos}{638}{50.35715} \pgfmath@def{acos}{639}{50.28270} -\pgfmath@def{acos}{640}{50.20818} \pgfmath@def{acos}{641}{50.13357} -\pgfmath@def{acos}{642}{50.05888} \pgfmath@def{acos}{643}{49.98411} -\pgfmath@def{acos}{644}{49.90926} \pgfmath@def{acos}{645}{49.83432} -\pgfmath@def{acos}{646}{49.75930} \pgfmath@def{acos}{647}{49.68420} -\pgfmath@def{acos}{648}{49.60902} \pgfmath@def{acos}{649}{49.53375} -\pgfmath@def{acos}{650}{49.45839} \pgfmath@def{acos}{651}{49.38296} -\pgfmath@def{acos}{652}{49.30743} \pgfmath@def{acos}{653}{49.23182} -\pgfmath@def{acos}{654}{49.15613} \pgfmath@def{acos}{655}{49.08035} -\pgfmath@def{acos}{656}{49.00448} \pgfmath@def{acos}{657}{48.92852} -\pgfmath@def{acos}{658}{48.85248} \pgfmath@def{acos}{659}{48.77634} -\pgfmath@def{acos}{660}{48.70012} \pgfmath@def{acos}{661}{48.62381} -\pgfmath@def{acos}{662}{48.54741} \pgfmath@def{acos}{663}{48.47092} -\pgfmath@def{acos}{664}{48.39434} \pgfmath@def{acos}{665}{48.31767} -\pgfmath@def{acos}{666}{48.24091} \pgfmath@def{acos}{667}{48.16405} -\pgfmath@def{acos}{668}{48.08710} \pgfmath@def{acos}{669}{48.01006} -\pgfmath@def{acos}{670}{47.93293} \pgfmath@def{acos}{671}{47.85570} -\pgfmath@def{acos}{672}{47.77838} \pgfmath@def{acos}{673}{47.70096} -\pgfmath@def{acos}{674}{47.62345} \pgfmath@def{acos}{675}{47.54585} -\pgfmath@def{acos}{676}{47.46814} \pgfmath@def{acos}{677}{47.39034} -\pgfmath@def{acos}{678}{47.31244} \pgfmath@def{acos}{679}{47.23445} -\pgfmath@def{acos}{680}{47.15635} \pgfmath@def{acos}{681}{47.07816} -\pgfmath@def{acos}{682}{46.99987} \pgfmath@def{acos}{683}{46.92147} -\pgfmath@def{acos}{684}{46.84298} \pgfmath@def{acos}{685}{46.76439} -\pgfmath@def{acos}{686}{46.68569} \pgfmath@def{acos}{687}{46.60690} -\pgfmath@def{acos}{688}{46.52800} \pgfmath@def{acos}{689}{46.44899} -\pgfmath@def{acos}{690}{46.36989} \pgfmath@def{acos}{691}{46.29068} -\pgfmath@def{acos}{692}{46.21136} \pgfmath@def{acos}{693}{46.13194} -\pgfmath@def{acos}{694}{46.05241} \pgfmath@def{acos}{695}{45.97278} -\pgfmath@def{acos}{696}{45.89304} \pgfmath@def{acos}{697}{45.81319} -\pgfmath@def{acos}{698}{45.73323} \pgfmath@def{acos}{699}{45.65317} -\pgfmath@def{acos}{700}{45.57299} \pgfmath@def{acos}{701}{45.49271} -\pgfmath@def{acos}{702}{45.41231} \pgfmath@def{acos}{703}{45.33180} -\pgfmath@def{acos}{704}{45.25118} \pgfmath@def{acos}{705}{45.17045} -\pgfmath@def{acos}{706}{45.08961} \pgfmath@def{acos}{707}{45.00865} -\pgfmath@def{acos}{708}{44.92757} \pgfmath@def{acos}{709}{44.84638} -\pgfmath@def{acos}{710}{44.76508} \pgfmath@def{acos}{711}{44.68366} -\pgfmath@def{acos}{712}{44.60212} \pgfmath@def{acos}{713}{44.52046} -\pgfmath@def{acos}{714}{44.43869} \pgfmath@def{acos}{715}{44.35680} -\pgfmath@def{acos}{716}{44.27478} \pgfmath@def{acos}{717}{44.19265} -\pgfmath@def{acos}{718}{44.11039} \pgfmath@def{acos}{719}{44.02802} -\pgfmath@def{acos}{720}{43.94552} \pgfmath@def{acos}{721}{43.86289} -\pgfmath@def{acos}{722}{43.78014} \pgfmath@def{acos}{723}{43.69727} -\pgfmath@def{acos}{724}{43.61427} \pgfmath@def{acos}{725}{43.53115} -\pgfmath@def{acos}{726}{43.44790} \pgfmath@def{acos}{727}{43.36452} -\pgfmath@def{acos}{728}{43.28101} \pgfmath@def{acos}{729}{43.19737} -\pgfmath@def{acos}{730}{43.11360} \pgfmath@def{acos}{731}{43.02970} -\pgfmath@def{acos}{732}{42.94567} \pgfmath@def{acos}{733}{42.86151} -\pgfmath@def{acos}{734}{42.77721} \pgfmath@def{acos}{735}{42.69278} -\pgfmath@def{acos}{736}{42.60821} \pgfmath@def{acos}{737}{42.52351} -\pgfmath@def{acos}{738}{42.43867} \pgfmath@def{acos}{739}{42.35370} -\pgfmath@def{acos}{740}{42.26858} \pgfmath@def{acos}{741}{42.18333} -\pgfmath@def{acos}{742}{42.09793} \pgfmath@def{acos}{743}{42.01240} -\pgfmath@def{acos}{744}{41.92672} \pgfmath@def{acos}{745}{41.84090} -\pgfmath@def{acos}{746}{41.75493} \pgfmath@def{acos}{747}{41.66882} -\pgfmath@def{acos}{748}{41.58257} \pgfmath@def{acos}{749}{41.49617} -\pgfmath@def{acos}{750}{41.40962} \pgfmath@def{acos}{751}{41.32292} -\pgfmath@def{acos}{752}{41.23607} \pgfmath@def{acos}{753}{41.14908} -\pgfmath@def{acos}{754}{41.06193} \pgfmath@def{acos}{755}{40.97463} -\pgfmath@def{acos}{756}{40.88717} \pgfmath@def{acos}{757}{40.79956} -\pgfmath@def{acos}{758}{40.71180} \pgfmath@def{acos}{759}{40.62388} -\pgfmath@def{acos}{760}{40.53580} \pgfmath@def{acos}{761}{40.44756} -\pgfmath@def{acos}{762}{40.35916} \pgfmath@def{acos}{763}{40.27061} -\pgfmath@def{acos}{764}{40.18189} \pgfmath@def{acos}{765}{40.09300} -\pgfmath@def{acos}{766}{40.00396} \pgfmath@def{acos}{767}{39.91474} -\pgfmath@def{acos}{768}{39.82537} \pgfmath@def{acos}{769}{39.73582} -\pgfmath@def{acos}{770}{39.64611} \pgfmath@def{acos}{771}{39.55622} -\pgfmath@def{acos}{772}{39.46617} \pgfmath@def{acos}{773}{39.37594} -\pgfmath@def{acos}{774}{39.28554} \pgfmath@def{acos}{775}{39.19496} -\pgfmath@def{acos}{776}{39.10421} \pgfmath@def{acos}{777}{39.01328} -\pgfmath@def{acos}{778}{38.92218} \pgfmath@def{acos}{779}{38.83089} -\pgfmath@def{acos}{780}{38.73942} \pgfmath@def{acos}{781}{38.64777} -\pgfmath@def{acos}{782}{38.55594} \pgfmath@def{acos}{783}{38.46392} -\pgfmath@def{acos}{784}{38.37171} \pgfmath@def{acos}{785}{38.27932} -\pgfmath@def{acos}{786}{38.18673} \pgfmath@def{acos}{787}{38.09396} -\pgfmath@def{acos}{788}{38.00100} \pgfmath@def{acos}{789}{37.90784} -\pgfmath@def{acos}{790}{37.81448} \pgfmath@def{acos}{791}{37.72093} -\pgfmath@def{acos}{792}{37.62719} \pgfmath@def{acos}{793}{37.53324} -\pgfmath@def{acos}{794}{37.43909} \pgfmath@def{acos}{795}{37.34474} -\pgfmath@def{acos}{796}{37.25019} \pgfmath@def{acos}{797}{37.15542} -\pgfmath@def{acos}{798}{37.06046} \pgfmath@def{acos}{799}{36.96528} -\pgfmath@def{acos}{800}{36.86989} \pgfmath@def{acos}{801}{36.77429} -\pgfmath@def{acos}{802}{36.67848} \pgfmath@def{acos}{803}{36.58245} -\pgfmath@def{acos}{804}{36.48621} \pgfmath@def{acos}{805}{36.38974} -\pgfmath@def{acos}{806}{36.29305} \pgfmath@def{acos}{807}{36.19615} -\pgfmath@def{acos}{808}{36.09901} \pgfmath@def{acos}{809}{36.00165} -\pgfmath@def{acos}{810}{35.90406} \pgfmath@def{acos}{811}{35.80625} -\pgfmath@def{acos}{812}{35.70820} \pgfmath@def{acos}{813}{35.60991} -\pgfmath@def{acos}{814}{35.51139} \pgfmath@def{acos}{815}{35.41263} -\pgfmath@def{acos}{816}{35.31364} \pgfmath@def{acos}{817}{35.21440} -\pgfmath@def{acos}{818}{35.11491} \pgfmath@def{acos}{819}{35.01518} -\pgfmath@def{acos}{820}{34.91520} \pgfmath@def{acos}{821}{34.81497} -\pgfmath@def{acos}{822}{34.71449} \pgfmath@def{acos}{823}{34.61375} -\pgfmath@def{acos}{824}{34.51276} \pgfmath@def{acos}{825}{34.41150} -\pgfmath@def{acos}{826}{34.30999} \pgfmath@def{acos}{827}{34.20821} -\pgfmath@def{acos}{828}{34.10616} \pgfmath@def{acos}{829}{34.00385} -\pgfmath@def{acos}{830}{33.90126} \pgfmath@def{acos}{831}{33.79840} -\pgfmath@def{acos}{832}{33.69526} \pgfmath@def{acos}{833}{33.59184} -\pgfmath@def{acos}{834}{33.48814} \pgfmath@def{acos}{835}{33.38416} -\pgfmath@def{acos}{836}{33.27989} \pgfmath@def{acos}{837}{33.17533} -\pgfmath@def{acos}{838}{33.07047} \pgfmath@def{acos}{839}{32.96532} -\pgfmath@def{acos}{840}{32.85988} \pgfmath@def{acos}{841}{32.75413} -\pgfmath@def{acos}{842}{32.64807} \pgfmath@def{acos}{843}{32.54171} -\pgfmath@def{acos}{844}{32.43504} \pgfmath@def{acos}{845}{32.32806} -\pgfmath@def{acos}{846}{32.22076} \pgfmath@def{acos}{847}{32.11314} -\pgfmath@def{acos}{848}{32.00520} \pgfmath@def{acos}{849}{31.89693} -\pgfmath@def{acos}{850}{31.78833} \pgfmath@def{acos}{851}{31.67939} -\pgfmath@def{acos}{852}{31.57012} \pgfmath@def{acos}{853}{31.46051} -\pgfmath@def{acos}{854}{31.35056} \pgfmath@def{acos}{855}{31.24026} -\pgfmath@def{acos}{856}{31.12961} \pgfmath@def{acos}{857}{31.01860} -\pgfmath@def{acos}{858}{30.90724} \pgfmath@def{acos}{859}{30.79551} -\pgfmath@def{acos}{860}{30.68341} \pgfmath@def{acos}{861}{30.57095} -\pgfmath@def{acos}{862}{30.45811} \pgfmath@def{acos}{863}{30.34489} -\pgfmath@def{acos}{864}{30.23128} \pgfmath@def{acos}{865}{30.11729} -\pgfmath@def{acos}{866}{30.00291} \pgfmath@def{acos}{867}{29.88813} -\pgfmath@def{acos}{868}{29.77294} \pgfmath@def{acos}{869}{29.65736} -\pgfmath@def{acos}{870}{29.54136} \pgfmath@def{acos}{871}{29.42494} -\pgfmath@def{acos}{872}{29.30810} \pgfmath@def{acos}{873}{29.19084} -\pgfmath@def{acos}{874}{29.07315} \pgfmath@def{acos}{875}{28.95502} -\pgfmath@def{acos}{876}{28.83645} \pgfmath@def{acos}{877}{28.71743} -\pgfmath@def{acos}{878}{28.59796} \pgfmath@def{acos}{879}{28.47803} -\pgfmath@def{acos}{880}{28.35763} \pgfmath@def{acos}{881}{28.23677} -\pgfmath@def{acos}{882}{28.11542} \pgfmath@def{acos}{883}{27.99360} -\pgfmath@def{acos}{884}{27.87128} \pgfmath@def{acos}{885}{27.74847} -\pgfmath@def{acos}{886}{27.62516} \pgfmath@def{acos}{887}{27.50134} -\pgfmath@def{acos}{888}{27.37700} \pgfmath@def{acos}{889}{27.25214} -\pgfmath@def{acos}{890}{27.12675} \pgfmath@def{acos}{891}{27.00082} -\pgfmath@def{acos}{892}{26.87434} \pgfmath@def{acos}{893}{26.74731} -\pgfmath@def{acos}{894}{26.61973} \pgfmath@def{acos}{895}{26.49157} -\pgfmath@def{acos}{896}{26.36283} \pgfmath@def{acos}{897}{26.23351} -\pgfmath@def{acos}{898}{26.10359} \pgfmath@def{acos}{899}{25.97306} -\pgfmath@def{acos}{900}{25.84193} \pgfmath@def{acos}{901}{25.71017} -\pgfmath@def{acos}{902}{25.57778} \pgfmath@def{acos}{903}{25.44475} -\pgfmath@def{acos}{904}{25.31106} \pgfmath@def{acos}{905}{25.17671} -\pgfmath@def{acos}{906}{25.04169} \pgfmath@def{acos}{907}{24.90598} -\pgfmath@def{acos}{908}{24.76958} \pgfmath@def{acos}{909}{24.63247} -\pgfmath@def{acos}{910}{24.49464} \pgfmath@def{acos}{911}{24.35608} -\pgfmath@def{acos}{912}{24.21678} \pgfmath@def{acos}{913}{24.07672} -\pgfmath@def{acos}{914}{23.93588} \pgfmath@def{acos}{915}{23.79427} -\pgfmath@def{acos}{916}{23.65185} \pgfmath@def{acos}{917}{23.50863} -\pgfmath@def{acos}{918}{23.36457} \pgfmath@def{acos}{919}{23.21967} -\pgfmath@def{acos}{920}{23.07391} \pgfmath@def{acos}{921}{22.92728} -\pgfmath@def{acos}{922}{22.77975} \pgfmath@def{acos}{923}{22.63132} -\pgfmath@def{acos}{924}{22.48195} \pgfmath@def{acos}{925}{22.33164} -\pgfmath@def{acos}{926}{22.18036} \pgfmath@def{acos}{927}{22.02810} -\pgfmath@def{acos}{928}{21.87483} \pgfmath@def{acos}{929}{21.72053} -\pgfmath@def{acos}{930}{21.56518} \pgfmath@def{acos}{931}{21.40876} -\pgfmath@def{acos}{932}{21.25124} \pgfmath@def{acos}{933}{21.09260} -\pgfmath@def{acos}{934}{20.93281} \pgfmath@def{acos}{935}{20.77185} -\pgfmath@def{acos}{936}{20.60969} \pgfmath@def{acos}{937}{20.44630} -\pgfmath@def{acos}{938}{20.28165} \pgfmath@def{acos}{939}{20.11570} -\pgfmath@def{acos}{940}{19.94844} \pgfmath@def{acos}{941}{19.77982} -\pgfmath@def{acos}{942}{19.60981} \pgfmath@def{acos}{943}{19.43837} -\pgfmath@def{acos}{944}{19.26546} \pgfmath@def{acos}{945}{19.09105} -\pgfmath@def{acos}{946}{18.91509} \pgfmath@def{acos}{947}{18.73754} -\pgfmath@def{acos}{948}{18.55835} \pgfmath@def{acos}{949}{18.37748} -\pgfmath@def{acos}{950}{18.19487} \pgfmath@def{acos}{951}{18.01047} -\pgfmath@def{acos}{952}{17.82423} \pgfmath@def{acos}{953}{17.63609} -\pgfmath@def{acos}{954}{17.44598} \pgfmath@def{acos}{955}{17.25385} -\pgfmath@def{acos}{956}{17.05962} \pgfmath@def{acos}{957}{16.86322} -\pgfmath@def{acos}{958}{16.66457} \pgfmath@def{acos}{959}{16.46359} -\pgfmath@def{acos}{960}{16.26020} \pgfmath@def{acos}{961}{16.05430} -\pgfmath@def{acos}{962}{15.84580} \pgfmath@def{acos}{963}{15.63459} -\pgfmath@def{acos}{964}{15.42057} \pgfmath@def{acos}{965}{15.20360} -\pgfmath@def{acos}{966}{14.98357} \pgfmath@def{acos}{967}{14.76033} -\pgfmath@def{acos}{968}{14.53374} \pgfmath@def{acos}{969}{14.30364} -\pgfmath@def{acos}{970}{14.06986} \pgfmath@def{acos}{971}{13.83221} -\pgfmath@def{acos}{972}{13.59049} \pgfmath@def{acos}{973}{13.34447} -\pgfmath@def{acos}{974}{13.09392} \pgfmath@def{acos}{975}{12.83856} -\pgfmath@def{acos}{976}{12.57811} \pgfmath@def{acos}{977}{12.31225} -\pgfmath@def{acos}{978}{12.04060} \pgfmath@def{acos}{979}{11.76278} -\pgfmath@def{acos}{980}{11.47834} \pgfmath@def{acos}{981}{11.18676} -\pgfmath@def{acos}{982}{10.88748} \pgfmath@def{acos}{983}{10.57984} -\pgfmath@def{acos}{984}{10.26309} \pgfmath@def{acos}{985}{9.93636} -\pgfmath@def{acos}{986}{9.59863} \pgfmath@def{acos}{987}{9.24870} -\pgfmath@def{acos}{988}{8.88512} \pgfmath@def{acos}{989}{8.50614} -\pgfmath@def{acos}{990}{8.10961} \pgfmath@def{acos}{991}{7.69281} -\pgfmath@def{acos}{992}{7.25224} \pgfmath@def{acos}{993}{6.78328} -\pgfmath@def{acos}{994}{6.27958} \pgfmath@def{acos}{995}{5.73196} -\pgfmath@def{acos}{996}{5.12640} \pgfmath@def{acos}{997}{4.43922} -\pgfmath@def{acos}{998}{3.62430} \pgfmath@def{acos}{999}{2.56255} -\pgfmath@def{acos}{1000}{0.00000} \ No newline at end of file +\pgfmath@def{atan}{0}{0.00000} \pgfmath@def{atan}{1}{0.05729} +\pgfmath@def{atan}{2}{0.11459} \pgfmath@def{atan}{3}{0.17188} +\pgfmath@def{atan}{4}{0.22918} \pgfmath@def{atan}{5}{0.28647} +\pgfmath@def{atan}{6}{0.34377} \pgfmath@def{atan}{7}{0.40106} +\pgfmath@def{atan}{8}{0.45835} \pgfmath@def{atan}{9}{0.51564} +\pgfmath@def{atan}{10}{0.57293} \pgfmath@def{atan}{11}{0.63022} +\pgfmath@def{atan}{12}{0.68751} \pgfmath@def{atan}{13}{0.74480} +\pgfmath@def{atan}{14}{0.80208} \pgfmath@def{atan}{15}{0.85937} +\pgfmath@def{atan}{16}{0.91665} \pgfmath@def{atan}{17}{0.97393} +\pgfmath@def{atan}{18}{1.03121} \pgfmath@def{atan}{19}{1.08848} +\pgfmath@def{atan}{20}{1.14576} \pgfmath@def{atan}{21}{1.20303} +\pgfmath@def{atan}{22}{1.26030} \pgfmath@def{atan}{23}{1.31757} +\pgfmath@def{atan}{24}{1.37483} \pgfmath@def{atan}{25}{1.43209} +\pgfmath@def{atan}{26}{1.48935} \pgfmath@def{atan}{27}{1.54661} +\pgfmath@def{atan}{28}{1.60386} \pgfmath@def{atan}{29}{1.66111} +\pgfmath@def{atan}{30}{1.71835} \pgfmath@def{atan}{31}{1.77560} +\pgfmath@def{atan}{32}{1.83284} \pgfmath@def{atan}{33}{1.89007} +\pgfmath@def{atan}{34}{1.94730} \pgfmath@def{atan}{35}{2.00453} +\pgfmath@def{atan}{36}{2.06175} \pgfmath@def{atan}{37}{2.11897} +\pgfmath@def{atan}{38}{2.17619} \pgfmath@def{atan}{39}{2.23340} +\pgfmath@def{atan}{40}{2.29061} \pgfmath@def{atan}{41}{2.34781} +\pgfmath@def{atan}{42}{2.40500} \pgfmath@def{atan}{43}{2.46220} +\pgfmath@def{atan}{44}{2.51938} \pgfmath@def{atan}{45}{2.57657} +\pgfmath@def{atan}{46}{2.63374} \pgfmath@def{atan}{47}{2.69092} +\pgfmath@def{atan}{48}{2.74808} \pgfmath@def{atan}{49}{2.80524} +\pgfmath@def{atan}{50}{2.86240} \pgfmath@def{atan}{51}{2.91955} +\pgfmath@def{atan}{52}{2.97669} \pgfmath@def{atan}{53}{3.03383} +\pgfmath@def{atan}{54}{3.09097} \pgfmath@def{atan}{55}{3.14809} +\pgfmath@def{atan}{56}{3.20521} \pgfmath@def{atan}{57}{3.26232} +\pgfmath@def{atan}{58}{3.31943} \pgfmath@def{atan}{59}{3.37653} +\pgfmath@def{atan}{60}{3.43363} \pgfmath@def{atan}{61}{3.49071} +\pgfmath@def{atan}{62}{3.54779} \pgfmath@def{atan}{63}{3.60487} +\pgfmath@def{atan}{64}{3.66193} \pgfmath@def{atan}{65}{3.71899} +\pgfmath@def{atan}{66}{3.77604} \pgfmath@def{atan}{67}{3.83308} +\pgfmath@def{atan}{68}{3.89012} \pgfmath@def{atan}{69}{3.94715} +\pgfmath@def{atan}{70}{4.00417} \pgfmath@def{atan}{71}{4.06118} +\pgfmath@def{atan}{72}{4.11819} \pgfmath@def{atan}{73}{4.17518} +\pgfmath@def{atan}{74}{4.23217} \pgfmath@def{atan}{75}{4.28915} +\pgfmath@def{atan}{76}{4.34612} \pgfmath@def{atan}{77}{4.40308} +\pgfmath@def{atan}{78}{4.46004} \pgfmath@def{atan}{79}{4.51698} +\pgfmath@def{atan}{80}{4.57392} \pgfmath@def{atan}{81}{4.63084} +\pgfmath@def{atan}{82}{4.68776} \pgfmath@def{atan}{83}{4.74467} +\pgfmath@def{atan}{84}{4.80157} \pgfmath@def{atan}{85}{4.85846} +\pgfmath@def{atan}{86}{4.91534} \pgfmath@def{atan}{87}{4.97221} +\pgfmath@def{atan}{88}{5.02907} \pgfmath@def{atan}{89}{5.08592} +\pgfmath@def{atan}{90}{5.14276} \pgfmath@def{atan}{91}{5.19959} +\pgfmath@def{atan}{92}{5.25641} \pgfmath@def{atan}{93}{5.31322} +\pgfmath@def{atan}{94}{5.37002} \pgfmath@def{atan}{95}{5.42681} +\pgfmath@def{atan}{96}{5.48359} \pgfmath@def{atan}{97}{5.54035} +\pgfmath@def{atan}{98}{5.59711} \pgfmath@def{atan}{99}{5.65385} +\pgfmath@def{atan}{100}{5.71059} \pgfmath@def{atan}{101}{5.76731} +\pgfmath@def{atan}{102}{5.82402} \pgfmath@def{atan}{103}{5.88072} +\pgfmath@def{atan}{104}{5.93741} \pgfmath@def{atan}{105}{5.99409} +\pgfmath@def{atan}{106}{6.05075} \pgfmath@def{atan}{107}{6.10741} +\pgfmath@def{atan}{108}{6.16405} \pgfmath@def{atan}{109}{6.22068} +\pgfmath@def{atan}{110}{6.27729} \pgfmath@def{atan}{111}{6.33390} +\pgfmath@def{atan}{112}{6.39049} \pgfmath@def{atan}{113}{6.44707} +\pgfmath@def{atan}{114}{6.50364} \pgfmath@def{atan}{115}{6.56019} +\pgfmath@def{atan}{116}{6.61673} \pgfmath@def{atan}{117}{6.67326} +\pgfmath@def{atan}{118}{6.72978} \pgfmath@def{atan}{119}{6.78628} +\pgfmath@def{atan}{120}{6.84277} \pgfmath@def{atan}{121}{6.89924} +\pgfmath@def{atan}{122}{6.95571} \pgfmath@def{atan}{123}{7.01216} +\pgfmath@def{atan}{124}{7.06859} \pgfmath@def{atan}{125}{7.12501} +\pgfmath@def{atan}{126}{7.18142} \pgfmath@def{atan}{127}{7.23781} +\pgfmath@def{atan}{128}{7.29419} \pgfmath@def{atan}{129}{7.35056} +\pgfmath@def{atan}{130}{7.40691} \pgfmath@def{atan}{131}{7.46324} +\pgfmath@def{atan}{132}{7.51957} \pgfmath@def{atan}{133}{7.57587} +\pgfmath@def{atan}{134}{7.63217} \pgfmath@def{atan}{135}{7.68844} +\pgfmath@def{atan}{136}{7.74471} \pgfmath@def{atan}{137}{7.80095} +\pgfmath@def{atan}{138}{7.85719} \pgfmath@def{atan}{139}{7.91340} +\pgfmath@def{atan}{140}{7.96961} \pgfmath@def{atan}{141}{8.02579} +\pgfmath@def{atan}{142}{8.08196} \pgfmath@def{atan}{143}{8.13812} +\pgfmath@def{atan}{144}{8.19426} \pgfmath@def{atan}{145}{8.25038} +\pgfmath@def{atan}{146}{8.30649} \pgfmath@def{atan}{147}{8.36258} +\pgfmath@def{atan}{148}{8.41866} \pgfmath@def{atan}{149}{8.47472} +\pgfmath@def{atan}{150}{8.53076} \pgfmath@def{atan}{151}{8.58679} +\pgfmath@def{atan}{152}{8.64280} \pgfmath@def{atan}{153}{8.69879} +\pgfmath@def{atan}{154}{8.75477} \pgfmath@def{atan}{155}{8.81073} +\pgfmath@def{atan}{156}{8.86667} \pgfmath@def{atan}{157}{8.92260} +\pgfmath@def{atan}{158}{8.97851} \pgfmath@def{atan}{159}{9.03440} +\pgfmath@def{atan}{160}{9.09027} \pgfmath@def{atan}{161}{9.14613} +\pgfmath@def{atan}{162}{9.20197} \pgfmath@def{atan}{163}{9.25779} +\pgfmath@def{atan}{164}{9.31359} \pgfmath@def{atan}{165}{9.36938} +\pgfmath@def{atan}{166}{9.42515} \pgfmath@def{atan}{167}{9.48090} +\pgfmath@def{atan}{168}{9.53663} \pgfmath@def{atan}{169}{9.59235} +\pgfmath@def{atan}{170}{9.64804} \pgfmath@def{atan}{171}{9.70372} +\pgfmath@def{atan}{172}{9.75938} \pgfmath@def{atan}{173}{9.81502} +\pgfmath@def{atan}{174}{9.87064} \pgfmath@def{atan}{175}{9.92624} +\pgfmath@def{atan}{176}{9.98182} \pgfmath@def{atan}{177}{10.03739} +\pgfmath@def{atan}{178}{10.09294} \pgfmath@def{atan}{179}{10.14846} +\pgfmath@def{atan}{180}{10.20397} \pgfmath@def{atan}{181}{10.25946} +\pgfmath@def{atan}{182}{10.31493} \pgfmath@def{atan}{183}{10.37037} +\pgfmath@def{atan}{184}{10.42580} \pgfmath@def{atan}{185}{10.48121} +\pgfmath@def{atan}{186}{10.53660} \pgfmath@def{atan}{187}{10.59197} +\pgfmath@def{atan}{188}{10.64732} \pgfmath@def{atan}{189}{10.70265} +\pgfmath@def{atan}{190}{10.75796} \pgfmath@def{atan}{191}{10.81325} +\pgfmath@def{atan}{192}{10.86852} \pgfmath@def{atan}{193}{10.92377} +\pgfmath@def{atan}{194}{10.97900} \pgfmath@def{atan}{195}{11.03420} +\pgfmath@def{atan}{196}{11.08939} \pgfmath@def{atan}{197}{11.14456} +\pgfmath@def{atan}{198}{11.19970} \pgfmath@def{atan}{199}{11.25483} +\pgfmath@def{atan}{200}{11.30993} \pgfmath@def{atan}{201}{11.36501} +\pgfmath@def{atan}{202}{11.42007} \pgfmath@def{atan}{203}{11.47511} +\pgfmath@def{atan}{204}{11.53013} \pgfmath@def{atan}{205}{11.58512} +\pgfmath@def{atan}{206}{11.64010} \pgfmath@def{atan}{207}{11.69505} +\pgfmath@def{atan}{208}{11.74998} \pgfmath@def{atan}{209}{11.80489} +\pgfmath@def{atan}{210}{11.85977} \pgfmath@def{atan}{211}{11.91464} +\pgfmath@def{atan}{212}{11.96948} \pgfmath@def{atan}{213}{12.02430} +\pgfmath@def{atan}{214}{12.07910} \pgfmath@def{atan}{215}{12.13388} +\pgfmath@def{atan}{216}{12.18863} \pgfmath@def{atan}{217}{12.24336} +\pgfmath@def{atan}{218}{12.29807} \pgfmath@def{atan}{219}{12.35275} +\pgfmath@def{atan}{220}{12.40741} \pgfmath@def{atan}{221}{12.46205} +\pgfmath@def{atan}{222}{12.51667} \pgfmath@def{atan}{223}{12.57126} +\pgfmath@def{atan}{224}{12.62583} \pgfmath@def{atan}{225}{12.68038} +\pgfmath@def{atan}{226}{12.73490} \pgfmath@def{atan}{227}{12.78940} +\pgfmath@def{atan}{228}{12.84388} \pgfmath@def{atan}{229}{12.89833} +\pgfmath@def{atan}{230}{12.95276} \pgfmath@def{atan}{231}{13.00717} +\pgfmath@def{atan}{232}{13.06155} \pgfmath@def{atan}{233}{13.11590} +\pgfmath@def{atan}{234}{13.17024} \pgfmath@def{atan}{235}{13.22455} +\pgfmath@def{atan}{236}{13.27883} \pgfmath@def{atan}{237}{13.33309} +\pgfmath@def{atan}{238}{13.38733} \pgfmath@def{atan}{239}{13.44154} +\pgfmath@def{atan}{240}{13.49573} \pgfmath@def{atan}{241}{13.54989} +\pgfmath@def{atan}{242}{13.60403} \pgfmath@def{atan}{243}{13.65814} +\pgfmath@def{atan}{244}{13.71223} \pgfmath@def{atan}{245}{13.76630} +\pgfmath@def{atan}{246}{13.82034} \pgfmath@def{atan}{247}{13.87435} +\pgfmath@def{atan}{248}{13.92834} \pgfmath@def{atan}{249}{13.98230} +\pgfmath@def{atan}{250}{14.03624} \pgfmath@def{atan}{251}{14.09015} +\pgfmath@def{atan}{252}{14.14404} \pgfmath@def{atan}{253}{14.19790} +\pgfmath@def{atan}{254}{14.25174} \pgfmath@def{atan}{255}{14.30555} +\pgfmath@def{atan}{256}{14.35933} \pgfmath@def{atan}{257}{14.41309} +\pgfmath@def{atan}{258}{14.46682} \pgfmath@def{atan}{259}{14.52053} +\pgfmath@def{atan}{260}{14.57421} \pgfmath@def{atan}{261}{14.62787} +\pgfmath@def{atan}{262}{14.68149} \pgfmath@def{atan}{263}{14.73510} +\pgfmath@def{atan}{264}{14.78867} \pgfmath@def{atan}{265}{14.84222} +\pgfmath@def{atan}{266}{14.89575} \pgfmath@def{atan}{267}{14.94924} +\pgfmath@def{atan}{268}{15.00271} \pgfmath@def{atan}{269}{15.05615} +\pgfmath@def{atan}{270}{15.10957} \pgfmath@def{atan}{271}{15.16296} +\pgfmath@def{atan}{272}{15.21632} \pgfmath@def{atan}{273}{15.26966} +\pgfmath@def{atan}{274}{15.32297} \pgfmath@def{atan}{275}{15.37625} +\pgfmath@def{atan}{276}{15.42950} \pgfmath@def{atan}{277}{15.48273} +\pgfmath@def{atan}{278}{15.53593} \pgfmath@def{atan}{279}{15.58910} +\pgfmath@def{atan}{280}{15.64224} \pgfmath@def{atan}{281}{15.69536} +\pgfmath@def{atan}{282}{15.74845} \pgfmath@def{atan}{283}{15.80151} +\pgfmath@def{atan}{284}{15.85454} \pgfmath@def{atan}{285}{15.90755} +\pgfmath@def{atan}{286}{15.96052} \pgfmath@def{atan}{287}{16.01347} +\pgfmath@def{atan}{288}{16.06640} \pgfmath@def{atan}{289}{16.11929} +\pgfmath@def{atan}{290}{16.17215} \pgfmath@def{atan}{291}{16.22499} +\pgfmath@def{atan}{292}{16.27780} \pgfmath@def{atan}{293}{16.33058} +\pgfmath@def{atan}{294}{16.38333} \pgfmath@def{atan}{295}{16.43605} +\pgfmath@def{atan}{296}{16.48875} \pgfmath@def{atan}{297}{16.54142} +\pgfmath@def{atan}{298}{16.59405} \pgfmath@def{atan}{299}{16.64666} +\pgfmath@def{atan}{300}{16.69924} \pgfmath@def{atan}{301}{16.75179} +\pgfmath@def{atan}{302}{16.80431} \pgfmath@def{atan}{303}{16.85680} +\pgfmath@def{atan}{304}{16.90927} \pgfmath@def{atan}{305}{16.96170} +\pgfmath@def{atan}{306}{17.01411} \pgfmath@def{atan}{307}{17.06648} +\pgfmath@def{atan}{308}{17.11883} \pgfmath@def{atan}{309}{17.17114} +\pgfmath@def{atan}{310}{17.22343} \pgfmath@def{atan}{311}{17.27569} +\pgfmath@def{atan}{312}{17.32792} \pgfmath@def{atan}{313}{17.38012} +\pgfmath@def{atan}{314}{17.43228} \pgfmath@def{atan}{315}{17.48442} +\pgfmath@def{atan}{316}{17.53653} \pgfmath@def{atan}{317}{17.58861} +\pgfmath@def{atan}{318}{17.64066} \pgfmath@def{atan}{319}{17.69268} +\pgfmath@def{atan}{320}{17.74467} \pgfmath@def{atan}{321}{17.79663} +\pgfmath@def{atan}{322}{17.84855} \pgfmath@def{atan}{323}{17.90045} +\pgfmath@def{atan}{324}{17.95232} \pgfmath@def{atan}{325}{18.00416} +\pgfmath@def{atan}{326}{18.05596} \pgfmath@def{atan}{327}{18.10774} +\pgfmath@def{atan}{328}{18.15949} \pgfmath@def{atan}{329}{18.21120} +\pgfmath@def{atan}{330}{18.26289} \pgfmath@def{atan}{331}{18.31454} +\pgfmath@def{atan}{332}{18.36616} \pgfmath@def{atan}{333}{18.41775} +\pgfmath@def{atan}{334}{18.46931} \pgfmath@def{atan}{335}{18.52084} +\pgfmath@def{atan}{336}{18.57234} \pgfmath@def{atan}{337}{18.62381} +\pgfmath@def{atan}{338}{18.67525} \pgfmath@def{atan}{339}{18.72665} +\pgfmath@def{atan}{340}{18.77803} \pgfmath@def{atan}{341}{18.82937} +\pgfmath@def{atan}{342}{18.88068} \pgfmath@def{atan}{343}{18.93196} +\pgfmath@def{atan}{344}{18.98321} \pgfmath@def{atan}{345}{19.03443} +\pgfmath@def{atan}{346}{19.08562} \pgfmath@def{atan}{347}{19.13677} +\pgfmath@def{atan}{348}{19.18789} \pgfmath@def{atan}{349}{19.23898} +\pgfmath@def{atan}{350}{19.29004} \pgfmath@def{atan}{351}{19.34107} +\pgfmath@def{atan}{352}{19.39206} \pgfmath@def{atan}{353}{19.44303} +\pgfmath@def{atan}{354}{19.49396} \pgfmath@def{atan}{355}{19.54486} +\pgfmath@def{atan}{356}{19.59572} \pgfmath@def{atan}{357}{19.64656} +\pgfmath@def{atan}{358}{19.69736} \pgfmath@def{atan}{359}{19.74813} +\pgfmath@def{atan}{360}{19.79887} \pgfmath@def{atan}{361}{19.84958} +\pgfmath@def{atan}{362}{19.90025} \pgfmath@def{atan}{363}{19.95089} +\pgfmath@def{atan}{364}{20.00150} \pgfmath@def{atan}{365}{20.05208} +\pgfmath@def{atan}{366}{20.10262} \pgfmath@def{atan}{367}{20.15313} +\pgfmath@def{atan}{368}{20.20361} \pgfmath@def{atan}{369}{20.25406} +\pgfmath@def{atan}{370}{20.30447} \pgfmath@def{atan}{371}{20.35485} +\pgfmath@def{atan}{372}{20.40520} \pgfmath@def{atan}{373}{20.45551} +\pgfmath@def{atan}{374}{20.50579} \pgfmath@def{atan}{375}{20.55604} +\pgfmath@def{atan}{376}{20.60626} \pgfmath@def{atan}{377}{20.65644} +\pgfmath@def{atan}{378}{20.70659} \pgfmath@def{atan}{379}{20.75670} +\pgfmath@def{atan}{380}{20.80679} \pgfmath@def{atan}{381}{20.85684} +\pgfmath@def{atan}{382}{20.90685} \pgfmath@def{atan}{383}{20.95684} +\pgfmath@def{atan}{384}{21.00678} \pgfmath@def{atan}{385}{21.05670} +\pgfmath@def{atan}{386}{21.10658} \pgfmath@def{atan}{387}{21.15643} +\pgfmath@def{atan}{388}{21.20625} \pgfmath@def{atan}{389}{21.25603} +\pgfmath@def{atan}{390}{21.30578} \pgfmath@def{atan}{391}{21.35549} +\pgfmath@def{atan}{392}{21.40517} \pgfmath@def{atan}{393}{21.45482} +\pgfmath@def{atan}{394}{21.50444} \pgfmath@def{atan}{395}{21.55402} +\pgfmath@def{atan}{396}{21.60356} \pgfmath@def{atan}{397}{21.65307} +\pgfmath@def{atan}{398}{21.70255} \pgfmath@def{atan}{399}{21.75200} +\pgfmath@def{atan}{400}{21.80140} \pgfmath@def{atan}{401}{21.85078} +\pgfmath@def{atan}{402}{21.90012} \pgfmath@def{atan}{403}{21.94943} +\pgfmath@def{atan}{404}{21.99870} \pgfmath@def{atan}{405}{22.04794} +\pgfmath@def{atan}{406}{22.09715} \pgfmath@def{atan}{407}{22.14632} +\pgfmath@def{atan}{408}{22.19546} \pgfmath@def{atan}{409}{22.24456} +\pgfmath@def{atan}{410}{22.29362} \pgfmath@def{atan}{411}{22.34266} +\pgfmath@def{atan}{412}{22.39166} \pgfmath@def{atan}{413}{22.44062} +\pgfmath@def{atan}{414}{22.48955} \pgfmath@def{atan}{415}{22.53845} +\pgfmath@def{atan}{416}{22.58731} \pgfmath@def{atan}{417}{22.63613} +\pgfmath@def{atan}{418}{22.68492} \pgfmath@def{atan}{419}{22.73368} +\pgfmath@def{atan}{420}{22.78240} \pgfmath@def{atan}{421}{22.83109} +\pgfmath@def{atan}{422}{22.87974} \pgfmath@def{atan}{423}{22.92836} +\pgfmath@def{atan}{424}{22.97694} \pgfmath@def{atan}{425}{23.02549} +\pgfmath@def{atan}{426}{23.07400} \pgfmath@def{atan}{427}{23.12248} +\pgfmath@def{atan}{428}{23.17092} \pgfmath@def{atan}{429}{23.21933} +\pgfmath@def{atan}{430}{23.26770} \pgfmath@def{atan}{431}{23.31604} +\pgfmath@def{atan}{432}{23.36434} \pgfmath@def{atan}{433}{23.41261} +\pgfmath@def{atan}{434}{23.46084} \pgfmath@def{atan}{435}{23.50904} +\pgfmath@def{atan}{436}{23.55720} \pgfmath@def{atan}{437}{23.60532} +\pgfmath@def{atan}{438}{23.65341} \pgfmath@def{atan}{439}{23.70147} +\pgfmath@def{atan}{440}{23.74949} \pgfmath@def{atan}{441}{23.79747} +\pgfmath@def{atan}{442}{23.84542} \pgfmath@def{atan}{443}{23.89334} +\pgfmath@def{atan}{444}{23.94122} \pgfmath@def{atan}{445}{23.98906} +\pgfmath@def{atan}{446}{24.03687} \pgfmath@def{atan}{447}{24.08464} +\pgfmath@def{atan}{448}{24.13238} \pgfmath@def{atan}{449}{24.18008} +\pgfmath@def{atan}{450}{24.22774} \pgfmath@def{atan}{451}{24.27537} +\pgfmath@def{atan}{452}{24.32296} \pgfmath@def{atan}{453}{24.37052} +\pgfmath@def{atan}{454}{24.41804} \pgfmath@def{atan}{455}{24.46553} +\pgfmath@def{atan}{456}{24.51298} \pgfmath@def{atan}{457}{24.56040} +\pgfmath@def{atan}{458}{24.60778} \pgfmath@def{atan}{459}{24.65512} +\pgfmath@def{atan}{460}{24.70243} \pgfmath@def{atan}{461}{24.74970} +\pgfmath@def{atan}{462}{24.79693} \pgfmath@def{atan}{463}{24.84413} +\pgfmath@def{atan}{464}{24.89130} \pgfmath@def{atan}{465}{24.93842} +\pgfmath@def{atan}{466}{24.98551} \pgfmath@def{atan}{467}{25.03257} +\pgfmath@def{atan}{468}{25.07959} \pgfmath@def{atan}{469}{25.12657} +\pgfmath@def{atan}{470}{25.17352} \pgfmath@def{atan}{471}{25.22043} +\pgfmath@def{atan}{472}{25.26731} \pgfmath@def{atan}{473}{25.31414} +\pgfmath@def{atan}{474}{25.36095} \pgfmath@def{atan}{475}{25.40771} +\pgfmath@def{atan}{476}{25.45444} \pgfmath@def{atan}{477}{25.50114} +\pgfmath@def{atan}{478}{25.54780} \pgfmath@def{atan}{479}{25.59442} +\pgfmath@def{atan}{480}{25.64100} \pgfmath@def{atan}{481}{25.68755} +\pgfmath@def{atan}{482}{25.73406} \pgfmath@def{atan}{483}{25.78054} +\pgfmath@def{atan}{484}{25.82698} \pgfmath@def{atan}{485}{25.87338} +\pgfmath@def{atan}{486}{25.91975} \pgfmath@def{atan}{487}{25.96608} +\pgfmath@def{atan}{488}{26.01237} \pgfmath@def{atan}{489}{26.05863} +\pgfmath@def{atan}{490}{26.10485} \pgfmath@def{atan}{491}{26.15103} +\pgfmath@def{atan}{492}{26.19718} \pgfmath@def{atan}{493}{26.24329} +\pgfmath@def{atan}{494}{26.28937} \pgfmath@def{atan}{495}{26.33541} +\pgfmath@def{atan}{496}{26.38141} \pgfmath@def{atan}{497}{26.42737} +\pgfmath@def{atan}{498}{26.47330} \pgfmath@def{atan}{499}{26.51919} +\pgfmath@def{atan}{500}{26.56505} \pgfmath@def{atan}{501}{26.61086} +\pgfmath@def{atan}{502}{26.65665} \pgfmath@def{atan}{503}{26.70239} +\pgfmath@def{atan}{504}{26.74810} \pgfmath@def{atan}{505}{26.79377} +\pgfmath@def{atan}{506}{26.83941} \pgfmath@def{atan}{507}{26.88500} +\pgfmath@def{atan}{508}{26.93057} \pgfmath@def{atan}{509}{26.97609} +\pgfmath@def{atan}{510}{27.02158} \pgfmath@def{atan}{511}{27.06703} +\pgfmath@def{atan}{512}{27.11244} \pgfmath@def{atan}{513}{27.15782} +\pgfmath@def{atan}{514}{27.20316} \pgfmath@def{atan}{515}{27.24846} +\pgfmath@def{atan}{516}{27.29373} \pgfmath@def{atan}{517}{27.33896} +\pgfmath@def{atan}{518}{27.38415} \pgfmath@def{atan}{519}{27.42931} +\pgfmath@def{atan}{520}{27.47443} \pgfmath@def{atan}{521}{27.51951} +\pgfmath@def{atan}{522}{27.56455} \pgfmath@def{atan}{523}{27.60956} +\pgfmath@def{atan}{524}{27.65453} \pgfmath@def{atan}{525}{27.69947} +\pgfmath@def{atan}{526}{27.74437} \pgfmath@def{atan}{527}{27.78923} +\pgfmath@def{atan}{528}{27.83405} \pgfmath@def{atan}{529}{27.87884} +\pgfmath@def{atan}{530}{27.92359} \pgfmath@def{atan}{531}{27.96830} +\pgfmath@def{atan}{532}{28.01297} \pgfmath@def{atan}{533}{28.05761} +\pgfmath@def{atan}{534}{28.10221} \pgfmath@def{atan}{535}{28.14678} +\pgfmath@def{atan}{536}{28.19130} \pgfmath@def{atan}{537}{28.23579} +\pgfmath@def{atan}{538}{28.28025} \pgfmath@def{atan}{539}{28.32466} +\pgfmath@def{atan}{540}{28.36904} \pgfmath@def{atan}{541}{28.41338} +\pgfmath@def{atan}{542}{28.45769} \pgfmath@def{atan}{543}{28.50196} +\pgfmath@def{atan}{544}{28.54619} \pgfmath@def{atan}{545}{28.59038} +\pgfmath@def{atan}{546}{28.63454} \pgfmath@def{atan}{547}{28.67865} +\pgfmath@def{atan}{548}{28.72274} \pgfmath@def{atan}{549}{28.76678} +\pgfmath@def{atan}{550}{28.81079} \pgfmath@def{atan}{551}{28.85476} +\pgfmath@def{atan}{552}{28.89869} \pgfmath@def{atan}{553}{28.94259} +\pgfmath@def{atan}{554}{28.98645} \pgfmath@def{atan}{555}{29.03027} +\pgfmath@def{atan}{556}{29.07405} \pgfmath@def{atan}{557}{29.11780} +\pgfmath@def{atan}{558}{29.16151} \pgfmath@def{atan}{559}{29.20519} +\pgfmath@def{atan}{560}{29.24882} \pgfmath@def{atan}{561}{29.29242} +\pgfmath@def{atan}{562}{29.33598} \pgfmath@def{atan}{563}{29.37951} +\pgfmath@def{atan}{564}{29.42299} \pgfmath@def{atan}{565}{29.46644} +\pgfmath@def{atan}{566}{29.50986} \pgfmath@def{atan}{567}{29.55323} +\pgfmath@def{atan}{568}{29.59657} \pgfmath@def{atan}{569}{29.63987} +\pgfmath@def{atan}{570}{29.68314} \pgfmath@def{atan}{571}{29.72636} +\pgfmath@def{atan}{572}{29.76955} \pgfmath@def{atan}{573}{29.81270} +\pgfmath@def{atan}{574}{29.85582} \pgfmath@def{atan}{575}{29.89890} +\pgfmath@def{atan}{576}{29.94194} \pgfmath@def{atan}{577}{29.98494} +\pgfmath@def{atan}{578}{30.02791} \pgfmath@def{atan}{579}{30.07084} +\pgfmath@def{atan}{580}{30.11373} \pgfmath@def{atan}{581}{30.15658} +\pgfmath@def{atan}{582}{30.19940} \pgfmath@def{atan}{583}{30.24218} +\pgfmath@def{atan}{584}{30.28492} \pgfmath@def{atan}{585}{30.32763} +\pgfmath@def{atan}{586}{30.37030} \pgfmath@def{atan}{587}{30.41293} +\pgfmath@def{atan}{588}{30.45552} \pgfmath@def{atan}{589}{30.49808} +\pgfmath@def{atan}{590}{30.54060} \pgfmath@def{atan}{591}{30.58308} +\pgfmath@def{atan}{592}{30.62553} \pgfmath@def{atan}{593}{30.66794} +\pgfmath@def{atan}{594}{30.71031} \pgfmath@def{atan}{595}{30.75264} +\pgfmath@def{atan}{596}{30.79494} \pgfmath@def{atan}{597}{30.83720} +\pgfmath@def{atan}{598}{30.87942} \pgfmath@def{atan}{599}{30.92160} +\pgfmath@def{atan}{600}{30.96375} \pgfmath@def{atan}{601}{31.00586} +\pgfmath@def{atan}{602}{31.04794} \pgfmath@def{atan}{603}{31.08997} +\pgfmath@def{atan}{604}{31.13197} \pgfmath@def{atan}{605}{31.17393} +\pgfmath@def{atan}{606}{31.21586} \pgfmath@def{atan}{607}{31.25775} +\pgfmath@def{atan}{608}{31.29960} \pgfmath@def{atan}{609}{31.34141} +\pgfmath@def{atan}{610}{31.38319} \pgfmath@def{atan}{611}{31.42493} +\pgfmath@def{atan}{612}{31.46663} \pgfmath@def{atan}{613}{31.50829} +\pgfmath@def{atan}{614}{31.54992} \pgfmath@def{atan}{615}{31.59151} +\pgfmath@def{atan}{616}{31.63306} \pgfmath@def{atan}{617}{31.67458} +\pgfmath@def{atan}{618}{31.71606} \pgfmath@def{atan}{619}{31.75750} +\pgfmath@def{atan}{620}{31.79891} \pgfmath@def{atan}{621}{31.84028} +\pgfmath@def{atan}{622}{31.88161} \pgfmath@def{atan}{623}{31.92290} +\pgfmath@def{atan}{624}{31.96416} \pgfmath@def{atan}{625}{32.00538} +\pgfmath@def{atan}{626}{32.04656} \pgfmath@def{atan}{627}{32.08771} +\pgfmath@def{atan}{628}{32.12882} \pgfmath@def{atan}{629}{32.16989} +\pgfmath@def{atan}{630}{32.21092} \pgfmath@def{atan}{631}{32.25192} +\pgfmath@def{atan}{632}{32.29288} \pgfmath@def{atan}{633}{32.33381} +\pgfmath@def{atan}{634}{32.37469} \pgfmath@def{atan}{635}{32.41554} +\pgfmath@def{atan}{636}{32.45636} \pgfmath@def{atan}{637}{32.49713} +\pgfmath@def{atan}{638}{32.53787} \pgfmath@def{atan}{639}{32.57857} +\pgfmath@def{atan}{640}{32.61924} \pgfmath@def{atan}{641}{32.65987} +\pgfmath@def{atan}{642}{32.70046} \pgfmath@def{atan}{643}{32.74101} +\pgfmath@def{atan}{644}{32.78153} \pgfmath@def{atan}{645}{32.82201} +\pgfmath@def{atan}{646}{32.86246} \pgfmath@def{atan}{647}{32.90286} +\pgfmath@def{atan}{648}{32.94323} \pgfmath@def{atan}{649}{32.98357} +\pgfmath@def{atan}{650}{33.02386} \pgfmath@def{atan}{651}{33.06412} +\pgfmath@def{atan}{652}{33.10435} \pgfmath@def{atan}{653}{33.14453} +\pgfmath@def{atan}{654}{33.18468} \pgfmath@def{atan}{655}{33.22479} +\pgfmath@def{atan}{656}{33.26487} \pgfmath@def{atan}{657}{33.30491} +\pgfmath@def{atan}{658}{33.34491} \pgfmath@def{atan}{659}{33.38488} +\pgfmath@def{atan}{660}{33.42481} \pgfmath@def{atan}{661}{33.46470} +\pgfmath@def{atan}{662}{33.50455} \pgfmath@def{atan}{663}{33.54437} +\pgfmath@def{atan}{664}{33.58416} \pgfmath@def{atan}{665}{33.62390} +\pgfmath@def{atan}{666}{33.66361} \pgfmath@def{atan}{667}{33.70328} +\pgfmath@def{atan}{668}{33.74292} \pgfmath@def{atan}{669}{33.78252} +\pgfmath@def{atan}{670}{33.82208} \pgfmath@def{atan}{671}{33.86161} +\pgfmath@def{atan}{672}{33.90110} \pgfmath@def{atan}{673}{33.94055} +\pgfmath@def{atan}{674}{33.97997} \pgfmath@def{atan}{675}{34.01935} +\pgfmath@def{atan}{676}{34.05869} \pgfmath@def{atan}{677}{34.09800} +\pgfmath@def{atan}{678}{34.13727} \pgfmath@def{atan}{679}{34.17650} +\pgfmath@def{atan}{680}{34.21570} \pgfmath@def{atan}{681}{34.25486} +\pgfmath@def{atan}{682}{34.29398} \pgfmath@def{atan}{683}{34.33307} +\pgfmath@def{atan}{684}{34.37212} \pgfmath@def{atan}{685}{34.41114} +\pgfmath@def{atan}{686}{34.45012} \pgfmath@def{atan}{687}{34.48906} +\pgfmath@def{atan}{688}{34.52797} \pgfmath@def{atan}{689}{34.56684} +\pgfmath@def{atan}{690}{34.60567} \pgfmath@def{atan}{691}{34.64447} +\pgfmath@def{atan}{692}{34.68323} \pgfmath@def{atan}{693}{34.72195} +\pgfmath@def{atan}{694}{34.76064} \pgfmath@def{atan}{695}{34.79930} +\pgfmath@def{atan}{696}{34.83791} \pgfmath@def{atan}{697}{34.87649} +\pgfmath@def{atan}{698}{34.91504} \pgfmath@def{atan}{699}{34.95354} +\pgfmath@def{atan}{700}{34.99202} \pgfmath@def{atan}{701}{35.03045} +\pgfmath@def{atan}{702}{35.06885} \pgfmath@def{atan}{703}{35.10721} +\pgfmath@def{atan}{704}{35.14554} \pgfmath@def{atan}{705}{35.18383} +\pgfmath@def{atan}{706}{35.22209} \pgfmath@def{atan}{707}{35.26031} +\pgfmath@def{atan}{708}{35.29849} \pgfmath@def{atan}{709}{35.33664} +\pgfmath@def{atan}{710}{35.37475} \pgfmath@def{atan}{711}{35.41282} +\pgfmath@def{atan}{712}{35.45086} \pgfmath@def{atan}{713}{35.48886} +\pgfmath@def{atan}{714}{35.52683} \pgfmath@def{atan}{715}{35.56476} +\pgfmath@def{atan}{716}{35.60266} \pgfmath@def{atan}{717}{35.64052} +\pgfmath@def{atan}{718}{35.67834} \pgfmath@def{atan}{719}{35.71613} +\pgfmath@def{atan}{720}{35.75388} \pgfmath@def{atan}{721}{35.79160} +\pgfmath@def{atan}{722}{35.82928} \pgfmath@def{atan}{723}{35.86692} +\pgfmath@def{atan}{724}{35.90453} \pgfmath@def{atan}{725}{35.94211} +\pgfmath@def{atan}{726}{35.97965} \pgfmath@def{atan}{727}{36.01715} +\pgfmath@def{atan}{728}{36.05461} \pgfmath@def{atan}{729}{36.09204} +\pgfmath@def{atan}{730}{36.12944} \pgfmath@def{atan}{731}{36.16680} +\pgfmath@def{atan}{732}{36.20412} \pgfmath@def{atan}{733}{36.24141} +\pgfmath@def{atan}{734}{36.27866} \pgfmath@def{atan}{735}{36.31588} +\pgfmath@def{atan}{736}{36.35306} \pgfmath@def{atan}{737}{36.39021} +\pgfmath@def{atan}{738}{36.42732} \pgfmath@def{atan}{739}{36.46440} +\pgfmath@def{atan}{740}{36.50144} \pgfmath@def{atan}{741}{36.53844} +\pgfmath@def{atan}{742}{36.57541} \pgfmath@def{atan}{743}{36.61234} +\pgfmath@def{atan}{744}{36.64924} \pgfmath@def{atan}{745}{36.68611} +\pgfmath@def{atan}{746}{36.72293} \pgfmath@def{atan}{747}{36.75973} +\pgfmath@def{atan}{748}{36.79648} \pgfmath@def{atan}{749}{36.83321} +\pgfmath@def{atan}{750}{36.86989} \pgfmath@def{atan}{751}{36.90654} +\pgfmath@def{atan}{752}{36.94316} \pgfmath@def{atan}{753}{36.97974} +\pgfmath@def{atan}{754}{37.01629} \pgfmath@def{atan}{755}{37.05280} +\pgfmath@def{atan}{756}{37.08928} \pgfmath@def{atan}{757}{37.12572} +\pgfmath@def{atan}{758}{37.16212} \pgfmath@def{atan}{759}{37.19849} +\pgfmath@def{atan}{760}{37.23483} \pgfmath@def{atan}{761}{37.27113} +\pgfmath@def{atan}{762}{37.30740} \pgfmath@def{atan}{763}{37.34363} +\pgfmath@def{atan}{764}{37.37982} \pgfmath@def{atan}{765}{37.41598} +\pgfmath@def{atan}{766}{37.45211} \pgfmath@def{atan}{767}{37.48820} +\pgfmath@def{atan}{768}{37.52426} \pgfmath@def{atan}{769}{37.56028} +\pgfmath@def{atan}{770}{37.59627} \pgfmath@def{atan}{771}{37.63222} +\pgfmath@def{atan}{772}{37.66814} \pgfmath@def{atan}{773}{37.70402} +\pgfmath@def{atan}{774}{37.73987} \pgfmath@def{atan}{775}{37.77568} +\pgfmath@def{atan}{776}{37.81146} \pgfmath@def{atan}{777}{37.84720} +\pgfmath@def{atan}{778}{37.88291} \pgfmath@def{atan}{779}{37.91859} +\pgfmath@def{atan}{780}{37.95423} \pgfmath@def{atan}{781}{37.98983} +\pgfmath@def{atan}{782}{38.02540} \pgfmath@def{atan}{783}{38.06094} +\pgfmath@def{atan}{784}{38.09644} \pgfmath@def{atan}{785}{38.13191} +\pgfmath@def{atan}{786}{38.16734} \pgfmath@def{atan}{787}{38.20274} +\pgfmath@def{atan}{788}{38.23811} \pgfmath@def{atan}{789}{38.27344} +\pgfmath@def{atan}{790}{38.30873} \pgfmath@def{atan}{791}{38.34399} +\pgfmath@def{atan}{792}{38.37922} \pgfmath@def{atan}{793}{38.41441} +\pgfmath@def{atan}{794}{38.44957} \pgfmath@def{atan}{795}{38.48469} +\pgfmath@def{atan}{796}{38.51979} \pgfmath@def{atan}{797}{38.55484} +\pgfmath@def{atan}{798}{38.58986} \pgfmath@def{atan}{799}{38.62485} +\pgfmath@def{atan}{800}{38.65980} \pgfmath@def{atan}{801}{38.69472} +\pgfmath@def{atan}{802}{38.72961} \pgfmath@def{atan}{803}{38.76446} +\pgfmath@def{atan}{804}{38.79928} \pgfmath@def{atan}{805}{38.83406} +\pgfmath@def{atan}{806}{38.86881} \pgfmath@def{atan}{807}{38.90353} +\pgfmath@def{atan}{808}{38.93821} \pgfmath@def{atan}{809}{38.97285} +\pgfmath@def{atan}{810}{39.00747} \pgfmath@def{atan}{811}{39.04205} +\pgfmath@def{atan}{812}{39.07659} \pgfmath@def{atan}{813}{39.11111} +\pgfmath@def{atan}{814}{39.14558} \pgfmath@def{atan}{815}{39.18003} +\pgfmath@def{atan}{816}{39.21444} \pgfmath@def{atan}{817}{39.24882} +\pgfmath@def{atan}{818}{39.28316} \pgfmath@def{atan}{819}{39.31747} +\pgfmath@def{atan}{820}{39.35175} \pgfmath@def{atan}{821}{39.38599} +\pgfmath@def{atan}{822}{39.42020} \pgfmath@def{atan}{823}{39.45438} +\pgfmath@def{atan}{824}{39.48852} \pgfmath@def{atan}{825}{39.52263} +\pgfmath@def{atan}{826}{39.55670} \pgfmath@def{atan}{827}{39.59074} +\pgfmath@def{atan}{828}{39.62475} \pgfmath@def{atan}{829}{39.65873} +\pgfmath@def{atan}{830}{39.69267} \pgfmath@def{atan}{831}{39.72658} +\pgfmath@def{atan}{832}{39.76045} \pgfmath@def{atan}{833}{39.79429} +\pgfmath@def{atan}{834}{39.82810} \pgfmath@def{atan}{835}{39.86188} +\pgfmath@def{atan}{836}{39.89562} \pgfmath@def{atan}{837}{39.92933} +\pgfmath@def{atan}{838}{39.96300} \pgfmath@def{atan}{839}{39.99665} +\pgfmath@def{atan}{840}{40.03025} \pgfmath@def{atan}{841}{40.06383} +\pgfmath@def{atan}{842}{40.09737} \pgfmath@def{atan}{843}{40.13088} +\pgfmath@def{atan}{844}{40.16436} \pgfmath@def{atan}{845}{40.19781} +\pgfmath@def{atan}{846}{40.23122} \pgfmath@def{atan}{847}{40.26459} +\pgfmath@def{atan}{848}{40.29794} \pgfmath@def{atan}{849}{40.33125} +\pgfmath@def{atan}{850}{40.36453} \pgfmath@def{atan}{851}{40.39778} +\pgfmath@def{atan}{852}{40.43099} \pgfmath@def{atan}{853}{40.46417} +\pgfmath@def{atan}{854}{40.49732} \pgfmath@def{atan}{855}{40.53044} +\pgfmath@def{atan}{856}{40.56352} \pgfmath@def{atan}{857}{40.59657} +\pgfmath@def{atan}{858}{40.62959} \pgfmath@def{atan}{859}{40.66257} +\pgfmath@def{atan}{860}{40.69553} \pgfmath@def{atan}{861}{40.72845} +\pgfmath@def{atan}{862}{40.76133} \pgfmath@def{atan}{863}{40.79419} +\pgfmath@def{atan}{864}{40.82701} \pgfmath@def{atan}{865}{40.85980} +\pgfmath@def{atan}{866}{40.89256} \pgfmath@def{atan}{867}{40.92528} +\pgfmath@def{atan}{868}{40.95798} \pgfmath@def{atan}{869}{40.99064} +\pgfmath@def{atan}{870}{41.02326} \pgfmath@def{atan}{871}{41.05586} +\pgfmath@def{atan}{872}{41.08842} \pgfmath@def{atan}{873}{41.12095} +\pgfmath@def{atan}{874}{41.15345} \pgfmath@def{atan}{875}{41.18592} +\pgfmath@def{atan}{876}{41.21836} \pgfmath@def{atan}{877}{41.25076} +\pgfmath@def{atan}{878}{41.28313} \pgfmath@def{atan}{879}{41.31547} +\pgfmath@def{atan}{880}{41.34777} \pgfmath@def{atan}{881}{41.38005} +\pgfmath@def{atan}{882}{41.41229} \pgfmath@def{atan}{883}{41.44450} +\pgfmath@def{atan}{884}{41.47668} \pgfmath@def{atan}{885}{41.50882} +\pgfmath@def{atan}{886}{41.54094} \pgfmath@def{atan}{887}{41.57302} +\pgfmath@def{atan}{888}{41.60507} \pgfmath@def{atan}{889}{41.63709} +\pgfmath@def{atan}{890}{41.66908} \pgfmath@def{atan}{891}{41.70103} +\pgfmath@def{atan}{892}{41.73296} \pgfmath@def{atan}{893}{41.76485} +\pgfmath@def{atan}{894}{41.79671} \pgfmath@def{atan}{895}{41.82854} +\pgfmath@def{atan}{896}{41.86034} \pgfmath@def{atan}{897}{41.89210} +\pgfmath@def{atan}{898}{41.92383} \pgfmath@def{atan}{899}{41.95554} +\pgfmath@def{atan}{900}{41.98721} \pgfmath@def{atan}{901}{42.01885} +\pgfmath@def{atan}{902}{42.05046} \pgfmath@def{atan}{903}{42.08203} +\pgfmath@def{atan}{904}{42.11358} \pgfmath@def{atan}{905}{42.14509} +\pgfmath@def{atan}{906}{42.17657} \pgfmath@def{atan}{907}{42.20802} +\pgfmath@def{atan}{908}{42.23944} \pgfmath@def{atan}{909}{42.27083} +\pgfmath@def{atan}{910}{42.30219} \pgfmath@def{atan}{911}{42.33352} +\pgfmath@def{atan}{912}{42.36481} \pgfmath@def{atan}{913}{42.39607} +\pgfmath@def{atan}{914}{42.42731} \pgfmath@def{atan}{915}{42.45851} +\pgfmath@def{atan}{916}{42.48968} \pgfmath@def{atan}{917}{42.52082} +\pgfmath@def{atan}{918}{42.55193} \pgfmath@def{atan}{919}{42.58300} +\pgfmath@def{atan}{920}{42.61405} \pgfmath@def{atan}{921}{42.64507} +\pgfmath@def{atan}{922}{42.67605} \pgfmath@def{atan}{923}{42.70701} +\pgfmath@def{atan}{924}{42.73793} \pgfmath@def{atan}{925}{42.76882} +\pgfmath@def{atan}{926}{42.79968} \pgfmath@def{atan}{927}{42.83051} +\pgfmath@def{atan}{928}{42.86131} \pgfmath@def{atan}{929}{42.89208} +\pgfmath@def{atan}{930}{42.92282} \pgfmath@def{atan}{931}{42.95353} +\pgfmath@def{atan}{932}{42.98421} \pgfmath@def{atan}{933}{43.01485} +\pgfmath@def{atan}{934}{43.04547} \pgfmath@def{atan}{935}{43.07605} +\pgfmath@def{atan}{936}{43.10661} \pgfmath@def{atan}{937}{43.13713} +\pgfmath@def{atan}{938}{43.16763} \pgfmath@def{atan}{939}{43.19809} +\pgfmath@def{atan}{940}{43.22853} \pgfmath@def{atan}{941}{43.25893} +\pgfmath@def{atan}{942}{43.28930} \pgfmath@def{atan}{943}{43.31964} +\pgfmath@def{atan}{944}{43.34996} \pgfmath@def{atan}{945}{43.38024} +\pgfmath@def{atan}{946}{43.41049} \pgfmath@def{atan}{947}{43.44071} +\pgfmath@def{atan}{948}{43.47090} \pgfmath@def{atan}{949}{43.50106} +\pgfmath@def{atan}{950}{43.53119} \pgfmath@def{atan}{951}{43.56130} +\pgfmath@def{atan}{952}{43.59137} \pgfmath@def{atan}{953}{43.62141} +\pgfmath@def{atan}{954}{43.65142} \pgfmath@def{atan}{955}{43.68140} +\pgfmath@def{atan}{956}{43.71135} \pgfmath@def{atan}{957}{43.74127} +\pgfmath@def{atan}{958}{43.77116} \pgfmath@def{atan}{959}{43.80102} +\pgfmath@def{atan}{960}{43.83086} \pgfmath@def{atan}{961}{43.86066} +\pgfmath@def{atan}{962}{43.89043} \pgfmath@def{atan}{963}{43.92017} +\pgfmath@def{atan}{964}{43.94988} \pgfmath@def{atan}{965}{43.97957} +\pgfmath@def{atan}{966}{44.00922} \pgfmath@def{atan}{967}{44.03884} +\pgfmath@def{atan}{968}{44.06844} \pgfmath@def{atan}{969}{44.09800} +\pgfmath@def{atan}{970}{44.12754} \pgfmath@def{atan}{971}{44.15704} +\pgfmath@def{atan}{972}{44.18652} \pgfmath@def{atan}{973}{44.21597} +\pgfmath@def{atan}{974}{44.24538} \pgfmath@def{atan}{975}{44.27477} +\pgfmath@def{atan}{976}{44.30413} \pgfmath@def{atan}{977}{44.33346} +\pgfmath@def{atan}{978}{44.36276} \pgfmath@def{atan}{979}{44.39203} +\pgfmath@def{atan}{980}{44.42127} \pgfmath@def{atan}{981}{44.45048} +\pgfmath@def{atan}{982}{44.47966} \pgfmath@def{atan}{983}{44.50882} +\pgfmath@def{atan}{984}{44.53794} \pgfmath@def{atan}{985}{44.56704} +\pgfmath@def{atan}{986}{44.59610} \pgfmath@def{atan}{987}{44.62514} +\pgfmath@def{atan}{988}{44.65415} \pgfmath@def{atan}{989}{44.68313} +\pgfmath@def{atan}{990}{44.71208} \pgfmath@def{atan}{991}{44.74100} +\pgfmath@def{atan}{992}{44.76989} \pgfmath@def{atan}{993}{44.79876} +\pgfmath@def{atan}{994}{44.82759} \pgfmath@def{atan}{995}{44.85640} +\pgfmath@def{atan}{996}{44.88517} \pgfmath@def{atan}{997}{44.91392} +\pgfmath@def{atan}{998}{44.94264} \pgfmath@def{atan}{999}{44.97133} +\pgfmath@def{atan}{1000}{45.00000} + +\pgfmath@def{acos}{0}{90.00000} \pgfmath@def{acos}{1}{89.94270} +\pgfmath@def{acos}{2}{89.88540} \pgfmath@def{acos}{3}{89.82811} +\pgfmath@def{acos}{4}{89.77081} \pgfmath@def{acos}{5}{89.71352} +\pgfmath@def{acos}{6}{89.65622} \pgfmath@def{acos}{7}{89.59892} +\pgfmath@def{acos}{8}{89.54162} \pgfmath@def{acos}{9}{89.48433} +\pgfmath@def{acos}{10}{89.42703} \pgfmath@def{acos}{11}{89.36973} +\pgfmath@def{acos}{12}{89.31243} \pgfmath@def{acos}{13}{89.25513} +\pgfmath@def{acos}{14}{89.19783} \pgfmath@def{acos}{15}{89.14053} +\pgfmath@def{acos}{16}{89.08322} \pgfmath@def{acos}{17}{89.02592} +\pgfmath@def{acos}{18}{88.96862} \pgfmath@def{acos}{19}{88.91131} +\pgfmath@def{acos}{20}{88.85400} \pgfmath@def{acos}{21}{88.79670} +\pgfmath@def{acos}{22}{88.73939} \pgfmath@def{acos}{23}{88.68208} +\pgfmath@def{acos}{24}{88.62476} \pgfmath@def{acos}{25}{88.56745} +\pgfmath@def{acos}{26}{88.51014} \pgfmath@def{acos}{27}{88.45282} +\pgfmath@def{acos}{28}{88.39550} \pgfmath@def{acos}{29}{88.33818} +\pgfmath@def{acos}{30}{88.28086} \pgfmath@def{acos}{31}{88.22354} +\pgfmath@def{acos}{32}{88.16622} \pgfmath@def{acos}{33}{88.10889} +\pgfmath@def{acos}{34}{88.05156} \pgfmath@def{acos}{35}{87.99423} +\pgfmath@def{acos}{36}{87.93690} \pgfmath@def{acos}{37}{87.87957} +\pgfmath@def{acos}{38}{87.82223} \pgfmath@def{acos}{39}{87.76489} +\pgfmath@def{acos}{40}{87.70755} \pgfmath@def{acos}{41}{87.65021} +\pgfmath@def{acos}{42}{87.59286} \pgfmath@def{acos}{43}{87.53552} +\pgfmath@def{acos}{44}{87.47817} \pgfmath@def{acos}{45}{87.42081} +\pgfmath@def{acos}{46}{87.36346} \pgfmath@def{acos}{47}{87.30610} +\pgfmath@def{acos}{48}{87.24874} \pgfmath@def{acos}{49}{87.19138} +\pgfmath@def{acos}{50}{87.13401} \pgfmath@def{acos}{51}{87.07664} +\pgfmath@def{acos}{52}{87.01927} \pgfmath@def{acos}{53}{86.96190} +\pgfmath@def{acos}{54}{86.90452} \pgfmath@def{acos}{55}{86.84714} +\pgfmath@def{acos}{56}{86.78975} \pgfmath@def{acos}{57}{86.73237} +\pgfmath@def{acos}{58}{86.67497} \pgfmath@def{acos}{59}{86.61758} +\pgfmath@def{acos}{60}{86.56018} \pgfmath@def{acos}{61}{86.50278} +\pgfmath@def{acos}{62}{86.44538} \pgfmath@def{acos}{63}{86.38797} +\pgfmath@def{acos}{64}{86.33056} \pgfmath@def{acos}{65}{86.27314} +\pgfmath@def{acos}{66}{86.21572} \pgfmath@def{acos}{67}{86.15830} +\pgfmath@def{acos}{68}{86.10087} \pgfmath@def{acos}{69}{86.04344} +\pgfmath@def{acos}{70}{85.98601} \pgfmath@def{acos}{71}{85.92857} +\pgfmath@def{acos}{72}{85.87113} \pgfmath@def{acos}{73}{85.81368} +\pgfmath@def{acos}{74}{85.75623} \pgfmath@def{acos}{75}{85.69877} +\pgfmath@def{acos}{76}{85.64131} \pgfmath@def{acos}{77}{85.58385} +\pgfmath@def{acos}{78}{85.52638} \pgfmath@def{acos}{79}{85.46891} +\pgfmath@def{acos}{80}{85.41143} \pgfmath@def{acos}{81}{85.35395} +\pgfmath@def{acos}{82}{85.29646} \pgfmath@def{acos}{83}{85.23897} +\pgfmath@def{acos}{84}{85.18147} \pgfmath@def{acos}{85}{85.12397} +\pgfmath@def{acos}{86}{85.06646} \pgfmath@def{acos}{87}{85.00895} +\pgfmath@def{acos}{88}{84.95144} \pgfmath@def{acos}{89}{84.89392} +\pgfmath@def{acos}{90}{84.83639} \pgfmath@def{acos}{91}{84.77886} +\pgfmath@def{acos}{92}{84.72132} \pgfmath@def{acos}{93}{84.66378} +\pgfmath@def{acos}{94}{84.60623} \pgfmath@def{acos}{95}{84.54868} +\pgfmath@def{acos}{96}{84.49112} \pgfmath@def{acos}{97}{84.43355} +\pgfmath@def{acos}{98}{84.37598} \pgfmath@def{acos}{99}{84.31841} +\pgfmath@def{acos}{100}{84.26083} \pgfmath@def{acos}{101}{84.20324} +\pgfmath@def{acos}{102}{84.14564} \pgfmath@def{acos}{103}{84.08805} +\pgfmath@def{acos}{104}{84.03044} \pgfmath@def{acos}{105}{83.97283} +\pgfmath@def{acos}{106}{83.91521} \pgfmath@def{acos}{107}{83.85759} +\pgfmath@def{acos}{108}{83.79996} \pgfmath@def{acos}{109}{83.74232} +\pgfmath@def{acos}{110}{83.68468} \pgfmath@def{acos}{111}{83.62703} +\pgfmath@def{acos}{112}{83.56938} \pgfmath@def{acos}{113}{83.51171} +\pgfmath@def{acos}{114}{83.45405} \pgfmath@def{acos}{115}{83.39637} +\pgfmath@def{acos}{116}{83.33869} \pgfmath@def{acos}{117}{83.28100} +\pgfmath@def{acos}{118}{83.22330} \pgfmath@def{acos}{119}{83.16560} +\pgfmath@def{acos}{120}{83.10789} \pgfmath@def{acos}{121}{83.05018} +\pgfmath@def{acos}{122}{82.99245} \pgfmath@def{acos}{123}{82.93472} +\pgfmath@def{acos}{124}{82.87698} \pgfmath@def{acos}{125}{82.81924} +\pgfmath@def{acos}{126}{82.76149} \pgfmath@def{acos}{127}{82.70373} +\pgfmath@def{acos}{128}{82.64596} \pgfmath@def{acos}{129}{82.58819} +\pgfmath@def{acos}{130}{82.53040} \pgfmath@def{acos}{131}{82.47261} +\pgfmath@def{acos}{132}{82.41482} \pgfmath@def{acos}{133}{82.35701} +\pgfmath@def{acos}{134}{82.29920} \pgfmath@def{acos}{135}{82.24138} +\pgfmath@def{acos}{136}{82.18355} \pgfmath@def{acos}{137}{82.12571} +\pgfmath@def{acos}{138}{82.06786} \pgfmath@def{acos}{139}{82.01001} +\pgfmath@def{acos}{140}{81.95215} \pgfmath@def{acos}{141}{81.89428} +\pgfmath@def{acos}{142}{81.83640} \pgfmath@def{acos}{143}{81.77851} +\pgfmath@def{acos}{144}{81.72062} \pgfmath@def{acos}{145}{81.66272} +\pgfmath@def{acos}{146}{81.60480} \pgfmath@def{acos}{147}{81.54688} +\pgfmath@def{acos}{148}{81.48895} \pgfmath@def{acos}{149}{81.43102} +\pgfmath@def{acos}{150}{81.37307} \pgfmath@def{acos}{151}{81.31511} +\pgfmath@def{acos}{152}{81.25715} \pgfmath@def{acos}{153}{81.19917} +\pgfmath@def{acos}{154}{81.14119} \pgfmath@def{acos}{155}{81.08320} +\pgfmath@def{acos}{156}{81.02520} \pgfmath@def{acos}{157}{80.96719} +\pgfmath@def{acos}{158}{80.90917} \pgfmath@def{acos}{159}{80.85114} +\pgfmath@def{acos}{160}{80.79310} \pgfmath@def{acos}{161}{80.73505} +\pgfmath@def{acos}{162}{80.67699} \pgfmath@def{acos}{163}{80.61893} +\pgfmath@def{acos}{164}{80.56085} \pgfmath@def{acos}{165}{80.50276} +\pgfmath@def{acos}{166}{80.44466} \pgfmath@def{acos}{167}{80.38656} +\pgfmath@def{acos}{168}{80.32844} \pgfmath@def{acos}{169}{80.27031} +\pgfmath@def{acos}{170}{80.21218} \pgfmath@def{acos}{171}{80.15403} +\pgfmath@def{acos}{172}{80.09587} \pgfmath@def{acos}{173}{80.03770} +\pgfmath@def{acos}{174}{79.97953} \pgfmath@def{acos}{175}{79.92134} +\pgfmath@def{acos}{176}{79.86314} \pgfmath@def{acos}{177}{79.80493} +\pgfmath@def{acos}{178}{79.74671} \pgfmath@def{acos}{179}{79.68848} +\pgfmath@def{acos}{180}{79.63024} \pgfmath@def{acos}{181}{79.57198} +\pgfmath@def{acos}{182}{79.51372} \pgfmath@def{acos}{183}{79.45545} +\pgfmath@def{acos}{184}{79.39716} \pgfmath@def{acos}{185}{79.33886} +\pgfmath@def{acos}{186}{79.28056} \pgfmath@def{acos}{187}{79.22224} +\pgfmath@def{acos}{188}{79.16391} \pgfmath@def{acos}{189}{79.10556} +\pgfmath@def{acos}{190}{79.04721} \pgfmath@def{acos}{191}{78.98885} +\pgfmath@def{acos}{192}{78.93047} \pgfmath@def{acos}{193}{78.87208} +\pgfmath@def{acos}{194}{78.81368} \pgfmath@def{acos}{195}{78.75527} +\pgfmath@def{acos}{196}{78.69685} \pgfmath@def{acos}{197}{78.63841} +\pgfmath@def{acos}{198}{78.57997} \pgfmath@def{acos}{199}{78.52151} +\pgfmath@def{acos}{200}{78.46304} \pgfmath@def{acos}{201}{78.40455} +\pgfmath@def{acos}{202}{78.34606} \pgfmath@def{acos}{203}{78.28755} +\pgfmath@def{acos}{204}{78.22903} \pgfmath@def{acos}{205}{78.17050} +\pgfmath@def{acos}{206}{78.11195} \pgfmath@def{acos}{207}{78.05339} +\pgfmath@def{acos}{208}{77.99482} \pgfmath@def{acos}{209}{77.93624} +\pgfmath@def{acos}{210}{77.87764} \pgfmath@def{acos}{211}{77.81903} +\pgfmath@def{acos}{212}{77.76041} \pgfmath@def{acos}{213}{77.70178} +\pgfmath@def{acos}{214}{77.64313} \pgfmath@def{acos}{215}{77.58447} +\pgfmath@def{acos}{216}{77.52579} \pgfmath@def{acos}{217}{77.46711} +\pgfmath@def{acos}{218}{77.40841} \pgfmath@def{acos}{219}{77.34969} +\pgfmath@def{acos}{220}{77.29096} \pgfmath@def{acos}{221}{77.23222} +\pgfmath@def{acos}{222}{77.17347} \pgfmath@def{acos}{223}{77.11470} +\pgfmath@def{acos}{224}{77.05591} \pgfmath@def{acos}{225}{76.99712} +\pgfmath@def{acos}{226}{76.93831} \pgfmath@def{acos}{227}{76.87948} +\pgfmath@def{acos}{228}{76.82064} \pgfmath@def{acos}{229}{76.76179} +\pgfmath@def{acos}{230}{76.70292} \pgfmath@def{acos}{231}{76.64404} +\pgfmath@def{acos}{232}{76.58515} \pgfmath@def{acos}{233}{76.52624} +\pgfmath@def{acos}{234}{76.46731} \pgfmath@def{acos}{235}{76.40837} +\pgfmath@def{acos}{236}{76.34942} \pgfmath@def{acos}{237}{76.29045} +\pgfmath@def{acos}{238}{76.23147} \pgfmath@def{acos}{239}{76.17247} +\pgfmath@def{acos}{240}{76.11346} \pgfmath@def{acos}{241}{76.05443} +\pgfmath@def{acos}{242}{75.99538} \pgfmath@def{acos}{243}{75.93632} +\pgfmath@def{acos}{244}{75.87725} \pgfmath@def{acos}{245}{75.81816} +\pgfmath@def{acos}{246}{75.75906} \pgfmath@def{acos}{247}{75.69994} +\pgfmath@def{acos}{248}{75.64080} \pgfmath@def{acos}{249}{75.58165} +\pgfmath@def{acos}{250}{75.52248} \pgfmath@def{acos}{251}{75.46330} +\pgfmath@def{acos}{252}{75.40410} \pgfmath@def{acos}{253}{75.34489} +\pgfmath@def{acos}{254}{75.28566} \pgfmath@def{acos}{255}{75.22641} +\pgfmath@def{acos}{256}{75.16715} \pgfmath@def{acos}{257}{75.10787} +\pgfmath@def{acos}{258}{75.04857} \pgfmath@def{acos}{259}{74.98926} +\pgfmath@def{acos}{260}{74.92993} \pgfmath@def{acos}{261}{74.87059} +\pgfmath@def{acos}{262}{74.81123} \pgfmath@def{acos}{263}{74.75185} +\pgfmath@def{acos}{264}{74.69245} \pgfmath@def{acos}{265}{74.63304} +\pgfmath@def{acos}{266}{74.57361} \pgfmath@def{acos}{267}{74.51417} +\pgfmath@def{acos}{268}{74.45471} \pgfmath@def{acos}{269}{74.39523} +\pgfmath@def{acos}{270}{74.33573} \pgfmath@def{acos}{271}{74.27621} +\pgfmath@def{acos}{272}{74.21668} \pgfmath@def{acos}{273}{74.15713} +\pgfmath@def{acos}{274}{74.09757} \pgfmath@def{acos}{275}{74.03798} +\pgfmath@def{acos}{276}{73.97838} \pgfmath@def{acos}{277}{73.91876} +\pgfmath@def{acos}{278}{73.85912} \pgfmath@def{acos}{279}{73.79946} +\pgfmath@def{acos}{280}{73.73979} \pgfmath@def{acos}{281}{73.68010} +\pgfmath@def{acos}{282}{73.62039} \pgfmath@def{acos}{283}{73.56066} +\pgfmath@def{acos}{284}{73.50091} \pgfmath@def{acos}{285}{73.44115} +\pgfmath@def{acos}{286}{73.38136} \pgfmath@def{acos}{287}{73.32156} +\pgfmath@def{acos}{288}{73.26174} \pgfmath@def{acos}{289}{73.20190} +\pgfmath@def{acos}{290}{73.14204} \pgfmath@def{acos}{291}{73.08216} +\pgfmath@def{acos}{292}{73.02226} \pgfmath@def{acos}{293}{72.96235} +\pgfmath@def{acos}{294}{72.90241} \pgfmath@def{acos}{295}{72.84246} +\pgfmath@def{acos}{296}{72.78248} \pgfmath@def{acos}{297}{72.72249} +\pgfmath@def{acos}{298}{72.66248} \pgfmath@def{acos}{299}{72.60244} +\pgfmath@def{acos}{300}{72.54239} \pgfmath@def{acos}{301}{72.48232} +\pgfmath@def{acos}{302}{72.42223} \pgfmath@def{acos}{303}{72.36212} +\pgfmath@def{acos}{304}{72.30198} \pgfmath@def{acos}{305}{72.24183} +\pgfmath@def{acos}{306}{72.18166} \pgfmath@def{acos}{307}{72.12147} +\pgfmath@def{acos}{308}{72.06125} \pgfmath@def{acos}{309}{72.00102} +\pgfmath@def{acos}{310}{71.94077} \pgfmath@def{acos}{311}{71.88049} +\pgfmath@def{acos}{312}{71.82019} \pgfmath@def{acos}{313}{71.75988} +\pgfmath@def{acos}{314}{71.69954} \pgfmath@def{acos}{315}{71.63918} +\pgfmath@def{acos}{316}{71.57880} \pgfmath@def{acos}{317}{71.51840} +\pgfmath@def{acos}{318}{71.45798} \pgfmath@def{acos}{319}{71.39754} +\pgfmath@def{acos}{320}{71.33707} \pgfmath@def{acos}{321}{71.27658} +\pgfmath@def{acos}{322}{71.21608} \pgfmath@def{acos}{323}{71.15555} +\pgfmath@def{acos}{324}{71.09499} \pgfmath@def{acos}{325}{71.03442} +\pgfmath@def{acos}{326}{70.97382} \pgfmath@def{acos}{327}{70.91321} +\pgfmath@def{acos}{328}{70.85257} \pgfmath@def{acos}{329}{70.79190} +\pgfmath@def{acos}{330}{70.73122} \pgfmath@def{acos}{331}{70.67051} +\pgfmath@def{acos}{332}{70.60978} \pgfmath@def{acos}{333}{70.54903} +\pgfmath@def{acos}{334}{70.48826} \pgfmath@def{acos}{335}{70.42746} +\pgfmath@def{acos}{336}{70.36664} \pgfmath@def{acos}{337}{70.30579} +\pgfmath@def{acos}{338}{70.24493} \pgfmath@def{acos}{339}{70.18404} +\pgfmath@def{acos}{340}{70.12312} \pgfmath@def{acos}{341}{70.06218} +\pgfmath@def{acos}{342}{70.00122} \pgfmath@def{acos}{343}{69.94024} +\pgfmath@def{acos}{344}{69.87923} \pgfmath@def{acos}{345}{69.81820} +\pgfmath@def{acos}{346}{69.75714} \pgfmath@def{acos}{347}{69.69606} +\pgfmath@def{acos}{348}{69.63496} \pgfmath@def{acos}{349}{69.57383} +\pgfmath@def{acos}{350}{69.51268} \pgfmath@def{acos}{351}{69.45150} +\pgfmath@def{acos}{352}{69.39030} \pgfmath@def{acos}{353}{69.32908} +\pgfmath@def{acos}{354}{69.26783} \pgfmath@def{acos}{355}{69.20655} +\pgfmath@def{acos}{356}{69.14525} \pgfmath@def{acos}{357}{69.08393} +\pgfmath@def{acos}{358}{69.02258} \pgfmath@def{acos}{359}{68.96120} +\pgfmath@def{acos}{360}{68.89980} \pgfmath@def{acos}{361}{68.83837} +\pgfmath@def{acos}{362}{68.77692} \pgfmath@def{acos}{363}{68.71544} +\pgfmath@def{acos}{364}{68.65394} \pgfmath@def{acos}{365}{68.59241} +\pgfmath@def{acos}{366}{68.53086} \pgfmath@def{acos}{367}{68.46928} +\pgfmath@def{acos}{368}{68.40767} \pgfmath@def{acos}{369}{68.34604} +\pgfmath@def{acos}{370}{68.28438} \pgfmath@def{acos}{371}{68.22269} +\pgfmath@def{acos}{372}{68.16098} \pgfmath@def{acos}{373}{68.09924} +\pgfmath@def{acos}{374}{68.03748} \pgfmath@def{acos}{375}{67.97568} +\pgfmath@def{acos}{376}{67.91386} \pgfmath@def{acos}{377}{67.85202} +\pgfmath@def{acos}{378}{67.79014} \pgfmath@def{acos}{379}{67.72824} +\pgfmath@def{acos}{380}{67.66631} \pgfmath@def{acos}{381}{67.60436} +\pgfmath@def{acos}{382}{67.54237} \pgfmath@def{acos}{383}{67.48036} +\pgfmath@def{acos}{384}{67.41832} \pgfmath@def{acos}{385}{67.35626} +\pgfmath@def{acos}{386}{67.29416} \pgfmath@def{acos}{387}{67.23204} +\pgfmath@def{acos}{388}{67.16988} \pgfmath@def{acos}{389}{67.10770} +\pgfmath@def{acos}{390}{67.04550} \pgfmath@def{acos}{391}{66.98326} +\pgfmath@def{acos}{392}{66.92099} \pgfmath@def{acos}{393}{66.85870} +\pgfmath@def{acos}{394}{66.79637} \pgfmath@def{acos}{395}{66.73402} +\pgfmath@def{acos}{396}{66.67164} \pgfmath@def{acos}{397}{66.60923} +\pgfmath@def{acos}{398}{66.54679} \pgfmath@def{acos}{399}{66.48432} +\pgfmath@def{acos}{400}{66.42182} \pgfmath@def{acos}{401}{66.35929} +\pgfmath@def{acos}{402}{66.29673} \pgfmath@def{acos}{403}{66.23414} +\pgfmath@def{acos}{404}{66.17152} \pgfmath@def{acos}{405}{66.10887} +\pgfmath@def{acos}{406}{66.04619} \pgfmath@def{acos}{407}{65.98348} +\pgfmath@def{acos}{408}{65.92074} \pgfmath@def{acos}{409}{65.85796} +\pgfmath@def{acos}{410}{65.79516} \pgfmath@def{acos}{411}{65.73233} +\pgfmath@def{acos}{412}{65.66946} \pgfmath@def{acos}{413}{65.60657} +\pgfmath@def{acos}{414}{65.54364} \pgfmath@def{acos}{415}{65.48068} +\pgfmath@def{acos}{416}{65.41769} \pgfmath@def{acos}{417}{65.35467} +\pgfmath@def{acos}{418}{65.29161} \pgfmath@def{acos}{419}{65.22853} +\pgfmath@def{acos}{420}{65.16541} \pgfmath@def{acos}{421}{65.10226} +\pgfmath@def{acos}{422}{65.03908} \pgfmath@def{acos}{423}{64.97586} +\pgfmath@def{acos}{424}{64.91261} \pgfmath@def{acos}{425}{64.84933} +\pgfmath@def{acos}{426}{64.78602} \pgfmath@def{acos}{427}{64.72267} +\pgfmath@def{acos}{428}{64.65929} \pgfmath@def{acos}{429}{64.59588} +\pgfmath@def{acos}{430}{64.53244} \pgfmath@def{acos}{431}{64.46896} +\pgfmath@def{acos}{432}{64.40544} \pgfmath@def{acos}{433}{64.34190} +\pgfmath@def{acos}{434}{64.27832} \pgfmath@def{acos}{435}{64.21470} +\pgfmath@def{acos}{436}{64.15105} \pgfmath@def{acos}{437}{64.08737} +\pgfmath@def{acos}{438}{64.02365} \pgfmath@def{acos}{439}{63.95990} +\pgfmath@def{acos}{440}{63.89611} \pgfmath@def{acos}{441}{63.83229} +\pgfmath@def{acos}{442}{63.76844} \pgfmath@def{acos}{443}{63.70455} +\pgfmath@def{acos}{444}{63.64062} \pgfmath@def{acos}{445}{63.57666} +\pgfmath@def{acos}{446}{63.51266} \pgfmath@def{acos}{447}{63.44863} +\pgfmath@def{acos}{448}{63.38456} \pgfmath@def{acos}{449}{63.32045} +\pgfmath@def{acos}{450}{63.25631} \pgfmath@def{acos}{451}{63.19213} +\pgfmath@def{acos}{452}{63.12792} \pgfmath@def{acos}{453}{63.06367} +\pgfmath@def{acos}{454}{62.99938} \pgfmath@def{acos}{455}{62.93506} +\pgfmath@def{acos}{456}{62.87070} \pgfmath@def{acos}{457}{62.80630} +\pgfmath@def{acos}{458}{62.74187} \pgfmath@def{acos}{459}{62.67740} +\pgfmath@def{acos}{460}{62.61289} \pgfmath@def{acos}{461}{62.54834} +\pgfmath@def{acos}{462}{62.48376} \pgfmath@def{acos}{463}{62.41913} +\pgfmath@def{acos}{464}{62.35447} \pgfmath@def{acos}{465}{62.28977} +\pgfmath@def{acos}{466}{62.22504} \pgfmath@def{acos}{467}{62.16026} +\pgfmath@def{acos}{468}{62.09545} \pgfmath@def{acos}{469}{62.03059} +\pgfmath@def{acos}{470}{61.96570} \pgfmath@def{acos}{471}{61.90077} +\pgfmath@def{acos}{472}{61.83580} \pgfmath@def{acos}{473}{61.77079} +\pgfmath@def{acos}{474}{61.70574} \pgfmath@def{acos}{475}{61.64065} +\pgfmath@def{acos}{476}{61.57552} \pgfmath@def{acos}{477}{61.51035} +\pgfmath@def{acos}{478}{61.44514} \pgfmath@def{acos}{479}{61.37988} +\pgfmath@def{acos}{480}{61.31459} \pgfmath@def{acos}{481}{61.24926} +\pgfmath@def{acos}{482}{61.18389} \pgfmath@def{acos}{483}{61.11847} +\pgfmath@def{acos}{484}{61.05302} \pgfmath@def{acos}{485}{60.98752} +\pgfmath@def{acos}{486}{60.92199} \pgfmath@def{acos}{487}{60.85641} +\pgfmath@def{acos}{488}{60.79078} \pgfmath@def{acos}{489}{60.72512} +\pgfmath@def{acos}{490}{60.65941} \pgfmath@def{acos}{491}{60.59367} +\pgfmath@def{acos}{492}{60.52787} \pgfmath@def{acos}{493}{60.46204} +\pgfmath@def{acos}{494}{60.39616} \pgfmath@def{acos}{495}{60.33025} +\pgfmath@def{acos}{496}{60.26428} \pgfmath@def{acos}{497}{60.19828} +\pgfmath@def{acos}{498}{60.13223} \pgfmath@def{acos}{499}{60.06613} +\pgfmath@def{acos}{500}{60.00000} \pgfmath@def{acos}{501}{59.93381} +\pgfmath@def{acos}{502}{59.86759} \pgfmath@def{acos}{503}{59.80132} +\pgfmath@def{acos}{504}{59.73500} \pgfmath@def{acos}{505}{59.66864} +\pgfmath@def{acos}{506}{59.60224} \pgfmath@def{acos}{507}{59.53579} +\pgfmath@def{acos}{508}{59.46929} \pgfmath@def{acos}{509}{59.40275} +\pgfmath@def{acos}{510}{59.33617} \pgfmath@def{acos}{511}{59.26953} +\pgfmath@def{acos}{512}{59.20285} \pgfmath@def{acos}{513}{59.13613} +\pgfmath@def{acos}{514}{59.06936} \pgfmath@def{acos}{515}{59.00254} +\pgfmath@def{acos}{516}{58.93568} \pgfmath@def{acos}{517}{58.86876} +\pgfmath@def{acos}{518}{58.80180} \pgfmath@def{acos}{519}{58.73480} +\pgfmath@def{acos}{520}{58.66774} \pgfmath@def{acos}{521}{58.60064} +\pgfmath@def{acos}{522}{58.53349} \pgfmath@def{acos}{523}{58.46629} +\pgfmath@def{acos}{524}{58.39905} \pgfmath@def{acos}{525}{58.33175} +\pgfmath@def{acos}{526}{58.26441} \pgfmath@def{acos}{527}{58.19702} +\pgfmath@def{acos}{528}{58.12957} \pgfmath@def{acos}{529}{58.06208} +\pgfmath@def{acos}{530}{57.99454} \pgfmath@def{acos}{531}{57.92695} +\pgfmath@def{acos}{532}{57.85931} \pgfmath@def{acos}{533}{57.79162} +\pgfmath@def{acos}{534}{57.72388} \pgfmath@def{acos}{535}{57.65608} +\pgfmath@def{acos}{536}{57.58824} \pgfmath@def{acos}{537}{57.52035} +\pgfmath@def{acos}{538}{57.45240} \pgfmath@def{acos}{539}{57.38441} +\pgfmath@def{acos}{540}{57.31636} \pgfmath@def{acos}{541}{57.24826} +\pgfmath@def{acos}{542}{57.18010} \pgfmath@def{acos}{543}{57.11190} +\pgfmath@def{acos}{544}{57.04364} \pgfmath@def{acos}{545}{56.97533} +\pgfmath@def{acos}{546}{56.90697} \pgfmath@def{acos}{547}{56.83855} +\pgfmath@def{acos}{548}{56.77008} \pgfmath@def{acos}{549}{56.70156} +\pgfmath@def{acos}{550}{56.63298} \pgfmath@def{acos}{551}{56.56435} +\pgfmath@def{acos}{552}{56.49567} \pgfmath@def{acos}{553}{56.42693} +\pgfmath@def{acos}{554}{56.35813} \pgfmath@def{acos}{555}{56.28928} +\pgfmath@def{acos}{556}{56.22038} \pgfmath@def{acos}{557}{56.15141} +\pgfmath@def{acos}{558}{56.08240} \pgfmath@def{acos}{559}{56.01333} +\pgfmath@def{acos}{560}{55.94420} \pgfmath@def{acos}{561}{55.87501} +\pgfmath@def{acos}{562}{55.80577} \pgfmath@def{acos}{563}{55.73647} +\pgfmath@def{acos}{564}{55.66712} \pgfmath@def{acos}{565}{55.59770} +\pgfmath@def{acos}{566}{55.52823} \pgfmath@def{acos}{567}{55.45871} +\pgfmath@def{acos}{568}{55.38912} \pgfmath@def{acos}{569}{55.31947} +\pgfmath@def{acos}{570}{55.24977} \pgfmath@def{acos}{571}{55.18001} +\pgfmath@def{acos}{572}{55.11019} \pgfmath@def{acos}{573}{55.04030} +\pgfmath@def{acos}{574}{54.97036} \pgfmath@def{acos}{575}{54.90036} +\pgfmath@def{acos}{576}{54.83030} \pgfmath@def{acos}{577}{54.76018} +\pgfmath@def{acos}{578}{54.69000} \pgfmath@def{acos}{579}{54.61976} +\pgfmath@def{acos}{580}{54.54945} \pgfmath@def{acos}{581}{54.47909} +\pgfmath@def{acos}{582}{54.40866} \pgfmath@def{acos}{583}{54.33817} +\pgfmath@def{acos}{584}{54.26762} \pgfmath@def{acos}{585}{54.19701} +\pgfmath@def{acos}{586}{54.12633} \pgfmath@def{acos}{587}{54.05559} +\pgfmath@def{acos}{588}{53.98479} \pgfmath@def{acos}{589}{53.91392} +\pgfmath@def{acos}{590}{53.84299} \pgfmath@def{acos}{591}{53.77199} +\pgfmath@def{acos}{592}{53.70093} \pgfmath@def{acos}{593}{53.62981} +\pgfmath@def{acos}{594}{53.55862} \pgfmath@def{acos}{595}{53.48736} +\pgfmath@def{acos}{596}{53.41604} \pgfmath@def{acos}{597}{53.34466} +\pgfmath@def{acos}{598}{53.27320} \pgfmath@def{acos}{599}{53.20168} +\pgfmath@def{acos}{600}{53.13010} \pgfmath@def{acos}{601}{53.05844} +\pgfmath@def{acos}{602}{52.98672} \pgfmath@def{acos}{603}{52.91494} +\pgfmath@def{acos}{604}{52.84308} \pgfmath@def{acos}{605}{52.77115} +\pgfmath@def{acos}{606}{52.69916} \pgfmath@def{acos}{607}{52.62710} +\pgfmath@def{acos}{608}{52.55497} \pgfmath@def{acos}{609}{52.48276} +\pgfmath@def{acos}{610}{52.41049} \pgfmath@def{acos}{611}{52.33815} +\pgfmath@def{acos}{612}{52.26574} \pgfmath@def{acos}{613}{52.19326} +\pgfmath@def{acos}{614}{52.12070} \pgfmath@def{acos}{615}{52.04808} +\pgfmath@def{acos}{616}{51.97538} \pgfmath@def{acos}{617}{51.90261} +\pgfmath@def{acos}{618}{51.82976} \pgfmath@def{acos}{619}{51.75685} +\pgfmath@def{acos}{620}{51.68386} \pgfmath@def{acos}{621}{51.61080} +\pgfmath@def{acos}{622}{51.53766} \pgfmath@def{acos}{623}{51.46445} +\pgfmath@def{acos}{624}{51.39117} \pgfmath@def{acos}{625}{51.31781} +\pgfmath@def{acos}{626}{51.24437} \pgfmath@def{acos}{627}{51.17086} +\pgfmath@def{acos}{628}{51.09728} \pgfmath@def{acos}{629}{51.02361} +\pgfmath@def{acos}{630}{50.94987} \pgfmath@def{acos}{631}{50.87606} +\pgfmath@def{acos}{632}{50.80216} \pgfmath@def{acos}{633}{50.72819} +\pgfmath@def{acos}{634}{50.65414} \pgfmath@def{acos}{635}{50.58001} +\pgfmath@def{acos}{636}{50.50580} \pgfmath@def{acos}{637}{50.43152} +\pgfmath@def{acos}{638}{50.35715} \pgfmath@def{acos}{639}{50.28270} +\pgfmath@def{acos}{640}{50.20818} \pgfmath@def{acos}{641}{50.13357} +\pgfmath@def{acos}{642}{50.05888} \pgfmath@def{acos}{643}{49.98411} +\pgfmath@def{acos}{644}{49.90926} \pgfmath@def{acos}{645}{49.83432} +\pgfmath@def{acos}{646}{49.75930} \pgfmath@def{acos}{647}{49.68420} +\pgfmath@def{acos}{648}{49.60902} \pgfmath@def{acos}{649}{49.53375} +\pgfmath@def{acos}{650}{49.45839} \pgfmath@def{acos}{651}{49.38296} +\pgfmath@def{acos}{652}{49.30743} \pgfmath@def{acos}{653}{49.23182} +\pgfmath@def{acos}{654}{49.15613} \pgfmath@def{acos}{655}{49.08035} +\pgfmath@def{acos}{656}{49.00448} \pgfmath@def{acos}{657}{48.92852} +\pgfmath@def{acos}{658}{48.85248} \pgfmath@def{acos}{659}{48.77634} +\pgfmath@def{acos}{660}{48.70012} \pgfmath@def{acos}{661}{48.62381} +\pgfmath@def{acos}{662}{48.54741} \pgfmath@def{acos}{663}{48.47092} +\pgfmath@def{acos}{664}{48.39434} \pgfmath@def{acos}{665}{48.31767} +\pgfmath@def{acos}{666}{48.24091} \pgfmath@def{acos}{667}{48.16405} +\pgfmath@def{acos}{668}{48.08710} \pgfmath@def{acos}{669}{48.01006} +\pgfmath@def{acos}{670}{47.93293} \pgfmath@def{acos}{671}{47.85570} +\pgfmath@def{acos}{672}{47.77838} \pgfmath@def{acos}{673}{47.70096} +\pgfmath@def{acos}{674}{47.62345} \pgfmath@def{acos}{675}{47.54585} +\pgfmath@def{acos}{676}{47.46814} \pgfmath@def{acos}{677}{47.39034} +\pgfmath@def{acos}{678}{47.31244} \pgfmath@def{acos}{679}{47.23445} +\pgfmath@def{acos}{680}{47.15635} \pgfmath@def{acos}{681}{47.07816} +\pgfmath@def{acos}{682}{46.99987} \pgfmath@def{acos}{683}{46.92147} +\pgfmath@def{acos}{684}{46.84298} \pgfmath@def{acos}{685}{46.76439} +\pgfmath@def{acos}{686}{46.68569} \pgfmath@def{acos}{687}{46.60690} +\pgfmath@def{acos}{688}{46.52800} \pgfmath@def{acos}{689}{46.44899} +\pgfmath@def{acos}{690}{46.36989} \pgfmath@def{acos}{691}{46.29068} +\pgfmath@def{acos}{692}{46.21136} \pgfmath@def{acos}{693}{46.13194} +\pgfmath@def{acos}{694}{46.05241} \pgfmath@def{acos}{695}{45.97278} +\pgfmath@def{acos}{696}{45.89304} \pgfmath@def{acos}{697}{45.81319} +\pgfmath@def{acos}{698}{45.73323} \pgfmath@def{acos}{699}{45.65317} +\pgfmath@def{acos}{700}{45.57299} \pgfmath@def{acos}{701}{45.49271} +\pgfmath@def{acos}{702}{45.41231} \pgfmath@def{acos}{703}{45.33180} +\pgfmath@def{acos}{704}{45.25118} \pgfmath@def{acos}{705}{45.17045} +\pgfmath@def{acos}{706}{45.08961} \pgfmath@def{acos}{707}{45.00865} +\pgfmath@def{acos}{708}{44.92757} \pgfmath@def{acos}{709}{44.84638} +\pgfmath@def{acos}{710}{44.76508} \pgfmath@def{acos}{711}{44.68366} +\pgfmath@def{acos}{712}{44.60212} \pgfmath@def{acos}{713}{44.52046} +\pgfmath@def{acos}{714}{44.43869} \pgfmath@def{acos}{715}{44.35680} +\pgfmath@def{acos}{716}{44.27478} \pgfmath@def{acos}{717}{44.19265} +\pgfmath@def{acos}{718}{44.11039} \pgfmath@def{acos}{719}{44.02802} +\pgfmath@def{acos}{720}{43.94552} \pgfmath@def{acos}{721}{43.86289} +\pgfmath@def{acos}{722}{43.78014} \pgfmath@def{acos}{723}{43.69727} +\pgfmath@def{acos}{724}{43.61427} \pgfmath@def{acos}{725}{43.53115} +\pgfmath@def{acos}{726}{43.44790} \pgfmath@def{acos}{727}{43.36452} +\pgfmath@def{acos}{728}{43.28101} \pgfmath@def{acos}{729}{43.19737} +\pgfmath@def{acos}{730}{43.11360} \pgfmath@def{acos}{731}{43.02970} +\pgfmath@def{acos}{732}{42.94567} \pgfmath@def{acos}{733}{42.86151} +\pgfmath@def{acos}{734}{42.77721} \pgfmath@def{acos}{735}{42.69278} +\pgfmath@def{acos}{736}{42.60821} \pgfmath@def{acos}{737}{42.52351} +\pgfmath@def{acos}{738}{42.43867} \pgfmath@def{acos}{739}{42.35370} +\pgfmath@def{acos}{740}{42.26858} \pgfmath@def{acos}{741}{42.18333} +\pgfmath@def{acos}{742}{42.09793} \pgfmath@def{acos}{743}{42.01240} +\pgfmath@def{acos}{744}{41.92672} \pgfmath@def{acos}{745}{41.84090} +\pgfmath@def{acos}{746}{41.75493} \pgfmath@def{acos}{747}{41.66882} +\pgfmath@def{acos}{748}{41.58257} \pgfmath@def{acos}{749}{41.49617} +\pgfmath@def{acos}{750}{41.40962} \pgfmath@def{acos}{751}{41.32292} +\pgfmath@def{acos}{752}{41.23607} \pgfmath@def{acos}{753}{41.14908} +\pgfmath@def{acos}{754}{41.06193} \pgfmath@def{acos}{755}{40.97463} +\pgfmath@def{acos}{756}{40.88717} \pgfmath@def{acos}{757}{40.79956} +\pgfmath@def{acos}{758}{40.71180} \pgfmath@def{acos}{759}{40.62388} +\pgfmath@def{acos}{760}{40.53580} \pgfmath@def{acos}{761}{40.44756} +\pgfmath@def{acos}{762}{40.35916} \pgfmath@def{acos}{763}{40.27061} +\pgfmath@def{acos}{764}{40.18189} \pgfmath@def{acos}{765}{40.09300} +\pgfmath@def{acos}{766}{40.00396} \pgfmath@def{acos}{767}{39.91474} +\pgfmath@def{acos}{768}{39.82537} \pgfmath@def{acos}{769}{39.73582} +\pgfmath@def{acos}{770}{39.64611} \pgfmath@def{acos}{771}{39.55622} +\pgfmath@def{acos}{772}{39.46617} \pgfmath@def{acos}{773}{39.37594} +\pgfmath@def{acos}{774}{39.28554} \pgfmath@def{acos}{775}{39.19496} +\pgfmath@def{acos}{776}{39.10421} \pgfmath@def{acos}{777}{39.01328} +\pgfmath@def{acos}{778}{38.92218} \pgfmath@def{acos}{779}{38.83089} +\pgfmath@def{acos}{780}{38.73942} \pgfmath@def{acos}{781}{38.64777} +\pgfmath@def{acos}{782}{38.55594} \pgfmath@def{acos}{783}{38.46392} +\pgfmath@def{acos}{784}{38.37171} \pgfmath@def{acos}{785}{38.27932} +\pgfmath@def{acos}{786}{38.18673} \pgfmath@def{acos}{787}{38.09396} +\pgfmath@def{acos}{788}{38.00100} \pgfmath@def{acos}{789}{37.90784} +\pgfmath@def{acos}{790}{37.81448} \pgfmath@def{acos}{791}{37.72093} +\pgfmath@def{acos}{792}{37.62719} \pgfmath@def{acos}{793}{37.53324} +\pgfmath@def{acos}{794}{37.43909} \pgfmath@def{acos}{795}{37.34474} +\pgfmath@def{acos}{796}{37.25019} \pgfmath@def{acos}{797}{37.15542} +\pgfmath@def{acos}{798}{37.06046} \pgfmath@def{acos}{799}{36.96528} +\pgfmath@def{acos}{800}{36.86989} \pgfmath@def{acos}{801}{36.77429} +\pgfmath@def{acos}{802}{36.67848} \pgfmath@def{acos}{803}{36.58245} +\pgfmath@def{acos}{804}{36.48621} \pgfmath@def{acos}{805}{36.38974} +\pgfmath@def{acos}{806}{36.29305} \pgfmath@def{acos}{807}{36.19615} +\pgfmath@def{acos}{808}{36.09901} \pgfmath@def{acos}{809}{36.00165} +\pgfmath@def{acos}{810}{35.90406} \pgfmath@def{acos}{811}{35.80625} +\pgfmath@def{acos}{812}{35.70820} \pgfmath@def{acos}{813}{35.60991} +\pgfmath@def{acos}{814}{35.51139} \pgfmath@def{acos}{815}{35.41263} +\pgfmath@def{acos}{816}{35.31364} \pgfmath@def{acos}{817}{35.21440} +\pgfmath@def{acos}{818}{35.11491} \pgfmath@def{acos}{819}{35.01518} +\pgfmath@def{acos}{820}{34.91520} \pgfmath@def{acos}{821}{34.81497} +\pgfmath@def{acos}{822}{34.71449} \pgfmath@def{acos}{823}{34.61375} +\pgfmath@def{acos}{824}{34.51276} \pgfmath@def{acos}{825}{34.41150} +\pgfmath@def{acos}{826}{34.30999} \pgfmath@def{acos}{827}{34.20821} +\pgfmath@def{acos}{828}{34.10616} \pgfmath@def{acos}{829}{34.00385} +\pgfmath@def{acos}{830}{33.90126} \pgfmath@def{acos}{831}{33.79840} +\pgfmath@def{acos}{832}{33.69526} \pgfmath@def{acos}{833}{33.59184} +\pgfmath@def{acos}{834}{33.48814} \pgfmath@def{acos}{835}{33.38416} +\pgfmath@def{acos}{836}{33.27989} \pgfmath@def{acos}{837}{33.17533} +\pgfmath@def{acos}{838}{33.07047} \pgfmath@def{acos}{839}{32.96532} +\pgfmath@def{acos}{840}{32.85988} \pgfmath@def{acos}{841}{32.75413} +\pgfmath@def{acos}{842}{32.64807} \pgfmath@def{acos}{843}{32.54171} +\pgfmath@def{acos}{844}{32.43504} \pgfmath@def{acos}{845}{32.32806} +\pgfmath@def{acos}{846}{32.22076} \pgfmath@def{acos}{847}{32.11314} +\pgfmath@def{acos}{848}{32.00520} \pgfmath@def{acos}{849}{31.89693} +\pgfmath@def{acos}{850}{31.78833} \pgfmath@def{acos}{851}{31.67939} +\pgfmath@def{acos}{852}{31.57012} \pgfmath@def{acos}{853}{31.46051} +\pgfmath@def{acos}{854}{31.35056} \pgfmath@def{acos}{855}{31.24026} +\pgfmath@def{acos}{856}{31.12961} \pgfmath@def{acos}{857}{31.01860} +\pgfmath@def{acos}{858}{30.90724} \pgfmath@def{acos}{859}{30.79551} +\pgfmath@def{acos}{860}{30.68341} \pgfmath@def{acos}{861}{30.57095} +\pgfmath@def{acos}{862}{30.45811} \pgfmath@def{acos}{863}{30.34489} +\pgfmath@def{acos}{864}{30.23128} \pgfmath@def{acos}{865}{30.11729} +\pgfmath@def{acos}{866}{30.00291} \pgfmath@def{acos}{867}{29.88813} +\pgfmath@def{acos}{868}{29.77294} \pgfmath@def{acos}{869}{29.65736} +\pgfmath@def{acos}{870}{29.54136} \pgfmath@def{acos}{871}{29.42494} +\pgfmath@def{acos}{872}{29.30810} \pgfmath@def{acos}{873}{29.19084} +\pgfmath@def{acos}{874}{29.07315} \pgfmath@def{acos}{875}{28.95502} +\pgfmath@def{acos}{876}{28.83645} \pgfmath@def{acos}{877}{28.71743} +\pgfmath@def{acos}{878}{28.59796} \pgfmath@def{acos}{879}{28.47803} +\pgfmath@def{acos}{880}{28.35763} \pgfmath@def{acos}{881}{28.23677} +\pgfmath@def{acos}{882}{28.11542} \pgfmath@def{acos}{883}{27.99360} +\pgfmath@def{acos}{884}{27.87128} \pgfmath@def{acos}{885}{27.74847} +\pgfmath@def{acos}{886}{27.62516} \pgfmath@def{acos}{887}{27.50134} +\pgfmath@def{acos}{888}{27.37700} \pgfmath@def{acos}{889}{27.25214} +\pgfmath@def{acos}{890}{27.12675} \pgfmath@def{acos}{891}{27.00082} +\pgfmath@def{acos}{892}{26.87434} \pgfmath@def{acos}{893}{26.74731} +\pgfmath@def{acos}{894}{26.61973} \pgfmath@def{acos}{895}{26.49157} +\pgfmath@def{acos}{896}{26.36283} \pgfmath@def{acos}{897}{26.23351} +\pgfmath@def{acos}{898}{26.10359} \pgfmath@def{acos}{899}{25.97306} +\pgfmath@def{acos}{900}{25.84193} \pgfmath@def{acos}{901}{25.71017} +\pgfmath@def{acos}{902}{25.57778} \pgfmath@def{acos}{903}{25.44475} +\pgfmath@def{acos}{904}{25.31106} \pgfmath@def{acos}{905}{25.17671} +\pgfmath@def{acos}{906}{25.04169} \pgfmath@def{acos}{907}{24.90598} +\pgfmath@def{acos}{908}{24.76958} \pgfmath@def{acos}{909}{24.63247} +\pgfmath@def{acos}{910}{24.49464} \pgfmath@def{acos}{911}{24.35608} +\pgfmath@def{acos}{912}{24.21678} \pgfmath@def{acos}{913}{24.07672} +\pgfmath@def{acos}{914}{23.93588} \pgfmath@def{acos}{915}{23.79427} +\pgfmath@def{acos}{916}{23.65185} \pgfmath@def{acos}{917}{23.50863} +\pgfmath@def{acos}{918}{23.36457} \pgfmath@def{acos}{919}{23.21967} +\pgfmath@def{acos}{920}{23.07391} \pgfmath@def{acos}{921}{22.92728} +\pgfmath@def{acos}{922}{22.77975} \pgfmath@def{acos}{923}{22.63132} +\pgfmath@def{acos}{924}{22.48195} \pgfmath@def{acos}{925}{22.33164} +\pgfmath@def{acos}{926}{22.18036} \pgfmath@def{acos}{927}{22.02810} +\pgfmath@def{acos}{928}{21.87483} \pgfmath@def{acos}{929}{21.72053} +\pgfmath@def{acos}{930}{21.56518} \pgfmath@def{acos}{931}{21.40876} +\pgfmath@def{acos}{932}{21.25124} \pgfmath@def{acos}{933}{21.09260} +\pgfmath@def{acos}{934}{20.93281} \pgfmath@def{acos}{935}{20.77185} +\pgfmath@def{acos}{936}{20.60969} \pgfmath@def{acos}{937}{20.44630} +\pgfmath@def{acos}{938}{20.28165} \pgfmath@def{acos}{939}{20.11570} +\pgfmath@def{acos}{940}{19.94844} \pgfmath@def{acos}{941}{19.77982} +\pgfmath@def{acos}{942}{19.60981} \pgfmath@def{acos}{943}{19.43837} +\pgfmath@def{acos}{944}{19.26546} \pgfmath@def{acos}{945}{19.09105} +\pgfmath@def{acos}{946}{18.91509} \pgfmath@def{acos}{947}{18.73754} +\pgfmath@def{acos}{948}{18.55835} \pgfmath@def{acos}{949}{18.37748} +\pgfmath@def{acos}{950}{18.19487} \pgfmath@def{acos}{951}{18.01047} +\pgfmath@def{acos}{952}{17.82423} \pgfmath@def{acos}{953}{17.63609} +\pgfmath@def{acos}{954}{17.44598} \pgfmath@def{acos}{955}{17.25385} +\pgfmath@def{acos}{956}{17.05962} \pgfmath@def{acos}{957}{16.86322} +\pgfmath@def{acos}{958}{16.66457} \pgfmath@def{acos}{959}{16.46359} +\pgfmath@def{acos}{960}{16.26020} \pgfmath@def{acos}{961}{16.05430} +\pgfmath@def{acos}{962}{15.84580} \pgfmath@def{acos}{963}{15.63459} +\pgfmath@def{acos}{964}{15.42057} \pgfmath@def{acos}{965}{15.20360} +\pgfmath@def{acos}{966}{14.98357} \pgfmath@def{acos}{967}{14.76033} +\pgfmath@def{acos}{968}{14.53374} \pgfmath@def{acos}{969}{14.30364} +\pgfmath@def{acos}{970}{14.06986} \pgfmath@def{acos}{971}{13.83221} +\pgfmath@def{acos}{972}{13.59049} \pgfmath@def{acos}{973}{13.34447} +\pgfmath@def{acos}{974}{13.09392} \pgfmath@def{acos}{975}{12.83856} +\pgfmath@def{acos}{976}{12.57811} \pgfmath@def{acos}{977}{12.31225} +\pgfmath@def{acos}{978}{12.04060} \pgfmath@def{acos}{979}{11.76278} +\pgfmath@def{acos}{980}{11.47834} \pgfmath@def{acos}{981}{11.18676} +\pgfmath@def{acos}{982}{10.88748} \pgfmath@def{acos}{983}{10.57984} +\pgfmath@def{acos}{984}{10.26309} \pgfmath@def{acos}{985}{9.93636} +\pgfmath@def{acos}{986}{9.59863} \pgfmath@def{acos}{987}{9.24870} +\pgfmath@def{acos}{988}{8.88512} \pgfmath@def{acos}{989}{8.50614} +\pgfmath@def{acos}{990}{8.10961} \pgfmath@def{acos}{991}{7.69281} +\pgfmath@def{acos}{992}{7.25224} \pgfmath@def{acos}{993}{6.78328} +\pgfmath@def{acos}{994}{6.27958} \pgfmath@def{acos}{995}{5.73196} +\pgfmath@def{acos}{996}{5.12640} \pgfmath@def{acos}{997}{4.43922} +\pgfmath@def{acos}{998}{3.62430} \pgfmath@def{acos}{999}{2.56255} +\pgfmath@def{acos}{1000}{0.00000} + + + +% Local Variables: +% tab-width: 2 +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex new file mode 100644 index 00000000000..d8837897558 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathode.code.tex @@ -0,0 +1,178 @@ +% Copyright 2011 by Christophe Jorssen +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. +\def\pgfmathode@stopadd{\pgfmathode@stopadd} + +\def\pgfmathode@addindextofunc[#1]#2{% + \begingroup + \gdef\pgfmathode@func{}% + \pgfmathode@addindextofunc@i[#1]#2\pgfmathode@stopadd} + +\def\pgfmathode@addindextofunc@i[#1]#2#3{% + \ifx#1#2 + \expandafter\gdef\expandafter\pgfmathode@func\expandafter{% + \pgfmathode@func #2[\pgfmathode@timeindex]}% + \else + \expandafter\gdef\expandafter\pgfmathode@func\expandafter{% + \pgfmathode@func #2}% + \fi + \ifx#3\pgfmathode@stopadd + \expandafter\gdef\expandafter\pgfmathode@func\expandafter{% + \expandafter{\pgfmathode@func}}% + \let\next\endgroup + \else + \def\next{\pgfmathode@addindextofunc@i[#1]#3}% + \fi + \next} + +%********************************************************************** +% Know limitation: fk cannot be a time function. Should be possible to +% use \Sol[0] as time in the set of equations. +%********************************************************************** + +% Numerically solve a differential system with 1st order Runge-Kutta +% (Euler method) +% dq1/dt = f1(t,q1,q2,...,qN) +% dq2/dt = f2(t,q1,q2,...,qN) +% ... +% dqN/dt = fN(t,q1,q2,...,qN) +% +% #1: A pgf array where the solution will be stored. +% At the end: +% #1 -> {{t(0),q1(t(0)),q2(t(0)),...,qN(t(0))}, +% {t(1),q1(t(1)),q2(t(1)),...,qN(t(1))}, +% ... +% {t(Nstep),q1(t(Nstep)),q2(t(Nstep)),...,qN(t(Nstep))}} +% #2: A pgf array with f1,f2,...,fN +% {f1} +% #3: A pgf array with initial conditions. +% {t(0),q1(t(0)),q2(t(0)),...,qN(t(0))} +% #4: t(Nstep) +% #5: Nstep (number of steps) +% +% * First order example: dq/dt = -q + 5 with IC=(t=0,q(0)=0) +% \pgfmathodeRKI{\Sol}{{-\Sol[1]+5}}{{0,0}}{3.5}{100} +% * Second order example: {dq1/dt=q2, dq2/dt=-q2/2-sin(q1)} (damped +% pendulum) +% \pgfmathodeRKI{\Sol}{{\Sol[2],-\Sol[2]/2-sin(deg(\Sol[1]))}}% +% {{0,-1,5}}{15}{50} + +\def\pgfmathode@generic@init@RK{% + \begingroup + % Sol array (#1) first element is given by the set of initial + % conditions (#3). We need to enclose it in brace so that is a now + % a "matrix" array. + \gdef#1{{#3}}% + % The set of rhs {f1(t,q1,q2,...,qN),...,fN(t,q1,q2,...,qN)} is + % given in terms of #1[0],#1[1],...,#1[N]. We need to transform to + % #1[\pgfmathode@timeindex][0],...,#1[\pgfmathode@timeindex][N], that is + % add [\pgfmathode@timeindex] after every occurence of #1 in #2. + % No need to brace #2 since it is already surounded by braces. The + % result is stored in \pgfmathode@func + \pgfmathode@addindextofunc[#1]#2% + % Set time step. Actually the number of time steps is #5-1, so we + % divide by (#5-1)+1 = #5. + \pgfmathsetmacro\pgfmathode@Sol@t{#1[0][0]}% + \pgfmathsetmacro\pgfmathode@Deltat{(#4-\pgfmathode@Sol@t)/#5}% + % Compute the order of the system: it is equal to the number of IC + % minus one (time). + \pgfmathsetmacro\pgfmathode@dimfunc{dim(#3)-1}% + \pgfmathsetmacro\pgfmathode@numstep{#5-1}} + +\def\pgfmathodeRKI#1#2#3#4#5{% + \pgfmathode@generic@init@RK + % Start the time loop for Runge-Kutta 1st order + \foreach \pgfmathode@timeindex in {0,...,\pgfmathode@numstep} {% + \message{Step \pgfmathode@timeindex...}% + % Start the function loop + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + % The RKI algorithm + % qk[t(i)] = Deltat*fk(t(i-1),q1(t(i-1)),...qN(t(i-1))) + + % qk[t(i-1)] + % Note: this part can be really slow due to array managment in + % pgfmath. + % TODO: find a better way (at least inside this loop) + \pgfmathparse{% + \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+ + #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}% + % Store the result in a helper macro + \expandafter\xdef\csname pgfmathode@Sol@\pgfmathode@funcindex + \endcsname{\pgfmathresult}% + } + % Store step i + \pgfmathparse{\pgfmathode@Sol@t+\pgfmathode@Deltat}% + \xdef\pgfmathode@Sol@t{\pgfmathresult}% + \xdef\pgfmathode@temp{}% + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + \ifx\pgfmathode@temp\pgfutil@empty + \xdef\pgfmathode@temp{% + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \else + \xdef\pgfmathode@temp{% + \pgfmathode@temp, + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \fi} + \xdef#1{% + {\expandafter\pgfutil@firstofone#1,% + {\pgfmathode@Sol@t,\pgfmathode@temp}}}% + } + \endgroup} + +% RKIV: far from working yet! +\def\pgfmathodeRKIV#1#2#3#4#5{% + \pgfmathode@generic@init@RK + % Start the time loop for Runge-Kutta 4th order + \foreach \pgfmathode@timeindex in {0,...,\pgfmathode@numstep} {% + \message{Step \pgfmathode@timeindex...}% + % Start the function loop + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + % The RKIV algorithm + % qk[t(i)] = qk[t(i-1)] + + % (1/6) * (j1k + 2j2k + 2j3k + j4k) + % where j1k = fk(t(i-1),q1(t(i-1)),...qN(t(i-1))) * Deltat + % j2k = fk(t(i-1)+.5*Deltat, + % q1(t(i-1))+.5*j11,...qN(t(i-1))+.5*j1N) * Deltat + % j3k = fk(t(i-1)+.5*Deltat, + % q1(t(i-1))+.5*j21,...qN(t(i-1))+.5*j2N) * Deltat + % j4k = fk(t(i-1)+Deltat, + % q1(t(i-1))+j31,...qN(t(i-1))+j3N) * Deltat + % + % Compute j1k + \pgfmathparse{% + \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+ + #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}% + \expandafter\xdef\csname pgfmathode@RKIV@1@\pgfmathode@funcindex + \endcsname{\pgfmathresult}% + % Compute j2k + \pgfmathparse{% + \pgfmathode@Deltat*(\pgfmathode@func[\pgfmathode@funcindex-1])+ + #1[\pgfmathode@timeindex][\pgfmathode@funcindex]}% + \expandafter\xdef\csname pgfmathode@RKIV@1@\pgfmathode@funcindex + \endcsname{\pgfmathresult}% + } + % Store step i + \pgfmathparse{\pgfmathode@Sol@t+\pgfmathode@Deltat}% + \xdef\pgfmathode@Sol@t{\pgfmathresult}% + \xdef\pgfmathode@temp{}% + \foreach \pgfmathode@funcindex in {1,...,\pgfmathode@dimfunc} {% + \ifx\pgfmathode@temp\pgfutil@empty + \xdef\pgfmathode@temp{% + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \else + \xdef\pgfmathode@temp{% + \pgfmathode@temp, + \csname pgfmathode@Sol@\pgfmathode@funcindex\endcsname}% + \fi} + \xdef#1{% + {\expandafter\pgfutil@firstofone#1,% + {\pgfmathode@Sol@t,\pgfmathode@temp}}}% + } + \endgroup} + + +\endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex index 81f6545897e..71843fb2499 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex @@ -7,83 +7,92 @@ \newif\ifpgfmath@quickparse \newif\ifpgfmathfloat \newif\ifpgfmathunitsdeclared +\newif\ifpgfmathmathunitsdeclared \newif\ifpgfmathignoreunitscale \def\pgfmathprint#1{\pgfmathparse{#1}\pgfmathresult} \def\pgfmathparse{% - \begingroup% - \pgfmath@catcodes% - \pgfmath@quickparsefalse% - \ifpgfmathfloat% - \let\pgfmath@parse@next=\pgfmathfloatparsenumber% - \else% - \let\pgfmath@parse@next=\pgfmathparse@% - \fi% - \pgfmath@parse@next} + \begingroup + \pgfmath@catcodes + \pgfmath@quickparsefalse + % Test for the fpu library + \ifpgfmathfloat + \let\pgfmath@parse@next=\pgfmathfloatparsenumber + \else + \let\pgfmath@parse@next=\pgfmathparse@ + \fi + \pgfmath@parse@next} \def\pgfmath@catcodes{% Maybe unecessary. - \catcode`\==12% - \catcode`\,=12% - \catcode`\|=12% - \catcode`\&=12% + \catcode`\==12% + \catcode`\,=12% + \catcode`\|=12% + \catcode`\&=12% } \def\pgfmathqparse{% - \begingroup% - \pgfmath@catcodes% - \pgfmath@quickparsetrue% - \pgfmathparse@} - + \begingroup + \pgfmath@catcodes + \pgfmath@quickparsetrue + \pgfmathparse@} + \def\pgfmathparse@#1{% - % Stuff for calc compatiability. - \let\real=\pgfmath@calc@real% - \let\minof=\pgfmath@calc@minof% - \let\maxof=\pgfmath@calc@maxof% - \let\ratio=\pgfmath@calc@ratio% - \let\widthof=\pgfmath@calc@widthof% - \let\heightof=\pgfmath@calc@heightof% - \let\depthof=\pgfmath@calc@depthof% - % Restore font. - \pgfmath@selectfont% + % We are inside a group (opened in |\pgfmathparse| or + % |\pgfmathqparse|). + % Stuff for calc compatiability. + \let\real=\pgfmath@calc@real + \let\minof=\pgfmath@calc@minof + \let\maxof=\pgfmath@calc@maxof + \let\ratio=\pgfmath@calc@ratio + \let\widthof=\pgfmath@calc@widthof + \let\heightof=\pgfmath@calc@heightof + \let\depthof=\pgfmath@calc@depthof + % Restore font (defined in pgfmathutil.code.tex) + \pgfmath@selectfont % Expand expression so any reamining CSs are registers - % or box dimensions (i.e., \wd, \ht, \dp). + % or box dimensions (i.e. |\wd|, |\ht|, |\dp|). \edef\pgfmath@expression{#1}% - % No units yet. - \global\pgfmathunitsdeclaredfalse% + % No (math) units yet. + \global\pgfmathunitsdeclaredfalse + \global\pgfmathmathunitsdeclaredfalse % Set up stack. \pgfmath@stack@operation={{}{}{}}% - \pgfmath@stack@operand={{}{}{}}% - \let\pgfmath@stack@operation@top=\pgfmath@stack@empty% - \let\pgfmath@stack@operand@top=\pgfmath@stack@empty% - % An expression always begins with an operand. - \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmath@expression}% - \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop% -}% + \pgfmath@stack@operand={{}{}{}}% + \let\pgfmath@stack@operation@top=\pgfmath@stack@empty + \let\pgfmath@stack@operand@top=\pgfmath@stack@empty + % An expression always begins with an operand. + \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmath@expression}% + % |\pgfmath@bgroup@stripped| is the result of + % |\pgfmath@bgroup@strip| + \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop% +} \def\pgfmath@parse@end#1\pgfmath@parse@stop{% - \pgfmathpostparse% - \pgfmath@smuggleone\pgfmathresult% - \endgroup% - \ignorespaces}% + \pgfmathpostparse + \pgfmath@smuggleone\pgfmathresult% + \endgroup + \ignorespaces} -\let\pgfmathpostparse=\relax% +\let\pgfmathpostparse=\relax % For compatiability with older version. % \def\pgfmathscaleresult{% - \ifpgfmathunitsdeclared% - \else% - \ifpgfmathignoreunitscale% - \else% - \afterassignment\pgfmath@gobbletilpgfmath@% + \ifpgfmathunitsdeclared + \else + \ifpgfmathignoreunitscale + \else + \afterassignment\pgfmath@gobbletilpgfmath@% \pgfmath@x\pgfmathresultunitscale pt\relax\pgfmath@% \expandafter\pgfmath@x\pgfmathresult\pgfmath@x% \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}% - \fi% - \fi% + \fi + \fi } + \def\pgfmathsetresultunitscale#1{\def\pgfmathresultunitscale{#1}} + \def\pgfmathresultunitscale{1} % Stuff for compatability with the calc package. @@ -116,19 +125,29 @@ \edef\pgfmath@char@hash{\the\pgfmath@toks} \def\pgfmath@tokens@make#1#2{% - \def\pgfmath@prefix{#1}% - \expandafter\pgfmath@tokens@@make#2{}} - + % Defines for each token or balenced text in |#2| a control sequence + % |\pgfmath@token@<#1>@\string| and stores |#2| + % in it. + \def\pgfmath@prefix{#1}% + % Note the empty group |{}| at the end that ends the loop in + % |\pgfmath@token@@make|. + \expandafter\pgfmath@tokens@@make#2{}} + \def\pgfmath@tokens@@make#1{% - \def\pgfmath@token{#1}% - \ifx\pgfmath@token\pgfmath@empty% - \else% - \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}% - \expandafter\pgfmath@tokens@@make% - \fi} + \def\pgfmath@token{#1}% + \ifx\pgfmath@token\pgfmath@empty + % End of loop: all tokens or balanced texts were parsed. + \else + \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}% + \expandafter\pgfmath@tokens@@make% + \fi} \pgfmath@tokens@make{box}{\wd\ht\dp} +\ifx\dimexpr\@undefined\else % needed for classic tex + \pgfmath@tokens@make{dimexpr}{\dimexpr\glueexpr} +\fi \pgfmath@tokens@make{unit}{{bp}{cc}{cm}{dd}{em}{ex}{in}{mm}{pc}{pt}{sp}} +\pgfmath@tokens@make{mathunit}{{mu}} \pgfmath@tokens@make{numeric}{.0123456789} \pgfmath@tokens@make{number}{0123456789} \pgfmath@tokens@make{functional}{_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ} @@ -145,39 +164,42 @@ \pgfmath@namedef{pgfmath@base@0B}{2} % Determine if a register is a count or a dimension/skip register. -% \newif\ifpgfmath@dimen@ \def\pgfmath@dimen@#1{% - \begingroup% - \afterassignment\pgfmath@dimen@@% - #1=0.0pt\relax\pgfmath@} + \begingroup + \afterassignment\pgfmath@dimen@@% + #1=0.0pt\relax\pgfmath@} \def\pgfmath@dimen@@#1#2\pgfmath@{% - \endgroup% - \ifx#1.% - \pgfmath@dimen@false% - \else% - \pgfmath@dimen@true% - \fi} + \endgroup + \ifx#1.% + \pgfmath@dimen@false + \else + \pgfmath@dimen@true + \fi} \def\pgfmath@parse@ifbgroup#1#2{% - \let\pgfmath@parse@bgroup@after=#1% - \let\pgfmath@parse@nobgroup@after=#2% - \futurelet\pgfmath@token@let% - \pgfmath@parse@@ifbgroup} - + \let\pgfmath@parse@bgroup@after=#1% + \let\pgfmath@parse@nobgroup@after=#2% + \futurelet\pgfmath@token@let% + \pgfmath@parse@@ifbgroup} + \def\pgfmath@parse@@ifbgroup{% - \ifx\pgfmath@token@let\bgroup% - \let\pgfmath@parse@next=\pgfmath@parse@@@ifbgroup% - \else% - \ifx\pgfmath@token@let\pgfmath@sptoken% - \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup% - \else% - \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after% - \fi% - \fi% - \pgfmath@parse@next} - -\def\pgfmath@parse@@@ifbgroup#1{\pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup} + \ifx\pgfmath@token@let\bgroup + \let\pgfmath@parse@next=\pgfmath@parse@@@ifbgroup + \else + % |\pgfmath@sptoken| defined in \file{pgfmathutil.code.tex}. + \ifx\pgfmath@token@let\pgfmath@sptoken + \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup + \else + \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after + \fi + \fi + \pgfmath@parse@next} + +% I (CJ) *think* it replaces |{| and |}| by |\pgfmath@bgroup| and +% |\pgfmath@egroup|? +\def\pgfmath@parse@@@ifbgroup#1{% + \pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup} { \def\:{\pgfmath@parse@@@@ifbgroup} @@ -185,81 +207,96 @@ } % Parse an operand. -% -\def\pgfmath@parse@operand{\expandafter\pgfmath@parse@@operand\pgfmath@token@next}% - -\def\pgfmath@parse@@operand{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}} - +\def\pgfmath@parse@operand{% + \expandafter\pgfmath@parse@@operand\pgfmath@token@next} + +% This is the entry point for the parser. It is called at the end of +% |\pgfmathparse@| with the following syntax +% |\expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped +% @@@@\pgfmath@parse@stop|. +% Note: we are inside a group. +\def\pgfmath@parse@@operand{% + \pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}} + +% An operand is +% * |+| (unary plus), +% * |-| (unary minus), +% * a prefix operator \def\pgfmath@parse@@operand@#1{% - \def\pgfmath@token{#1}% - \ifx\pgfmath@token\pgfmath@char@plus% Ignore. - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \else% - \ifx\pgfmath@token\pgfmath@char@minus% - \pgfmath@stack@push@operation{neg}% Unary minus. - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \else% - \expandafter\ifx\csname pgfmath@operation@\expandafter\string\pgfmath@token @prefix\endcsname\pgfmath@token% - \let\pgfmath@parse@next=\pgfmath@parse@prefix@operator% - \else% - \ifpgfmath@quickparse% - \let\pgfmath@parse@next=\pgfmath@qparse@operand% - \else% - \let\pgfmath@number=\pgfmath@empty% - \expandafter\ifx\csname pgfmath@token@functional@\string#1\endcsname\relax% - \let\pgfmath@base=\pgfmath@empty% - \let\pgfmath@token@next=\pgfmath@token% - \if#10% Check for octal prefix. - \def\pgfmath@base{8}% - \fi% - \let\pgfmath@parse@next=\pgfmath@parse@number% - \else% - \let\pgfmath@function=\pgfmath@token% - \let\pgfmath@parse@next=\pgfmath@parse@function% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgfmath@parse@next% + \def\pgfmath@token{#1}% + \ifx\pgfmath@token\pgfmath@char@plus + % Unary (prefix) plus + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \else + \ifx\pgfmath@token\pgfmath@char@minus + % Unary (prefix) minus + \pgfmath@stack@push@operation{neg}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand + \else + % See |\pgfmathdeclareoperator| (below). Note that |+| and |-| + % that are also declared as operators have been tested before so + % they should never be parsed as binary (infix) operator at this stage. + \expandafter\ifx\csname pgfmath@operation@\expandafter\string\pgfmath@token @prefix\endcsname\pgfmath@token + \let\pgfmath@parse@next=\pgfmath@parse@prefix@operator + \else + \ifpgfmath@quickparse + \let\pgfmath@parse@next=\pgfmath@qparse@operand + \else + \let\pgfmath@number=\pgfmath@empty + \expandafter\ifx\csname pgfmath@token@functional@\string#1\endcsname\relax% + \let\pgfmath@base=\pgfmath@empty% + \let\pgfmath@token@next=\pgfmath@token% + \if#10% Check for octal prefix. + \def\pgfmath@base{8}% + \fi% + \let\pgfmath@parse@next=\pgfmath@parse@number% + \else% + \let\pgfmath@function=\pgfmath@token% + \let\pgfmath@parse@next=\pgfmath@parse@function% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgfmath@parse@next% } % Parse prefix operators. % \def\pgfmath@parse@prefix@operator{% - \ifx\pgfmath@token\pgfmath@char@quote% Quote character. - \let\pgfmath@parse@next=\pgfmath@parse@operand@quote% - \else% - \ifx\pgfmath@token\pgfmath@char@exclamation% Prefix !. - \pgfmath@stack@push@operation{not}% - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \else% Anything else, just push and hope. - \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@token}% - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \fi% - \fi% - \pgfmath@parse@next% + \ifx\pgfmath@token\pgfmath@char@quote% Quote character. + \let\pgfmath@parse@next=\pgfmath@parse@operand@quote% + \else% + \ifx\pgfmath@token\pgfmath@char@exclamation% Prefix !. + \pgfmath@stack@push@operation{not}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \else% Anything else, just push and hope. + \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@token}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \fi% + \fi% + \pgfmath@parse@next% }% % Quote part of an expression. % \def\pgfmath@parse@operand@quote#1"{% - \def\pgfmathresult{#1}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \pgfmath@parse@@operator% + \def\pgfmathresult{#1}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% } % Quick operand parsing. Should always have units. % No functions, base conversion, quoting or scientific notation % are permitted. \def\pgfmath@qparse@operand{% - \afterassignment\pgfmath@qparse@@operand% - \pgfmath@dimen\pgfmath@token} + \afterassignment\pgfmath@qparse@@operand% + \pgfmath@dimen\pgfmath@token} \def\pgfmath@qparse@@operand{% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \pgfmath@parse@@operator% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% } % Parse a number, which can take the form: @@ -274,337 +311,414 @@ % \def\pgfmath@parse@number{\pgfmath@parse@ifbgroup{\pgfmath@parse@number}{\pgfmath@parse@number@}} \def\pgfmath@parse@number@#1{% - \let\pgfmath@token=\pgfmath@token@next% - \def\pgfmath@token@next{#1}% - \pgfmath@parse@@number} + \let\pgfmath@token=\pgfmath@token@next% + \def\pgfmath@token@next{#1}% + \pgfmath@parse@@number} \def\pgfmath@parse@@number{% - \ifx\pgfmath@token\pgfmath@egroup@token% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmath@number}% - \let\pgfmath@parse@next=\pgfmath@parse@@@operator% - \else% - \expandafter\ifcat\pgfmath@token\relax% A CS? - \expandafter\ifx\csname pgfmath@token@box@\expandafter\string\pgfmath@token\endcsname\relax% - % So, is the CS is a dimension or a count register? - \expandafter\pgfmath@dimen@\pgfmath@token% - \ifpgfmath@dimen@% A dimension register. - \global\pgfmathunitsdeclaredtrue% - \pgfmath@dimen=\pgfmath@number\pgfmath@token% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \else% A count register. - \pgfmath@count=\pgfmath@token% - \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}% - \expandafter\ifcat\pgfmath@token@next\relax% - % A CS following a count register should be \wd, \ht or \dp. - \let\pgfmath@parse@next=\pgfmath@parse@number% - \else% - \let\pgfmathresult=\pgfmath@number% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \fi% - \fi% - \else% - % This should be a box specification, for example, 0.5\wd\mybox. - \global\pgfmathunitsdeclaredtrue% - \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@operator% - \fi% - \else% - \expandafter\ifx\csname pgfmath@token@numeric@\expandafter\string\pgfmath@token\endcsname\relax% - % It isn't numeric (i.e., 012345679.), so it might be units... - \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% - % ...or the exponent characters... - \expandafter\ifx\csname pgfmath@token@exponent@\pgfmath@token\endcsname\relax% - % ...or a base prefix... - \expandafter\ifx\csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname\relax% - % ...none of the above... - \ifx\pgfmath@base\pgfmath@empty% - \let\pgfmathresult=\pgfmath@number% - \else% - \ifx\pgfmath@number\pgfmath@char@zero% - \let\pgfmathresult=\pgfmath@number% - \else% - % Convert from octal. - \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{8}{10}% - \fi% - \fi% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@@operator% - \else% - % ...here, it is a base prefix 0x, 0X, 0b or 0B - \expandafter\let\expandafter\pgfmath@base\expandafter=% - \csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname% - \let\pgfmath@parse@next=\pgfmath@parse@base% - \fi% - \else% ... and here, it is the exponent characters. - \let\pgfmath@parse@next=\pgfmath@parse@exponent% - \fi% - \else% ...but here it is units. - \global\pgfmathunitsdeclaredtrue% - \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax% - \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@operator% - \fi% - \else% It is numeric. - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfmath@number% - \expandafter\expandafter\expandafter{\expandafter\pgfmath@number\pgfmath@token}% - \ifx\pgfmath@token\pgfmath@char@period% - \let\pgfmath@base=\pgfmath@empty% - \fi% - \let\pgfmath@parse@next=\pgfmath@parse@number% - \fi% - \fi% - \fi% - \pgfmath@parse@next% + \ifx\pgfmath@token\pgfmath@egroup@token% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmath@number}% + \let\pgfmath@parse@next=\pgfmath@parse@@@operator% + \else% + \expandafter\ifcat\pgfmath@token\relax% A CS? + \expandafter\ifx\csname pgfmath@token@dimexpr@\expandafter\string\pgfmath@token\endcsname\relax% + \expandafter\ifx\pgfmath@token\numexpr% + \let\pgfmath@parse@next=\pgfmath@parse@numexpr% + \else% + \expandafter\ifx\pgfmath@token\muexpr% + \let\pgfmath@parse@next=\pgfmath@parse@muexpr% + \else% + \expandafter\ifx\csname pgfmath@token@box@\expandafter\string\pgfmath@token\endcsname\relax% + % So, is the CS is a dimension or a count register? + \expandafter\pgfmath@dimen@\pgfmath@token% + \ifpgfmath@dimen@% A dimension register. + \global\pgfmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number\pgfmath@token% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \else% A count register. + \pgfmath@count=\pgfmath@token% + \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}% + \expandafter\ifcat\pgfmath@token@next\relax% + % A CS following a count register should be \wd, \ht or \dp. + \let\pgfmath@parse@next=\pgfmath@parse@number% + \else% + \let\pgfmathresult=\pgfmath@number% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \fi% + \fi% + \else% + % This should be a box specification, for example, 0.5\wd\mybox. + \global\pgfmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \fi% + \fi% + \fi% + \else% + \global\pgfmathunitsdeclaredtrue% + \let\pgfmath@parse@next=\pgfmath@parse@dimexpr% + \fi% + \else% + \expandafter\ifx\csname pgfmath@token@numeric@\expandafter\string\pgfmath@token\endcsname\relax% + % It isn't numeric (i.e., 012345679.), so it might be units... + \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% + % ...or the exponent characters... + \expandafter\ifx\csname pgfmath@token@exponent@\pgfmath@token\endcsname\relax% + % ...or a base prefix... + \expandafter\ifx\csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname\relax% + % ...or a math unit... + \expandafter\ifx\csname pgfmath@token@mathunit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% + % ...none of the above... + \ifx\pgfmath@base\pgfmath@empty% + \let\pgfmathresult=\pgfmath@number% + \else% + \ifx\pgfmath@number\pgfmath@char@zero% + \let\pgfmathresult=\pgfmath@number% + \else% + % Convert from octal. + \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{8}{10}% + \fi% + \fi% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@@operator% + \else% + % ...here, it is a math unit (mu). Treat it as a pt. + \global\pgfmathunitsdeclaredtrue% + \global\pgfmathmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number pt\relax% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \fi% + \else% + % ...here, it is a base prefix 0x, 0X, 0b or 0B + \expandafter\let\expandafter\pgfmath@base\expandafter=% + \csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname% + \let\pgfmath@parse@next=\pgfmath@parse@base% + \fi% + \else% ... and here, it is the exponent characters. + \let\pgfmath@parse@next=\pgfmath@parse@exponent% + \fi% + \else% ...but here it is units. + \global\pgfmathunitsdeclaredtrue% + \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \fi% + \else% It is numeric. + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfmath@number% + \expandafter\expandafter\expandafter{\expandafter\pgfmath@number\pgfmath@token}% + \ifx\pgfmath@token\pgfmath@char@period% + \let\pgfmath@base=\pgfmath@empty% + \fi% + \let\pgfmath@parse@next=\pgfmath@parse@number% + \fi% + \fi% + \fi% + \pgfmath@parse@next% +} + + +% Parse a \dimexpr +\def\pgfmath@parse@dimexpr{% + \afterassignment\pgfmath@parse@dimexpr@% + \expandafter\expandafter\expandafter\pgfmath@dimen\expandafter\pgfmath@token\pgfmath@token@next% +} +\def\pgfmath@parse@dimexpr@{% + \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% +} + + +% Parse a \muexpr +\def\pgfmath@parse@muexpr{% + \begingroup% + \afterassignment\pgfmath@parse@muexpr@% + \expandafter\expandafter\expandafter\muskip\expandafter\expandafter\expandafter0\expandafter\pgfmath@token\expandafter\pgfmath@token@next% +} +\def\pgfmath@parse@muexpr@{% + \expandafter\endgroup% + \expandafter\edef\expandafter\pgfmathresult\expandafter{\expandafter\pgfMATH@STRIPMU\the\muskip0}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% +} + +{ +\catcode`\m=12 +\catcode`\u=12 +\gdef\pgfMATH@STRIPMU#1mu{#1} +} + + +% Parse a \numexpr +\def\pgfmath@parse@numexpr{% + \afterassignment\pgfmath@parse@numexpr@% + \expandafter\expandafter\expandafter\pgfmath@count\expandafter\pgfmath@token\pgfmath@token@next% +} +\def\pgfmath@parse@numexpr@#1{% + \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}% + \def\pgfmath@token@next{#1}% + \expandafter\ifcat\pgfmath@token@next\relax% + % A CS following a count register should be \wd, \ht or \dp. + \let\pgfmath@parse@next=\pgfmath@parse@number% + \else% + \let\pgfmathresult=\pgfmath@number% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \fi% + \pgfmath@parse@next% } + % Parse the exponent of a number. % % REMARK: this method will be overwritten by the FPU library. Please % keep changes consistent... \def\pgfmath@parse@exponent{% - \afterassignment\pgfmath@parse@@exponent% - \pgfmath@count\pgfmath@token@next} + \afterassignment\pgfmath@parse@@exponent% + \pgfmath@count\pgfmath@token@next} \def\pgfmath@parse@@exponent{% - \pgfmathscientific{\pgfmath@number}{\the\pgfmath@count}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \pgfmath@parse@@operator% + \pgfmathscientific{\pgfmath@number}{\the\pgfmath@count}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \pgfmath@parse@@operator% } % Parse binary or hexadecimal numbers (octal numbers done elsehwere). % \def\pgfmath@parse@base{% - \ifnum\pgfmath@base=2\relax% - \let\pgfmath@parse@next=\pgfmath@parse@binary% - \else% - \ifnum\pgfmath@base=16\relax% - \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% - \else% - \pgfmath@error{Unexpected numerical base `\pgfmath@base'}{}% - \def\pgfmathresult{0}% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \fi% - \fi% - \let\pgfmath@number=\pgfmath@empty% - \expandafter\pgfmath@parse@next\pgfmath@token@next% + \ifnum\pgfmath@base=2\relax% + \let\pgfmath@parse@next=\pgfmath@parse@binary% + \else% + \ifnum\pgfmath@base=16\relax% + \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% + \else% + \pgfmath@error{Unexpected numerical base `\pgfmath@base'}{}% + \def\pgfmathresult{0}% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \fi% + \fi% + \let\pgfmath@number=\pgfmath@empty% + \expandafter\pgfmath@parse@next\pgfmath@token@next% } - + \def\pgfmath@parse@binary#1{% - \expandafter\ifx\csname pgfmath@token@binary@#1\endcsname\relax% - \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{2}{10}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \def\pgfmath@token@next{#1}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \else% - \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% - \let\pgfmath@parse@next=\pgfmath@parse@binary% - \fi% - \pgfmath@parse@next% + \expandafter\ifx\csname pgfmath@token@binary@#1\endcsname\relax% + \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{2}{10}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \def\pgfmath@token@next{#1}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \else% + \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% + \let\pgfmath@parse@next=\pgfmath@parse@binary% + \fi% + \pgfmath@parse@next% } \def\pgfmath@parse@hexadecimal#1{% - \expandafter\ifx\csname pgfmath@token@hexadecimal@#1\endcsname\relax% - \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{16}{10}% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \def\pgfmath@token@next{#1}% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \else% - \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% - \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% - \fi% - \pgfmath@parse@next% + \expandafter\ifx\csname pgfmath@token@hexadecimal@#1\endcsname\relax% + \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{16}{10}% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \def\pgfmath@token@next{#1}% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \else% + \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}% + \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal% + \fi% + \pgfmath@parse@next% } - + % Parse a function. % \def\pgfmath@parse@function{\pgfmath@parse@ifbgroup{\pgfmath@parse@function}{\pgfmath@parse@@function}} \def\pgfmath@parse@function@{\futurelet\pgfmath@token@let\pgfmath@parse@@function} \def\pgfmath@parse@@function{% - \ifx\pgfmath@token@let\pgfmath@sptoken% - \let\pgfmath@token=\pgfmath@empty% - \let\pgfmath@parse@next=\pgfmath@parse@@@@function% - \else% - \let\pgfmath@parse@next=\pgfmath@parse@@@function% - \fi% - \pgfmath@parse@next} + \ifx\pgfmath@token@let\pgfmath@sptoken% + \let\pgfmath@token=\pgfmath@empty% + \let\pgfmath@parse@next=\pgfmath@parse@@@@function% + \else% + \let\pgfmath@parse@next=\pgfmath@parse@@@function% + \fi% + \pgfmath@parse@next} \def\pgfmath@parse@@@function#1{% - \expandafter\ifx\csname pgfmath@token@functional@\expandafter\string#1\endcsname\relax% - \expandafter\ifx\csname pgfmath@token@number@\expandafter\string#1\endcsname\relax% - \def\pgfmath@token{#1}% Not from A-Z, a-z, 0-9, or _. - \let\pgfmath@parse@next=\pgfmath@parse@@@@function% - \else% It is from 0-9. - \expandafter\def\expandafter\pgfmath@function\expandafter{\pgfmath@function#1}% - \let\pgfmath@parse@next=\pgfmath@parse@function@% - \fi% - \else% It is from from A-Z, a-z, or _. - \edef\pgfmath@function{\pgfmath@function#1}% - \let\pgfmath@parse@next=\pgfmath@parse@function@% - \fi% - \pgfmath@parse@next} + \expandafter\ifx\csname pgfmath@token@functional@\expandafter\string#1\endcsname\relax% + \expandafter\ifx\csname pgfmath@token@number@\expandafter\string#1\endcsname\relax% + \def\pgfmath@token{#1}% Not from A-Z, a-z, 0-9, or _. + \let\pgfmath@parse@next=\pgfmath@parse@@@@function% + \else% It is from 0-9. + \expandafter\def\expandafter\pgfmath@function\expandafter{\pgfmath@function#1}% + \let\pgfmath@parse@next=\pgfmath@parse@function@% + \fi% + \else% It is from from A-Z, a-z, or _. + \edef\pgfmath@function{\pgfmath@function#1}% + \let\pgfmath@parse@next=\pgfmath@parse@function@% + \fi% + \pgfmath@parse@next} \def\pgfmath@parse@@@@function{% - \expandafter\ifx\csname pgfmath@function@\pgfmath@function\endcsname\relax% - \pgfmath@error{Unknown function `\pgfmath@function'}{}% - \def\pgfmathresult{0}% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \else% - \expandafter\ifnum\csname pgfmath@operation@\pgfmath@function @arity\endcsname=0\relax% - % Functions with zero arity are called directly. - \csname pgfmath\pgfmath@function @\endcsname% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \let\pgfmath@parse@next=\pgfmath@parse@@operator% - \else% Otherwise, they are pushed onto the operator stack - \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@function}% - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \fi% - \fi% - \expandafter\pgfmath@parse@next\pgfmath@token} + \expandafter\ifx\csname pgfmath@function@\pgfmath@function\endcsname\relax% + \pgfmath@error{Unknown function `\pgfmath@function'}{}% + \def\pgfmathresult{0}% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \else% + \expandafter\ifnum\csname pgfmath@operation@\pgfmath@function @arity\endcsname=0\relax% + % Functions with zero arity are called directly. + \csname pgfmath\pgfmath@function @\endcsname% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \let\pgfmath@parse@next=\pgfmath@parse@@operator% + \else% Otherwise, they are pushed onto the operator stack + \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@function}% + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \fi% + \fi% + \expandafter\pgfmath@parse@next\pgfmath@token} % Parse an operator. % \def\pgfmath@parse@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@operator}{\pgfmath@parse@operator@}}% \def\pgfmath@parse@operator@#1{% Get one token. - \let\pgfmath@token=\pgfmath@token@next% - \def\pgfmath@token@next{#1}% - \pgfmath@parse@@@operator} + \let\pgfmath@token=\pgfmath@token@next% + \def\pgfmath@token@next{#1}% + \pgfmath@parse@@@operator} \def\pgfmath@parse@@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operator}{\pgfmath@parse@@operator@}}% \def\pgfmath@parse@@operator@#1{% Get first token... - \def\pgfmath@token{#1}% - \pgfmath@parse@ifbgroup{\pgfmath@parse@@operator@@}{\pgfmath@parse@@operator@@}}% + \def\pgfmath@token{#1}% + \pgfmath@parse@ifbgroup{\pgfmath@parse@@operator@@}{\pgfmath@parse@@operator@@}}% \def\pgfmath@parse@@operator@@#1{% ...and second token. - \def\pgfmath@token@next{#1}% - \pgfmath@parse@@@operator} + \def\pgfmath@token@next{#1}% + \pgfmath@parse@@@operator} \def\pgfmath@parse@@@operator{% - \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% - % Not a double character operator. - \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\endcsname\relax% - % Not a single character operator. - \pgfmath@error{Unknown operator `\pgfmath@token' or `\pgfmath@token\pgfmath@token@next'}{}% - \def\pgfmathresult{0}% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \else% - \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% - \ifx\pgfmath@token\pgfmath@text@@% - \let\pgfmath@parse@next=\pgfmath@parse@end% - \else% - \expandafter\ifx\csname pgfmath@operation@\pgfmath@token @postfix\endcsname\pgfmath@token% - % Postfix operators are followed by an operator. - \ifx\pgfmath@token@next\pgfmath@char@leftbracket% Except [. - \let\pgfmath@parse@next=\pgfmath@parse@operand% - \else% - \let\pgfmath@parse@next=\pgfmath@parse@operator% - \fi% - \else% - % Any other operator is followed by an operand. - \let\pgfmath@parse@next=\pgfmath@parse@operand% - \fi% - \fi% - \fi% - \else% - % A double character operator... - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgfmath@token\expandafter\expandafter\expandafter% - {\expandafter\pgfmath@token\pgfmath@token@next}% - \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% - % ...is always followed by an operand. - \let\pgfmath@parse@next=\pgfmath@parse@@operand% - \fi% - \pgfmath@parse@next% + \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax% + % Not a double character operator. + \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\endcsname\relax% + % Not a single character operator. + \pgfmath@error{Unknown operator `\pgfmath@token' or `\pgfmath@token\pgfmath@token@next'}{}% + \def\pgfmathresult{0}% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \else% + \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% + \ifx\pgfmath@token\pgfmath@text@@% + \let\pgfmath@parse@next=\pgfmath@parse@end% + \else% + \expandafter\ifx\csname pgfmath@operation@\pgfmath@token @postfix\endcsname\pgfmath@token% + % Postfix operators are followed by an operator. + \ifx\pgfmath@token@next\pgfmath@char@leftbracket% Except [. + \let\pgfmath@parse@next=\pgfmath@parse@operand% + \else% + \let\pgfmath@parse@next=\pgfmath@parse@operator% + \fi% + \else% + % Any other operator is followed by an operand. + \let\pgfmath@parse@next=\pgfmath@parse@operand% + \fi% + \fi% + \fi% + \else% + % A double character operator... + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgfmath@token\expandafter\expandafter\expandafter% + {\expandafter\pgfmath@token\pgfmath@token@next}% + \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}% + % ...is always followed by an operand. + \let\pgfmath@parse@next=\pgfmath@parse@@operand% + \fi% + \pgfmath@parse@next% } % Process an operation. % \def\pgfmath@operation@process#1{% - \def\pgfmath@operator{#1}% - \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% - \else% - \pgfmath@operation@@process% - \fi% - \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax% - \pgfmath@stack@push@operation{#1}% - \fi% + \def\pgfmath@operator{#1}% + \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% + \else% + \pgfmath@operation@@process% + \fi% + \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax% + \pgfmath@stack@push@operation{#1}% + \fi% } % Process the operation stack. % \def\pgfmath@operation@@process{% - \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% - \let\pgfmath@parse@next=\relax% - \else% - \ifnum\csname pgfmath@operation@\pgfmath@operator @precedence\endcsname>% - \csname pgfmath@operation@\pgfmath@stack@operation@top @precedence\endcsname\relax% - % If the precedence of the scanned operator is greater than the - % precedence of the operator at the top of the stack, do nothing. - \let\pgfmath@parse@next=\relax% - \else% - \let\pgfmath@stack@operation@last=\pgfmath@stack@operation@top% - \expandafter\ifx\csname pgfmath@operator@\pgfmath@stack@operation@top\endcsname\relax% - \pgfmath@function@@@process% - \else% - \pgfmath@operator@@@process% - \fi% - \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% - \expandafter\ifx\csname pgfmath@token@group@\pgfmath@stack@operation@last\pgfmath@operator\endcsname\relax% - \let\pgfmath@parse@next=\pgfmath@operation@@process% - \else% - \let\pgfmath@parse@next=\relax% - \fi% - \fi% - \fi% - \pgfmath@parse@next% + \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty% + \let\pgfmath@parse@next=\relax% + \else% + \ifnum\csname pgfmath@operation@\pgfmath@operator @precedence\endcsname>% + \csname pgfmath@operation@\pgfmath@stack@operation@top @precedence\endcsname\relax% + % If the precedence of the scanned operator is greater than the + % precedence of the operator at the top of the stack, do nothing. + \let\pgfmath@parse@next=\relax% + \else% + \let\pgfmath@stack@operation@last=\pgfmath@stack@operation@top% + \expandafter\ifx\csname pgfmath@operator@\pgfmath@stack@operation@top\endcsname\relax% + \pgfmath@function@@@process% + \else% + \pgfmath@operator@@@process% + \fi% + \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}% + \expandafter\ifx\csname pgfmath@token@group@\pgfmath@stack@operation@last\pgfmath@operator\endcsname\relax% + \let\pgfmath@parse@next=\pgfmath@operation@@process% + \else% + \let\pgfmath@parse@next=\relax% + \fi% + \fi% + \fi% + \pgfmath@parse@next% } % Process an operator. % \def\pgfmath@operator@@@process{% Process an operator. - \pgfmath@stack@pop@operation\pgfmath@@operator% - \pgfmath@stack@pop@operand\pgfmath@operand@a% - \ifcase\csname pgfmath@operation@\pgfmath@@operator @arity\endcsname\relax% - % Zero arity operators (!). - \or% - \pgfmath@operator@@@@process{\pgfmath@operand@a}% - \or% - \pgfmath@stack@pop@operand\pgfmath@operand@b% - \pgfmath@operator@@@@process{\pgfmath@operand@b}{\pgfmath@operand@a}% - \or% - \pgfmath@stack@pop@operand\pgfmath@operand@b% - \expandafter\pgfmath@operator@@@@process\expandafter% - {\expandafter\pgfmath@operand@b\expandafter}\pgfmath@operand@a% - \else% - % No operators with more than tenary arity. - \fi% + \pgfmath@stack@pop@operation\pgfmath@@operator% + \pgfmath@stack@pop@operand\pgfmath@operand@a% + \ifcase\csname pgfmath@operation@\pgfmath@@operator @arity\endcsname\relax% + % Zero arity operators (!). + \or% + \pgfmath@operator@@@@process{\pgfmath@operand@a}% + \or% + \pgfmath@stack@pop@operand\pgfmath@operand@b% + \pgfmath@operator@@@@process{\pgfmath@operand@b}{\pgfmath@operand@a}% + \or% + \pgfmath@stack@pop@operand\pgfmath@operand@b% + \expandafter\pgfmath@operator@@@@process\expandafter% + {\expandafter\pgfmath@operand@b\expandafter}\pgfmath@operand@a% + \else% + % No operators with more than tenary arity. + \fi% } \def\pgfmath@operator@@@@process{% - \csname pgfmath% - \csname pgfmath@operation@\pgfmath@@operator @name\endcsname% - @\endcsname} + \csname pgfmath% + \csname pgfmath@operation@\pgfmath@@operator @name\endcsname% + @\endcsname} % Process a function. % \def\pgfmath@function@@@process{% Process a function. - \ifnum\csname pgfmath@operation@\pgfmath@stack@operation@top @arity\endcsname>0\relax% - \pgfmath@stack@pop@operation\pgfmath@@function% - \pgfmath@stack@pop@operand\pgfmath@@operand% - \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>1\relax% - \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>9\relax% - \csname pgfmath\pgfmath@@function @\endcsname{\pgfmath@@operand}% - \else% - \expandafter\pgfmath@function@@@@process\pgfmath@@operand% - \fi - \else% - \expandafter\pgfmath@function@@@@process\expandafter{\pgfmath@@operand}% - \fi% - \fi% + \ifnum\csname pgfmath@operation@\pgfmath@stack@operation@top @arity\endcsname>0\relax% + \pgfmath@stack@pop@operation\pgfmath@@function% + \pgfmath@stack@pop@operand\pgfmath@@operand% + \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>1\relax% + \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>9\relax% + \csname pgfmath\pgfmath@@function @\endcsname{\pgfmath@@operand}% + \else% + \expandafter\pgfmath@function@@@@process\pgfmath@@operand% + \fi + \else% + \expandafter\pgfmath@function@@@@process\expandafter{\pgfmath@@operand}% + \fi% + \fi% } \def\pgfmath@function@@@@process{\csname pgfmath\pgfmath@@function @\endcsname} @@ -616,32 +730,32 @@ \let\pgfmath@stack@empty=\pgfmath@empty \def\pgfmath@stack@push#1#2{% - \def\pgfmath@stack@top{#2}% - \expandafter\expandafter\expandafter#1% - \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% - {\expandafter\pgfmath@stack@top\expandafter}\the#1}}% + \def\pgfmath@stack@top{#2}% + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% + {\expandafter\pgfmath@stack@top\expandafter}\the#1}}% \def\pgfmath@stack@pop#1#2{\expandafter\pgfmath@stack@@pop\the#1\pgfmath@stack@stop{#1}{#2}} \def\pgfmath@stack@@pop#1#2#3\pgfmath@stack@stop#4#5{\def#5{#1}#4={{#2}#3}\def\pgfmath@stack@top{#2}} \def\pgfmath@stack@push@operation#1{% - \pgfmath@stack@push\pgfmath@stack@operation{#1}% - \let\pgfmath@stack@operation@top=\pgfmath@stack@top} + \pgfmath@stack@push\pgfmath@stack@operation{#1}% + \let\pgfmath@stack@operation@top=\pgfmath@stack@top} \def\pgfmath@stack@pop@operation#1{% - \pgfmath@stack@pop\pgfmath@stack@operation{#1}% - \let\pgfmath@stack@operation@top=\pgfmath@stack@top} - + \pgfmath@stack@pop\pgfmath@stack@operation{#1}% + \let\pgfmath@stack@operation@top=\pgfmath@stack@top} + % REMARK: This method will be overwritten by the FPU library. Please % keep any changes consistent. \def\pgfmath@stack@push@operand#1{% - \pgfmath@stack@push\pgfmath@stack@operand{#1}% - \let\pgfmath@stack@operand@top=\pgfmath@stack@top} + \pgfmath@stack@push\pgfmath@stack@operand{#1}% + \let\pgfmath@stack@operand@top=\pgfmath@stack@top} \def\pgfmath@stack@pop@operand#1{% - \pgfmath@stack@pop\pgfmath@stack@operand{#1}% - \let\pgfmath@stack@operand@top=\pgfmath@stack@top} - + \pgfmath@stack@pop\pgfmath@stack@operand{#1}% + \let\pgfmath@stack@operand@top=\pgfmath@stack@top} + % Declare an operator for the parser. % @@ -649,13 +763,20 @@ % the parser is not fully robust for arbitrary operators. % \def\pgfmathdeclareoperator#1#2#3#4#5{% - \pgfmath@namedef{pgfmath@operator@\string#1}{#1}% - \pgfmath@namedef{pgfmath@operation@\string#1@name}{#2}% - \pgfmath@namedef{pgfmath@operation@\string#1@arity}{#3}% - \pgfmath@namedef{pgfmath@operation@\string#1@#4}{#1}% - \pgfmath@namedef{pgfmath@operation@\string#1@precedence}{#5}% + \ifx\pgfmath@operatorlist\pgfutil@empty + \edef\pgfmath@operatorlist{{\string#1}}% + \else + \edef\pgfmath@operatorlist{\pgfmath@operatorlist,{\string#1}}% + \fi + \pgfmath@namedef{pgfmath@operator@\string#1}{#1}% + \pgfmath@namedef{pgfmath@operation@\string#1@name}{#2}% + \pgfmath@namedef{pgfmath@operation@\string#1@arity}{#3}% + \pgfmath@namedef{pgfmath@operation@\string#1@#4}{#1}% + \pgfmath@namedef{pgfmath@operation@\string#1@precedence}{#5}% } +\def\pgfmath@operatorlist{} + \pgfmathdeclareoperator{+}{add} {2}{infix}{500} \pgfmathdeclareoperator{-}{subtract}{2}{infix}{500} \pgfmathdeclareoperator{*}{multiply}{2}{infix}{700} @@ -671,7 +792,7 @@ \pgfmathdeclareoperator{<=}{notgreater}{2}{infix} {250} \pgfmathdeclareoperator{&&}{and} {2}{infix} {200} \pgfmathdeclareoperator{||}{or} {2}{infix} {200} -\pgfmathdeclareoperator{!=}{notequalto}{2}{infix} {250} +\pgfmathdeclareoperator{!=}{notequal} {2}{infix} {250} \pgfmathdeclareoperator{!} {not} {1}{prefix}{975} \pgfmathdeclareoperator{?} {ifthenelse}{3}{infix} {100} \pgfmathdeclareoperator{:} {@@collect} {2}{infix}{101} @@ -702,11 +823,11 @@ % Begin and end array access []. % \def\pgfmath@startindex@#1#2{% - \expandafter\pgfmatharray@#1{#2}% - \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmathresult}% - \ifx\pgfmath@token@let\bgroup% - \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmathresult}}% - \fi} + \expandafter\pgfmatharray@#1{#2}% + \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmathresult}% + \ifx\pgfmath@token@let\bgroup% + \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmathresult}}% + \fi} \def\pgfmath@endindex@{}% Never actually called. % Begin and end array {}. @@ -716,57 +837,63 @@ \def\pgfmath@@collect@#1#2{% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% - {\expandafter#1\expandafter}\expandafter{#2}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter% + {\expandafter#1\expandafter}\expandafter{#2}}% } % Collect items separated by ,. % \def\pgfmath@collect@#1#2{% - \expandafter\def\expandafter\pgfmath@collect@original\expandafter{#1}% - \expandafter\pgfmath@bgroup@strip\expandafter{#1}% - \ifx\pgfmath@token@let\bgroup% - \ifx\pgfmath@collect@original\pgfmath@bgroup@stripped% - \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}% - \else% - \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% - \fi% - \else% - \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% - \fi% - \expandafter\pgfmath@bgroup@strip\expandafter{#2}% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgfmathresult\expandafter\expandafter\expandafter% - {\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}}% + \expandafter\def\expandafter\pgfmath@collect@original\expandafter{#1}% + \expandafter\pgfmath@bgroup@strip\expandafter{#1}% + \ifx\pgfmath@token@let\bgroup% + \ifx\pgfmath@collect@original\pgfmath@bgroup@stripped% + \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}% + \else% + \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% + \fi% + \else% + \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}% + \fi% + \expandafter\pgfmath@bgroup@strip\expandafter{#2}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgfmathresult\expandafter\expandafter\expandafter% + {\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}}% } % Strip braces from a token sequence. % \def\pgfmath@bgroup@strip#1{% - \def\pgfmath@bgroup@strip@last{#1}% - \pgfmath@bgroup@@strip{#1}\pgfmath@\pgfmath@@\pgfmath@@@} + \def\pgfmath@bgroup@strip@last{#1}% + \pgfmath@bgroup@@strip{#1}\pgfmath@\pgfmath@@\pgfmath@@@} \def\pgfmath@bgroup@strip@#1{% - \def\pgfmath@bgroup@strip@last{#1}% - \pgfmath@bgroup@@strip#1\pgfmath@\pgfmath@@\pgfmath@@@} + \def\pgfmath@bgroup@strip@last{#1}% + \pgfmath@bgroup@@strip#1\pgfmath@\pgfmath@@\pgfmath@@@} \def\pgfmath@bgroup@pgfmath@{\pgfmath@} -\def\pgfmath@bgroup@@strip{\futurelet\pgfmath@token@let\pgfmath@bgroup@@@strip} -\def\pgfmath@bgroup@@@strip#1#2#3\pgfmath@@@{% - \ifx\pgfmath@token@let\bgroup% - \def\pgfmath@bgroup@test{#2}% - \ifx\pgfmath@bgroup@test\pgfmath@bgroup@pgfmath@% - \def\pgfmath@next{\pgfmath@bgroup@strip@{#1}}% - \else% - \let\pgfmath@bgroup@stripped=\pgfmath@bgroup@strip@last% - \let\pgfmath@next=\relax% - \fi% - \else% - \pgfmath@bgroup@@@@strip#1#2#3% - \let\pgfmath@next=\relax% - \fi% - \pgfmath@next% -} +\def\pgfmath@bgroup@@strip{% + \futurelet\pgfmath@token@let\pgfmath@bgroup@@@strip} -\def\pgfmath@bgroup@@@@strip#1\pgfmath@\pgfmath@@{\def\pgfmath@bgroup@stripped{#1}}% +\def\pgfmath@bgroup@@@strip#1#2#3\pgfmath@@@{% + \ifx\pgfmath@token@let\bgroup + \def\pgfmath@bgroup@test{#2}% + \ifx\pgfmath@bgroup@test\pgfmath@bgroup@pgfmath@ + \def\pgfmath@next{\pgfmath@bgroup@strip@{#1}}% + \else + \let\pgfmath@bgroup@stripped=\pgfmath@bgroup@strip@last + \let\pgfmath@next=\relax + \fi + \else + \pgfmath@bgroup@@@@strip#1#2#3% + \let\pgfmath@next=\relax + \fi + \pgfmath@next} + +\def\pgfmath@bgroup@@@@strip#1\pgfmath@\pgfmath@@{% + \def\pgfmath@bgroup@stripped{#1}} + +% Local Variables: +% tab-width: 2 +% End: \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex index 5e353007618..44d39c75b6a 100644 --- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathutil.code.tex @@ -80,7 +80,7 @@ \let\pgfmath@yc\pgf@yc \let\pgfmath@tempdima\pgfutil@tempdima -\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdimb\pgfutil@tempdimb \let\c@pgfmath@counta\c@pgf@counta \let\c@pgfmath@countb\c@pgf@countb @@ -177,7 +177,7 @@ \let\pgfmath@PackageWarning\PackageWarning% \fi% \ifx\PackageError\pgfmath@undefined - \def\pgfmath@PackageError#1#2#3{\immediate\write-1{Package #1: Error! #2.}}% + \def\pgfmath@PackageError#1#2#3{\errmessage{Package #1 Error: #2.}}% \else% \let\pgfmath@PackageError\PackageError% \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex new file mode 100644 index 00000000000..f0a28bfff68 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulebending.code.tex @@ -0,0 +1,355 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulebending.code.tex,v 1.18 2013/09/30 18:30:15 tantau Exp $ + + +% +% This file defines commands for drawing bending arrows and lines. +% + +\usepgfmodule{nonlineartransformations} +\usepgflibrary{curvilinear} + + +% Configuration options for arrow tips: + +\pgfkeys{ + /pgf/arrow keys/flex/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex}, + /pgf/arrow keys/flex/.default=1, + /pgf/arrow keys/flex'/.code=\pgfarrowsaddtooptions{\pgf@arrows@the@rigidity#1pt\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex@prime}, + /pgf/arrow keys/flex'/.default=1, + /pgf/arrow keys/bend/.code=\pgfarrowsaddtooptions{\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@bend} +} + + +\def\pgf@arrow@mode@is@flex{1} +\def\pgf@arrow@mode@is@flex@prime{2} +\def\pgf@arrow@mode@is@bend{3} + +\newdimen\pgf@arrows@the@rigidity + +% +% +% Handle the end of a curve +% +% + +% First, the preparation. This is, essenatially, setting up the +% nonlinear transformation + +\def\pgf@prep@curveend{ + \pgftransformreset% + \pgfsetcurvilinearbeziercurve{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath} +} + +% Second, the shortening. + +\def\pgf@do@shorten@curvedend{% + \expandafter\expandafter\expandafter\pgf@do@shorten@curvedend@unpack\expandafter\pgfpointfourthlastonpath\pgfpointthirdlastonpath% +} +\def\pgf@do@shorten@curvedend@unpack\pgfqpoint#1#2\pgfqpoint#3#4{% + \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}% + % Compute new curve: + \pgfpointcurveattime{\pgf@x}{\pgfpointlastonpath}{\pgfpointsecondlastonpath}{\pgfpointthirdlastonpath}{\pgfpointfourthlastonpath}% + % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector... + \pgf@xb#3% + \pgf@yb#4% + \pgf@xb\pgf@time@t\pgf@xb% + \pgf@yb\pgf@time@t\pgf@yb% + \advance\pgf@xb by\pgf@time@s\pgf@xc% + \advance\pgf@yb by\pgf@time@s\pgf@yc% + \edef\pgfprocessresultsubpathsuffix{% + \expandafter\noexpand\pgfsubpathfourthlasttoken{#1}{#2}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xb}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@curvetotoken{\the\pgf@x}{\the\pgf@y}}% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultsubpathprefix\pgfprocessresultsubpathsuffix}% +} + +% Third, the drawing + +\def\pgf@do@draw@curvedend{% + \pgf@do@draw@curved\pgf@end@tip@sequence% +} + +\def\pgf@do@draw@curved#1{% + {% + \pgftransformreset% + \pgf@xb\pgf@arrow@tip@total@length% xb will keep track of the total length + \let\pgf@arrow@handle\pgf@draw@curved% + \let\pgf@arrow@handle@dot\relax% + #1% + }% +} + +\def\pgf@draw@curved#1#2{% + % Prepare: + {% + \pgfarrows@getid{#1}{#2}% + % Do shift: + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid@shift\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + \expandafter\let\expandafter\pgf@arrow@bending@mode\csname pgf@ar@bending@mode@#1\endcsname% + \ifx\pgf@arrow@bending@mode\pgfutil@empty\let\pgf@arrow@flex@mode\pgf@arrow@mode@is@flex\fi% + % do swap: + {% + \csname pgf@ar@saves@\pgf@arrow@id\endcsname% + \ifcase\pgf@arrow@flex@mode\relax% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% like flex + \or% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@visual@\pgf@arrow@id\endcsname% + \or% + \expandafter\expandafter\expandafter\pgf@arrow@drawer@rigid\csname pgf@ar@ends@\pgf@arrow@id\endcsname% + \or% + \pgf@arrow@drawer@bend% + \fi% + % hull points inside the above + }% + \expandafter}% + % Transform to next tip: + \expandafter\pgf@xb\the\pgf@xb% +} +\def\pgf@falsetext{false} + +\def\pgf@arrow@drawer@rigid@shift#1#2#3{% tip end, back end, line end, sep + % Let xa be the actual back end of the current arrow plus the back end: + \advance\pgf@xb by#2% + \pgf@xa\pgf@xb% + % Update the xb: + \pgf@x#1% + \advance\pgf@x by\pgfarrowsep% + \advance\pgf@xb by-\pgf@x% +} + + +\def\pgf@arrow@drawer@bend{% + \pgftransformnonlinear{\pgf@arrow@bending@mode{\pgf@x}{\pgf@y}} + \pgftransformscale{-1}% + \pgftransformxshift{-\pgf@xa}% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% + {% + \pgf@relevantforpicturesizefalse% + \pgfscope% + \pgf@arrows@color@setup% + \csname pgf@ar@inst@code@\pgf@arrow@id\endcsname% + \endpgfscope% + }% + \pgf@arrows@bending@hull% +} + +\def\pgf@arrow@drawer@rigid#1#2#3{% (rigid) start, (rigid) end, dummy + % Compute the rigid positions: + \pgf@x#1% start + \pgf@y#2% flexibility*(end-start) + start + \advance\pgf@y by-\pgf@x% + \pgf@y\pgf@sys@tonumber\pgf@arrows@the@rigidity\pgf@y% + \advance\pgf@y by\pgf@x% + % Are they equal? + \ifdim\pgf@x=\pgf@y% + % Yes, do tangent: + \pgf@bending@do@tangent% + \else% + \pgf@bending@do@flex% + \fi% + \pgf@xc#1% + \pgf@xc-\pgf@xc% + \pgftransformxshift{+\pgf@xc}% + % Do slant: + \ifdim\pgfarrows@slant pt=0pt% + \else% + \pgftransformxslant{\pgfarrows@slant}% + \fi% + % do swap: + \ifpgfarrowswap% + \pgftransformyscale{-1}% + \fi% + \pgfscope% + \pgf@arrows@color@setup% + \pgflowlevelsynccm\csname pgf@ar@cache@\pgf@arrow@id\endcsname% + \endpgfscope% + \pgf@arrows@rigid@hull% +} + +\def\pgf@bending@do@tangent{% + \pgf@xb\pgf@xa% + \advance\pgf@xb by-\pgf@x% + \pgfcurvilineardistancetotime{\pgf@xb}% + \pgf@xb\pgf@x% + % Compute points: + \ifdim\pgf@xb=0pt% + \pgf@bending@possible@degenerate% + \else% + \pgf@bending@do@tangent@normal% + \fi% + \pgf@ya-\pgf@y% + \pgfsettransformentries% + {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% + {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{\pgf@xc}{\pgf@yc}% +}% + +\def\pgf@bending@do@tangent@normal{% + \pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}% + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + % compute normal: + \advance\pgf@xb by-\pgf@xa% + \advance\pgf@yb by-\pgf@ya% + \pgf@process{\pgfpointnormalised{\pgf@x=\pgf@xb\pgf@y=\pgf@yb}} +} + +\def\pgf@bending@possible@degenerate{% + \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@b% degenerate! + \ifx\pgf@curvilinear@line@a\pgf@curvilinear@line@c% double degenerate! + \let\pgf@ref\pgf@curvilinear@line@d% + \else + \let\pgf@ref\pgf@curvilinear@line@c% + \fi% + \pgf@process{\pgf@curvilinear@line@a}% + \pgf@xc\pgf@x% save + \pgf@yc\pgf@y% save + \pgf@process{\pgf@ref}% + \advance\pgf@x by-\pgf@xc + \advance\pgf@y by-\pgf@yc + \pgf@process{\pgfpointnormalised{}} + \pgf@x-\pgf@x + \pgf@y-\pgf@y + \else% + \pgf@bending@do@tangent@normal% + \fi% +} + +\def\pgf@bending@do@flex{ + \pgf@xb\pgf@xa% + \pgf@xc\pgf@xa% + \advance\pgf@xc by-\pgf@x% + \advance\pgf@xb by-\pgf@y% + \pgfcurvilineardistancetotime{\pgf@xc}% + \pgf@xc\pgf@x% + \pgfcurvilineardistancetotime{\pgf@xb}% + \pgf@xb\pgf@x% + % Compute points: + \pgf@process{\pgfpointcurveattime{\pgf@xc}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \pgf@process{\pgfpointcurveattime{\pgf@xb}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \pgftransformarrow{\pgfqpoint{\pgf@xb}{\pgf@yb}}{\pgfqpoint{\pgf@xc}{\pgf@yc}}% +} + + + + + + +% Convex hull stuff: + +\def\pgf@arrows@bending@hull{% + \ifpgf@relevantforpicturesize% + % Do bb update: + \expandafter\let\expandafter\pgf@temp\csname pgf@ar@hull@\pgf@arrow@id\endcsname% + \ifx\pgf@temp\pgfutil@empty\else% + \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@first% + \pgf@temp% + \pgf@arrow@bending@update@bb% + \fi% + \fi% +} + +\def\pgf@arrow@bending@hull@point@first#1#2{% + \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}% + \pgf@xa\pgf@x\pgf@xb\pgf@x% + \pgf@ya\pgf@y\pgf@yb\pgf@y% + \let\pgf@arrow@hull@point\pgf@arrow@bending@hull@point@other% +} +\def\pgf@arrow@bending@hull@point@other#1#2{% + \pgfpointtransformednonlinear{\pgfqpoint{#1}{#2}}% + \ifdim\pgf@x<\pgf@xa\pgf@xa\pgf@x\else\ifdim\pgf@x>\pgf@xb\pgf@xb\pgf@x\fi\fi% + \ifdim\pgf@y<\pgf@ya\pgf@ya\pgf@y\else\ifdim\pgf@y>\pgf@yb\pgf@yb\pgf@y\fi\fi% +} + +\def\pgf@arrow@bending@update@bb{% + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picminx\pgf@xa% + \global\pgf@picmaxx\pgf@xb% + \global\pgf@picminy\pgf@ya% + \global\pgf@picmaxy\pgf@yb% + \else% + \ifdim\pgf@xa<\pgf@picminx\global\pgf@picminx\pgf@xa\fi% + \ifdim\pgf@ya<\pgf@picminy\global\pgf@picminy\pgf@ya\fi% + \ifdim\pgf@xb>\pgf@picmaxx\global\pgf@picmaxx\pgf@xb\fi% + \ifdim\pgf@yb>\pgf@picmaxy\global\pgf@picmaxy\pgf@yb\fi% + \fi% +} + + + + +% +% +% Handle the start of a curve +% +% + + +% First, the preparation. + +\def\pgf@prep@curvedstart{ + \pgftransformreset% + \pgfsetcurvilinearbeziercurve{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}% +} + +% Second, the shortening. + +\def\pgf@do@shorten@curvedstart{% + \expandafter\expandafter\expandafter\pgf@do@shorten@curvedstart@unpack\expandafter\pgfpointthirdonpath\pgfpointfourthonpath% +} +\def\pgf@do@shorten@curvedstart@unpack\pgfqpoint#1#2\pgfqpoint#3#4{% + \pgf@process{\pgfcurvilineardistancetotime{\pgf@path@shortening@distance}}% + % Compute new curve: + \pgfpointcurveattime{\pgf@x}{\pgfpointfirstonpath}{\pgfpointsecondonpath}{\pgfpointthirdonpath}{\pgfpointfourthonpath}% + % \pgfx/y and \pgf xa/xb already correct. Need to setup remaining vector... + \pgf@xb#1% + \pgf@yb#2% + \pgf@xb\pgf@time@t\pgf@xb% + \pgf@yb\pgf@time@t\pgf@yb% + \advance\pgf@xb by\pgf@time@s\pgf@xc% + \advance\pgf@yb by\pgf@time@s\pgf@yc% + \edef\pgfpointfirstonpath{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + \edef\pgfpointsecondonpath{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \edef\pgfprocessresultpathsuffix{% + \noexpand\pgfsyssoftpath@movetotoken{\the\pgf@x}{\the\pgf@y}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{\the\pgf@xa}{\the\pgf@ya}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{\the\pgf@xb}{\the\pgf@yb}% + \noexpand\pgfsyssoftpath@curvetotoken{#3}{#4}% + } + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter\pgfprocessresultpathsuffix% + \expandafter\expandafter\expandafter{\expandafter\pgfprocessresultpathsuffix\pgfsubpathend}% +} + + +% Third, the drawing + +\def\pgf@do@draw@curvedstart{% + \pgf@do@draw@curved\pgf@start@tip@sequence% +} + + + + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex index 1c78bb221e6..243f8ce225d 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledatavisualization.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.37 2010/08/24 21:28:58 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduledatavisualization.code.tex,v 1.47 2013/07/19 13:16:48 tantau Exp $ \usepgfmodule{oo,shapes} \usepgflibrary{fpu} @@ -156,6 +156,7 @@ \def\pgfdvpathlinetotoken{6} \def\pgfdvdirectionfromtoken{7} \def\pgfdvdirectiontotoken{8} + \def\pgfdvdirectionattoken{9} % Method % @@ -169,7 +170,10 @@ % Add data that is to be visualized. The code #1 should call the % \pgfdatapoint macro for each data point it creates. \method add data(#1) { - \pgfooappend{data}{#1} + \pgf@dv@stripped@add#1\pgf@stop + } + \def\pgf@dv@stripped@add#1\pgf@stop{% + \pgfooappend{data}{#1}% } @@ -480,20 +484,22 @@ -% Compute a normalized vector pointing from some point to another. +% Compute a normalized vector at the current point pointing along a +% line from #1 to #2. % % #1 = code for setting the attributes of the first point % #2 = code for setting the attributes of the second point % -% Using #1 and #2 you specify two data points. These are then -% localized on the canvas and a vector pointing from the first data -% point to the second one is returned. However, for instance in polar +% The current point should be a point on a line from #1 to +% #2. Both points as well as the current point are +% localized on the canvas and a vector pointing from the first point +% to the second one is returned. However, for instance in polar % coordinates the vector may actually "point along" the angle axis. % % Internally, this command first sets up the first data point and then -% emits a "path" signal with the \pgfdvpathdirectionfromtoken set and +% emits a "direction" signal with the \pgfdvpathdirectionfromtoken set and % then sets up the second point and emits the corresponding -% ...totoken. +% ...totoken. Finally, the \pgfdvpathdirectionattoken is emitted. % \def\pgfpointdvdirection#1#2{% @@ -504,16 +510,14 @@ } { #2 - \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{ - \edef\pgf@dv@dir@xa{\the\pgf@x} - \edef\pgf@dv@dir@ya{\the\pgf@y} + \pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectiontotoken}{\xdef\pgf@dv@to{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}} + } + {\pgfdv@generic{\pgf@signaldirection}{\pgfdvdirectionattoken}{% \pgf@process{ \pgfpointnormalised{% - \pgfpointdiff{\pgf@dv@from}{\pgfqpoint{\pgf@dv@dir@xa}{\pgf@dv@dir@ya}} + \pgfpointdiff{\pgf@dv@from}{\pgf@dv@to} } - } - } - } + }}} } } @@ -529,7 +533,7 @@ -% Run the rendering pipeline on a dataset. +% Run the rendering pipeline on a dataset and/or save the dataset. % % #1 = options with path /pgf/data/ % #2 = optionally data given inline in curly braces. @@ -541,14 +545,27 @@ % accumulate. Data can be in different formats, as specified by the % "format" key, and you can define new formats. % -% The setting of the following keys is important: +% The settings of the following keys are important: +% +% /pgf/data visualization/obj +% contains a handle to the dv-object +% +% /pgf/data/format +% stores the format (see below) +% +% /pgf/data/read from file +% determines where the data is. +% +% /pgf/data/store in group +% when nonempty, the data is stored here instead of being fed to the +% rendering pipeline % -% /pgf/data visualization/obj contains a handle to the dv-object -% /pgf/data/format stores the format (see below) -% /pgf/data/source determines where the data is. +% /pgf/data/use group +% when nonempty, data that has previsouly been stored here using +% |define group| is read from here and all other keys are ignored % -% If source is empty, the data is stored in the argument that -% follows. Otherwise, the file whose name is stored in source is read. +% If "read from file" is empty, the data is stored in the argument that +% follows. Otherwise, the data is read from the specified source file. % This data is stored in an internal variable, which is local to the % current group. % @@ -594,51 +611,78 @@ % 2200, 2300, 2250, 2260 % } % -% \pgfdata[source=data,format=comma separated columns] +% \pgfdata[read from file=data.csv,format=comma separated columns] % % \dv.survey() % \dv.visualize() -\def\pgfdata{\pgfutil@ifnextchar[{\pgf@dataset@data@opt}{\pgf@dataset@data@opt[]}}%} -\def\pgf@dataset@data@opt[#1]{% +\def\pgfdata{\pgfutil@ifnextchar[{\pgf@datagroup@data@opt}{\pgf@datagroup@data@opt[]}}%} +\def\pgf@datagroup@data@opt[#1]{% % Ok, add one data thing... - \pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})% \begingroup% \pgfkeys{/pgf/data/.cd,/pgf/every data/.try,#1}% \pgfkeysgetvalue{/pgf/data/continue code}\pgf@dv@cont@code% \global\let\pgf@dv@cont@code\pgf@dv@cont@code% - \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format% - \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname% - \ifx\pgf@dv@format@catcodes\relax - \PackageError{pgf}{Unknown data format '\pgf@dv@format'}{}% + \pgfkeysgetvalue{/pgf/data/use group}\pgf@dv@use@group% + \ifx\pgf@dv@use@group\pgfutil@empty% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data(\pgf@do@data{#1})}% + \expandafter\pgf@datagroup@data@opt@cont% \else% - \pgfkeysgetvalue{/pgf/data/source}\pgf@dv@source% - \ifx\pgf@dv@source\pgfutil@empty% - \let\pgf@next\pgf@dataset@grab@inline% + \expandafter\ifx\csname pgf@dv@group@@\pgf@dv@use@group\endcsname\relax% + \pgferror{Undefined data group '\pgf@dv@use@group'}% \else% - \let\pgf@next\pgf@dataset@grab@external% + {% + \pgfkeys{/pgf/data/define group/.code=}% no redefinitions during use + \csname pgf@dv@group@@\pgf@dv@use@group\endcsname% + }% \fi% - \pgf@next% + \endgroup% + \expandafter\pgf@dv@cont@code% + \fi% +} +\def\pgf@datagroup@data@opt@cont{% + \pgfkeysgetvalue{/pgf/data/format}\pgf@dv@format% + \expandafter\let\expandafter\pgf@dv@format@catcodes\csname pgfdv@format@\pgf@dv@format @catcodes\endcsname% + \ifx\pgf@dv@format@catcodes\relax + \pgferror{Unknown data format '\pgf@dv@format'}% + \else% + \pgfkeysgetvalue{/pgf/data/read from file}\pgf@dv@source% + \ifx\pgf@dv@source\pgfutil@empty% + \let\pgf@next\pgf@datagroup@grab@inline% + \else% + \let\pgf@next\pgf@datagroup@grab@external% + \fi% + \pgf@next% } -\def\pgf@dataset@grab@inline{% + +\def\pgf@datagroup@grab@inline{% \pgfutil@ifnextchar\bgroup{% \begingroup% \catcode`\^^M=\active% \pgf@dv@format@catcodes% - \pgf@dataset@grab@@inline}% - {\PackageError{pgf}{Opening brace expected}{}}% + \pgf@datagroup@grab@@inline}% + {\pgferror{Opening brace expected}}% } -\def\pgf@dataset@grab@external{% +\def\pgf@datagroup@grab@external{% \fi% \endgroup% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@external}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@external}}})}% \pgf@dv@cont@code% } +\def\pgf@dv@do@adddata#1{% + \pgfkeysgetvalue{/pgf/data/store in group}\pgf@dv@temp% + \ifx\pgf@dv@temp\pgfutil@empty% + #1% + \else% + \expandafter\pgfutil@g@addto@macro\csname pgf@dv@group@@\pgf@dv@temp\endcsname{#1}% + \fi% +} + {\catcode`\^^M=\active% - \gdef\pgf@dataset@grab@@inline#1{% + \gdef\pgf@datagroup@grab@@inline#1{% \endgroup% - \pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@dataset@do@inline#1^^M\pgf@@eol}}})% + \pgf@dv@do@adddata{\pgfkeysvalueof{/pgf/data visualization/obj}.add data({{{\pgf@datagroup@do@inline#1^^M\pgf@@eol}}})}% \fi% \endgroup% \pgf@dv@cont@code% @@ -663,19 +707,19 @@ % Read external file % -\def\pgf@dataset@do@external{% +\def\pgf@datagroup@do@external{% \csname pgfdv@format@\pgfkeysvalueof{/pgf/data/format}@catcodes\endcsname% - \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/source} % + \immediate\openin\r@pgf@reada=\pgfkeysvalueof{/pgf/data/read from file} % \ifeof\r@pgf@reada\relax - \PackageError{pgf}{Data source '\pgfkeysvalueof{/pgf/data/source}' not found}{}% + \pgferror{Data file '\pgfkeysvalueof{/pgf/data/read from file}' not found}% \else - \pgf@dataset@readline% + \pgf@datagroup@readline% \fi \immediate\closein\r@pgf@reada% } \def\pgf@partext{\par}% -\def\pgf@dataset@readline{% +\def\pgf@datagroup@readline{% \immediate\read\r@pgf@reada to \pgf@temp% \ifx\pgf@temp\pgf@partext% \pgf@dv@format@emptyline% @@ -686,7 +730,7 @@ \expandafter\pgf@dv@format@line\pgf@temp\pgfeol% \fi% \fi% - \ifeof\r@pgf@reada\else\expandafter\pgf@dataset@readline\fi% + \ifeof\r@pgf@reada\else\expandafter\pgf@datagroup@readline\fi% } @@ -694,7 +738,7 @@ % Read inline data % -\def\pgf@dataset@do@inline{% +\def\pgf@datagroup@do@inline{% \pgf@dv@handle@line% } @@ -712,8 +756,12 @@ \pgfkeys{ /pgf/data/data visualization obj/.initial=\undefined, /pgf/data/format/.initial=table,% the default format - /pgf/data/source/.initial=, - /pgf/data/continue code/.initial= + /pgf/data/read from file/.initial=, + /pgf/data/inline/.style={read from file=}, + /pgf/data/continue code/.initial=, + /pgf/data/store in group/.initial=, + /pgf/data/new group/.code={\expandafter\global\expandafter\let\csname pgf@dv@group@@#1\endcsname\pgfutil@empty}, + /pgf/data/use group/.initial=, } @@ -737,7 +785,7 @@ % a data set is visualized and the format is set to #1, this handler % is used to parse the data. % -% In detail, the \dataset command will select a source. Before this +% In detail, the \pgfdata command will select a source. Before this % source is read, #2 will be executed to setup the % catcodes. Additionally, each time the data is parsed, #3 will be % called. Then, for each nonempty line of the source, the @@ -791,12 +839,23 @@ % % Example: % -% \data[format=key value pairs] { +% \data[format=named] { % x=5, y=6, hi=9 % x=7, y=6, lo=10 % } -\pgfdeclaredataformat{key value pairs}{}{}{#1}{{\pgfkeys{/data point/.cd,#1}\pgfdatapoint}}{}{} +\pgfdeclaredataformat{named}{}{}{#1}{\pgf@dv@parse@named#1,\pgf@stop}{}{} +\def\pgf@dv@parse@named{% + \pgfutil@ifnextchar\pgf@stop{\pgfdatapoint\pgfutil@gobble}{\pgf@dv@parse@named@} +} +\def\pgf@dv@parse@named@#1=#2,#3\pgf@stop{% + \foreach \pgf@dv@temp in {#2} {% + \def\pgf@dv@tempb{/data point/#1=}% + \expandafter\expandafter\expandafter\pgfkeys% + \expandafter\expandafter\expandafter{\expandafter\pgf@dv@tempb\pgf@dv@temp}% + \pgf@dv@parse@named#3\pgf@stop% + } +} @@ -892,7 +951,7 @@ \def\pgf@dv@parse@table{% \pgfutil@ifnextchar"% Special, but ignored right now... - {\PackageError{pgf}{csv with quotes not yet implemented}{}} + {\pgferror{csv with quotes not yet implemented}} {\pgf@dv@till@separator} } \def\pgf@dv@table@handle#1{% @@ -924,7 +983,7 @@ \def\pgf@dv@doparse@headline{% \pgfutil@ifnextchar"% Special, but ignored right now... - {\PackageError{pgf}{csv with quotes not yet implemented}{}} + {\pgferror{csv with quotes not yet implemented}} {\pgf@dv@till@separator@head} } \def\pgf@dv@head@handle#1{% @@ -1158,6 +1217,27 @@ \let#1=\pgfmathresult% } +% Multiply by small number +% +% #1 = macro that should store the result of applying the +% corresponding operation to the following: +% #2 = entered number +% #3 = fixed point number like 2 or 0.5, but not 10000000000 +% +% Description: +% +% Sets #1 to the result of applying an operation to #2 and #3 +% +% Example: +% +% \pgfdvmathenter{\a}{2000} +% \pgfdvmathadd{\b}{\a}{0.2} +% % \b now stores 400 + +\def\pgfdvmathmulfixed#1#2#3{% + \pgfmathfloatmultiplyfixed{#2}{#3}% + \let#1=\pgfmathresult% +} @@ -1457,12 +1537,15 @@ \attribute out min; % Start of the second range (the value of c). + \attribute out min; + % End of the second range (the value of d). + \attribute trans in min; % Transformed value of the start of the first range (the value % f(a)). \attribute scale; - % The scaling factor, that is, the value of (f(d)-f(c))/(b-a). + % The scaling factor, that is, the value of (f(b)-f(a))/(d-c). % Constructor @@ -1540,6 +1623,7 @@ \pgfdvmathenter{\pgf@out@interval@max}{#4} % Let's start with the output, it's easier... \pgfoolet{out min}{\pgf@out@interval@min} + \pgfoolet{out max}{\pgf@out@interval@max} \pgfdvmathsub{\pgf@out@diff}{\pgf@out@interval@max}{\pgf@out@interval@min} \let\pgfvalue=\pgf@in@interval@min \pgfoovalueof{trans} @@ -1568,8 +1652,10 @@ \pgfkeysgetvalue{/data point/\pgfoovalueof{in}}\pgf@dv@external@value% \fi% \ifx\pgf@dv@external@value\pgfutil@empty% + \pgf@dv@mapper@pos@check% \else% \ifx\pgf@dv@external@value\relax% + \pgf@dv@mapper@pos@check% \else% % % Clip? \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% @@ -1581,20 +1667,20 @@ % \fi% \fi% \fi% - \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value% - \ifx\pgf@dv@external@value\relax\else% - \ifx\pgf@dv@external@value\pgfutil@empty\else% - \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% - \pgf@dv@mapper@trans{/min} - \fi - \fi - \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value% - \ifx\pgf@dv@external@value\relax\else% - \ifx\pgf@dv@external@value\pgfutil@empty\else% - \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% - \pgf@dv@mapper@trans{/max} - \fi - \fi +% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/min}\pgf@dv@external@value% +% \ifx\pgf@dv@external@value\relax\else% +% \ifx\pgf@dv@external@value\pgfutil@empty\else% +% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% +% \pgf@dv@mapper@trans{/min} +% \fi +% \fi +% \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/max}\pgf@dv@external@value% +% \ifx\pgf@dv@external@value\relax\else% +% \ifx\pgf@dv@external@value\pgfutil@empty\else% +% \pgfdvmathenter{\pgfvalue}{\pgf@dv@external@value}% +% \pgf@dv@mapper@trans{/max} +% \fi +% \fi \fi% } @@ -1616,6 +1702,22 @@ \pgfdvmathexitbyserializing{\pgf@temp}{\pgfvalue}% \pgfkeyslet{/data point/\pgfoovalueof{out}#1}\pgf@temp% } + + \def\pgf@dv@mapper@pos@check{% + \pgfkeysgetvalue{/data point/\pgfoovalueof{in}/out pos}\pgf@dv@pos@value% + \ifx\pgf@dv@pos@value\relax\else\if\pgf@dv@pos@value\pgfutil@empty\else% + \pgfmathsetmacro{\pgf@dv@pos@num}{\pgf@dv@pos@value}% + \pgfmathsetmacro{\pgf@dv@pos@num@prime}{1-\pgf@dv@pos@num}% + % Ok, compute transformed min position: + \pgfooget{out min}{\pgf@out@interval@min} + \pgfooget{out max}{\pgf@out@interval@max} + \pgfdvmathmulfixed{\pgf@out@interval@min}{\pgf@out@interval@min}{\pgf@dv@pos@num@prime} + \pgfdvmathmulfixed{\pgf@out@interval@max}{\pgf@out@interval@max}{\pgf@dv@pos@num} + \pgfdvmathadd{\pgf@out@val}{\pgf@out@interval@min}{\pgf@out@interval@max}% + \pgfdvmathexitbyserializing{\pgf@temp}{\pgf@out@val}% + \pgfkeyslet{/data point/\pgfoovalueof{out}}\pgf@temp% + \fi\fi% + } } @@ -1868,8 +1970,15 @@ % "seen" during the survey phase. Based on this value, the size of, % say, an axis can be detemined later on. % - % In case the attribute has the sub-attributes "min" and "max", they - % are also taken into account. + % You can also set the key "sub attributes" of the attribute. In + % this case, this key should contain -- as the name suggests -- a + % list of subkeys that should also be taken into account for the + % computation of the minimum and maximum value. Inside the "sub + % attributes" key, each subkey should be surrounded by a call of + % \pgfdvsub. For instance, if there are two sub attributes "/data + % point/velocity/min" and "/data point/velocity/max" for a key + % "/data point/velocity", then "/data point/velocity/sub attributes" + % should be set to "\pgfdvsub{/min}\pgfdvsub{/max}". \attribute attribute; % The to-be-surveyed attribute @@ -1902,9 +2011,12 @@ % Adjust the interval as if during the survey this value were % encountered \method include attribute value(#1) { - \def\pgf@dv@val{#1} + \pgf@dv@assign@val@stripped#1\pgf@stop% \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) } + \def\pgf@dv@assign@val@stripped#1\pgf@stop{% + \def\pgf@dv@val{#1} + } % Slot % @@ -1913,34 +2025,36 @@ % interval. % \method survey() { - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/min}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}/max}\pgf@dv@val% - \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv) + \let\pgfdvsub\pgf@dv@range@surv@sub + \pgfdvsub{}% + \pgfkeysvalueof{/data point/\pgfoovalueof{attribute}/sub attributes} } - \def\pgf@dv@range@surv{% + \def\pgf@dv@range@surv@sub#1{ + \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute}#1}\pgf@dv@val% \ifx\pgf@dv@val\relax% \else% \edef\pgf@dv@val{\pgf@dv@val}% \ifx\pgf@dv@val\pgfutil@empty% \else% - \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}% - % Now, protocol value - \ifx\pgfdvmin\pgfutil@empty% - \let\pgfdvmin\pgf@dv@value% - \else% - \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}% - \fi% - \ifx\pgfdvmax\pgfutil@empty% - \let\pgfdvmax\pgf@dv@value% - \else% - \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}% - \fi% + \pgfoovalueof{interval obj}.adjust(\pgf@dv@range@surv)% \fi% - \fi + \fi% + } + + \def\pgf@dv@range@surv{% + \pgfdvmathenter{\pgf@dv@value}{\pgf@dv@val}% + % Now, protocol value + \ifx\pgfdvmin\pgfutil@empty% + \let\pgfdvmin\pgf@dv@value% + \else% + \pgfdvmathifless{\pgf@dv@value}{\pgfdvmin}{\let\pgfdvmin\pgf@dv@value}{}% + \fi% + \ifx\pgfdvmax\pgfutil@empty% + \let\pgfdvmax\pgf@dv@value% + \else% + \pgfdvmathifless{\pgfdvmax}{\pgf@dv@value}{\let\pgfdvmax\pgf@dv@value}{}% + \fi% } } @@ -1976,6 +2090,10 @@ % filter should set \pgfdvfilterpassedfalse for to-be-filtered data % point. % + % You can specify "projection code" that changes the canvas x and + % canvas y positions. This projection code allows you to draw, say, + % projected points instead of the actual data point. + % % The keys /data point//execute at begin and /data % point//execute at end, where is the name of % the visualizer, should store code that is to be executed directly @@ -1987,7 +2105,7 @@ % The to-be-used handlers \attribute name; - % Filter code + % The attribute \attribute filter=\pgfdvnamedvisualizerfilter; % Filter code @@ -2000,7 +2118,15 @@ % cache. Every 100 steps this cache is moved to positions. The idea % behind this is that it will avoid the quadratic time increase that % is normally caused when a protocol is build in TeX. - + + \attribute projection code; + % This code is empty by default. However, you can set it for + % instance to the following + % + % \pgfkeyssetvalue{/data point/y=0}\pgfdvmapdatapointtocanvas + % + % in order to visualize the data point with its y-coordinate + % replaced by 0. % Constructor % @@ -2025,6 +2151,11 @@ \pgfooset{filter}{#1} } + % Setter + \method set projection code(#1) { + \pgfooset{projection code}{#1} + } + % Slot \method protocol() { \pgfdvfilterpassedtrue @@ -2037,7 +2168,17 @@ \def\pgf@dv@line@cache@it{ % Cache it \pgfooget{cache}\pgf@dv@cache - \edef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}% + \pgfkeysgetvalue{/data point/outlier}\pgf@temp% + \ifx\pgf@temp\pgfutil@empty + {% + \pgfoovalueof{projection code} + \xdef\pgf@dv@add{\noexpand\pgf@dv@ph{\pgfkeysvalueof{/data + point/canvas x}}{\pgfkeysvalueof{/data point/canvas y}}}% + } + \else% + % An outlier! + \gdef\pgf@dv@add{\pgf@dv@outliner}% + \fi% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\pgf@dv@cache% \expandafter\expandafter\expandafter{\expandafter\pgf@dv@cache\pgf@dv@add}% @@ -2072,10 +2213,10 @@ \else \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} \tikz@dv@temp - \pgfplotstreamstart + \pgfdvnewstreamtrue \pgfoovalueof{positions} \pgfoovalueof{cache} - \pgfplotstreamend + \ifpgfdvnewstream\else\pgfplotstreamend\fi \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} \fi } @@ -2084,15 +2225,22 @@ \pgfoolet{cache}\pgfutil@empty } - \def\pgf@dv@ph#1#2{\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} + \def\pgf@dv@ph#1#2{\ifpgfdvnewstream\pgfplotstreamstart\pgfdvnewstreamfalse\fi\pgfplotstreampoint{\pgfqpoint{#1}{#2}}} + \def\pgf@dv@outliner{\ifpgfdvnewstream\else\pgfplotstreamend\pgfdvnewstreamtrue\fi} } +\newif\ifpgfdvnewstream \newcount\pgf@lib@dv@cache@count +\pgfkeys{% + /data point/outlier/.initial=, + /data point/outlier/.default=true +} + % A possible filter for unnamed visualizers % -% #1 = Text to be compared with key /data point/visualizer +% #1 = Text to be compared with key /data point/set % % Description: % @@ -2103,10 +2251,10 @@ % point/visualizer. % % When objects allow you to set a filter, you can use this filter to -% test against /data point/visualizer being equal to #1. +% test against /data point/set being equal to #1. \def\pgfdvvisualizerfilter#1{% - \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer% + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% \def\pgf@temp{#1}% \ifx\pgf@temp\pgf@dv@visualizer% \else @@ -2122,10 +2270,10 @@ % % This filter works like \pgfdvvisualizerfilter, only it assumes the % the object defines a "name" attribute. In this case, the value of -% /data point/visualizer is tested against this attribute. +% /data point/set is tested against this attribute. \def\pgfdvnamedvisualizerfilter{% - \pgfkeysgetvalue{/data point/visualizer}\pgf@dv@visualizer% + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% \pgfooget{name}\pgf@temp% \ifx\pgf@temp\pgf@dv@visualizer% \else @@ -2140,16 +2288,19 @@ % Class rectangle visualizer % % This visualizer visualizes a datapoint as a rectangle. It needs - % two attributes a1 and a2, each of which must have min and max - % subattributes. Then, it draws a rectangle between (a1/min,a2/min) - % and (a1/max,a2/max). - - \attribute attribute 1; - \attribute attribute 2; - % The attributes + % a name, so that /data point//attribute 1 and /data + % point//attribute 2 store two attributes names a1 to a2. Then, + % provided the current value of /data point/set equals name, for + % each data point a rectangle between (a1/min,a2/min) and + % (a1/max,a2/max) is created. + - \attribute use path attribute; - % The attribute that stores the to-be-taken action + \attribute name; + % The name + + \attribute a1; + \attribute a2; + % The attributes, filled from /data point//attribute 1 and 2 % Constructor @@ -2157,47 +2308,65 @@ % #1 = first attribute % #2 = second attribute % - \method rectangle visualizer(#1,#2,#3) { - \pgfooset{attribute 1}{#1} - \pgfooset{attribute 2}{#2} - \pgfooset{use path attribute}{#3} + \method rectangle visualizer(#1) { + \pgfooset{name}{#1} } % Method \method default connects() { \pgfoothis.get handle(\pgf@dv@me) \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,visualize,visualize datapoint signal) + \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal) } - + + % Slot + \method phase(#1) {% + \ifx#1\pgfdvbeginsurvey% + \pgfooeset{a1}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 1}} + \pgfooeset{a2}{/data point/\pgfkeysvalueof{/data point/\pgfoovalueof{name}/attribute 2}} + \pgfkeyssetvalue{\pgfoovalueof{a1}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}} + \pgfkeyssetvalue{\pgfoovalueof{a2}/sub attributes}{\pgfdvsub{/min}\pgfdvsub{/max}} + \fi% + } + % Slot \method visualize() { { - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/min}\pgf@dv@amin - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 1}/max}\pgf@dv@amax - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/min}\pgf@dv@bmin - \pgfkeysgetvalue{/data point/\pgfoovalueof{attribute 2}/max}\pgf@dv@bmax + \pgfkeysgetvalue{/data point/set}\pgf@dv@visualizer% + \pgfooget{name}\pgf@temp% + \ifx\pgf@temp\pgf@dv@visualizer% + \pgf@dv@rect@do + \fi + } + } + + \def\pgf@dv@rect@do{ + \pgfkeysgetvalue{\pgfoovalueof{a1}/min}\pgf@dv@amin \ifx\pgf@dv@amin\relax\else\ifx\pgf@dv@amin\pgfutil@empty\else - \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a1}/max}\pgf@dv@amax \ifx\pgf@dv@amax\relax\else\ifx\pgf@dv@amax\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a2}/min}\pgf@dv@bmin + \ifx\pgf@dv@bmin\relax\else\ifx\pgf@dv@bmin\pgfutil@empty\else + \pgfkeysgetvalue{\pgfoovalueof{a2}/max}\pgf@dv@bmax \ifx\pgf@dv@bmax\relax\else\ifx\pgf@dv@bmax\pgfutil@empty\else - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin} - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin} - \pgfpathdvmoveto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmax} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amax} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 2}}{\pgf@dv@bmin} - \pgfpathdvlineto - \pgfkeyssetvalue{/data point/\pgfoovalueof{attribute 1}}{\pgf@dv@amin} - \pgfpathdvlineto - \pgfpathclose - \pgfkeysvalueof{/data point/\pgfoovalueof{use path attribute}} + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at begin} + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin} + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin} + \pgfpathdvmoveto + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmax} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amax} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a2}}{\pgf@dv@bmin} + \pgfpathdvlineto + \pgfkeyssetvalue{\pgfoovalueof{a1}}{\pgf@dv@amin} + \pgfpathdvlineto + \pgfpathclose + \pgfkeysvalueof{/data point/\pgfoovalueof{name}/execute at end} \fi\fi \fi\fi \fi\fi \fi\fi - } } } @@ -2253,10 +2422,7 @@ % \method label visualizer(#1,#2,#3,#4) { \pgfooset{attribute}{#1} - \ifx#2\pgfutil@empty - \else - \pgfdvmathenter{\pgf@temp}{#2} - \fi + \expandafter\pgfdvmathenter\expandafter{\expandafter\pgf@temp\expandafter}\expandafter{#2} \pgfoolet{threshold}\pgf@temp \pgfooset{code}{#3} \pgfooset{filter}{#4} @@ -2531,6 +2697,10 @@ \pgfooset{strategy}{#4} } + % Method + \method default connects() { + } + % Method \method add entry(#1) { \pgfooappend{entries}{{#1}} @@ -2795,6 +2965,12 @@ \method set max(#1) { \pgfooset{max}{#1} } + \method let min(#1) { + \pgfoolet{min}{#1} + } + \method let max(#1) { + \pgfoolet{max}{#1} + } % Getter % @@ -2835,16 +3011,9 @@ % present or that have a certain property. By default, for every % data point a counter is incremented and the value of this counter % is stored in an attribute. You can also specify an increment for - % the counter and some action that should be taken when the counter - % reaches zero. You can also specify that certain data points should + % the counter. You can specify that certain data points should % not have an effect on the counter. - % - % Counters can serve different purposes. - % - % 1. For plotting points in a table or sequence, the counter can be - % used to provide the position along one axis. - % 2. By using the counter as a repetitive count down one can for - % instance have only every 10th data point be marked. + \attribute attribute; % The attribute that will be set to the current value of the counter @@ -2852,6 +3021,9 @@ \attribute val=0; % The current value of the counter + \attribute max=0; + % The current value of the counter + \attribute step=1; % The stepping by which the counter is incremented for each % datapoint @@ -2880,6 +3052,11 @@ \pgfkeysvalueof{/pgf/data visualization/obj}.connect(\pgf@dv@me,phase,phase signal) } + % Getter + \method get max(#1) { + \pgfooget{max}{#1} + } + % Setter \method set value(#1) { \pgfooset{val}{#1} @@ -2889,6 +3066,7 @@ % Setter \method set start value(#1) { \pgfooset{start val}{#1} + \pgfooset{max}{#1} } % Setter @@ -2909,6 +3087,11 @@ \pgfmathparse{\pgfoovalueof{val}+\pgfoovalueof{step}}% \pgfoolet{val}\pgfmathresult% \pgfkeyslet{/data point/\pgfoovalueof{attribute}}\pgfmathresult% + \ifdim\pgfmathresult pt>\pgfoovalueof{max}pt\relax% + \pgfoolet{max}\pgfmathresult% + \fi% + \pgfooget{max}\pgfmathresult% + \pgfkeyslet{/data point/\pgfoovalueof{attribute}/max}\pgfmathresult% \fi% } diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex index 9834e91f0ec..c2bf2582a29 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduledecorations.code.tex @@ -92,8 +92,8 @@ \long\def\pgfdeclaredecoration#1#2#3{% \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% \pgfifmetadecoration{#1}{% - \PackageError{pgf}{You cannot declare a decoration of the same - name as a meta-decoration}{}% + \pgferror{You cannot declare a decoration of the same + name as a meta-decoration}% \let\pgf@mod@dec@next=\pgfutil@gobble% }{}% \pgf@mod@dec@next @@ -141,8 +141,8 @@ \long\def\pgfdeclaremetadecoration#1#2#3{% \let\pgf@mod@dec@next=\pgf@mod@dec@firstofone% \pgfifdecoration{#1}{% - \PackageError{pgf}{You cannot declare a meta-decoration of the - same name as a decoration}{}% + \pgferror{You cannot declare a meta-decoration of the + same name as a decoration}% \let\pgf@mod@dec@next=\pgfutil@gobble% }{}% \pgf@mod@dec@next{% @@ -193,38 +193,38 @@ % % Example: % -% \pgfdeclaredecoration{circles}{red circles}{ -% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetstrokecolor{red!\pgfmathresult!brown} -% \pgfsetfillcolor{orange!\pgfmathresult!yellow} -% \pgfpathcircle{\pgfpointorigin}{2.5pt} -% \pgfusepath{stroke,fill} -% } -% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetstrokecolor{blue!\pgfmathresult!gray} -% \pgfsetfillcolor{blue!\pgfmathresult!white} -% \pgfpathcircle{\pgfpointorigin}{2.5pt} -% \pgfusepath{stroke,fill} -% } -% \state{final}{} -% } -% -% \pgfpicture -% \pgfdecoratepath{circles} -% { -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} -% } -% \endpgfpicture +% \pgfdeclaredecoration{circles}{red circles}{ +% \state{red circles}[width=10pt, repeat state=2, next state=blue circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{red!\pgfmathresult!brown} +% \pgfsetfillcolor{orange!\pgfmathresult!yellow} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{blue circles}[width=10pt, repeat state=1, next state=red circles] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetstrokecolor{blue!\pgfmathresult!gray} +% \pgfsetfillcolor{blue!\pgfmathresult!white} +% \pgfpathcircle{\pgfpointorigin}{2.5pt} +% \pgfusepath{stroke,fill} +% } +% \state{final}{} +% } +% +% \pgfpicture +% \pgfdecoratepath{circles} +% { +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{3cm}}{\pgfpoint{4cm}{0cm}}{\pgfpoint{4cm}{3cm}} +% } +% \endpgfpicture % \long\def\pgfdecoratepath#1#2{% - \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% - #2% - \endpgfdecoration} + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + #2% + \endpgfdecoration} @@ -240,37 +240,37 @@ % % Example: % -% \pgfdeclaredecoration{stars}{move}{ -% \state{move}[width=7.5pt, next state=star]{} -% \state{star}[width=7.5pt, next state=move] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetfillcolor{yellow!\pgfmathresult!orange} -% \pgfsetstrokecolor{yellow!\pgfmathresult!red} -% \pgfmathparse{rnd*.75+.25} -% \pgftransformscale{\pgfmathresult} -% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} -% } -% \state{final} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathlast} -% } -% } -% -% \pgfpicture -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} -% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} -% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} -% \pgfdecoratecurrentpath{stars} -% \endpgfpicture +% \pgfdeclaredecoration{stars}{move}{ +% \state{move}[width=7.5pt, next state=star]{} +% \state{star}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{yellow!\pgfmathresult!orange} +% \pgfsetstrokecolor{yellow!\pgfmathresult!red} +% \pgfmathparse{rnd*.75+.25} +% \pgftransformscale{\pgfmathresult} +% \pgfnode{star}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \pgfdecoratecurrentpath{stars} +% \endpgfpicture % \def\pgfdecoratecurrentpath#1{% - \pgfgetpath\pgf@decorate@currentpath% - \pgfsetpath\pgfutil@empty% - \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% - \pgfsetpath\pgf@decorate@currentpath% - \endpgfdecoration} + \pgfgetpath\pgf@decorate@currentpath% + \pgfsetpath\pgfutil@empty% + \pgfdecoration{{#1}{\pgfdecoratedpathlength}{\pgfdecoratebeforecode}{\pgfdecorateaftercode}}% + \pgfsetpath\pgf@decorate@currentpath% + \endpgfdecoration} @@ -282,22 +282,22 @@ % Definitions: % % `existing path' -% - any unsed path exsiting prior to the environment. +% - any unsed path exsiting prior to the environment. % % `decorated path' -% - the path that is being decorated. +% - the path that is being decorated. % -% `decoration path' -% - any unused path left by the decoration automaton. +% `decoration path' +% - any unused path left by the decoration automaton. % % The action of the environment is as follows: % -% 1. Any existing path is saved. -% 2. Construction commands are executed forming the decorated path. -% 3. If the first command in the decorated path is not a `move to', +% 1. Any existing path is saved. +% 2. Construction commands are executed forming the decorated path. +% 3. If the first command in the decorated path is not a `move to', % the last known position from the exisiting path is inserted. -% 4. The saved existing path is reinstalled. -% 5. The decoration automaton is executed along the decorated path. +% 4. The saved existing path is reinstalled. +% 5. The decoration automaton is executed along the decorated path. % % Parameters: % @@ -322,142 +322,142 @@ % is executed just before the decoration automaton % starts and is executed just after the automaton stops. % If or are empty, they can be omitted. -% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast +% The macros \pgfdecoratedpathfirst and \pgfdecoratedpathlast % will be set up as the first and last points on the current section % of the decorated path. % % When the environment exits, the following macros will be set up: % -% \pgfdecorateexistingpath -% - the existing path. +% \pgfdecorateexistingpath +% - the existing path. % -% \pgfdecoratedpath -% - the decorated path. +% \pgfdecoratedpath +% - the decorated path. % -% \pgfdecorationpath -% - any unused decoration path. +% \pgfdecorationpath +% - any unused decoration path. % -% \pgfpointdecoratedpathlast +% \pgfpointdecoratedpathlast % - the last point on the decorated path. % % Examples (require pgfdecorations library): % -% \pgfpicture -% \pgfdecoration -% { -% {lineto}{\pgfdecoratedpathlength/3}, -% {zigzag}{\pgfdecoratedpathlength/3}, -% {lineto}{\pgfdecoratedpathlength/3} -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% \pgfusepath{stroke} -% \endpgfpicture -% -% -% \pgfpicture -% \pgfdecoration -% { -% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, -% {zigzag}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% }, -% {lineto}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% }, -% {zigzag}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% }, -% {lineto}{\pgfdecoratedpathlength/5} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathfirst} -% } -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% -% \endpgfpicture -% -% -% -% \pgfdeclaredecoration{polygons}{move}{ -% \state{move}[width=7.5pt, next state=polygon]{} -% \state{polygon}[width=7.5pt, next state=move] -% { -% \pgfmathparse{round(rnd*100)} -% \pgfsetfillcolor{green!\pgfmathresult!yellow} -% \pgfsetstrokecolor{green!\pgfmathresult!brown} -% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} -% } -% \state{final} -% { -% \pgfpathmoveto{\pgfpointdecoratedpathlast} -% } -% } -% -% \pgfpicture -% \pgfdecoration -% { -% {polygons}{45pt}, -% {lineto}{30pt} -% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% { -% \pgfsetstrokecolor{yellow!50!orange} -% \pgfusepath{stroke} -% }, -% {polygons}{45pt}, -% {lineto}{30pt} -% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% { -% \pgfsetstrokecolor{green!50!blue} -% \pgfusepath{stroke} -% }, -% {polygons}{\pgfdecoratedremainingdistance} -% } -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \endpgfdecoration -% \endpgfpicture -% -% -% \pgfpicture -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} -% \pgfgetpath\temppath -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% -% \pgfset{decoration text={Here is some text all the way along this curve!}} -% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} -% \pgfsetpath\temppath -% \endpgfdecoration -% \endpgfpicture +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/3}, +% {zigzag}{\pgfdecoratedpathlength/3}, +% {lineto}{\pgfdecoratedpathlength/3} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \pgfusepath{stroke} +% \endpgfpicture +% +% +% \pgfpicture +% \pgfdecoration +% { +% {lineto}{\pgfdecoratedpathlength/5}{}{\pgfusepath{stroke}}, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% }, +% {zigzag}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% }, +% {lineto}{\pgfdecoratedpathlength/5} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathfirst} +% } +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% +% \endpgfpicture +% +% +% +% \pgfdeclaredecoration{polygons}{move}{ +% \state{move}[width=7.5pt, next state=polygon]{} +% \state{polygon}[width=7.5pt, next state=move] +% { +% \pgfmathparse{round(rnd*100)} +% \pgfsetfillcolor{green!\pgfmathresult!yellow} +% \pgfsetstrokecolor{green!\pgfmathresult!brown} +% \pgfnode{regular polygon}{center}{}{}{\pgfusepath{stroke,fill}} +% } +% \state{final} +% { +% \pgfpathmoveto{\pgfpointdecoratedpathlast} +% } +% } +% +% \pgfpicture +% \pgfdecoration +% { +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{yellow!50!orange} +% \pgfusepath{stroke} +% }, +% {polygons}{45pt}, +% {lineto}{30pt} +% {\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% { +% \pgfsetstrokecolor{green!50!blue} +% \pgfusepath{stroke} +% }, +% {polygons}{\pgfdecoratedremainingdistance} +% } +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \endpgfdecoration +% \endpgfpicture +% +% +% \pgfpicture +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfpoint{0cm}{4cm}}{\pgfpoint{5cm}{0cm}}{\pgfpoint{5cm}{4cm}} +% \pgfgetpath\temppath +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% +% \pgfset{decoration text={Here is some text all the way along this curve!}} +% \pgfdecoration{{text}{\pgfdecoratedremainingdistance}} +% \pgfsetpath\temppath +% \endpgfdecoration +% \endpgfpicture % \def\pgfdecoration#1{% \begingroup% \def\pgf@decorate@decorationlist{#1}% - \pgf@decoration@env% + \pgf@decoration@env% } \def\endpgfdecoration{% @@ -498,47 +498,47 @@ % % Example: % -% \pgfdeclaremetadecoration{fancy line}{line to}{ -% \state{line to}[width=1cm, next state=zigzag] -% { -% \decoration{lineto} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% \state{zigzag}[width=2cm, next state=line to] -% { -% \decoration{zigzag} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{red} -% \pgfusepath{stroke} -% } -% } -% \state{final} -% { -% \decoration{lineto} -% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} -% \afterdecoration -% { -% \pgfsetstrokecolor{black} -% \pgfusepath{stroke} -% } -% } -% } -% -% \pgfpicture -% \pgfmetadecoration{fancy line} -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} -% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} -% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} -% \endpgfmetadecoration -% \endpgfpicture +% \pgfdeclaremetadecoration{fancy line}{line to}{ +% \state{line to}[width=1cm, next state=zigzag] +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% \state{zigzag}[width=2cm, next state=line to] +% { +% \decoration{zigzag} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{red} +% \pgfusepath{stroke} +% } +% } +% \state{final} +% { +% \decoration{lineto} +% \beforedecoration{\pgfpathmoveto{\pgfpointdecoratedpathfirst}} +% \afterdecoration +% { +% \pgfsetstrokecolor{black} +% \pgfusepath{stroke} +% } +% } +% } +% +% \pgfpicture +% \pgfmetadecoration{fancy line} +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathcurveto{\pgfqpoint{0cm}{2cm}}{\pgfqpoint{3cm}{2cm}}{\pgfqpoint{3cm}{0cm}} +% \pgfpathcurveto{\pgfqpoint{3cm}{-3cm}}{\pgfqpoint{0cm}{0cm}}{\pgfqpoint{0cm}{-3cm}} +% \pgfpathcurveto{\pgfqpoint{0cm}{-5cm}}{\pgfqpoint{3cm}{-5cm}}{\pgfqpoint{3cm}{-3cm}} +% \endpgfmetadecoration +% \endpgfpicture % \def\pgfmetadecoration#1{% \begingroup% @@ -550,47 +550,47 @@ } \def\endpgfmetadecoration{% - \pgf@decoration@endenv% - \ifx\pgfdecoratedpath\pgfutil@empty% - \else% - \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% - \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% - \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% - % - % Perform the meta decoration... - % - \expandafter\let\expandafter\pgf@metadecoration@current@state% - \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% - \pgf@metadecoration@run% - % - % ..until the final state. - % - \let\pgf@decorate@tempname\pgfutil@empty% - \let\pgf@decorate@tempbefore\pgfutil@empty% - \let\pgf@decorate@tempafter\pgfutil@empty% - \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% - \ifx\pgf@decorate@tempname\pgfutil@empty% - \def\pgf@decorate@tempname{moveto} - \fi% - \pgf@decorate@invoke{% - {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% - {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% - }% - \fi% - \pgfgetpath\pgfdecorationpath% - % - % Take stuff outside the group. - % - \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% - \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% - \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% - \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% - \endgroup% - % - % Are we in LaTeX? - % - \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% - {\pgf@decorate@installmacrosatend}% + \pgf@decoration@endenv% + \ifx\pgfdecoratedpath\pgfutil@empty% + \else% + \let\pgfmetadecoratedpathlength\pgf@decorate@totalpathlength% + \def\pgfmetadecoratedinputsegmentremainingdistance{\pgfdecoratedremainingdistance}% + \def\pgfmetadecoratedinputsegmentcompleteddistance{\pgfdecoratedcompleteddistance}% + % + % Perform the meta decoration... + % + \expandafter\let\expandafter\pgf@metadecoration@current@state% + \csname pgf@metadecoration@@\pgf@metadecoration@name @initial\endcsname% + \pgf@metadecoration@run% + % + % ..until the final state. + % + \let\pgf@decorate@tempname\pgfutil@empty% + \let\pgf@decorate@tempbefore\pgfutil@empty% + \let\pgf@decorate@tempafter\pgfutil@empty% + \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% + \ifx\pgf@decorate@tempname\pgfutil@empty% + \def\pgf@decorate@tempname{moveto} + \fi% + \pgf@decorate@invoke{% + {\pgf@decorate@tempname}{\pgfdecoratedremainingdistance}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + }% + \fi% + \pgfgetpath\pgfdecorationpath% + % + % Take stuff outside the group. + % + \global\let\pgf@decorate@decorationpathtemp\pgfdecorationpath% + \global\let\pgf@decorate@decoratedpathtemp\pgfdecoratedpath% + \global\let\pgf@decorate@existingpathtemp\pgfdecorateexistingpath% + \global\let\pgfpoint@decorated@pathlasttemp\pgfpoint@decorated@pathlast% + \endgroup% + % + % Are we in LaTeX? + % + \pgfutil@ifnextchar\@checkend{\aftergroup\pgf@decorate@installmacrosatend}% + {\pgf@decorate@installmacrosatend}% } @@ -606,26 +606,26 @@ \let\pgfdecorationpath\pgfutil@empty% \let\pgfdecoratedpath\pgfutil@empty% \let\pgfpoint@decorated@pathlast\pgfpointorigin% - \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% + \edef\pgfpoint@decorate@existingpathlast{\pgf@x\the\pgf@path@lastx\pgf@y\the\pgf@path@lasty}% % % Begin a group so transformations don't mess things up. % - \bgroup% + \bgroup% } \def\pgf@decorate@path@check@moveto#1{% - \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} + \expandafter\pgf@decorate@path@@check@moveto#1\pgf@decorate@stop\pgf@decorate@@stop} \def\pgf@decorate@token@stop{\pgf@decorate@stop}% \def\pgf@decorate@path@@check@moveto#1#2#3#4\pgf@decorate@@stop#5#6{% - \def\pgf@decorate@temp{#4}% - \pgf@x=#2\relax% - \pgf@y=#3\relax% - \ifx\pgf@decorate@temp\pgf@decorate@token@stop% - #5% - \else% - #6% - \fi% + \def\pgf@decorate@temp{#4}% + \pgf@x=#2\relax% + \pgf@y=#3\relax% + \ifx\pgf@decorate@temp\pgf@decorate@token@stop% + #5% + \else% + #6% + \fi% } \def\pgf@decoration@endenv{% @@ -638,20 +638,20 @@ \pgfsetpath\pgfdecorateexistingpath% % \ifx\pgfdecoratedpath\pgfutil@empty% - \PackageError{PGF}{I cannot decorate an empty path}{}% + \pgferror{I cannot decorate an empty path}% \else% - % - % If the path consists of a single moveto token, make it - % a very small horizontal line. - % - \pgf@decorate@path@check@moveto\pgfdecoratedpath{% - \advance\pgf@x by0.0001pt\relax% - \edef\pgfdecoratedpath{% - \expandafter\noexpand\pgfdecoratedpath% - \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}% - }% - }% - {}% + % + % If the path consists of a single moveto token, make it + % a very small horizontal line. + % + \pgf@decorate@path@check@moveto\pgfdecoratedpath{% + \advance\pgf@x by0.0001pt\relax% + \edef\pgfdecoratedpath{% + \expandafter\noexpand\pgfdecoratedpath% + \noexpand\pgfsyssoftpath@linetotoken{\the\pgf@x}{\the\pgf@y}% + }% + }% + {}% % % Remove special round tokens and get points. % @@ -668,7 +668,7 @@ % Reverse objects if necessary. % \ifpgf@decorate@inputsegmentobjects@reverse% - \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}% + \pgf@decorate@inputsegmentobjects@reverse{\pgf@decorate@inputsegmentobjects}{\pgf@decorate@inputsegmentobjects}% \fi% % \let\pgf@decorated@remainingdistance\pgf@decorate@totalpathlength% @@ -687,13 +687,13 @@ \pgf@decorate@processnextinputsegmentobject% \pgf@decorate@distancetomove0pt\relax% \fi% -}% +}% \def\pgf@decorate@installmacrosatend{% - \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% + \let\pgfdecorationpath\pgf@decorate@decorationpathtemp% \let\pgfdecoratedpath\pgf@decorate@decoratedpathtemp% \let\pgfdecorateexistingpath\pgf@decorate@existingpathtemp% \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@pathlasttemp% @@ -710,18 +710,18 @@ % A version of \pgfutil@for which doesn't expand each value in #3. % \def\pgf@decorate@for#1:=#2\do#3{% - \def\pgf@decorate@for@var{#1}% - \def\pgf@decorate@for@action{#3}% - \expandafter\pgf@decorate@@for#2,\pgf@stop,} - + \def\pgf@decorate@for@var{#1}% + \def\pgf@decorate@for@action{#3}% + \expandafter\pgf@decorate@@for#2,\pgf@stop,} + \def\pgf@decorate@@for#1,{% - \ifx#1\pgf@stop% - \expandafter\let\pgf@decorate@for@var\pgfutil@empty% - \else% - \expandafter\def\pgf@decorate@for@var{#1}% - \pgf@decorate@for@action% - \expandafter\pgf@decorate@@for% - \fi% + \ifx#1\pgf@stop% + \expandafter\let\pgf@decorate@for@var\pgfutil@empty% + \else% + \expandafter\def\pgf@decorate@for@var{#1}% + \pgf@decorate@for@action% + \expandafter\pgf@decorate@@for% + \fi% } @@ -730,97 +730,97 @@ % #1 - {}{}{}{} % \def\pgf@decorate@invoke#1{% - \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} - + \pgf@decorate@@invoke#1\pgf@decorate@invoke\pgf@decorate@invoke\pgf@decorate@invoke\pgf@stop} + \def\pgf@decorate@@invoke#1#2#3#4#5\pgf@stop{% - \pgfutil@ifundefined{pgf@decorate@@#1@initial}% - {% - \PackageError{PGF}{Unknown decoration `#1'}{}% - }% - {% - \def\pgf@decorate@name{#1}% - \ifx\pgf@decorate@invoke#3% - \let\pgf@decorate@beforecode\pgfutil@empty% - \else% - \def\pgf@decorate@beforecode{#3}% - \fi% - \ifx\pgf@decorate@invoke#4% - \let\pgf@decorate@aftercode\pgfutil@empty% - \else% - \def\pgf@decorate@aftercode{#4}% - \fi% - % - % Make remaining distance and the decorated path length `public'. - % - \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% - \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% - % - \pgfmathsetlength\pgf@xa{#2}% - \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% - \pgf@xa\pgf@decorated@remainingdistance\relax% - \fi% - \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% - % - % Calculate the distance remaining to the end of the entire path. - % - \pgf@xa-\pgf@decorate@currentpathlength\relax% - \advance\pgf@xa\pgf@decorated@remainingdistance\relax% - \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% - % - % Set up the macros and distances for the current section - % of the decorated path. - % - \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% - \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% - \pgfdecoratedcompleteddistance0pt\relax% - % - % Execute user-defined code beore decoration. - % - \pgf@decorate@beforecode% - % - % Run the decoration... - % - \expandafter\let\expandafter\pgf@decorate@current@state% - \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% - \pgf@decorate@run% - % - % ...until the final state. - % - \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. - \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% - \else% - % - % Set up \pgfpoint@decorated@pathlast if the end of - % the total decorated path has not been reached. - % - {% - \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% - \pgf@decorate@transformtoinputsegment% - \pgfpointorigin% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% - \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% - \fi% - {% - \pgftransformreset% - \pgf@decorate@transformtoinputsegment% - \pgf@decorate@additionaltransform% - \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% - }% - \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% - % - % Execute user-defined code after decoration. - % - \pgf@decorate@aftercode% - % - % Update the input segment objects. - % - \let\pgf@decorate@additionaltransform\pgfutil@empty% - \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% - \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% - }% + \pgfutil@ifundefined{pgf@decorate@@#1@initial}% + {% + \pgferror{Unknown decoration `#1'}% + }% + {% + \def\pgf@decorate@name{#1}% + \ifx\pgf@decorate@invoke#3% + \let\pgf@decorate@beforecode\pgfutil@empty% + \else% + \def\pgf@decorate@beforecode{#3}% + \fi% + \ifx\pgf@decorate@invoke#4% + \let\pgf@decorate@aftercode\pgfutil@empty% + \else% + \def\pgf@decorate@aftercode{#4}% + \fi% + % + % Make remaining distance and the decorated path length `public'. + % + \pgfdecoratedremainingdistance\pgf@decorated@remainingdistance\relax% + \let\pgfdecoratedpathlength\pgf@decorate@totalpathlength% + % + \pgfmathsetlength\pgf@xa{#2}% + \ifdim\pgf@xa>\pgf@decorated@remainingdistance\relax% + \pgf@xa\pgf@decorated@remainingdistance\relax% + \fi% + \edef\pgf@decorate@currentpathlength{\the\pgf@xa}% + % + % Calculate the distance remaining to the end of the entire path. + % + \pgf@xa-\pgf@decorate@currentpathlength\relax% + \advance\pgf@xa\pgf@decorated@remainingdistance\relax% + \edef\pgf@decorated@remainingdistance{\the\pgf@xa}% + % + % Set up the macros and distances for the current section + % of the decorated path. + % + \let\pgfdecoratedpathlength\pgf@decorate@currentpathlength% + \pgfdecoratedremainingdistance\pgfdecoratedpathlength\relax% + \pgfdecoratedcompleteddistance0pt\relax% + % + % Execute user-defined code beore decoration. + % + \pgf@decorate@beforecode% + % + % Run the decoration... + % + \expandafter\let\expandafter\pgf@decorate@current@state% + \csname pgf@decorate@@\pgf@decorate@name @initial\endcsname% + \pgf@decorate@run% + % + % ...until the final state. + % + \ifdim\pgf@decorated@remainingdistance<1pt\relax% Should be =0pt, but need to control for inaccuracies. + \let\pgfpoint@decorated@pathlast\pgfpoint@decorated@totalpathlast% + \else% + % + % Set up \pgfpoint@decorated@pathlast if the end of + % the total decorated path has not been reached. + % + {% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + \pgf@decorate@transformtoinputsegment% + \pgfpointorigin% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% + \edef\pgfpoint@decorated@pathlast{\pgf@x\the\pgf@x\pgf@y\the\pgf@y}% + \fi% + {% + \pgftransformreset% + \pgf@decorate@transformtoinputsegment% + \pgf@decorate@additionaltransform% + \csname pgf@decorate@@\pgf@decorate@name @final@code\endcsname% + }% + \pgf@decorate@movealonginputsegment{\the\pgfdecoratedremainingdistance}% + % + % Execute user-defined code after decoration. + % + \pgf@decorate@aftercode% + % + % Update the input segment objects. + % + \let\pgf@decorate@additionaltransform\pgfutil@empty% + \let\pgf@decorate@inputsegmentobjects\pgf@decorate@inputsegmentobjects@aftersplit% + \let\pgfpoint@decorated@pathfirst\pgfpoint@decorated@pathlast% + }% } @@ -832,25 +832,25 @@ % \pgfpointdecoratedpathfirst % \def\pgfpointdecoratedpathfirst{% - {% - \pgftransforminvert% - \pgfpoint@decorated@pathfirst% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathfirst% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% % \pgfpointdecoratedpathlast % \def\pgfpointdecoratedpathlast{% - {% - \pgftransforminvert% - \pgfpoint@decorated@pathlast% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgfpoint@decorated@pathlast% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% % \pgfpointdecoratedinputsegmentfirst @@ -858,27 +858,27 @@ % The first point of the current sub-path. % \def\pgfpointdecoratedinputsegmentfirst{% - {% - \pgftransforminvert% - \pgf@decorate@inputsegment@first% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% -}% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@first% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% +}% % \pgfpointdecoratedinputsegmentlast % % The final point of the current sub-path. % \def\pgfpointdecoratedinputsegmentlast{% - {% - \pgftransforminvert% - \pgf@decorate@inputsegment@last% - \pgf@pos@transform{\pgf@x}{\pgf@y}% - \global\pgf@x\pgf@x% - \global\pgf@y\pgf@y% - }% + {% + \pgftransforminvert% + \pgf@decorate@inputsegment@last% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \global\pgf@x\pgf@x% + \global\pgf@y\pgf@y% + }% }% @@ -887,7 +887,7 @@ % Run a normal decoration. % \def\pgf@decorate@run{% - \let\pgf@decorate@next\pgf@decorate@do@state% + \let\pgf@decorate@next\pgf@decorate@do@state% \ifx\pgf@decorate@current@state\pgf@final@text% \let\pgf@decorate@next\relax% \fi% @@ -931,10 +931,10 @@ % Next iteration. % \ifnum\pgf@decorate@repeatstate>0\relax% - \advance\pgf@decorate@repeatstate-1\relax% + \advance\pgf@decorate@repeatstate-1\relax% \else% - \pgf@decorate@repeatstate-1\relax% - \let\pgf@decorate@current@state\pgf@decorate@next@state% + \pgf@decorate@repeatstate-1\relax% + \let\pgf@decorate@current@state\pgf@decorate@next@state% \fi% \pgf@decorate@run% } @@ -1063,13 +1063,13 @@ \def\pgf@metadecoration@decoration#1{% - \edef\pgf@decorate@tempname{#1}% + \edef\pgf@decorate@tempname{#1}% } \def\pgf@metadecoration@beforedecoration#1{% - \def\pgf@decorate@tempbefore{#1}% + \def\pgf@decorate@tempbefore{#1}% } \def\pgf@metadecoration@afterdecoration#1{% - \def\pgf@decorate@tempafter{#1}% + \def\pgf@decorate@tempafter{#1}% } @@ -1078,7 +1078,7 @@ % Run a meta decoration. % \def\pgf@metadecoration@run{% - \let\pgf@metadecoration@next\pgf@metadecoration@do@state% + \let\pgf@metadecoration@next\pgf@metadecoration@do@state% \ifx\pgf@metadecoration@current@state\pgf@final@text% \let\pgf@metadecoration@next\relax% \fi% @@ -1086,7 +1086,7 @@ } \def\pgf@metadecoration@do@state{% - \let\pgf@metadecoration@next\relax% + \let\pgf@metadecoration@next\relax% \let\pgf@metadecoration@next@state\pgf@metadecoration@current@state% % % Set up some macros. @@ -1107,7 +1107,7 @@ } \def\pgf@metadecoration@do@code{% - % + % % Execute code. % \let\pgf@decorate@tempname\pgfutil@empty% @@ -1117,11 +1117,11 @@ \let\pgfpointmetadecoratedpathlast\pgfpointdecoratedpathlast% \csname pgf@metadecoration@@\pgf@metadecoration@name @\pgf@metadecoration@current@state @code\endcsname% \ifx\pgf@decorate@tempname\pgfutil@empty% - \def\pgf@decorate@tempname{moveto} - \fi% + \def\pgf@decorate@tempname{moveto} + \fi% \pgf@decorate@invoke{% - {\pgf@decorate@tempname}{\pgf@metadecoration@width}% - {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% + {\pgf@decorate@tempname}{\pgf@metadecoration@width}% + {\pgf@decorate@tempbefore}{\pgf@decorate@tempafter}% }% % % Next iteration. @@ -1141,7 +1141,7 @@ \def\pgf@metadecoration@switch@if#1to #2\pgf@stop{% \ifx\pgf@metadecoration@next\relax% - \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@x{#1}% \ifdim\pgf@decorated@remainingdistance<\pgf@x% \def\pgf@metadecoration@current@state{#2}% \let\pgf@metadecoration@next\pgf@metadecoration@run% @@ -1151,7 +1151,7 @@ \def\pgf@metadecoration@switch@ifinputsegment#1to #2\pgf@stop{% \ifx\pgf@metadecoration@next\relax% - \pgfmathsetlength\pgf@x{#1}% + \pgfmathsetlength\pgf@x{#1}% \ifdim\pgfdecoratedinputsegmentremainingdistance<\pgf@x% \def\pgf@metadecoration@current@state{#2}% \let\pgf@metadecoration@next\pgf@metadecoration@run% @@ -1164,10 +1164,10 @@ % Move along the path by a specified distance. % \def\pgf@decorate@movealongpath#1{% - \pgfmathsetlength\pgf@decorate@distancetomove{#1}% - \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% - \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% - \pgf@decorate@@movealongpath% + \pgfmathsetlength\pgf@decorate@distancetomove{#1}% + \advance\pgfdecoratedcompleteddistance\pgf@decorate@distancetomove% + \advance\pgfdecoratedremainingdistance-\pgf@decorate@distancetomove% + \pgf@decorate@@movealongpath% } \def\pgf@decorate@@movealongpath{% \advance\pgfdecoratedinputsegmentcompleteddistance\pgf@decorate@distancetomove% @@ -1188,107 +1188,107 @@ } \def\pgf@decorate@@@movealongpath{% - % - % Move along input segment for real. - % - \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% - \pgf@decorate@distancetomove0pt\relax% - % - % Grrr. Hacking to control some inaccuracies. - % - \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% - \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% - \pgf@decorate@processnextinputsegmentobject% - \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% - \advance\pgf@x-1pt\relax% - \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% - \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% - \pgfdecoratedremainingdistance0pt\relax% - \fi% - \fi% + % + % Move along input segment for real. + % + \pgf@decorate@movealonginputsegment{\the\pgf@decorate@distancetomove}% + \pgf@decorate@distancetomove0pt\relax% + % + % Grrr. Hacking to control some inaccuracies. + % + \ifdim\pgf@decorate@inputsegmenttime pt>1pt\relax% + \let\pgf@decorate@inputsegmenttimetemp\pgf@decorate@inputsegmenttime% + \pgf@decorate@processnextinputsegmentobject% + \pgf@x\pgf@decorate@inputsegmenttimetemp pt\relax% + \advance\pgf@x-1pt\relax% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@x}}% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \pgfdecoratedremainingdistance0pt\relax% + \fi% + \fi% } % Return the next input segment object in a macro % \def\pgf@decorate@getnextinputsegmentobject#1{% - \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% - \let\pgf@next\relax% - \else% - \def\pgf@decorate@temp{#1}% - \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% - \fi% - \pgf@next% + \ifx\pgf@decorate@currentinputsegmentobjects\pgfutil@empty% + \let\pgf@next\relax% + \else% + \def\pgf@decorate@temp{#1}% + \let\pgf@next\pgf@decorate@@getnextinputsegmentobject% + \fi% + \pgf@next% } \def\pgf@decorate@@getnextinputsegmentobject{% - \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} + \expandafter\pgf@decorate@@@getnextinputsegmentobject\pgf@decorate@currentinputsegmentobjects\pgf@stop} \def\pgf@decorate@@@getnextinputsegmentobject#1#2\pgf@stop{% - \expandafter\def\pgf@decorate@temp{#1}% - \def\pgf@decorate@currentinputsegmentobjects{#2}} + \expandafter\def\pgf@decorate@temp{#1}% + \def\pgf@decorate@currentinputsegmentobjects{#2}} % Process the next input segment object. % \def\pgf@decorate@processnextinputsegmentobject{% - \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment% - \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% - % - % If the current input segment object is a moveto, execute the - % object macro and get the next input segment object. - % - \pgf@decorate@is@closepath@false% - \pgf@decorate@currentinputsegmentobject% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% - \pgfpathmoveto{\pgf@decorate@inputsegment@first}% - \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment% - \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% - \pgf@decorate@is@closepath@false% - \pgf@decorate@currentinputsegmentobject% - \fi% - % - % Teensy hack in case a path goes nowhere. - % - \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% - \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. - \fi% - \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% - \pgfdecoratedinputsegmentcompleteddistance0pt\relax% - \def\pgf@decorate@inputsegmenttime{0}% - % - % Get the angle at the start of the input segment. - % - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - \let\pgfdecoratedangle\pgfmathresult% - \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \let\pgfdecoratedinputsegmentendangle\pgfmathresult% - \else% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% - \let\pgfdecoratedangle\pgfmathresult% - \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% - \let\pgfdecoratedinputsegmentendangle\pgfmathresult% - \fi% - % - % Get the angle to the next input segment. - % - \begingroup% - \pgf@decorate@nextinputsegmentobject% - \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% - \expandafter\pgf@decorate@currentinputsegmentobject% - \fi% - \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - \else% - \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% - \fi% - \pgf@x-\pgfdecoratedangle pt\relax% - \advance\pgf@x\pgfmathresult pt\relax% - \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}% - \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment% - \endgroup% - \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp% + \let\pgfdecorationpreviousinputsegment\pgfdecoratecurrentinputsegment% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + % + % If the current input segment object is a moveto, execute the + % object macro and get the next input segment object. + % + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \pgfpathmoveto{\pgf@decorate@inputsegment@first}% + \let\pgfdecorationpreviousinputsegment\pgfdecorationcurrentinputsegment% + \let\pgf@decorate@currentinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@getnextinputsegmentobject\pgf@decorate@nextinputsegmentobject% + \pgf@decorate@is@closepath@false% + \pgf@decorate@currentinputsegmentobject% + \fi% + % + % Teensy hack in case a path goes nowhere. + % + \ifdim\pgfdecoratedinputsegmentlength=0pt\relax% + \def\pgfdecoratedinputsegmentlength{0.05pt}% Arbitrary choice >0pt. + \fi% + \pgfdecoratedinputsegmentremainingdistance\pgfdecoratedinputsegmentlength\relax% + \pgfdecoratedinputsegmentcompleteddistance0pt\relax% + \def\pgf@decorate@inputsegmenttime{0}% + % + % Get the angle at the start of the input segment. + % + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \let\pgfdecoratedangle\pgfmathresult% + \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \let\pgfdecoratedinputsegmentendangle\pgfmathresult% + \else% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% + \let\pgfdecoratedangle\pgfmathresult% + \let\pgfdecoratedinputsegmentstartangle\pgfmathresult% + \let\pgfdecoratedinputsegmentendangle\pgfmathresult% + \fi% + % + % Get the angle to the next input segment. + % + \begingroup% + \pgf@decorate@nextinputsegmentobject% + \global\let\pgf@decorate@temp\pgfdecorationcurrentinputsegment% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \expandafter\pgf@decorate@currentinputsegmentobject% + \fi% + \ifx\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + \else% + \pgfmathanglebetweenpoints{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last}% + \fi% + \pgf@x-\pgfdecoratedangle pt\relax% + \advance\pgf@x\pgfmathresult pt\relax% + \edef\pgfdecoratedangletonextinputsegment{\the\pgf@x}% + \pgfmath@smuggleone\pgfdecoratedangletonextinputsegment% + \endgroup% + \let\pgfdecorationnextinputsegmentobject\pgf@decorate@temp% } @@ -1315,56 +1315,55 @@ % Input segment object moveto. % \def\pgf@decorate@inputsegmentobject@moveto#1{% - \def\pgf@decorate@inputsegment@first{#1}% - \def\pgf@decorate@inputsegment@supporta{#1}% - \def\pgf@decorate@inputsegment@supportb{#1}% - \def\pgf@decorate@inputsegment@last{#1}% - \edef\pgf@decorate@lastmoveto{#1}% - \def\pgfdecoratedinputsegmentlength{0pt}% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% + \def\pgf@decorate@inputsegment@first{#1}% + \def\pgf@decorate@inputsegment@supporta{#1}% + \def\pgf@decorate@inputsegment@supportb{#1}% + \def\pgf@decorate@inputsegment@last{#1}% + \edef\pgf@decorate@lastmoveto{#1}% + \def\pgfdecoratedinputsegmentlength{0pt}% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentmoveto% } % Input segment object lineto. % \def\pgf@decorate@inputsegmentobject@lineto#1#2#3{% - \def\pgfdecoratedinputsegmentlength{#1}% - \def\pgf@decorate@inputsegment@first{#2}% - \def\pgf@decorate@inputsegment@last{#3}% - % - % Supports should be defined like this, so if treated as a curve, - % equal time steps will correspond to equal distances. - % - \pgfpointdiff{#2}{#3}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\pgf@decorate@inputsegment@supporta{% - \pgf@process{#2}% - \advance\pgf@x0.333333\pgf@xa% - \advance\pgf@y0.333333\pgf@ya% - }% - \pgfextract@process\pgf@decorate@inputsegment@supportb{% - \pgf@process{#2}% - \advance\pgf@x0.666666\pgf@xa% - \advance\pgf@y0.666666\pgf@ya% - }% - % - \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% - \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@last{#3}% + % + % Supports should be defined like this, so if treated as a curve, + % equal time steps will correspond to equal distances. + % + \pgfpointdiff{#2}{#3}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\pgf@decorate@inputsegment@supporta{% + \pgf@process{#2}% + \advance\pgf@x0.333333\pgf@xa% + \advance\pgf@y0.333333\pgf@ya% + }% + \pgfextract@process\pgf@decorate@inputsegment@supportb{% + \pgf@process{#2}% + \advance\pgf@x0.666666\pgf@xa% + \advance\pgf@y0.666666\pgf@ya% + }% + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlineto% } % Input segment object curveto. % \def\pgf@decorate@inputsegmentobject@curveto#1#2#3#4#5{% - \def\pgfdecoratedinputsegmentlength{#1}% - \def\pgf@decorate@inputsegment@first{#2}% - \def\pgf@decorate@inputsegment@supporta{#3}% - \def\pgf@decorate@inputsegment@supportb{#4}% - \def\pgf@decorate@inputsegment@last{#5}% - % - \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% - \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% + \def\pgfdecoratedinputsegmentlength{#1}% + \def\pgf@decorate@inputsegment@first{#2}% + \def\pgf@decorate@inputsegment@supporta{#3}% + \def\pgf@decorate@inputsegment@supportb{#4}% + \def\pgf@decorate@inputsegment@last{#5}% + % + \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@curve% + \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@curve% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentcurveto% } % Input segment object closepath. @@ -1377,31 +1376,31 @@ \def\pgfdecoratedinputsegmentlength{#1}% \def\pgf@decorate@inputsegment@first{#2}% \def\pgf@decorate@inputsegment@last{#3}% - % - \pgfpointdiff{#2}{#3}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgfextract@process\pgf@decorate@inputsegment@supporta{% - \pgf@process{#2}% - \advance\pgf@x0.333333\pgf@xa% - \advance\pgf@y0.333333\pgf@ya% - }% - \pgfextract@process\pgf@decorate@inputsegment@supportb{% - \pgf@process{#2}% - \advance\pgf@x0.666666\pgf@xa% - \advance\pgf@y0.666666\pgf@ya% - }% - % + % + \pgfpointdiff{#2}{#3}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgfextract@process\pgf@decorate@inputsegment@supporta{% + \pgf@process{#2}% + \advance\pgf@x0.333333\pgf@xa% + \advance\pgf@y0.333333\pgf@ya% + }% + \pgfextract@process\pgf@decorate@inputsegment@supportb{% + \pgf@process{#2}% + \advance\pgf@x0.666666\pgf@xa% + \advance\pgf@y0.666666\pgf@ya% + }% + % \let\pgf@decorate@movealonginputsegment\pgf@decorate@movealonginputsegment@line% \let\pgf@decorate@transformtoinputsegment\pgf@decorate@transformtoinputsegment@line% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentclosepath% } % Input segment object endofinputsegments. % \def\pgf@decorate@inputsegmentobject@endofinputsegments{% - \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast% + \let\pgfdecorationcurrentinputsegment\pgfdecorationinputsegmentlast% } @@ -1414,93 +1413,92 @@ % This macro controls how the automaton moves along a curve sub-path. % \def\pgf@decorate@movealonginputsegment@curve#1{% - \ifdim#1=0pt\relax% - \else% - \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% - % - % Reduce the initial time step, depending on the length - % of the path. To do: Optimise this step (should also depend on #1). - % - \ifdim\pgf@decorate@currentpathlength<128pt\relax% - \pgf@yb.03125pt\relax% - \else% - \ifdim\pgf@decorate@currentpathlength<512pt\relax% - \pgf@yb.015625pt\relax% - \else% - \ifdim\pgf@decorate@currentpathlength<2048pt\relax% - \pgf@yb.00390625pt\relax% - \else% - \pgf@yb.0009765625pt\relax% - \fi% - \fi% - \fi% - \c@pgf@counta1\relax% - \pgfutil@tempdima0pt\relax% - \pgfmathloop% - \advance\pgf@xb\c@pgf@counta\pgf@yb% - % - % We would like to use \pgfpointcurveattime. However, we must not - % overuse \pgf@process or \pgfmath stuff within this loop, - % otherwise we increase the chances of save stack overflow. - % - \edef\pgf@decorate@temp{% - \pgf@xa\the\pgf@xa% - \pgf@xb\the\pgf@xb% - \pgf@ya\the\pgf@ya% - \pgf@yb\the\pgf@yb% - }% - % - \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - % - \pgf@decorate@temp% - % - \pgf@xc\pgf@xa% - \pgf@yc\pgf@ya% - \pgf@xa\pgf@x% - \pgf@ya\pgf@y% - \advance\pgf@x-\pgf@xc% - \advance\pgf@y-\pgf@yc% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% - \ifnum\c@pgf@counta>0\relax% - \ifdim\pgfutil@tempdima>#1\relax% - \c@pgf@counta-\c@pgf@counta% - \pgf@yb.5\pgf@yb% - \fi% - \else% - \ifdim\pgfutil@tempdima<#1\relax% - \c@pgf@counta-\c@pgf@counta% - \pgf@yb.5\pgf@yb% - \fi% - \fi% - \ifdim\pgf@yb=0pt\relax% *Should* be OK. - \else% - \repeatpgfmathloop% - \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% - % - % Now calculate the angle at the new time on the curve. - % - % We can use \pgfpointcurveattime safely here. - % - \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% - \edef\pgf@marshal{% - \noexpand\pgfmathanglebetweenpoints% - {\pgf@x\the\pgf@xb\pgf@y\pgf@yb}% - {\pgf@x\the\pgf@xa\pgf@y\pgf@ya}% - }% - \pgf@marshal% - \let\pgfdecoratedangle\pgfmathresult% - \fi% + \ifdim#1=0pt\relax% + \else% + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \pgf@xb\pgf@decorate@inputsegmenttime pt\relax% + % + % Reduce the initial time step, depending on the length + % of the path. To do: Optimise this step (should also depend on #1). + % + \ifdim\pgf@decorate@currentpathlength<128pt\relax% + \pgf@yb.03125pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<512pt\relax% + \pgf@yb.015625pt\relax% + \else% + \ifdim\pgf@decorate@currentpathlength<2048pt\relax% + \pgf@yb.00390625pt\relax% + \else% + \pgf@yb.0009765625pt\relax% + \fi% + \fi% + \fi% + \c@pgf@counta1\relax% + \pgfutil@tempdima0pt\relax% + \pgfmathloop% + \advance\pgf@xb\c@pgf@counta\pgf@yb% + % + % We would like to use \pgfpointcurveattime. However, we must not + % overuse \pgf@process or \pgfmath stuff within this loop, + % otherwise we increase the chances of save stack overflow. + % + \edef\pgf@decorate@temp{% + \pgf@xa\the\pgf@xa% + \pgf@xb\the\pgf@xb% + \pgf@ya\the\pgf@ya% + \pgf@yb\the\pgf@yb% + }% + % + \pgfpoint@decorate@curveattime{\pgfmath@tonumber{\pgf@xb}}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgf@decorate@temp% + % + \pgf@xc\pgf@xa% + \pgf@yc\pgf@ya% + \pgf@xa\pgf@x% + \pgf@ya\pgf@y% + \advance\pgf@x-\pgf@xc% + \advance\pgf@y-\pgf@yc% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \advance\pgfutil@tempdima\c@pgf@counta\pgfutil@tempdimb% + \ifnum\c@pgf@counta>0\relax% + \ifdim\pgfutil@tempdima>#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \else% + \ifdim\pgfutil@tempdima<#1\relax% + \c@pgf@counta-\c@pgf@counta% + \pgf@yb.5\pgf@yb% + \fi% + \fi% + \ifdim\pgf@yb=0pt\relax% *Should* be OK. + \else% + \repeatpgfmathloop% + \edef\pgf@decorate@inputsegmenttime{\pgfmath@tonumber{\pgf@xb}}% + % + % Now calculate the angle at the new time on the curve. + % + % We can use \pgfpointcurveattime safely here. + % + \pgfpointcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \edef\pgf@marshal{% + \noexpand\pgfmathanglebetweenpoints% + {\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}% + }% + \pgf@marshal% + \let\pgfdecoratedangle\pgfmathresult% + \fi% } % \pgfpoint@decorate@curveattime @@ -1549,141 +1547,140 @@ % Applies the necessary transform for a line sub-path. % \def\pgf@decorate@transformtoinputsegment@line{% - \pgftransformshift{% - \pgfpointadd{\pgf@decorate@inputsegment@first}% - {\pgfpointpolar{\pgfdecoratedangle}{\pgfdecoratedinputsegmentcompleteddistance}}% - }% - \pgftransformrotate{\pgfdecoratedangle}% + \pgftransformshift{% + \pgfpointlineatdistance{\pgfdecoratedinputsegmentcompleteddistance}{\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@last} + }% + \pgftransformrotate{\pgfdecoratedangle}% } % Applies the necessary transform for a curve sub-path. % \def\pgf@decorate@transformtoinputsegment@curve{% - \pgfslopedattimetrue% - \pgfallowupsidedownattimetrue% - \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% - {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% - {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% + \pgfslopedattimetrue% + \pgfallowupsidedownattimetrue% + \pgftransformcurveattime{\pgf@decorate@inputsegmenttime}% + {\pgf@decorate@inputsegment@first}{\pgf@decorate@inputsegment@supporta}% + {\pgf@decorate@inputsegment@supportb}{\pgf@decorate@inputsegment@last}% } -% \pgf@decorate@parsesoftpath -% -% Parses an instance of a soft path into intermediate line and curve -% sub-path objects which the decoration automaton can use to traverse +% \pgf@decorate@parsesoftpath +% +% Parses an instance of a soft path into intermediate line and curve +% sub-path objects which the decoration automaton can use to traverse % the decorated path. -% -% The soft path should be well formed and only contain `primative' -% soft path tokens, that is: moveto, lineto, curvetosupporta, -% curvetosupportb, curveto, rectcorner, rectsize, and closepath. -% (i.e., all specialround tokens should have removed using -% \pgfprocessround) -% -% The overall length of the path is also calculated and returned -% in the macro \pgfdecoratedpathlength. -% -% Parameters: -% -% #1 - a macro containing a well formed soft path. -% #2 - a macro to store the intermediate sub-path representations. -% -% Example: -% -% \pgfpathmoveto{\pgfpointorigin} -% \pgfpathlineto{\pgfpoint{0pt}{12pt}} -% \pgfpathlineto{\pgfpoint{12pt}{0pt}} -% \pgfgetpath\softpath -% -% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath} -% -% results in: -% -% \parsedsoftpath -> -% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} -% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} -% -% \pgfdecoratedpathlength -> -% 24pt +% +% The soft path should be well formed and only contain `primative' +% soft path tokens, that is: moveto, lineto, curvetosupporta, +% curvetosupportb, curveto, rectcorner, rectsize, and closepath. +% (i.e., all specialround tokens should have removed using +% \pgfprocessround) +% +% The overall length of the path is also calculated and returned +% in the macro \pgfdecoratedpathlength. +% +% Parameters: +% +% #1 - a macro containing a well formed soft path. +% #2 - a macro to store the intermediate sub-path representations. +% +% Example: +% +% \pgfpathmoveto{\pgfpointorigin} +% \pgfpathlineto{\pgfpoint{0pt}{12pt}} +% \pgfpathlineto{\pgfpoint{12pt}{0pt}} +% \pgfgetpath\softpath +% +% \pgf@decorate@parsesoftpath{\softpath}{\parsedsoftpath} +% +% results in: +% +% \parsedsoftpath -> +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 0pt}{\pgf@x 0pt\pgf@y 12pt}} +% {\pgf@decorate@inputsegmentobject@lineto{12pt}{\pgf@x 0pt\pgf@y 12pt}{\pgf@x 12pt\pgf@y 12pt}} +% +% \pgfdecoratedpathlength -> +% 24pt % \def\pgf@decorate@parsesoftpath#1#2{% - \def\pgf@decorate@inputsegmentobjectsmacro{#2}% - \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% - \pgfutil@tempdima0pt\relax% - \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \let\pgfpoint@decorated@firstparsed\pgfutil@empty% - \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% + \def\pgf@decorate@inputsegmentobjectsmacro{#2}% + \let\pgf@decorate@inputsegmentobjects\pgfutil@empty% + \pgfutil@tempdima0pt\relax% + \let\pgfpoint@decorate@lastparsed\pgfpoint@decorate@existingpathlast% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@origin% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \let\pgfpoint@decorated@firstparsed\pgfutil@empty% + \expandafter\pgf@decorate@@parsesoftpath#1\pgf@stop% } \def\pgf@decorate@@parsesoftpath#1{% - \ifx#1\pgf@stop% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). - \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% - \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% - \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% - \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% - \let\pgf@next\relax% - \else% - \ifx#1\pgfsyssoftpath@movetotoken% - \let\pgf@next\pgf@decorate@parsemoveto% - \else% - \ifx#1\pgfsyssoftpath@linetotoken% - \let\pgf@next\pgf@decorate@parselineto% - \else% - \ifx#1\pgfsyssoftpath@curvetosupportatoken% - \let\pgf@next\pgf@decorate@parsecurveto% - \else% - \ifx#1\pgfsyssoftpath@closepathtoken% - \let\pgf@next\pgf@decorate@parseclosepath% - \else% - \ifx#1\pgfsyssoftpath@rectcornertoken% - \let\pgf@next\pgf@decorate@parserect% - \else% - \PackageError{PGF}{Unrecognised soft path token `#1'}{}% - \fi% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgf@next} + \ifx#1\pgf@stop% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% <- removes final moveto (may not be desirable). + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \pgf@decorate@addtoinputsegmentobjects{\pgf@decorate@inputsegmentobject@endofinputsegments}% + \expandafter\let\pgf@decorate@inputsegmentobjectsmacro\pgf@decorate@inputsegmentobjects% + \edef\pgf@decorate@totalpathlength{\the\pgfutil@tempdima}% + \let\pgf@next\relax% + \else% + \ifx#1\pgfsyssoftpath@movetotoken% + \let\pgf@next\pgf@decorate@parsemoveto% + \else% + \ifx#1\pgfsyssoftpath@linetotoken% + \let\pgf@next\pgf@decorate@parselineto% + \else% + \ifx#1\pgfsyssoftpath@curvetosupportatoken% + \let\pgf@next\pgf@decorate@parsecurveto% + \else% + \ifx#1\pgfsyssoftpath@closepathtoken% + \let\pgf@next\pgf@decorate@parseclosepath% + \else% + \ifx#1\pgfsyssoftpath@rectcornertoken% + \let\pgf@next\pgf@decorate@parserect% + \else% + \pgferror{Unrecognised soft path token `#1'}% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@next} \def\pgf@decorate@addtoinputsegmentobjects#1{% - % - % If there is an input segment object waiting (i.e. a moveto), insert it here. - % - \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \else% - \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% - \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \fi% - \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% - #1% - \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% - \fi% - \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% - {\pgf@decorate@inputsegmentobjects{#1}}% -} - -% Convert \pgfsyssoftpath@movetotoken{}{} into the following + % + % If there is an input segment object waiting (i.e. a moveto), insert it here. + % + \ifx\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \else% + \let\pgf@decorate@temp\pgf@decorate@queueinputsegmentobject% + \let\pgf@decorate@queueinputsegmentobject\pgfutil@empty% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \fi% + \ifx\pgfpoint@decorated@firstparsed\pgfutil@empty% + #1% + \let\pgfpoint@decorated@firstparsed\pgf@decorate@inputsegment@first% + \fi% + \expandafter\def\expandafter\pgf@decorate@inputsegmentobjects\expandafter% + {\pgf@decorate@inputsegmentobjects{#1}}% +} + +% Convert \pgfsyssoftpath@movetotoken{}{} into the following % representation: -% -% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} +% +% \pgf@decorate@inputsegmentobject@moveto{\pgf@x X\pgf@y Y} % -% The moveto input segment object is not added immediately, so that -% only the last of multiple movetos is inserted. -% +% The moveto input segment object is not added immediately, so that +% only the last of multiple movetos is inserted. +% \def\pgf@decorate@parsemoveto#1#2{% - \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% - \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \pgf@decorate@@parsesoftpath% + \def\pgf@decorate@queueinputsegmentobject{\pgf@decorate@inputsegmentobject@moveto{\pgf@x#1\pgf@y#2}}% + \def\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \pgf@decorate@@parsesoftpath% } % Convert \pgfsyssoftpath@linetotoken{}{} into the following @@ -1692,47 +1689,47 @@ % \pgf@decorate@inputsegmentobject@lineto{}{\pgf@x \pgf@y \pgf@y } % \def\pgf@decorate@parselineto#1#2{% - \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - }% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \pgf@decorate@@parsesoftpath% -} - + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@lineto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \pgf@decorate@@parsesoftpath% +} + % Convert \pgfsyssoftpath@curvetosupportatoken{}{}...etc % into the following representation: % % \pgf@decorate@inputsegmentobject@curveto{}{\pgf@x \pgf@y \pgf@y }{\pgf@x \pgf@y }{\pgf@x \pgf@y } +% {\pgf@x \pgf@y }{\pgf@x \pgf@y }{\pgf@x \pgf@y } % \def\pgf@decorate@parsecurveto#1#2\pgfsyssoftpath@curvetosupportbtoken#3#4\pgfsyssoftpath@curvetotoken#5#6{% - \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% - {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% - }% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \pgf@decorate@@parsesoftpath% + \pgf@decorate@curvelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@curveto{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}% + {\pgf@x#1\pgf@y#2}{\pgf@x#3\pgf@y#4}{\pgf@x#5\pgf@y#6}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#5\pgf@y#6}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% } \def\pgf@decorate@parseclosepath#1#2{% - \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - \advance\pgfutil@tempdima\pgfmathresult pt\relax% - \edef\pgf@decorate@temp{% - \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% - }% - \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% - \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% - \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% - \pgf@decorate@@parsesoftpath% + \pgf@decorate@linelength{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + \advance\pgfutil@tempdima\pgfmathresult pt\relax% + \edef\pgf@decorate@temp{% + \noexpand\pgf@decorate@inputsegmentobject@closepath{\pgfmathresult pt}{\pgfpoint@decorate@lastparsed}{\pgf@x#1\pgf@y#2}% + }% + \expandafter\pgf@decorate@addtoinputsegmentobjects\expandafter{\pgf@decorate@temp}% + \edef\pgfpoint@decorate@lastparsed{\pgf@x#1\pgf@y#2}% + \let\pgfpoint@decorate@lastnonmovetoparsed\pgfpoint@decorate@lastparsed% + \pgf@decorate@@parsesoftpath% } % Convert \pgfsyssoftpath@rectcornertoken{}{}\pgfsyssoftpath@rectsizetoken{}{} @@ -1756,52 +1753,52 @@ % \newif\ifpgfdecoraterectangleclockwise \def\pgf@decorate@parserect#1#2\pgfsyssoftpath@rectsizetoken#3#4{% - % - % Subvert \pgf@decorate@parsesoftpath so parsing macros will - % return here instead of continuing to parse the soft path. - % - \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% - \let\pgf@decorate@@parsesoftpath\relax% - \pgf@decorate@parsemoveto{#1}{#2}% - \pgf@xa#1\relax% - \pgf@ya#2\relax% - \ifpgfdecoraterectangleclockwise% - \advance\pgf@ya#4% - \pgf@yb\pgf@ya% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa#3% - \pgf@xb\pgf@xa% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya-#4% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa-#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parseclosepath\pgf@temp% - \else% - \advance\pgf@xa#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \pgf@xb\pgf@xa% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya#4% - \pgf@yb\pgf@ya% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@xa-#3% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parselineto\pgf@temp% - \advance\pgf@ya-#4% - \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% - \expandafter\pgf@decorate@parseclosepath\pgf@temp% - \fi% - % - % Restore the parsing. - % - \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% - \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% - \pgf@marshal% + % + % Subvert \pgf@decorate@parsesoftpath so parsing macros will + % return here instead of continuing to parse the soft path. + % + \let\pgf@decorate@orig@@parsesoftpath\pgf@decorate@@parsesoftpath% + \let\pgf@decorate@@parsesoftpath\relax% + \pgf@decorate@parsemoveto{#1}{#2}% + \pgf@xa#1\relax% + \pgf@ya#2\relax% + \ifpgfdecoraterectangleclockwise% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa#3% + \pgf@xb\pgf@xa% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \else% + \advance\pgf@xa#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \pgf@xb\pgf@xa% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya#4% + \pgf@yb\pgf@ya% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@xa-#3% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parselineto\pgf@temp% + \advance\pgf@ya-#4% + \edef\pgf@temp{{\the\pgf@xa}{\the\pgf@ya}}% + \expandafter\pgf@decorate@parseclosepath\pgf@temp% + \fi% + % + % Restore the parsing. + % + \let\pgf@decorate@@parsesoftpath\pgf@decorate@orig@@parsesoftpath% + \edef\pgf@marshal{\noexpand\pgf@decorate@parsemoveto{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@marshal% } @@ -1812,8 +1809,8 @@ % Define \pgfmathresult as the distance between #1 and #2 (without units). % \def\pgf@decorate@linelength#1#2{% - \pgf@process{\pgfpointdiff{#1}{#2}}% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + \pgf@process{\pgfpointdiff{#1}{#2}}% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% } % \pgf@decorate@curvelength @@ -1824,138 +1821,138 @@ % To approximate the length of the curve P (sort of) use: % % curveLength(P,q) -% Q = subdivideLeft(P); -% R = subdivideRight(P); +% Q = subdivideLeft(P); +% R = subdivideRight(P); % return curveLength'(Q,q) + curveLength'(R,q); % % curveLength'(P,q) -% <- P; +% <- P; % P' = P4 - P1; % x = P'.x(); -% y = P'.y(); +% y = P'.y(); % if (x < q) && (y < q) -% return |P'|; -% else% -% Q = subdivideLeft(P); -% R = subdivideRight(P); +% return |P'|; +% else% +% Q = subdivideLeft(P); +% R = subdivideRight(P); % return curveLength'(Q,q) + curveLength'(R,q); % % Where q is some small value (`tolerance'). % \newif\ifpgf@decorate@subdivide \def\pgf@decorate@curvelength#1#2#3#4{% - % - % Always begin with a subdivision in case #1 = #4. - % - \begingroup% - \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% - \advance\pgfutil@tempdimb\pgfmathresult pt\relax% - \pgfmath@returnone\pgfutil@tempdimb% - \endgroup% -} - + % + % Always begin with a subdivision in case #1 = #4. + % + \begingroup% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \pgfmath@returnone\pgfutil@tempdimb% + \endgroup% +} + \def\pgf@decorate@@curvelength#1#2#3#4{% - \begingroup% - \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% - \ifpgf@decorate@subdivide% - \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% - \pgfutil@tempdimb\pgfmathresult pt\relax% - \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% - \advance\pgfutil@tempdimb\pgfmathresult pt\relax% - \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% - \else% - \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% - \fi% - \endgroup% + \begingroup% + \pgf@decorate@curvecordlength{#1}{#2}{#3}{#4}% + \ifpgf@decorate@subdivide% + \pgf@decorate@recursive@subdividecurve@left{#1}{#2}{#3}{#4}% + \pgfutil@tempdimb\pgfmathresult pt\relax% + \pgf@decorate@recursive@subdividecurve@right{#1}{#2}{#3}{#4}% + \advance\pgfutil@tempdimb\pgfmathresult pt\relax% + \expandafter\pgfmath@returnone\expandafter\pgfutil@tempdimb% + \else% + \expandafter\pgfmath@returnone\expandafter\pgfmathresult\expandafter p\expandafter t\expandafter% + \fi% + \endgroup% } \def\pgf@decorate@curvelength@tolerance{1pt} \def\pgf@decorate@curvecordlength#1#2#3#4{% - % - % Calculate the curve cord vector. - % - #4\relax% - \pgf@xa\pgf@x\pgf@ya\pgf@y% - #1\relax% - \advance\pgf@xa-\pgf@x% - \advance\pgf@ya-\pgf@y% - \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% - \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% - % - % Always subdivide, unless... - % - \pgf@decorate@subdividetrue% - % - % The cord vector is small. - % - \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% - \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% - \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% - \pgf@decorate@subdividefalse% - \fi% - \fi% + % + % Calculate the curve cord vector. + % + #4\relax% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + #1\relax% + \advance\pgf@xa-\pgf@x% + \advance\pgf@ya-\pgf@y% + \ifdim\pgf@xa<0pt\relax\pgf@xa-\pgf@xa\fi% + \ifdim\pgf@ya<0pt\relax\pgf@ya-\pgf@ya\fi% + % + % Always subdivide, unless... + % + \pgf@decorate@subdividetrue% + % + % The cord vector is small. + % + \ifdim\pgf@xa<\pgf@decorate@curvelength@tolerance\relax% + \ifdim\pgf@ya<\pgf@decorate@curvelength@tolerance\relax% + \pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + \pgf@decorate@subdividefalse% + \fi% + \fi% } \def\pgf@decorate@recursive@subdividecurve@left#1#2#3#4{% - {% - % - % The left curve (from t=0 to t=.5) - % - #1\relax% - \pgfutil@tempdima\pgf@x% - \pgfutil@tempdimb\pgf@y% - \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% - \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% - \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% - #2\relax% - \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% - \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% - \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% - #3\relax% - \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% - \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% - #4\relax% - \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% - \xdef\pgf@marshal{% - \noexpand\pgf@decorate@@curvelength% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% - }% - }% - \pgf@marshal% + {% + % + % The left curve (from t=0 to t=.5) + % + #1\relax% + \pgfutil@tempdima\pgf@x% + \pgfutil@tempdimb\pgf@y% + \pgf@xa.5\pgf@x\pgf@ya.5\pgf@y% + \pgf@xb.25\pgf@x\pgf@yb.25\pgf@y% + \pgf@xc.125\pgf@x\pgf@yc.125\pgf@y% + #2\relax% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #3\relax% + \advance\pgf@xb.25\pgf@x\advance\pgf@yb.25\pgf@y% + \advance\pgf@xc.375\pgf@x\advance\pgf@yc.375\pgf@y% + #4\relax% + \advance\pgf@xc.125\pgf@x\advance\pgf@yc.125\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% } \def\pgf@decorate@recursive@subdividecurve@right#1#2#3#4{% - {% - % - % The right curve (from t=0.5 to t=1) - % - #1\relax% - \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% - #2\relax% - \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% - \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% - #3\relax% - \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% - \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% - \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% - #4\relax% - \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% - \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% - \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% - \pgf@xc\pgf@x\pgf@yc\pgf@y% - \xdef\pgf@marshal{% - \noexpand\pgf@decorate@@curvelength% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% - }% - }% - \pgf@marshal% + {% + % + % The right curve (from t=0.5 to t=1) + % + #1\relax% + \pgfutil@tempdima.125\pgf@x\pgfutil@tempdimb.125\pgf@y% + #2\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \pgf@xa.25\pgf@x\pgf@ya.25\pgf@y% + #3\relax% + \advance\pgfutil@tempdima.375\pgf@x\advance\pgfutil@tempdimb.375\pgf@y% + \advance\pgf@xa.5\pgf@x\advance\pgf@ya.5\pgf@y% + \pgf@xb.5\pgf@x\pgf@yb.5\pgf@y% + #4\relax% + \advance\pgfutil@tempdima.125\pgf@x\advance\pgfutil@tempdimb.125\pgf@y% + \advance\pgf@xa.25\pgf@x\advance\pgf@ya.25\pgf@y% + \advance\pgf@xb.5\pgf@x\advance\pgf@yb.5\pgf@y% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@marshal{% + \noexpand\pgf@decorate@@curvelength% + {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% + {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} + {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + }% + }% + \pgf@marshal% } @@ -1965,138 +1962,138 @@ % #2 - a macro holding the reversed input segment objects. % \def\pgf@decorate@inputsegmentobjects@reverse#1#2{% - \def\pgf@decorate@path@storein{#2}% - \def\pgf@decorate@inputsegments@@temp{}% - \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop} + \def\pgf@decorate@path@storein{#2}% + \def\pgf@decorate@inputsegments@@temp{}% + \expandafter\pgf@decorate@inputsegments@@reverse@pass@first#1\pgf@stop} \def\pgf@decorate@inputsegments@@reverse@pass@first#1#2\pgf@stop{% - \def\pgf@decorate@temp{#1}% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}% - \def\pgf@decorate@test{#2} - \ifx\pgf@decorate@test\pgfutil@empty% - \def\pgf@decorate@next{% - \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop% - }% - \else% - \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}% - \fi% - \pgf@decorate@next% -} + \def\pgf@decorate@temp{#1}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@temp\pgf@decorate@inputsegments@@temp}% + \def\pgf@decorate@test{#2} + \ifx\pgf@decorate@test\pgfutil@empty% + \def\pgf@decorate@next{% + \expandafter\pgf@decorate@inputsegmentobjects@reverse@pass@second\pgf@decorate@inputsegments@@temp\pgf@stop% + }% + \else% + \def\pgf@decorate@next{\pgf@decorate@inputsegments@@reverse@pass@first#2\pgf@stop}% + \fi% + \pgf@decorate@next% +} \def\pgf@decorate@inputsegmentobjects@reverse@pass@second#1#2#3\pgf@stop{% - \def\pgf@decorate@inputsegments@temp{#3}% - \def\pgf@decorate@inputsegments@@temp{}% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty - \let\pgf@decorate@last@object=\pgfutil@empty - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}% + \def\pgf@decorate@inputsegments@temp{#3}% + \def\pgf@decorate@inputsegments@@temp{}% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty + \let\pgf@decorate@last@object=\pgfutil@empty + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \expandafter\pgf@decorate@path@@reverse@pass@second\pgf@decorate@inputsegments@temp\pgf@stop}% \def\pgf@decorate@path@@reverse@pass@second#1{% - \ifx#1\pgf@stop% - \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{% - \pgf@decorate@inputsegments@@temp% - {\pgf@decorate@inputsegmentobject@endofinputsegments}% - {\pgf@decorate@inputsegmentobject@endofinputsegments} - }% - \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp% - \let\pgf@decorate@next=\relax% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@moveto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@lineto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@curveto% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto% - \else% - \ifx#1\pgf@decorate@inputsegmentobject@closepath% - \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath% - \else% - \fi% - \fi% - \fi% - \fi% - \fi% - \pgf@decorate@next% + \ifx#1\pgf@stop% + \expandafter\def\expandafter\pgf@decorate@inputsegments@@temp\expandafter{% + \pgf@decorate@inputsegments@@temp% + {\pgf@decorate@inputsegmentobject@endofinputsegments}% + {\pgf@decorate@inputsegmentobject@endofinputsegments} + }% + \expandafter\let\pgf@decorate@path@storein=\pgf@decorate@inputsegments@@temp% + \let\pgf@decorate@next=\relax% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@moveto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@moveto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@lineto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@lineto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@curveto% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@curveto% + \else% + \ifx#1\pgf@decorate@inputsegmentobject@closepath% + \let\pgf@decorate@next=\pgf@decorate@inputsegmentobjects@reverse@closepath% + \else% + \fi% + \fi% + \fi% + \fi% + \fi% + \pgf@decorate@next% } \newif\ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting \def\pgf@decorate@inputsegmentobjects@reverse@moveto#1{% - \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% - \edef\pgf@decorate@current@inputsegmentobject{% - {\noexpand\pgf@decorate@inputsegmentobject@closepath% - {\pgf@decorate@reverse@closepath@length}% - {\pgf@decorate@last}% - {#1}% - }% - }% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \else% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% - \fi% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% - \pgf@decorate@path@@@reverse@pass@second% + \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% + \edef\pgf@decorate@current@inputsegmentobject{% + {\noexpand\pgf@decorate@inputsegmentobject@closepath% + {\pgf@decorate@reverse@closepath@length}% + {\pgf@decorate@last}% + {#1}% + }% + }% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \else% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% + \fi% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingtrue% + \pgf@decorate@path@@@reverse@pass@second% } \newif\ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting \def\pgf@decorate@inputsegmentobjects@reverse@closepath#1#2#3{% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue% - \def\pgf@decorate@reverse@closepath@length{#1}% - \def\pgf@decorate@current@inputsegmentobject{}% - \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingtrue% + \def\pgf@decorate@reverse@closepath@length{#1}% + \def\pgf@decorate@current@inputsegmentobject{}% + \pgf@decorate@inputsegmentobjects@reverse@lineto{#1}{#2}{#3}% } \def\pgf@decorate@inputsegmentobjects@reverse@lineto#1#2#3#4{% - \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% - \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% - \else% - \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% - \fi% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% - \ifx#4\pgf@decorate@inputsegmentobject@moveto% - \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}% - \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% - \else% - \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% - \fi% - \fi% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject} - \def\pgf@decorate@last{#2}% - \pgf@decorate@path@@@reverse@pass@second#4% + \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% + \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@moveto{#3}}}% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% + \else% + \let\pgf@decorate@current@inputsegmentobject=\pgfutil@empty% + \fi% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% + \ifx#4\pgf@decorate@inputsegmentobject@moveto% + \ifpgf@decorate@inputsegmentobjects@reverse@closepath@waiting% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@closepath{#1}{#3}{#2}}}% + \pgf@decorate@inputsegmentobjects@reverse@closepath@waitingfalse% + \else% + \def\pgf@decorate@append@inputsegmentobject{{\pgf@decorate@inputsegmentobject@lineto{#1}{#3}{#2}}}% + \fi% + \fi% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@current@inputsegmentobject\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@current@inputsegmentobject\pgf@decorate@append@inputsegmentobject} + \def\pgf@decorate@last{#2}% + \pgf@decorate@path@@@reverse@pass@second#4% } \def\pgf@decorate@inputsegmentobjects@reverse@curveto#1#2#3#4#5{% - \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% - \def\pgf@decorate@current@inputsegmentobject{% - {\pgf@decorate@inputsegmentobject@moveto{#5}}% - {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}% - }% - \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% - \else% - \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}% - \fi% - \def\pgf@decorate@last{#2}% - \pgf@decorate@path@@@reverse@pass@second% + \ifpgf@decorate@inputsegmentobjects@reverse@moveto@waiting% + \def\pgf@decorate@current@inputsegmentobject{% + {\pgf@decorate@inputsegmentobject@moveto{#5}}% + {\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}% + }% + \pgf@decorate@inputsegmentobjects@reverse@moveto@waitingfalse% + \else% + \def\pgf@decorate@current@inputsegmentobject{{\pgf@decorate@inputsegmentobject@curveto{#1}{#5}{#4}{#3}{#2}}}% + \fi% + \def\pgf@decorate@last{#2}% + \pgf@decorate@path@@@reverse@pass@second% } \def\pgf@decorate@path@@@reverse@pass@second{% - \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty% - \else% - \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% - \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% - {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}% - \fi% - \pgf@decorate@path@@reverse@pass@second% + \ifx\pgf@decorate@current@inputsegmentobject\pgfutil@empty% + \else% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter% + \pgf@decorate@inputsegments@@temp\expandafter\expandafter\expandafter% + {\expandafter\pgf@decorate@inputsegments@@temp\pgf@decorate@current@inputsegmentobject}% + \fi% + \pgf@decorate@path@@reverse@pass@second% }% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex index 32024c047d6..a9344f6c95c 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulematrix.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.4 2010/08/24 21:28:58 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulematrix.code.tex,v 1.8 2013/09/17 17:34:00 tantau Exp $ \usepgfmodule{shapes} @@ -156,7 +156,7 @@ \def\pgfmatrix#1#2#3#4#5#6{% \ifpgfmatrix% - \PackageError{pgf}{You cannot nest pgfmatrix environments, yet}{} + \pgferror{You cannot nest pgfmatrix environments, yet} \fi% \bgroup% \everycr{}% @@ -270,26 +270,7 @@ \pgfutil@ifnextchar[{\pgf@matrix@cell@cont}{\pgf@matrix@cell@cont[0pt]}}%} \def\pgf@matrix@cell@cont[#1]{% - \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns% - \else% - {% - \global\pgf@matrix@fixedfalse% - \pgf@x=0pt% - \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}% - \pgf@matrix@addtolength{\pgf@x}{#1}% - \ifpgf@matrix@fixed% - \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% - {\global\pgf@picmaxx=0pt}% - \fi% - \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following: - \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}% - \ifpgf@matrix@fixed% - \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}% - \else% - \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty% - \fi% - }% - \fi% + \xdef\pgf@matrix@last@nextcell@options{#1}% &\pgf@matrix@correct@calltrue&% }% @@ -402,19 +383,41 @@ \def\pgf@matrix@endcell{% \ifpgf@matrix@empty@cell@% \else% - \expandafter\pgfmatrixendcode% - \fi + \expandafter\expandafter\expandafter\pgfmatrixendcode% + \expandafter\ifpgf@matrix@last@cell@in@row\expandafter\pgf@matrix@last@cell@in@rowtrue\expandafter\fi% + \fi% \pgfsys@endpicture% + \ifnum\pgfmatrixcurrentcolumn<\pgf@matrix@numberofcolumns% + \else% + \ifpgf@matrix@last@cell@in@row\else% + {% + \global\pgf@matrix@fixedfalse% + \pgf@x=0pt% + \pgf@matrix@addtolength{\pgf@x}{\pgfmatrixcolumnsep}% + \pgf@matrix@addtolength{\pgf@x}{\pgf@matrix@last@nextcell@options}% + \ifpgf@matrix@fixed% + \expandafter\pgfutil@g@addto@macro\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% + {\global\pgf@picmaxx=0pt}% + \fi% + \advance\pgfmatrixcurrentcolumn by1\relax % only temporary for the following: + \expandafter\xdef\csname pgf@matrix@column@sep@\the\pgfmatrixcurrentcolumn\endcsname{\the\pgf@x}% + \ifpgf@matrix@fixed% + \expandafter\gdef\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname{\global\pgf@picminx=0pt}% + \else% + \expandafter\global\expandafter\let\csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname=\pgfutil@empty% + \fi% + }% + \fi\fi% + % Special case of the empty picture + \ifdim\pgf@picmaxx=-16000pt\relax% + \global\pgf@picmaxx=0pt\relax% + \global\pgf@picminx=0pt\relax% + \global\pgf@picmaxy=0pt\relax% + \global\pgf@picminy=0pt\relax% + \fi% \csname pgf@matrix@column@finish@\the\pgfmatrixcurrentcolumn\endcsname% \pgf@matrix@row@finish% \egroup\egroup% - % Special case of the empty picture - \ifdim\pgf@picmaxx=-16000pt\relax% - \pgf@picmaxx=0pt\relax% - \pgf@picminx=0pt\relax% - \pgf@picmaxy=0pt\relax% - \pgf@picminy=0pt\relax% - \fi% % % Step 5: Horizontal gap % @@ -495,8 +498,7 @@ \def\pgf@matrix@padding{% \ifpgf@matrix@correct@call% \else% - \PackageError{pgfbasematrix}{Single ampersand used with wrong - catcode}{}% + \pgferror{Single ampersand used with wrong catcode}% \fi% \hskip\pgf@matrix@paddingskip\hfil% } @@ -599,13 +601,15 @@ % if the cell contains nothing, the following \let will be at the % beginning (macro expansion has stopped here since neither \omit % nor \span was found) - \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end% + \let\pgf@matrix@signal@cell@end=\pgf@matrix@signal@cell@end + \pgf@matrix@last@cell@in@rowtrue% &\pgf@matrix@correct@calltrue% \global\pgf@matrix@fixedfalse% \pgf@y=0pt% \pgf@matrix@addtolength\pgf@y{\pgfmatrixrowsep}% \pgfutil@ifnextchar[{\pgfmatrixendrow@skip}{\pgf@matrix@finish@line}% } +\newif\ifpgf@matrix@last@cell@in@row \def\pgf@matrix@signal@cell@end{\pgf@matrix@signal@cell@end} % exact definition does not matter, only needs to be unique. diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex new file mode 100644 index 00000000000..913f2edff9d --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex @@ -0,0 +1,342 @@ +% Copyright 2013 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulenonlineartransformations.code.tex,v 1.4 2013/10/09 18:30:27 tantau Exp $ + + +% +% This file defines commands for nonlinear coordinate systems. This is +% needed, for instance, for bend arrow heads. +% +% +% Non-linear coordinate systems transform coordinates, in addition to +% the normal linear transformations, in a, well, non-linear way. An +% example are polar coordinates. +% +% Like the linear transformations, non-linear transformations are +% applied on a low level and they are integrated into the whole path +% construction mechanism. So, while \pgfpointpolar also "does +% something nonlinear", it just provides a way of computing a +% coordinate. In contrast, installing a polar transformation will +% transform everything being drawn using the \pgfpath... commands an +% will even turn a straight line into a circle. +% +% Since computing non-linear transformations is expensive, they are +% only applied "if really necessary". + + + + +% Return a transformed point +% +% #1 = a point +% +% Description: +% +% Applies the current transformation and the current nonlinear +% transformation to the given point and returns the result in \pgf@x/y. + +\def\pgfpointtransformednonlinear#1{% + \pgf@process{% + #1% + \pgf@pos@transform{\pgf@x}{\pgf@y}% + \pgf@nlt@list% + } +} + + + + +% Approximate the nonlinear translation locally +% +% Description: +% +% Does a "local syncronization" of the nonlinear transformation with +% the linear transformation regarding the translation part of the +% current nonlinear transformatoin. The *linear* transformation will be +% updated so that it translates things to the point to which the +% nonlinear transformation transforms the origin. The nonlinear +% transformation will be reset. +% +% The net effect is that you can now draw things near the origin as +% before, but with just a linear transformation in force. Note that +% the coordinate system will not be rotated, only a shift is done (use +% the "real" local sync for a full sync). + +\def\pgfapproximatenonlineartranslation{% + \ifx\pgf@nlt@list\pgfutil@empty% + \else% + \pgfpointtransformednonlinear{\pgfpointorigin}% + \pgf@pt@x=\pgf@x% + \pgf@pt@y=\pgf@y% + \let\pgf@nlt@list\pgfutil@empty% + \let\pgf@nlt@moveto\pgf@lt@moveto% + \let\pgf@nlt@lineto\pgf@lt@lineto% + \let\pgf@nlt@curveto\pgf@lt@curveto% + \let\pgf@nlt@closepath\pgf@lt@closepath% + \fi% +} + + + +% Local sync translation +% +% Description: +% +% Does a "complete local syncronization" of the nonlinear +% transformation with the linear transformation. The *linear* +% transformation will be updated so that it transforms things to the +% point to which the nonlinear transformation transforms the +% origin. The nonlinear transformation will be reset. +% +% The net effect is that you can now draw things near the origin as +% before, but with just a linear transformation in force. + +\def\pgfapproximatenonlineartransformation{% + \ifx\pgf@nlt@list\pgfutil@empty% + \else% + \pgfpointtransformednonlinear{\pgfpoint{1pt}{0pt}}% + \pgf@xa\pgf@x + \pgf@ya\pgf@y + \pgfpointtransformednonlinear{\pgfpoint{0pt}{1pt}}% + \pgf@xb\pgf@x + \pgf@yb\pgf@y + \pgfpointtransformednonlinear{\pgfpointorigin}% + \advance\pgf@xa by-\pgf@x + \advance\pgf@xb by-\pgf@x + \advance\pgf@ya by-\pgf@y + \advance\pgf@yb by-\pgf@y + \pgfsettransformentries{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@xb}{\pgf@sys@tonumber\pgf@yb}{\pgf@x}{\pgf@y}% + \let\pgf@nlt@list\pgfutil@empty% + \let\pgf@nlt@moveto\pgf@lt@moveto% + \let\pgf@nlt@lineto\pgf@lt@lineto% + \let\pgf@nlt@curveto\pgf@lt@curveto% + \let\pgf@nlt@closepath\pgf@lt@closepath% + \fi% +} + + + +% Adds a non-linear transformation to the current list of +% transformations. +% +% #1 = code +% +% Description: +% +% When the code #1 is called, \pgf@x and \pgf@y will be set to some +% values, let us call this the point p. The nonlinear transformation +% will now map this point to a new point f(p). The coordinates of this +% point shoudl be returned in \pgf@x and \pgf@y. Furthermore, consider +% the two "unit tangents" (going in $x$-direction and in +% $y$-direction) at point p. The nonlinear transformaiton will map +% these to new tangents, t_x and t_y. The (not necessarily normalized) +% vectors t_x and t_y should be returned in pgf@xa and -ya and pgf@xb +% and pgf@yb. The macro should not do any global assignments except to +% \pgf@x and \pgf@y, but may do arbitrary local assignments. +% +% The effect of installing a new transformation is the following: As +% long as there is at least one nonlinear transformation installed, +% whenever the path construction commands add a curve or line to the +% softpath, the line or curve will be "bend" by applying all of the +% nonlinear transformation installed. In particular, straight lines +% will be replaced by curves. +% +% Note that the normal linear transformation are always applied before +% any nonlinear transformations are applied. + +\def\pgftransformnonlinear#1{% + \expandafter\def\expandafter\pgf@nlt@list\expandafter{\pgf@nlt@list#1}% + \let\pgf@nlt@moveto\pgf@nlt@moveto@nlt + \let\pgf@nlt@lineto\pgf@nlt@lineto@nlt + \let\pgf@nlt@curveto\pgf@nlt@curveto@nlt + \let\pgf@nlt@closepath\pgf@nlt@closepath@nlt +} + +\def\pgf@nlt@moveto@nlt#1#2{% + {% + \pgfutil@tempdima#1% + \pgfutil@tempdimb#2% + \pgf@x\pgfutil@tempdima% + \pgf@y\pgfutil@tempdimb% + \xdef\pgf@nlt@last@moveto@orig{{\the\pgf@x}{\the\pgf@y}}% + \pgf@nlt@list% + \xdef\pgf@nlt@last@moveto@trans{{\the\pgf@x}{\the\pgf@y}}% + \xdef\pgf@nlt@last@moveto@xaxis{{\the\pgf@xa}{\the\pgf@ya}}% + \xdef\pgf@nlt@last@moveto@yaxis{{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \pgfsyssoftpath@moveto{\the\pgf@x}{\the\pgf@y}% + \global\let\pgf@nlt@last@coord@orig\pgf@nlt@last@moveto@orig% + \global\let\pgf@nlt@last@coord@trans\pgf@nlt@last@moveto@trans% + \global\let\pgf@nlt@last@coord@xaxis\pgf@nlt@last@moveto@xaxis% + \global\let\pgf@nlt@last@coord@yaxis\pgf@nlt@last@moveto@yaxis% + }% +} + + +\def\pgf@nlt@lineto@nlt#1#2{% + {% + \edef\pgf@temp{\pgf@xc\the#1\pgf@yc\the#2}% + \pgf@temp% + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@trans% + % Test, whether the points are quite near: + \pgf@xa\pgf@x\advance\pgf@xa by-\pgf@xc% + \pgf@ya\pgf@y\advance\pgf@ya by-\pgf@yc% + \pgfutil@tempswafalse% + \ifdim\pgf@xa<0.1pt\relax\ifdim\pgf@xa>-0.1pt\relax\ifdim\pgf@ya<0.1pt\relax\ifdim\pgf@ya>-0.1pt\relax\pgfutil@tempswatrue\fi\fi\fi\fi% + \ifpgfutil@tempswa% + \pgf@x\pgf@xc\pgf@y\pgf@yc% + \xdef\pgf@nlt@last@coord@orig{{\the\pgf@x}{\the\pgf@y}}% + \pgf@process{\pgf@nlt@list}% + \xdef\pgf@nlt@last@coord@trans{{\the\pgf@x}{\the\pgf@y}}% + \xdef\pgf@nlt@last@coord@xaxis{{\the\pgf@xa}{\the\pgf@ya}}% + \xdef\pgf@nlt@last@coord@yaxis{{\the\pgf@xb}{\the\pgf@yb}}% + \pgf@protocolsizes{\pgf@x}{\pgf@y}% + \pgfsyssoftpath@lineto{\the\pgf@x}{\the\pgf@y}% + \else% + % Compute support points + \pgf@xb=.333333\pgf@x% + \advance\pgf@xb by.666666\pgf@xc% + \pgf@yb=.333333\pgf@y% + \advance\pgf@yb by.666666\pgf@yc% + \pgf@xa=.333333\pgf@xc% + \advance\pgf@xa by.666666\pgf@x% + \pgf@ya=.333333\pgf@yc% + \advance\pgf@ya by.666666\pgf@y% + \pgf@nlt@inner@curve% + \fi% + }% +} + +\def\pgf@nlt@set@temps#1#2{% + \pgfutil@tempdima#1\pgfutil@tempdimb#2% +} + +\def\pgf@nlt@curveto@nlt#1#2#3#4#5#6{% + {% + \edef\pgf@temp{\pgf@xa\the#1\pgf@ya\the#2\pgf@xb\the#3\pgf@yb\the#4\pgf@xc\the#5\pgf@yc\the#6}% + \pgf@temp% + \pgf@nlt@inner@curve% + }% +} + +\newdimen\pgftransformnonlinearflatness +\pgftransformnonlinearflatness=5pt +\def\pgfsettransformnonlinearflatness#1{\pgfmathsetlength\pgftransformnonlinearflatness{#1}} + + + +% Compute a curve from \pgf@nlt@last@coord@orig to \pgf@xc/\pgf@yc via the +% controls \pgf@xa/\pgf@ya and \pgf@xb/\pgf@yb. +\def\pgf@nlt@inner@curve{% + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + % Save delta of supports: + \pgfutil@tempdima\pgf@xa\advance\pgfutil@tempdima by-\pgf@xb + \pgfutil@tempdimb\pgf@ya\advance\pgfutil@tempdimb by-\pgf@yb + \begingroup + % Replace supports by relative supports + \advance\pgf@xa by-\pgf@x% + \advance\pgf@ya by-\pgf@y% + \advance\pgf@xb by-\pgf@xc% + \advance\pgf@yb by-\pgf@yc% + % + % Now, test whether the flatness is satisfied: + % + \pgfutil@tempswafalse + \ifdim\pgfutil@tempdima>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdima<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdimb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgfutil@tempdimb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xa>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xa<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@ya>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@ya<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@xb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@yb>\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifdim\pgf@yb<-\pgftransformnonlinearflatness\pgfutil@tempswatrue\fi% + \ifpgfutil@tempswa% + \endgroup% Undo the adjustmenst... + {% + \edef\pgf@orig@xya{\pgf@xa\the\pgf@xa\pgf@ya\the\pgf@ya} + \edef\pgf@orig@xyb{\pgf@xb\the\pgf@xb\pgf@yb\the\pgf@yb} + \edef\pgf@orig@xyc{\pgf@xc\the\pgf@xc\pgf@yc\the\pgf@yc} + \pgfpointcurveattime{.5}% + {\expandafter\pgfqpoint\pgf@nlt@last@coord@orig}% + {\pgf@x\pgf@xa\pgf@y\pgf@ya}% + {\pgf@x\pgf@xb\pgf@y\pgf@yb}% + {\pgf@x\pgf@xc\pgf@y\pgf@yc}% + % First new curve: + % Start is at last@coord@orig, + % first support is at last@coord@orig*t + s*(original xa/ya) + % second support is at xb/yb + % target is at x/y + {% + % Target: + \pgf@xc\pgf@x\pgf@yc\pgf@y + % First support: + \expandafter\pgfqpoint\pgf@nlt@last@coord@orig% + \pgf@orig@xya% + \pgf@xa\pgf@time@s\pgf@xa\advance\pgf@xa by\pgf@time@t\pgf@x% + \pgf@ya\pgf@time@s\pgf@ya\advance\pgf@ya by\pgf@time@t\pgf@y% + \pgf@nlt@inner@curve% + }% + % Second new curve: + % Start is at (new) last@coord@orig + % first support is at xa/ya + % second support is at t*(original xb/yb) + s*(original xc/yc) + % target is at original xc/yc + {% + \pgf@orig@xyb% + \pgf@orig@xyc% + \pgf@xb\pgf@time@t\pgf@xb\advance\pgf@xb by\pgf@time@s\pgf@xc% + \pgf@yb\pgf@time@t\pgf@yb\advance\pgf@yb by\pgf@time@s\pgf@yc% + \pgf@nlt@inner@curve% + }% + }% + \else% + \endgroup% Snap back... + \pgf@nlt@do@inner@curve% + \fi% +} + +\def\pgf@nlt@do@inner@curve{% + \pgf@process{\pgf@x\pgf@xa\pgf@y\pgf@ya\pgf@nlt@list}% + \pgf@xa\pgf@x\pgf@ya\pgf@y% + \pgf@process{\pgf@x\pgf@xb\pgf@y\pgf@yb\pgf@nlt@list}% + \pgf@xb\pgf@x\pgf@yb\pgf@y% + \xdef\pgf@nlt@last@coord@orig{{\the\pgf@xc}{\the\pgf@yc}}% + \pgf@process{\pgf@x\pgf@xc\pgf@y\pgf@yc\pgf@nlt@list}% + \pgf@xc\pgf@x\pgf@yc\pgf@y% + \xdef\pgf@nlt@last@coord@trans{{\the\pgf@xc}{\the\pgf@yc}}% + \pgf@protocolsizes{\pgf@xa}{\pgf@ya}% + \pgf@protocolsizes{\pgf@xb}{\pgf@yb}% + \pgf@protocolsizes{\pgf@xc}{\pgf@yc}% + \pgfsyssoftpath@curveto{\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}% +} + + +\def\pgf@nlt@closepath@nlt{% + {% + \expandafter\pgfqpoint\pgf@nlt@last@moveto@orig% + \expandafter\pgf@nlt@set@temps\pgf@nlt@last@coord@orig% + \advance\pgfutil@tempdima by-\pgf@x% + \advance\pgfutil@tempdimb by-\pgf@y% + \pgfutil@tempswatrue% + \ifdim\pgfutil@tempdima<0.01pt\relax\ifdim\pgfutil@tempdima>-0.01pt\relax\ifdim\pgfutil@tempdimb<0.01pt\relax\ifdim\pgfutil@tempdimb>-0.01pt\relax\pgfutil@tempswafalse\fi\fi\fi\fi% + \ifpgfutil@tempswa% + \pgf@nlt@lineto@nlt{\pgf@x}{\pgf@y}% + \fi% + \pgfsyssoftpath@closepath% + }% +} + + +\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex index e80d3ac06bb..eba114885ea 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleoo.code.tex @@ -1,4 +1,5 @@ % Copyright 2006 by Till Tantau +% Copyright 2011 by Saso Zivanovic % % This file may be distributed and/or modified % @@ -6,12 +7,12 @@ % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleoo.code.tex,v 1.8 2010/02/22 22:49:21 tantau Exp $ +% +% Based on pgfmoduleoo.code.tex v1.8 by Till Tantau. This version adds inheritance. -% Support of object-oriented programming in TeX. +% Support of object-oriented programming in TeX, with inheritance. % The oo support works as follows: @@ -52,30 +53,215 @@ % % Description: % -% This command declares a class for futurue use. Inside #2, the macro +% This command declares a class for future use. Inside #2, the macro % \method can be used to declare a method. The \method macro takes a % method name, parameters (methods are normal TeX macros, after all) % and body. -\long\def\pgfooclass#1#2{% - \def\pgfoo@classname{#1}% +% base classes are put in parenthesis before the new class name, but +% are optional. +\def\pgfooclass{% + \pgfutil@ifnextchar ({% + \pgfooclass@ + }{% + \pgfooclass@() + }% +} +\long\def\pgfooclass@(#1)#2#3{% + \def\pgfoo@classname{#2}% + \expandafter\ifx\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\relax\else + \pgferror{class #2 is already defined}% + \fi + \pgfoo@ciii{#2}{#1}% + \expandafter\let\csname pgfooY#2@pgfoo@mro\endcsname\pgfoo@mro \let\pgfoo@origmethod=\method% \let\pgfoo@origattribute=\attribute% \let\method=\pgfoo@declaremethod% \let\attribute=\pgfoo@declareattribute% - \let\pgfoo@attribute@collection=\pgfutil@empty% - \let\pgfoo@attribute@collection@gc=\pgfutil@empty% - #2% - % Attribute initializer: - \expandafter\let\csname pgfooY\pgfoo@classname.@pgfooinit\endcsname\pgfoo@attribute@collection% - \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoogc\endcsname\pgfoo@attribute@collection@gc% - % Always persent methods: + \let\pgfoo@attributes=\pgfutil@empty% + \let\pgfoo@methods=\pgfutil@empty% + #3% + % inherit + \def\pgfoo@temp@baseclasses{#1}% + \pgfoo@inherit@methods + \pgfoo@inherit@attributes + % Always present (and never inherited) methods: \expandafter\let\csname pgfooY\pgfoo@classname.get handle\endcsname\pgfoo@obj% \expandafter\let\csname pgfooY\pgfoo@classname.get id\endcsname\pgfoo@id% + % for compatibility with previous versions of pgfoo, define method + % with the same name as the class as a synonym for init + \expandafter\let\expandafter\pgfoo@init\csname pgfooY\pgfoo@classname.init\endcsname + \expandafter\let\csname pgfooY\pgfoo@classname.\pgfoo@classname\endcsname\pgfoo@init + % Cleanup \let\method=\pgfoo@origmethod% \let\attribute=\pgfoo@origattribute% } +\def\pgfoo@emptyinit(){} +\def\pgfoo@escapeif#1#2\fi{\fi#1}% a little helper + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Compute MRO using C3 algorithm +% The sequences are enclosed in brackets; elements of sequences and +% the big list are terminated by a comma and a dot, respectively. (Why +% comma *and* a dot: TeX's parset---brackets don't form groups! Soooo, +% why not braces? Because I don't know how do delete excess "{},"s...) + +% #1 = current class, #2 = list of base classes +\def\pgfoo@ciii#1#2{% + % \pgfoo@seq will hold a list of sequences. + % (i) the first sequence has just one element: the current class + \def\pgfoo@seq{[#1,].}% + % (ii) every subclass has a sequence (in the order as they were + % given): the class' sequence is its mro. + \pgfutil@for\pgfoo@baseclass:={#2}\do{% + \edef\pgfoo@baseclass@mro{\csname pgfooY\pgfoo@baseclass @pgfoo@mro\endcsname}% + \expandafter\ifx\expandafter\relax\pgfoo@baseclass@mro\relax\else + \edef\pgfoo@seq{\pgfoo@seq[\pgfoo@baseclass@mro,].}% + \fi + }% + % The final sequence is a sequence of base classes, in the order as + % they were given. + \ifx\relax#2\relax\else + \edef\pgfoo@seq{\pgfoo@seq[#2,].}% + \fi + \edef\pgfoo@temp{()(\pgfoo@seq)}% + \expandafter\pgfoo@ciii@merge\pgfoo@temp +} + +% #1 = MRO so far +% #2 = remaining sequences +% no empty sequences [] should arrive here: they should be removed +% before calling this macro +\def\pgfoo@ciii@merge(#1)(#2){% + \ifx\relax#2\relax + \pgfoo@ciii@done(#1)% + \else\pgfoo@escapeif{% split #2 + \pgfoo@ciii@merge@A(#1)(#2)% + }\fi% +} +% a splitter: to be only called from \pgfoo@ciii@merge +\def\pgfoo@ciii@merge@A(#1)(#2.#3){% + \ifx\relax#3\relax % if #3 is empty, we can take the shortcut + \pgfoo@ciii@mergeA@done(#1)(#2)% + \else\pgfoo@escapeif{% + \pgfoo@ciii@merge@checkHead(#1)()(#2)()(#3)% + }\fi +} + +\def\pgfoo@ciii@mergeA@done(#1)([#2]){% + \pgfoo@ciii@done(#1#2)% +} + +% #1 = MRO so far +% #2 = sequences with bad heads (dot after each sequence) +% [#3,#4] = the sequence whose head we're testing right +% now---obviously, it should not be empty! (#3 has no comma, +% #4 has a comma after each class name) +% #5 = #3 does not occur in the tail of these sequences (dot after +% each sequence) +% #6 = the remaining sequences (dot after each sequence) +\def\pgfoo@ciii@merge@checkHead(#1)(#2)([#3,#4])(#5)(#6){% + \pgfutil@in@{[#3,}{#2}% + \ifpgfutil@in@\pgfoo@escapeif{% #3 is already blacklisted + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5#6)}% + }\else\pgfoo@escapeif{% + \ifx\relax#6\relax\pgfoo@escapeif{% no more sequences to test the head against! + % so, #3 is a good head, and we can recurse + \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5)% + }\else\pgfoo@escapeif{% split #6 and get to work + \pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6)% + }\fi + }\fi +} +% splitter: to be only called from \pgfoo@ciii@merge@checkHead +% we will check if #3 occurs in the tail of #6 +\def\pgfoo@ciii@merge@checkHead@A(#1)(#2)([#3,#4])(#5)(#6.#7){% + \pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)(#6)(#7)% +} +% splitter: to be only called from \pgfoo@ciii@merge@checkHead@A +% &worker: we will check if #3 occurs in #7. If it does, #3 is a bad head. +\def\pgfoo@ciii@merge@checkHead@B(#1)(#2)([#3,#4])(#5)([#6,#7])(#8){% +% \def\pgfoo@ciii@tempA{#3}\def\pgfoo@ciii@tempB{#5}% +% \ifx\pgfoo@ciii@tempA\pgfoo@ciii@tempB +% \pgferror{An attempt to derive from the same class twice}% +% \else\pgfoo@escapeif{% + \pgfutil@in@{,#3,}{,#7}% + \ifpgfutil@in@\pgfoo@escapeif{% bad head! get next head and restart + % but: need to clean up first! + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead@P{(#1)(#2[#3,#4].)(#5[#6,#7].#8)}% + }\else\pgfoo@escapeif{% so far, so good + \ifx\relax#8\relax\pgfoo@escapeif{% if #8 is empty, we won: + % #3 is a good head! we will move it to MRO + % but clean-up first! + \pgfoo@ciii@goodHeadFound(#1)(#3)(#2[#4].#5[#6,#7].)% + }\else\pgfoo@escapeif{% proceed to the first seq in #8 + \pgfoo@ciii@clean\pgfoo@ciii@merge@checkHead{(#1)(#2)([#3,#4])(#5[#6,#7].)(#8)}% + }\fi + }\fi +% }\fi +} + +% #1 = MRO +% #2 = good head +% #3 = the remaining sequences (in need of removing the good head from +% them, and then also some general cleanup) +\def\pgfoo@ciii@goodHeadFound(#1)(#2)(#3){% + \pgfutil@in@{,#2,}{#3}% + \ifpgfutil@in@\pgfoo@escapeif{% + \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3,#2,##4){% + \pgfoo@ciii@goodHeadFound(##1)(##2)(##3,##4)}% + \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)% + }\else\pgfoo@escapeif{% + \pgfutil@in@{[#2,}{#3}% + \ifpgfutil@in@\pgfoo@escapeif{% + \def\pgfoo@ciii@removeGoodHead(##1)(##2)(##3[#2,##4){% + \pgfoo@ciii@goodHeadFound(##1)(##2)(##3[##4)}% + \pgfoo@ciii@removeGoodHead(#1)(#2)(#3)% + }\else\pgfoo@escapeif{% + \pgfoo@ciii@clean\pgfoo@ciii@merge{(#1#2,)(#3)}% + }\fi + }\fi +} + +% mediates between the bad head exit of \pgfoo@ciii@merge@checkHead@B +% and \pgfoo@ciii@merge@checkHead; we need the mediator because #3 +% below might have been affected by cleaning. +\def\pgfoo@ciii@merge@checkHead@P(#1)(#2)(#3){% + \if\relax#3\relax % no more good head candidates! + \pgferror{Bad MRO: There is no good (monotonic etc.) + Method Resolution Order for your class hierarchy}% + \else\pgfoo@escapeif{% + \pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3)% + }\fi +} +% splitter for \pgfoo@ciii@merge@checkHead@P +% #3 = the sequence containing the newest good head candidate +\def\pgfoo@ciii@merge@checkHead@Q(#1)(#2)(#3.#4){% + \pgfoo@ciii@merge@checkHead(#1)(#2)(#3)()(#4)% +} + +% cyclically removes all occurrences of "[]," and "[]." (i.e., empty +% sequences) in #2. When done, calls #1 with whatever remains. +\def\pgfoo@ciii@clean#1#2{% clean commas + \pgfutil@in@{[].}{#2}% clean dots + \ifpgfutil@in@\pgfoo@escapeif{% + \pgfoo@ciii@clean@dot#1#2\pgfoo@ciii@clean@END + }\else\pgfoo@escapeif{% + #1#2% + }\fi +} +\def\pgfoo@ciii@clean@dot#1#2[].#3\pgfoo@ciii@clean@END{% + \pgfoo@ciii@clean#1{#2#3}% +} + +\def\pgfoo@ciii@done(#1,){% + \def\pgfoo@mro{#1}% +} + +% end of C3 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Declare a method @@ -111,10 +297,71 @@ % } % } +% define the method macro and append the method to the method collection \def\pgfoo@declaremethod#1(#2)#3{% - \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.#1\endcsname(#2){#3}% + \def\pgfoo@method{#1}% + \ifx\pgfoo@classname\pgfoo@method + \def\pgfoo@method{init}% + \fi + \expandafter\long\expandafter\def\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname(#2){#3}% + \edef\pgfoo@methods{\pgfoo@methods,\pgfoo@method}% +} + +\def\pgfoo@inherit@methods{% + % for non-derived classes: + \expandafter\ifx\expandafter\relax\pgfoo@temp@baseclasses\relax + % if init is not defined, define an empty one + \expandafter\ifx\csname pgfooY\pgfoo@classname.init\endcsname\relax + \expandafter\let\csname pgfooY\pgfoo@classname.init\endcsname\pgfoo@emptyinit% + \edef\pgfoo@methods{,init\pgfoo@methods}% + \fi + \fi + \if\relax\pgfoo@methods\relax\else + % gobble the initial comma + \edef\pgfoo@methods{\expandafter\pgfutil@gobble\pgfoo@methods}% + \fi + % remember the list of collected methods + \expandafter\let\csname pgfooY\pgfoo@classname @pgfoo@methods\endcsname\pgfoo@methods + % get MRO + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + % loop throough base classes in MRO + \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% + \ifx\pgfoo@baseclass\pgfoo@classname % skip self + \else\pgfoo@escapeif{% + % get methods defined in this base class + \expandafter\let\expandafter\pgfoo@methods\csname pgfooY\pgfoo@baseclass @pgfoo@methods\endcsname + \pgfutil@for\pgfoo@method:=\pgfoo@methods\do{% for each method + % check if it is already defined in our class + \expandafter\ifx\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname\relax + % if not, link the method name from our class to base class + \edef\pgfoo@temp{\noexpand\let + \expandafter\noexpand\csname pgfooY\pgfoo@classname.\pgfoo@method\endcsname + \expandafter\noexpand\csname pgfooY\pgfoo@baseclass.\pgfoo@method\endcsname}% + \pgfoo@temp + \fi + }% + }\fi + }% } +\def\pgfoosuper(#1,#2).#3({% + #2.get id(\pgfoo@temp@id)% + \edef\pgfoo@classname{\csname pgfooX\pgfoo@temp@id @class\endcsname}% + \def\pgfoo@super@A##1,#1,##2.##3({% + \pgfoo@super@B##2.##3(% + }% + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + \expandafter\pgfoo@super@A\expandafter,\pgfoo@mro,.#3(% +} +\def\pgfoo@super@B#1,#2.#3({% + \expandafter\ifx\csname pgfooY#1.#3\endcsname\relax + \pgfoo@escapeif{\pgfoo@super@B#2.#3(}% + \else + \pgfoo@escapeif{\expandafter\pgfoo@caller\pgfoo@temp@id.#1.#3(}% + \fi +} + + % Declare an attribute % @@ -136,21 +383,78 @@ \ifpgfutil@in@% \pgfoo@declareunpack#1;% \else% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfoolet{#1}\pgfutil@empty}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% + \pgfoo@declareattribute@\let{#1}\pgfutil@empty \fi% \fi% } -\def\pgfoo@declareunpack#1=#2;{% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfooset{#1}{#2}}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% +\def\pgfoo@declareunpack#1=#2;{\pgfoo@declareattribute@\def{#1}{{#2}}} +\def\pgfoo@declareunpackspace#1 =#2;{\pgfoo@declareattribute@\def{#1}{{#2}}} + +% put the initial value in the class's namespace +% put the attr name in a list +\def\pgfoo@declareattribute@#1#2#3{% + \expandafter#1\csname pgfooY\pgfoo@classname @#2\endcsname#3% + \expandafter\def\expandafter\pgfoo@attributes\expandafter{\pgfoo@attributes,#2}% } -\def\pgfoo@declareunpackspace#1 =#2;{% - \expandafter\def\expandafter\pgfoo@attribute@collection\expandafter{\pgfoo@attribute@collection\pgfooset{#1}{#2}}% - \expandafter\def\expandafter\pgfoo@attribute@collection@gc\expandafter{\pgfoo@attribute@collection@gc\pgfoolet{#1}\relax}% + +% for each base class: +% for each attribute declared in that class: +% add the attr on a list if it's not there yet +% convert the list of (attr,class which it comes from) into an +% efficient sequence of triples \op{attrname}\pointer-to-initial-value +% (\op is then set differently in init and garbage collection) +\def\pgfoo@inherit@attributes{% + % store the list of attributes declared in this class for use in + % derived classes + \if\relax\pgfoo@attributes\relax\else + \edef\pgfoo@attributes{\expandafter\pgfutil@gobble\pgfoo@attributes}% gobble comma + \fi + \expandafter\let\csname pgfooY\pgfoo@classname.@pgfoo@attributes\endcsname\pgfoo@attributes% + % get MRO + \expandafter\let\expandafter\pgfoo@mro\csname pgfooY\pgfoo@classname @pgfoo@mro\endcsname + \def\pgfoo@allattributes{}% here we will store the attrs declared in base classes + \pgfutil@for\pgfoo@baseclass:=\pgfoo@mro\do{% for each base class in MRO order + % the attributes declared in this base class + \expandafter\let\expandafter\pgfoo@attributes\csname pgfooY\pgfoo@baseclass.@pgfoo@attributes\endcsname + \pgfutil@for\pgfoo@attribute:=\pgfoo@attributes\do{% for each attribute + % check if we have already found it in some previous base class + \edef\pgfoo@temp{{,\pgfoo@attribute=}{\pgfoo@allattributes,}} + \expandafter\pgfutil@in@\pgfoo@temp + \ifpgfutil@in@\else % don't overwrite + % append to the list + \edef\pgfoo@allattributes{\pgfoo@allattributes,\pgfoo@attribute=\pgfoo@baseclass}% + \fi + }% + }% + \if\relax\pgfoo@allattributes\relax\else + \edef\pgfoo@allattributes{\expandafter\pgfutil@gobble\pgfoo@allattributes}% gobble comma + \fi + % this macro will hold a list of attributes from all base classes + % we run this macro at init and gc + \def\pgfoo@process@attributes{} + \pgfutil@for\pgfoo@attributeclass:=\pgfoo@allattributes\do{% for each (attribute, class) pair + % append to the attribute processor + \expandafter\pgfoo@inherit@attributes@appendattribute\pgfoo@attributeclass.% + }% + \expandafter\let\csname pgfooY\pgfoo@classname .@pgfoo@process@attributes\endcsname\pgfoo@process@attributes } +% #1=attr, #2=class which the attr comes from +\def\pgfoo@inherit@attributes@appendattribute#1=#2.{% + \def\pgfoo@tempA{\pgfoo@attribute@op{#1}}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@tempB\expandafter\expandafter\expandafter{\expandafter\pgfoo@tempA\csname pgfooY#2@#1\endcsname}% + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfoo@process@attributes\expandafter\expandafter\expandafter{\expandafter\pgfoo@process@attributes\pgfoo@tempB}% + % above is just this: + % \def\pgfoo@process@attributes{\pgfoo@process@attributes\pgfoo@attribute@op{#1}% + % \csname pgfooY#2@#1\endcsname} + % with \pgfoo@process@attributes and \csname expanded exactly once: +} + +% \pgfoo@attribute@op for garbace collection +\def\pgfoo@gc@attribute#1#2{\pgfoolet{#1}\relax} + + \newcount\pgfoo@objectcount \newcount\pgfoothis@count @@ -250,6 +554,21 @@ +% Help macro for scanning arguments +\newtoks\pgfoo@toks + +\def\pgfoo@collect@args{% + \pgfutil@ifnextchar\bgroup\pgfoo@collect@args@group\pgfoo@collect@args@nogroup% +} +\def\pgfoo@collect@args@nogroup#1){% + \pgfoo@toks{#1}% + \pgfoo@continue% +} +\def\pgfoo@collect@args@group#1{% + \pgfutil@ifnextchar){\pgfoo@toks{{#1}}\expandafter\pgfoo@continue\pgfutil@gobble}{\pgfoo@collect@args@nogroup{#1}}% +} + + % Instantiate an object % % Possible syntax: @@ -276,32 +595,73 @@ }% }% } -\def\pgfoo@new#1=new #2(#3){% +\def\pgfoo@new#1=new #2({% \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax% - \PackageError{pgfoo}{Unknown class '#2'}{}% + \pgferror{Unknown class '#2'}% \else% - \advance\pgfoo@objectcount by 1\relax% - \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}% - \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}% - \let#1\pgfoolastobj% + \pgfoo@new@create#1{#2}% {% \pgfoothis@count\pgfoo@objectcount% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfooinit\endcsname% + \let\pgfoo@attribute@op\pgfoolet + \csname pgfooY#2.@pgfoo@process@attributes\endcsname% }% - \pgfoolastobj.#2(#3)% - \aftergroup\pgfoogc% cleanup after group + \let\pgfoo@continue=\pgf@oo@new@cont% + \expandafter\pgfoo@collect@args% \fi% } -\def\pgfoo@new@attribute#1=new #2(#3){% - \pgfoo@new\pgf@oo@temp=new #2(#3)% - \pgfoolet{#1}\pgf@oo@temp% + +\def\pgf@oo@new@cont{% + \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)% + \aftergroup\pgfoogc% cleanup after group } +\def\pgfoo@new@attribute#1=new #2({% + \expandafter\ifx\csname pgfooY#2.get id\endcsname\relax% + \pgferror{Unknown class '#2'}% + \else% + \pgfoo@new@create\pgfoo@temp{#2}% + {% + \pgfoothis@count\pgfoo@objectcount% + \let\pgfoo@attribute@op\pgfoolet% + \csname pgfooY#2.@pgfoo@process@attributes\endcsname% + }% + \pgfoolet{#1}\pgfoo@temp% + \let\pgfoo@continue=\pgf@oo@new@cont% + \expandafter\pgfoo@collect@args% + \fi% +} -\def\pgfoo@caller#1.#2(#3){% +\def\pgf@oo@new@cont{% + \expandafter\pgfoolastobj\expandafter.\expandafter i\expandafter n\expandafter i\expandafter t\expandafter(\the\pgfoo@toks)% + \aftergroup\pgfoogc% cleanup after group +} + +\def\pgfoo@new@create#1#2{% + \advance\pgfoo@objectcount by 1\relax% + \edef\pgfoolastobj{\noexpand\pgfoo@caller{\the\pgfoo@objectcount}}% + \expandafter\gdef\csname pgfooX\the\pgfoo@objectcount @class\endcsname{#2}% + \let#1\pgfoolastobj% +} + +\def\pgfoo@caller#1.#2({% + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX#1@class\endcsname.#2\endcsname% + \ifx\pgfoo@caller@temp\relax% + % assume that #2 is of form "superclass.method" + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#2\endcsname% + \ifx\pgfoo@caller@temp\relax% + \pgferror{Object #1 has no method '#2'}% + \fi% + \fi% \def\pgf@marshal{% \pgfoothis@count=#1\relax% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#2\endcsname(#3)% + }% + \let\pgfoo@continue\pgfoo@caller@cont% + \pgfoo@collect@args% +} +\def\pgfoo@caller@cont{% + \edef\pgf@marshal{% + \pgf@marshal% + \noexpand\pgfoo@caller@temp(\the\pgfoo@toks)% }% \expandafter\pgf@marshal\expandafter\pgfoothis@count\the\pgfoothis@count\relax% } @@ -309,11 +669,18 @@ % The special "this" object -\def\pgfoothis.#1(#2){% - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname(#2)% +\def\pgfoothis.#1({% + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.#1\endcsname% + \ifx\pgfoo@caller@temp\relax% + % assume that #1 is of form "superclass.method" + \expandafter\let\expandafter\pgfoo@caller@temp\csname pgfooY#1\endcsname% + \fi% + \let\pgfoo@continue\pgfoothis@cont% + \pgfoo@collect@args% +} +\def\pgfoothis@cont{% + \expandafter\pgfoo@caller@temp\expandafter(\the\pgfoo@toks)% } - - @@ -390,7 +757,8 @@ \else% % Cleanup this object: % The following is the fast version of \pgfooobj{\the\pgfoo@objectcount}.@pgfoogc: - \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoogc\endcsname% + \let\pgfoo@attribute@op\pgfoo@gc@attribute + \csname pgfooY\csname pgfooX\the\pgfoothis@count @class\endcsname.@pgfoo@process@attributes\endcsname% \expandafter\global\expandafter\let\csname pgfooX\the\pgfoothis@count @class\endcsname\relax% \fi% \pgfoo@next% @@ -398,6 +766,28 @@ +% +% +% Object class +% defines method "copy" +% +% + +\pgfooclass{object}{% + \method copy(#1) {% + % create a new object + \edef\pgfoo@temp@classname{\csname pgfooX\the\pgfoothis@count @class\endcsname}% + \expandafter\pgfoo@new@create\expandafter#1\expandafter{\pgfoo@temp@classname}% + \def\pgfoo@copy@attributes##1##2{% + \pgfooget{##1}\pgfoo@attrvalue + \expandafter\let\csname pgfooX\the\pgfoo@objectcount @##1\endcsname\pgfoo@attrvalue + }% + \let\pgfoo@attribute@op\pgfoo@copy@attributes + \csname pgfooY\pgfoo@temp@classname .@pgfoo@process@attributes\endcsname + \aftergroup\pgfoogc% cleanup after group + } +} + % % diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex index ed13b25324c..0a08a5e9d4e 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleparser.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleparser.code.tex,v 1.1 2009/01/12 12:56:09 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleparser.code.tex,v 1.2 2013/07/15 12:05:34 tantau Exp $ % % This file defines commands for defining a letter-by-letter parser @@ -43,9 +43,9 @@ \expandafter\let\expandafter\pgf@parser@action% \csname pgf@parser@a@\pgf@parser @all@\meaning\pgf@parser@symbol\endcsname% \ifx\pgf@parser@action\relax% - \PackageError{pgfparse}{Unexpected character + \pgferror{Unexpected character '\meaning\pgf@parser@symbol' in parser '\pgf@parser' in state - '\pgf@parser@state'}{}% + '\pgf@parser@state'}% \fi% \fi% \pgf@parser@action% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex index ea55ca8517b..8620a91e4de 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleplot.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.8 2010/10/22 17:34:17 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleplot.code.tex,v 1.12 2013/07/31 16:22:24 tantau Exp $ % PGF's plotting interface works as follows: @@ -16,26 +16,35 @@ % need to provide the coordinates (obviously) of the points that % should be plotted. The coordinates are given via a long stream of % commands. These commands are \pgfplotstreamstart, which is -% given exactly once at the beginning, \pgfplotstreampoint, of which there -% are numerous in the middle, \pgfplotstreamspecial, of which there may be -% numerous in the middle, and \pgfplotstreamend, which must be given -% at the end. Between these commands arbitrary other commands may be -% given. Here is an example: +% given exactly once at the beginning, the commands +% \pgfplotstreampoint, \pgfplotstreampointoutlier, +% \pgfplotstreampointundefined, \pgfplotstreamnewdataset, of which +% there are numerous in the middle, the special \pgfplotstreamspecial, +% of which there may be numerous in the middle, and \pgfplotstreamend, +% which must be given at the end. Between these commands arbitrary +% other commands may be given. Here is an example: % % ... % \pgfplotstreamstart % \pgfplotstreampoint{\pgfpointxy{0}{0}} % \pgfplotstreampoint{\pgfpointxy{1}{1}} +% \pgfplotstreamnewdataset % \pgfplotstreampoint{\pgfpointxy{2}{4}} % \relax -% \pgfplotstreampoint{\pgfpointxy{3}{9}} +% \pgfplotstreampointoutlier{\pgfpointxy{3}{9}} % \pgfplotstreamspecial{some handler-dependent special stuff} % \pgfplotstreamend % % By themselves, the \pgfplotstreamxxxx commands do not do anything by % default. Rather, to ``use'' such a stream, you must first install a % stream handler. For example, the ``lineto'' handler will simply -% translate every \pgfplotstreampoint into a \pgfpathlineto. +% basically every \pgfplotstreampoint into a \pgfpathlineto. +% +% One special things is the handling of "jumps" in a stream. For +% instance, when a lineto handler encounters an "outlier" or a new +% data set, the current line should end and a new subpath should start +% (unless configured otherwise). For this, the special jump handler is +% important. % % Example: % @@ -55,9 +64,111 @@ % are set by the handlers: \def\pgfplotstreamstart{\pgf@plotstreamstart} \def\pgfplotstreampoint#1{\gdef\pgfplotlastpoint{#1}\pgf@plotstreampoint{#1}} +\def\pgfplotstreampointoutlier#1{\pgfplot@outliers{}{\pgf@plotstreamjump}{\pgfplotstreampoint{#1}}}% +\def\pgfplotstreampointundefined{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}% +\def\pgfplotstreamnewdataset{\pgfplot@outliers{}{\pgf@plotstreamjump}{}}% \def\pgfplotstreamspecial{\pgf@plotstreamspecial} \def\pgfplotstreamend{\pgf@plotstreamend} +\def\pgfplot@ignorer#1#2#3{#1} +\def\pgfplot@jumper#1#2#3{#2} +\def\pgfplot@plotter#1#2#3{#3} + +\let\pgfplot@outliers\pgfplot@jumper +\let\pgfplot@undefined\pgfplot@jumper +\let\pgfplot@newdata\pgfplot@jumper + +\pgfset{ + handle outlier points in plots/.is choice, + handle outlier points in plots/ignore/.code=\let\pgfplot@outliers\pgfplot@ignorer, + handle outlier points in plots/jump/.code=\let\pgfplot@outliers\pgfplot@jumper, + handle outlier points in plots/plot/.code=\let\pgfplot@outliers\pgfplot@plotter, + handle undefined points in plots/.is choice, + handle undefined points in plots/ignore/.code=\let\pgfplot@undefined\pgfplot@ignorer, + handle undefined points in plots/jump/.code=\let\pgfplot@undefined\pgfplot@jumper, + handle new data sets in plots/.is choice, + handle new data sets in plots/ignore/.code=\let\pgfplot@newdata\pgfplot@ignorer, + handle new data sets in plots/jump/.code=\let\pgfplot@newdata\pgfplot@jumper, +} + + +% Declares a new plot handler +% +% #1 = macro that should install the stream handler subsequently +% #2 = parameter list of said macro. +% #3 = keys as described below +% +% Description: +% +% When you declare a new plot handler, you provide, through keys, +% different "actions" that should be taken when the different stream +% commands are used: +% +% start = some code to be executed when \pgfplotstreamstart is called +% for this plothandler +% end = same for the end of the stream +% point = code to be executed for a point of the stream +% jump = code to be executed for a "jump" in the stream +% special = code to be executed for \pgfplotstreamspecial +% start macro = here and for the following keys, the to-be-executed +% code is stored in the given macro +% end macro = see above +% jump macro = see above +% point macro = see above +% special macro = see above +% +% Example: +% +% \pgfdeclareplothandler{\ultrasimplehandler}{}{ +% point=\pgfpathlineto{##1} +% } + +\def\pgfdeclareplothandler#1#2#3{% + \def#1#2{% + \pgfkeys{% + /pgf/plots/@handler options/.cd, + start=\relax, + end macro=\relax, + point macro=\pgfutil@gobble, + jump macro=\relax, + special macro=\pgfutil@gobble,% + #3% + }% + }% +} + +\pgfkeys{% + /pgf/plots/@handler options/.cd, + start/.code=% + \gdef\pgf@plotstreamstart{% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreamend\pgf@plotstreamend@init% + \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init% + \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init% + \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init% + #1% + },% + start macro/.code=% + \gdef\pgf@plotstreamstart{% + \global\pgf@plot@startedfalse% + \global\let\pgf@plotstreamend\pgf@plotstreamend@init% + \global\let\pgf@plotstreampoint\pgf@plotstreampoint@init% + \global\let\pgf@plotstreamjump\pgf@plotstreamjump@init% + \global\let\pgf@plotstreamspecial\pgf@plotstreamspecial@init% + #1% + },% + end/.code=\gdef\pgf@plotstreamend@init{#1}, + end macro/.code=\global\let\pgf@plotstreamend@init#1, + point/.code=\gdef\pgf@plotstreampoint@init##1{#1}, + point macro/.code=\global\let\pgf@plotstreampoint@init#1, + jump/.code=\gdef\pgf@plotstreamjump@init{#1}, + jump macro/.code=\global\let\pgf@plotstreamjump@init#1, + special/.code=\gdef\pgf@plotstreamspecial@init##1{#1}, + special macro/.code=\global\let\pgf@plotstreamspecial@init#1, +} + +\newif\ifpgf@plot@started + @@ -88,6 +199,7 @@ + % % Handlers % @@ -103,12 +215,9 @@ % \pgfplothandlerlineto % \pgfplotxyfile{mytable} -\def\pgfplothandlerlineto{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@line@handler% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% +\pgfdeclareplothandler{\pgfplothandlerlineto}{}{ + point macro=\pgf@plot@line@handler, + jump=\global\let\pgf@plotstreampoint\pgf@plot@line@handler@move% } \def\pgf@plot@line@handler#1{% @@ -116,29 +225,48 @@ \global\let\pgf@plotstreampoint=\pgfpathlineto% } +\def\pgf@plot@line@handler@move#1{% + \pgfpathmoveto{#1}% + \global\let\pgf@plotstreampoint=\pgfpathlineto% +} + % This handler turns creates a series of lineto commands, with the -% last command being a closepath, resulting in a closed path. +% last command being a closepath, resulting in a closed path. If a +% jump is encountered, the current subpath is closed and a new subpath +% is started. % % Example: % % \pgfplothandlerpolygon % \pgfplotxyfile{mytable} -\def\pgfplothandlerpolygon{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgf@plot@line@handler@close% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\pgfpathclose% - }% -} +\pgfdeclareplothandler{\pgfplothandlerpolygon}{}{% + point macro=\pgf@plot@line@handler@close, + jump macro=\pgf@plot@next@close@and@moveto, + end macro=\pgf@plot@polygon@stop +}% \def\pgf@plot@line@handler@close#1{% \pgfpathmoveto{#1}% + \global\pgf@plot@startedtrue% \global\let\pgf@plotstreampoint=\pgfpathlineto% } +\def\pgf@plot@polygon@stop{% + \ifpgf@plot@started% + \pgfpathclose% + \fi% + \global\pgf@plot@startedfalse% +} + +\def\pgf@plot@next@close@and@moveto{% + \ifpgf@plot@started% + \pgfpathclose% + \fi% + \global\let\pgf@plotstreampoint\pgf@plot@line@handler@close% +} % More handlers are defined in pgflibraryplothandlers @@ -154,14 +282,7 @@ % \pgfplothandlerdiscard % \pgfplotxyfile{mytable} -\def\pgfplothandlerdiscard{% - \def\pgf@plotstreamstart{% - \global\let\pgf@plotstreampoint=\pgfutil@gobble% - \global\let\pgf@plotstreamspecial=\pgfutil@gobble% - \global\let\pgf@plotstreamend=\relax% - }% -} - +\pgfdeclareplothandler{\pgfplothandlerdiscard}{}{} @@ -178,14 +299,12 @@ % \pgftransformxshift{1cm} % \myplot -\def\pgfplothandlerrecord#1{% - \def\pgf@plot@recordto{#1}% - \gdef#1{\pgfplotstreamstart}% - \def\pgf@plotstreamstart{% - \gdef\pgf@plotstreampoint####1{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{####1}}}% - \gdef\pgf@plotstreamspecial####1{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{####1}}}% - \gdef\pgf@plotstreamend{\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}}% - }% +\pgfdeclareplothandler{\pgfplothandlerrecord}{#1}{% + start=\gdef#1{\pgfplotstreamstart}, + point=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreampoint{##1}}, + jump=\expandafter\gdef\expandafter#1\expandafter{#1\pgf@plotstreamjump}, + special=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamspecial{##1}}, + end=\expandafter\gdef\expandafter#1\expandafter{#1\pgfplotstreamend}, } @@ -212,9 +331,10 @@ \pgfplotstreamstart% \openin\r@pgf@reada=#1 \ifeof\r@pgf@reada - \PackageWarning{pgf}{Plot data file `#1' not found.} + \pgfwarning{Plot data file `#1' not found.} \else \catcode`\#=14 + \catcode`\^^M=5 \pgf@readxyfile% \fi \pgfplotstreamend% @@ -228,7 +348,9 @@ \let\par=\pgf@savedpar% \edef\pgf@temp{\pgf@temp}% \ifx\pgf@temp\pgfutil@empty% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else\ifx\pgf@temp\pgf@partext% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else% \expandafter\pgf@parsexyline\pgf@temp\pgf@stop% \fi\fi% @@ -236,9 +358,18 @@ } \def\pgf@parsexyline#1 #2 #3\pgf@stop{% - \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% + \edef\pgf@xyline@flag@val{#3}% + \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% + \pgfplotstreampointundefined% + \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% + \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}% + \else% + \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% + \fi\fi% } +\edef\pgf@xyline@flag@out{o\space}% +\edef\pgf@xyline@flag@undef{u\space}% @@ -261,9 +392,10 @@ \pgfplotstreamstart% \openin\r@pgf@reada=#1 \ifeof\r@pgf@reada - \PackageWarning{pgf}{Plot data file `#1' not found.} + \pgfwarning{Plot data file `#1' not found.} \else \catcode`\#=14 + \catcode`\^^M=5 \pgf@readxyzfile% \fi \pgfplotstreamend% @@ -273,7 +405,9 @@ \def\pgf@readxyzfile{% \pgfutil@read\r@pgf@reada to \pgf@temp% \ifx\pgf@temp\pgfutil@empty% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else\ifx\pgf@temp\pgf@partext% + \ifeof\r@pgf@reada\else\pgfplotstreamnewdataset\fi% \else% \expandafter\pgf@parsexyzline\pgf@temp\pgf@stop% \fi\fi% @@ -281,7 +415,14 @@ } \def\pgf@parsexyzline#1 #2 #3 #4\pgf@stop{% - \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}% + \edef\pgf@xyline@flag@val{#4}% + \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% + \pgfplotstreampointundefined% + \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% + \pgfplotstreampointoutlier{\pgfpointxyz{#1}{#2}{#3}}% + \else% + \pgfplotstreampoint{\pgfpointxyz{#1}{#2}{#3}}% + \fi\fi% } @@ -314,6 +455,9 @@ \let\pgf@plotwrite=\w@pgf@writea \newif\ifpgf@resample@plot +\pgfkeys{% + /pgf/plot/gnuplot call/.initial={gnuplot}} + \def\pgfplotgnuplot{\pgfutil@ifnextchar[{\pgf@plotgnuplot}{\pgf@plotgnuplot[\jobname]}}%} \def\pgf@plotgnuplot[#1]#2{% \pgf@resample@plottrue% @@ -344,25 +488,27 @@ \immediate\pgfutil@write\pgf@plotwrite{\pgf@gnuplot@head}% \immediate\pgfutil@write\pgf@plotwrite{#2}% \immediate\closeout\pgf@plotwrite% - \immediate\pgfutil@write18{gnuplot \pgf@plotgnuplotfile}% + \immediate\pgfutil@write18{% + \pgfkeysvalueof{/pgf/plot/gnuplot call} \pgf@plotgnuplotfile}% \fi% - % temporarily redefine \pgf@parsexyline - \let\pgf@savedparsexyline=\pgf@parsexyline% - \let\pgf@parsexyline=\pgf@parsegnuplotxyline% +% \let\pgf@savedparsexyline=\pgf@parsexyline% +% \let\pgf@parsexyline=\pgf@parsegnuplotxyline% \pgfplotxyfile{\pgf@plottablefile}% - \let\pgf@parsexyline=\pgf@savedparsexyline% -} - -\def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{% - \edef\pgf@xyline@flag@val{#3}% - \edef\pgf@xyline@flag@undef{u\space}% - \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% - \else% - \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% - \fi% +% \let\pgf@parsexyline=\pgf@savedparsexyline% } - +% \def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{% +% \edef\pgf@xyline@flag@val{#3}% +% \edef\pgf@xyline@flag@out{o\space}% +% \edef\pgf@xyline@flag@undef{u\space}% +% \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef% +% \pgfplotstreampointundefined% +% \else\ifx\pgf@xyline@flag@val\pgf@xyline@flag@out% +% \pgfplotstreampointoutlier{\pgfpointxy{#1}{#2}}% +% \else% +% \pgfplotstreampoint{\pgfpointxy{#1}{#2}}% +% \fi\fi% +% } % This producer handler plots a function using pgf's mathematical engine. % diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex index da75b3e2e43..7e4e65d4c38 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmoduleshapes.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.13 2010/09/09 13:52:57 cjorssen Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmoduleshapes.code.tex,v 1.34 2013/10/31 15:44:19 tantau Exp $ @@ -38,12 +38,12 @@ \def\pgfmultipartnode#1#2#3#4{% \pgfutil@ifundefined{pgf@sh@s@#1}% - {\PackageError{pgf}{Unknown shape ``#1''}{}}% + {\pgferror{Unknown shape ``#1''}}% {% {% \let\pgf@sh@savedmacros=\pgfutil@empty% MW \let\pgf@sh@savedpoints=\pgfutil@empty% - \def\shape@name{#1}% CJ + \def\pgf@sm@shape@name{#1}% CJ % TT added prefix! \csname pgf@sh@s@#1\endcsname% \pgf@sh@savedpoints% \pgf@sh@savedmacros% MW @@ -57,15 +57,8 @@ }% % Save the saved points and the transformation matrix \edef\pgf@node@name{#3}% - \ifx\pgf@positionnodelater@macro\relax% - \else% - % Rename node - \edef\pgf@node@name{not yet positioned@\pgf@node@name}% - % Interrupt bounding box! - \pgfinterruptboundingbox% - % Put everything in our box: - \setbox\pgfpositionnodelaterbox=\hbox\bgroup% - % + \ifpgflatenodepositioning + \pgf@shapes@late@pos@begin% \fi% \ifx\pgf@node@name\pgfutil@empty% \else% @@ -74,20 +67,29 @@ \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedpoints}% \edef\pgf@sh@@temp{\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW \expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW - \pgfgettransform\pgf@temp + \pgfgettransform\pgf@temp% \expandafter\xdef\csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}% \expandafter\xdef\csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}% \fi% \pgfutil@ifundefined{pgf@sh@bbg@#1}{} {{\pgfscope\csname pgf@sh@bbg@#1\endcsname\endpgfscope}}% - \pgfutil@ifundefined{pgf@sh@bg@#1}{}% - {\csname pgf@sh@bg@#1\endcsname#4}% + \pgfutil@ifundefined{pgf@sh@bg@#1}{% + \global\let\pgfpositionnodelaterpath\pgfutil@empty% + }% + {\csname pgf@sh@bg@#1\endcsname% + \ifpgflatenodepositioning% + \pgfsyssoftpath@getcurrentpath\pgfpositionnodelaterpath% + \pgfprocessround{\pgfpositionnodelaterpath}{\pgfpositionnodelaterpath}% + \global\let\pgfpositionnodelaterpath\pgfpositionnodelaterpath% + \fi% + #4}% \pgfutil@ifundefined{pgf@sh@fbg@#1}{} {{\pgfscope\csname pgf@sh@fbg@#1\endcsname\endpgfscope}}% {% \expandafter\pgfutil@for\expandafter\pgf@shape@com\expandafter:\expandafter=\csname pgf@sh@boxes@#1\endcsname\do{% {% \pgftransformshift{\pgf@sh@reanchor{#1}{\pgf@shape@com}}% + \pgfapproximatenonlineartransformation% \expandafter\pgfqboxsynced\expandafter{\csname pgfnodepart\pgf@shape@com box\endcsname}% }% }% @@ -98,23 +100,44 @@ {\csname pgf@sh@fg@#1\endcsname#4}% \pgfutil@ifundefined{pgf@sh@ffg@#1}{}% {{\pgfscope\csname pgf@sh@ffg@#1\endcsname\endpgfscope}}% - \ifx\pgf@positionnodelater@macro\relax% - \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}% + \ifpgflatenodepositioning% + \pgf@shapes@late@pos@end% \else% - \egroup% Close box - \edef\pgfpositionnodelaterminx{\the\pgf@picminx}% - \edef\pgfpositionnodelaterminy{\the\pgf@picminy}% - \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}% - \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}% - \let\pgfpositionnodelatername=\pgf@node@name% - \pgf@positionnodelater@macro% - \endpgfinterruptboundingbox% + \expandafter\pgf@nodecallback\expandafter{\pgf@node@name}% \fi% }% }% } - +\def\pgf@shapes@late@pos@begin{% + % Rename node + \edef\pgf@node@name{not yet positionedPGFINTERNAL\pgf@node@name}% + % Interrupt bounding box! + \pgfinterruptboundingbox% + % Put everything in our box: + \pgf@relevantforpicturesizetrue% + \setbox\pgfpositionnodelaterbox=\hbox% + \bgroup% +} + +\def\pgf@shapes@late@pos@end{% + \egroup% Close box + \ifdim\pgf@picminx>\pgf@picmaxx\relax% happens for empty nodes + \def\pgfpositionnodelaterminx{0.0pt}% + \let\pgfpositionnodelaterminy\pgfpositionnodelaterminx% + \let\pgfpositionnodelatermaxx\pgfpositionnodelaterminx% + \let\pgfpositionnodelatermaxy\pgfpositionnodelaterminx% + \else% + \edef\pgfpositionnodelaterminx{\the\pgf@picminx}% + \edef\pgfpositionnodelaterminy{\the\pgf@picminy}% + \edef\pgfpositionnodelatermaxx{\the\pgf@picmaxx}% + \edef\pgfpositionnodelatermaxy{\the\pgf@picmaxy}% + \fi% + \let\pgfpositionnodelatername=\pgf@node@name% + \pgf@positionnodelater@macro% + \endpgfinterruptboundingbox% +} + \def\pgf@shift@node#1#2{% % This internal command shifts the recorded coordinates for node #1 % by the vector #2. It is used to @@ -199,7 +222,7 @@ % \pgfpositionnodelatername % The name of the just-created-node. This name will be the % originally "desired" name of the box plus the prefix "not yet -% positioned box@". +% positioned boxPGFINTERNAL". % % \pgfpositionnodelaterminx % \pgfpositionnodelatermaxx @@ -218,11 +241,21 @@ % When \pgfpositionnodenow is called, the macros mentioned above % should have the exact same values they had when #1 is called. -\def\pgfpositionnodelater#1{\let\pgf@positionnodelater@macro=#1\relax} +\def\pgfpositionnodelater#1{% + \let\pgf@positionnodelater@macro=#1% + \ifx\pgf@positionnodelater@macro\relax% + \pgflatenodepositioningfalse% + \else% + \pgflatenodepositioningtrue% + \fi% +} +\newif\ifpgflatenodepositioning \pgfpositionnodelater{\relax} \def\pgfpositionnodelaterbox{0} + + % Position a node that has been scheduled for later insertion % % #1 = position in the picture, where the original anchor should go, @@ -232,7 +265,7 @@ % % This command works in concert with \pgfpositionnodelater, see the % description there. When \pgfpositionnodenow is called, the macros -% \pgfpositionnodelaterbox and so one should be set to the values they +% \pgfpositionnodelaterbox and so on should be set to the values they % had when the macro given to \pgfpositionnodelater was called. Then, % the box described by these macros will be inserted into the picture % at the position given #1. More precisely, the original node will @@ -241,13 +274,13 @@ % into the actual picture. \def\pgfpositionnodenow#1{% + \pgfinterruptpath% {% \pgfpointtransformed{#1}% \edef\pgf@temp@shift{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}} \pgftransformreset% \pgftransformshift{\pgf@temp@shift}% - \setbox\pgfpositionnodelaterbox=\hbox{\pgfsys@beginpicture\box\pgfpositionnodelaterbox\pgfsys@endpicture}% - \pgfqboxsynced{\pgfpositionnodelaterbox}% + \pgfsys@pictureboxsynced\pgfpositionnodelaterbox% \pgf@shift@node{\pgfpositionnodelatername}{\pgf@temp@shift}% % Bounding box update... \pgfpointtransformed{\pgfqpoint{\pgfpositionnodelaterminx}{\pgfpositionnodelaterminy}}% @@ -257,15 +290,65 @@ % Naming and callbacks \expandafter\pgfpositionnodenow@rename\pgfpositionnodelatername\relax% }% + % Late setup% + {% + \csname pgf@lns@\pgfpositionnodelatername\endcsname% + \expandafter\global\expandafter\let\csname pgf@lns@\pgfpositionnodelatername\endcsname\relax% + }% + \endpgfinterruptpath% } -\def\pgfpositionnodenow@rename not yet positioned@#1\relax{% - \pgfnoderename{#1}{not yet positioned@#1} +\def\pgfpositionnodenow@rename not yet positionedPGFINTERNAL#1\relax{% + \pgfnoderename{#1}{not yet positionedPGFINTERNAL#1} \pgf@nodecallback{#1}% } +% "Fake" a node +% +% #1 = node name +% +% Description: +% +% This command will setup things so that it "looks like" a node named +% #1 has been created, but, in reality, no node is created. The idea +% is that a node created in this way can be referenced by systems +% using the late positioning, which will only create the node later +% on. +% +\def\pgffakenode#1{% + \edef\pgf@temp{\ifpgflatenodepositioning not yet positionedPGFINTERNAL\fi#1}% + \expandafter\gdef\csname pgf@sh@ns@\pgf@temp\endcsname{coordinate}% + \expandafter\gdef\csname pgf@sh@np@\pgf@temp\endcsname{\def\centerpoint{\pgfpointorigin}}% + \expandafter\gdef\csname pgf@sh@nt@\pgf@temp\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@\pgf@temp\endcsname\pgfutil@empty% + \expandafter\xdef\csname pgf@sh@pi@\pgf@temp\endcsname{\pgfpictureid}% +} + + + +% Specify code that should be executed after a node has been created +% +% #1 = node name +% #2 = later code +% +% Description: +% +% This macro allows you to provide some code #2 that will be executed +% right after a node has been positioned using \pgfpositionnodenow. If +% the node has already been positioned (if the late positioning is not +% switched on), nothing happens. + +\def\pgfnodepostsetupcode#1#2{% + \ifpgflatenodepositioning% + \expandafter\ifx\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname\relax% + \expandafter\gdef\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}% + \else% + \expandafter\pgfutil@g@addto@macro\csname pgf@lns@not yet positionedPGFINTERNAL#1\endcsname{#2}% + \fi% + \fi% +} @@ -334,19 +417,23 @@ \edef\pgf@temp{#1}% \ifx\pgf@temp\pgfutil@empty% do nothing \else% - \pgf@process{\pgfpointtransformed{#2}}% - \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% - \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% - \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% - } - \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% - \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% - \expandafter\gdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \ifpgflatenodepositioning% + {\pgftransformshift{#2}\pgfnode{coordinate}{center}{}{#1}{}}% + \else% + \pgf@process{\pgfpointtransformed{#2}}% + \expandafter\gdef\csname pgf@sh@ns@#1\endcsname{coordinate}% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\centerpoint{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + } + \expandafter\gdef\csname pgf@sh@nt@#1\endcsname{{1}{0}{0}{1}{0pt}{0pt}}% + \expandafter\global\expandafter\let\csname pgf@sh@ma@#1\endcsname\pgfutil@empty% + \expandafter\xdef\csname pgf@sh@pi@#1\endcsname{\pgfpictureid}% + \fi% \fi% } \def\pgf@sh@redeferredanchor#1#2{% CJ - \expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}}% CJ + \expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}}% CJ @@ -393,7 +480,7 @@ {% \pgfutil@ifundefined{pgf@anchor@generic@#2}{% \pgfmathsetcounter{pgf@counta}{#2}% - \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\c@pgf@counta}{1pt}}% + \csname pgf@anchor@#1@border\endcsname{\pgfqpointpolar{\the\c@pgf@counta}{1pt}}% }{% \csname pgf@anchor@generic@#2\endcsname{#1}% }% @@ -414,7 +501,7 @@ % can be used to query the referenced node's name. % This macro is not defined during node creation. \def\pgfdeclaregenericanchor#1#2{% - \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}% + \expandafter\def\csname pgf@anchor@generic@#1\endcsname##1{#2}% }% @@ -435,7 +522,10 @@ \def\pgfpointanchor#1#2{% % Ok, check whether #1 is known! \pgfutil@ifundefined{pgf@sh@ns@#1} - {\PackageError{pgf}{No shape named #1 is known}{}% + {\pgfutil@ifundefined{pgf@sh@ns@not yet positionedPGFINTERNAL#1}{% + \pgferror{No shape named #1 is known}}{ + % else, fail silently + }% \pgfpointorigin}% {% \pgf@process{% @@ -500,7 +590,7 @@ \def\pgfpointshapeborder#1#2{% % Ok, check whether #1 is known! \pgfutil@ifundefined{pgf@sh@ns@#1} - {\PackageError{pgf}{No shape named #1 is known}{}% + {\pgferror{No shape named #1 is known}% \pgfpointorigin}% {% \pgf@process{% @@ -536,6 +626,25 @@ } +% Retrieve the list of node parts of a shape +% +% #1 = a macro +% #2 = a shape name +% +% Description: +% +% Stores the list of node parts of a shape #2 in the macro #1. +% +% Example: +% +% \pgfgetnodeparts\mylist{circle split} +% +% This will set \mylist\ to "text,lower" + +\def\pgfgetnodeparts#1#2{% + \expandafter\let\expandafter#1\csname pgf@sh@boxes@#2\endcsname% +} + % Declares a shape type % @@ -605,7 +714,7 @@ \long\def\pgfdeclareshape#1#2{% { - \def\shape@name{#1} + \def\pgf@sm@shape@name{#1} \let\savedanchor=\pgf@sh@savedanchor \let\saveddimen=\pgf@sh@saveddimen \let\savedmacro=\pgf@sh@savedmacro% MW @@ -632,48 +741,48 @@ \anchorborder{\csname pgf@anchor@#1@center\endcsname}% \anchor{text}{\pgfpointorigin}% \nodeparts{text}% - \expandafter\global\expandafter\let\csname pgf@sh@s@\shape@name\endcsname=\pgfutil@empty% + \expandafter\global\expandafter\let\csname pgf@sh@s@\pgf@sm@shape@name\endcsname=\pgfutil@empty% #2 } } \def\pgf@sh@savedanchor#1#2{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedanchor{#1}{#2}}} \def\pgf@sh@saveddimen#1#2{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resaveddimen{#1}{#2}}} \def\pgf@sh@savedmacro#1#2{% MW - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW -\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\shape@name @#1\endcsname{#2}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@resavedmacro{#1}{#2}}}% MW +\def\pgf@sh@anchor#1#2{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @#1\endcsname{#2}} \def\pgf@sh@deferredanchor#1#2{% CJ \expandafter\pgfutil@g@addto@macro - \csname pgf@sh@s@\shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ -\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\shape@name @border\endcsname##1{\pgf@process{##1}#1}} -\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\shape@name\endcsname{#1}} -\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sg@ffg@\shape@name\endcsname{#1}} -\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\shape@name\endcsname{#1}} + \csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\pgf@sh@redeferredanchor{#1}{#2}}}% CJ +\def\pgf@sh@anchorborder#1{\expandafter\gdef\csname pgf@anchor@\pgf@sm@shape@name @border\endcsname##1{\pgf@process{##1}#1}} +\long\def\pgf@sh@behindbgpath#1{\expandafter\gdef\csname pgf@sh@bbg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@bgpath#1{\expandafter\gdef\csname pgf@sh@bg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@beforebgpath#1{\expandafter\gdef\csname pgf@sh@fbg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@behindfgpath#1{\expandafter\gdef\csname pgf@sh@bfg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@fgpath#1{\expandafter\gdef\csname pgf@sh@fg@\pgf@sm@shape@name\endcsname{#1}} +\long\def\pgf@sh@beforefgpath#1{\expandafter\gdef\csname pgf@sh@ffg@\pgf@sm@shape@name\endcsname{#1}} +\def\pgf@sh@boxes#1{\expandafter\gdef\csname pgf@sh@boxes@\pgf@sm@shape@name\endcsname{#1}} \def\pgf@sh@inheritsavedanchors[from=#1]{% - \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}} + \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@\pgf@sm@shape@name\endcsname{\csname pgf@sh@s@#1\endcsname}} \def\pgf@sh@inheritanchor[from=#1]#2{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@anchor@\shape@name @#2\endcsname=\expandafter\noexpand\csname + pgf@anchor@\pgf@sm@shape@name @#2\endcsname=\expandafter\noexpand\csname pgf@anchor@#1@#2\endcsname}% \pgf@marshal% } \def\pgf@sh@inheritanchorborder[from=#1]{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@anchor@\shape@name @border\endcsname=\expandafter\noexpand\csname + pgf@anchor@\pgf@sm@shape@name @border\endcsname=\expandafter\noexpand\csname pgf@anchor@#1@border\endcsname}% \pgf@marshal% } \def\pgf@sh@inheritor#1#2{% \edef\pgf@marshal{\global\let\expandafter\noexpand\csname - pgf@sh@#1@\shape@name\endcsname=\expandafter\noexpand\csname + pgf@sh@#1@\pgf@sm@shape@name\endcsname=\expandafter\noexpand\csname pgf@sh@#1@#2\endcsname}% \pgf@marshal% } @@ -932,6 +1041,15 @@ } +% Special current path start coordinate: +\expandafter\def\csname pgf@sh@ns@current subpath start\endcsname{coordinate} +\expandafter\def\csname pgf@sh@np@current subpath start\endcsname{% + \def\centerpoint{\expandafter\pgfqpoint\pgfsyssoftpath@lastmoveto}% +} +\expandafter\def\csname pgf@sh@nt@current subpath start\endcsname{{1}{0}{0}{1}{0pt}{0pt}} +\expandafter\def\csname pgf@sh@pi@current subpath start\endcsname{\pgfpictureid} + + % Special current bounding box rectangle: \expandafter\def\csname pgf@sh@ns@current bounding box\endcsname{rectangle} @@ -956,8 +1074,8 @@ % Special current page bounding box rectangle: \expandafter\def\csname pgf@sh@ns@current page\endcsname{rectangle} \expandafter\def\csname pgf@sh@np@current page\endcsname{% - \def\southwest{\pgfqpoint{0pt}{0pt}}% - \def\northeast{\pgfqpoint{\paperwidth}{\paperheight}}% + \def\southwest{\pgfpointorigin}% + \def\northeast{\pgfpoint{\pgfsys@thepagewidth}{\pgfsys@thepageheight}}% } \expandafter\def\csname pgf@sh@nt@current page\endcsname{{1}{0}{0}{1}{0pt}{0pt}} \expandafter\def\csname pgf@sh@pi@current page\endcsname{pgfpageorigin} @@ -978,7 +1096,20 @@ \expandafter\gdef\csname pgf@lbb@miny@#1\endcsname{16000pt}% \pgf@size@hookedtrue% \expandafter\def\expandafter\pgf@path@size@hook\expandafter{\pgf@path@size@hook\pgf@lbb@do{#1}} - }% + }, + /pgf/freeze local bounding box/.code={% + {% + \csname pgf@sh@np@#1\endcsname% + \southwest% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \northeast% + \expandafter\xdef\csname pgf@sh@np@#1\endcsname{% + \noexpand\def\noexpand\southwest{\noexpand\pgfqpoint{\the\pgf@xa}{\the\pgf@ya}}% + \noexpand\def\noexpand\northeast{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% + }% + }% + } } \def\pgf@lbb@do#1{% \ifdim\pgf@size@hook@x<\csname pgf@lbb@minx@#1\endcsname\expandafter\xdef\csname pgf@lbb@minx@#1\endcsname{\the\pgf@size@hook@x}\fi% @@ -1121,7 +1252,7 @@ % % Background path % - \backgroundpath{ + \backgroundpath{% \pgfutil@tempdima=\radius% \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% diff --git a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex index 0d3ad5dfdeb..5f6479a1d7b 100644 --- a/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/modules/pgfmodulesnakes.code.tex @@ -7,10 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulesnakes.code.tex,v 1.2 2008/01/17 20:09:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/modules/pgfmodulesnakes.code.tex,v 1.3 2013/07/15 12:05:34 tantau Exp $ -\PackageWarning{pgf}{Snakes have been superseded by decorations. Use -the module decorations instead of snakes} +\pgfwarning{Snakes have been superseded by decorations. Use the module decorations instead of snakes} \usepgfmodule{decorations} @@ -251,7 +250,7 @@ the module decorations instead of snakes} % \pgfpathsnakealongvector{zig zag}{100pt}{\pgfpolar{30}{1pt}} \def\pgfpathsnakealongvector#1#2#3{% - \pgfutil@ifundefined{pgf@snake@@#1@initial}{\PackageError{pgf}{Undefined snake ``#1''}{}} + \pgfutil@ifundefined{pgf@snake@@#1@initial}{\pgferror{Undefined snake ``#1''}} { \begingroup% keep things local \pgftransformreset% diff --git a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex b/Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex deleted file mode 100644 index 48d36bae8bf..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrenderpoints.code.tex +++ /dev/null @@ -1,138 +0,0 @@ -% Copyright 2006 by Till Tantau -% -% This file may be distributed and/or modified -% -% 1. under the LaTeX Project Public License and/or -% 2. under the GNU Public License. -% -% See the file doc/generic/pgf/licenses/LICENSE for more details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/rendering/pgfrenderpoints.code.tex,v 1.2 2007/03/09 17:49:33 tantau Exp $ - - - - - -% Create a 3D point -% -% #1 = macro name in which the point object should be stored -% #2 to #4 = x-, y- and z-coordinate of the point -% -% Note: -% -% The quick version does not call \setlength and is faster. -% -% Example: -% -% \pgfrenderpointcreate{\pgfpoint{2pt+3cm}{3cm}} - -\def\pgfrenderpointcreate#1#2#3#4{% - \pgfmathsetlength\pgf@xa{#2}% - \pgfmathsetlength\pgf@xb{#3}% - \pgfmathsetlength\pgf@xc{#4}% - \pgfqrenderpointcreate{\the\pgf@xa}{\the\pgf@xb}{\the\pgf@xc}% -} - -\def\pgfqrenderpointcreate#1#2#3#4{% - \edef#1{\pgf@xa=#2\relax\pgf@xb=#3\pgf@xc=#4\relax}% -} - -\def\pgf@render@unpack#1{% - #1% -} - - -% The origin point object -% -% Description: -% -% This object is always the origin. -% - -\pgfqrenderpointcreate\pgfrenderobjorigin{0pt}{0pt}{0pt} - - - - -% Add two 3D vectors -% -% #1 = name of new vector (may be one of the input) -% #2 = name of first vector -% #3 = name of second vector -% -% Description: -% -% The points #2 and #3 are added and the result is stored in #1. If #1 -% equals either #2 or #3, to point is overwritten. -% -% Example: -% -% \pgfrenderpointcreate{\myvec}{1cm}{2cm}{3cm} -% \pgfrenderpointcreate{\offset}{1cm}{0cm}{0cm} -% \pgfrenderpointadd{\myvec}{\myvec}{\offset} - -\def\pgfrenderpointadd#1#2#3{% - \pgf@render@unpack#2% - \pgf@ya=\pgf@xa% - \pgf@yb=\pgf@xb% - \pgf@yc=\pgf@xc% - \pgf@render@unpack#3% - \advance\pgf@xa by\pgf@ya% - \advance\pgf@xb by\pgf@yb% - \advance\pgf@xc by\pgf@yc% - \pgfqrenderpointcreate#1{\the\pgf@xa}{\the\pgf@xb}{\the\pgf@xc}% -} - - -% Scale a 3D vectors -% -% #1 = name of new vector (may be one of the input) -% #2 = scale -% #3 = name of vector to be scaled -% -% Description: -% -% Sets #1 := #2*#3. -% -% Example: -% -% \pgfrenderpointcreate{\myvec}{1cm}{2cm}{3cm} -% \pgfrenderpointscale{\myvec}{2}{\myvec} - -\def\pgfrenderpointscale#1#2#3{% - \pgf@render@unpack#3% - \pgf@xa=#2\pgf@xa% - \pgf@xb=#2\pgf@xb% - \pgf@xc=#2\pgf@xc% - \pgfqrenderpointcreate#1{\the\pgf@xa}{\the\pgf@xb}{\the\pgf@xc}% -} - - - - -% Project a 3D point to 2D -% -% #1 = 3D point object -% -% Description: -% -% This command takes a 3D point object and sets \pgf@x to the x-value -% of the point and \pgf@y to the y-value. -% -% Example: -% -% \pgfpointprojection{\mypoint} - -\def\pgfpointprojection#1{% - \pgf@render@unpack{#1}% - \pgf@x=\pgf@xa% - \pgf@y=\pgf@ya% -} - - - - - - - -\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex b/Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex deleted file mode 100644 index fb6802e9f1c..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/rendering/pgfrendertransform.code.tex +++ /dev/null @@ -1,117 +0,0 @@ -% Copyright 2006 by Till Tantau -% -% This file may be distributed and/or modified -% -% 1. under the LaTeX Project Public License and/or -% 2. under the GNU Public License. -% -% See the file doc/generic/pgf/licenses/LICENSE for more details. - -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/rendering/pgfrendertransform.code.tex,v 1.1 2006/11/12 14:18:46 tantau Exp $ - - - - -% Create a 3D transformation matrix -% -% #1 = macro name in which the transformation matrix should be stored -% #2 = three comma-separated numbers, representing the first line of -% the matrix. -% #3 = three numbers, representing the second line of the matrix. -% #4 = three numbers, representing the thrid line of the matrix. -% #5 = 3D point object, used for the offset. -% -% Example: -% -% \pgfrendertransformcreate{\mymatrix}{1,0,0}{0,1,0}{0,0,1}{\pgfrenderobjorigin} - -\def\pgfrendertransformcreate#1#2#3#4#5{% - \pgf@render@unpack#5% - \edef#1{{#2}{#3}{#4}{\pgf@xa=\the\pgf@xa\pgf@xb=\the\pgf@xb\pgf@xc=\the\pgf@xc}}% -} - - - -% Apply a 3D transformation matrix to a 3D point -% -% #1 = new point (may be the old point) (#1 := #2*#3) -% #2 = transformation matrix object -% #3 = point to be transformed -% -% Example: -% -% \pgfrendertransform{\newvec}{\mymatrix}{\oldvec} - -\def\pgfrendertransform#1#2#3{% - \pgf@render@unpack#3% - \expandafter\pgf@rendertransform#2% - \pgf@xa=\pgf@ya% - \pgf@xb=\pgf@yb% - \pgf@xc=\pgf@yc% -} - -\def\pgf@rendertransform#1#2#3#4{% - \pgf@@rendertransform\pgf@ya#1\relax% - \pgf@@rendertransform\pgf@yb#2\relax% - \pgf@@rendertransform\pgf@yc#3\relax% - #4% - \advance\pgf@ya by \pgf@xa% - \advance\pgf@yb by \pgf@xb% - \advance\pgf@yc by \pgf@xc% -} - -\def\pgf@@rendertransform#1#2,#3,#4\relax{% - #1=#2\pgf@xa% - \advance#1by#3\pgf@xb% - \advance#1by#4\pgf@xc% -} - - - -% Concatenate two 3D transformation matrices -% -% #1 = new matrix, (#1 := #2*#3) -% #2 = first matrix -% #3 = second matrix -% -% Example: -% -% \pgfrendertransformconcat{\mymatrix}{\rotationmatrix}{\mymatrix} - -\def\pgfrendertransformconcat#1#2#3{% - \expandafter\pgf@render@extract@columns#3% - \pgfrendertransform\pgf@render@temp@a#2\pgf@render@temp@a% - \pgfrendertransform\pgf@render@temp@b#2\pgf@render@temp@b% - \pgfrendertransform\pgf@render@temp@c#2\pgf@render@temp@c% - \pgfrendertransform\pgf@render@temp@d#2\pgf@render@temp@d% - \pgf@render@unpack\pgf@render@temp@a% - \edef\pgf@temp@a{\pgf@sys@tonumber\pgf@xa}% - \edef\pgf@temp@b{\pgf@sys@tonumber\pgf@xb}% - \edef\pgf@temp@c{\pgf@sys@tonumber\pgf@xc}% - \pgf@render@unpack\pgf@render@temp@b% - \edef\pgf@temp@a{\pgf@temp@a,\pgf@sys@tonumber\pgf@xa}% - \edef\pgf@temp@b{\pgf@temp@b,\pgf@sys@tonumber\pgf@xb}% - \edef\pgf@temp@c{\pgf@temp@c,\pgf@sys@tonumber\pgf@xc}% - \pgf@render@unpack\pgf@render@temp@c% - \edef\pgf@temp@a{\pgf@temp@a,\pgf@sys@tonumber\pgf@xa}% - \edef\pgf@temp@b{\pgf@temp@b,\pgf@sys@tonumber\pgf@xb}% - \edef\pgf@temp@c{\pgf@temp@c,\pgf@sys@tonumber\pgf@xc}% - \pgfrendertransformcreate#1{\pgf@temp@a}{\pgf@temp@b}{\pgf@temp@c}{\pgf@render@temp@c}% -} - -\def\pgf@render@extract@columns#1#2#3#4{% - \pgf@@render@extract@columns#1,#2,#3\relax% - \def\pgf@render@temp@d{#4}% -} - -\def\pgf@@render@extract@columns#1,#2,#3,#4,#5,#6,#7,#8,#9\relax{% - \pgfqrenderpointcreate\pgf@render@temp@a{#1pt}{#4pt}{#7pt}% - \pgfqrenderpointcreate\pgf@render@temp@b{#2pt}{#5pt}{#8pt}% - \pgfqrenderpointcreate\pgf@render@temp@c{#3pt}{#6pt}{#9pt}% -} - - - - - -\endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def index 5cbf2fd66ca..1605a956260 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def,v 1.7 2008/05/19 12:52:49 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf-via-dvi.def,v 1.8 2013/07/12 13:52:50 tantau Exp $ % Common driver commands for all drivers that produce pdf via the % detour of a dvi file @@ -23,6 +23,7 @@ % not show anything {\hbox to 0pt{\pgfutil@font@normalfont\pgfutil@selectfont.\hss}}% enforce font change \pgfsys@invoke{0 Tr}% + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash \wd#1=0pt% \ht#1=0pt% \dp#1=0pt% @@ -41,6 +42,7 @@ \pgflowlevelsynccm% \pgfsys@invoke{q -1 0 0 -1 0 0 cm}% \special{pdf: content -1 0 0 -1 0 0 cm q}% translate to original coordinate system + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash \wd#1=0pt% \ht#1=0pt% \dp#1=0pt% diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def index c48d1c15238..32906ad3b64 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-pdf.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf.def,v 1.10 2008/05/19 12:52:49 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-pdf.def,v 1.13 2013/10/10 12:00:15 tantau Exp $ % Common driver commands for all drivers that produce pdf @@ -63,7 +63,6 @@ % Opacity \def\pgfsys@stroke@opacity#1{% \expandafter\ifx\csname pgf@sys@pdf@so@#1\endcsname\relax% - % Hmm... define... \expandafter\gdef\csname pgf@sys@pdf@so@#1\endcsname{/pgf@CA#1}% \pgfutil@addpdfresource@extgs{/pgf@CA#1 << /CA #1 >>}%<< \fi% @@ -71,13 +70,40 @@ } \def\pgfsys@fill@opacity#1{% \expandafter\ifx\csname pgf@sys@pdf@fo@#1\endcsname\relax% - % Hmm... define... \expandafter\gdef\csname pgf@sys@pdf@fo@#1\endcsname{/pgf@ca#1}% \pgfutil@addpdfresource@extgs{/pgf@ca#1 << /ca #1 >>}%<< \fi% \pgfsysprotocol@literal{\csname pgf@sys@pdf@fo@#1\endcsname\space gs}% } - +\def\pgfsys@blend@mode#1{% + \expandafter\ifx\csname pgf@sys@pdf@bm@#1\endcsname\relax% + \expandafter\let\expandafter\pgf@temp\csname pgf@sys@pdf@blend@mode@map@#1\endcsname% + \expandafter\xdef\csname pgf@sys@pdf@bm@#1\endcsname{/pgf@bm\pgf@temp}% + \ifx\pgf@temp\relax% + \pgferror{Unknown blend mode '#1'}% + \def\pgf@temp{Normal}% + \fi% + \edef\pgf@temp{/pgf@bm\pgf@temp << /BM [ /\pgf@temp ] >>}%<< + \expandafter\pgfutil@addpdfresource@extgs\expandafter{\pgf@temp}% + \fi% + \pgfsysprotocol@literal{\csname pgf@sys@pdf@bm@#1\endcsname\space gs}% +} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@normal\endcsname{Normal} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@multiply\endcsname{Multiply} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@screen\endcsname{Screen} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@overlay\endcsname{Overlay} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@darken\endcsname{Darken} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@lighten\endcsname{Lighten} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color dodge\endcsname{ColorDodge} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color burn\endcsname{ColorBurn} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hard light\endcsname{HardLight} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@soft light\endcsname{SoftLight} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@difference\endcsname{Difference} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@exclusion\endcsname{Exclusion} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@saturation\endcsname{Saturation} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@color\endcsname{Color} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@hue\endcsname{Hue} +\expandafter\def\csname pgf@sys@pdf@blend@mode@map@luminosity\endcsname{Luminosity} \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def index fa1cf889bd4..f2edbedf3c9 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-common-svg.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-svg.def,v 1.21 2009/03/20 10:31:30 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-common-svg.def,v 1.24 2013/08/28 11:00:54 tantau Exp $ % Driver commands for svg @@ -26,13 +26,16 @@ \def\pgf@sys@addtosvgpath#1{\pgfutil@g@addto@macro\pgf@sys@svgpath{#1\space}} \def\pgf@sys@flushsvgpath{\pgfsysprotocol@literal{\pgf@sys@svgpath}\global\let\pgf@sys@svgpath=\pgfutil@empty} \def\pgf@sys@svg@gs#1{% - {\pgfsysprotocol@literal{\Hnewline }}\global\advance\pgf@sys@svg@scopecount by1\relax% + {\pgfsysprotocol@literal{\pgfsys@svg@newline }}\global\advance\pgf@sys@svg@scopecount by1\relax% } \newcount\pgf@sys@svg@objectcount -\let\Hnewline=\pgfutil@empty -\catcode`\%=12 -\def\pgf@sys@svg@percentchar{%} -\catcode`\%=14 + +{\catcode`\%=12 +\gdef\pgf@sys@svg@percentchar{%} +} +{\catcode`\#=11 +\gdef\pgf@sys@svg@hash{#} +} % Path construction: \def\pgfsys@lineto#1#2{\pgf@sys@addtosvgpath{L }\pgf@sys@svgnum{#1}\pgf@sys@svgnum{#2}} @@ -58,14 +61,14 @@ \pgfsysprotocol@literal{ \Hnewline \Hnewline } - \pgfsysprotocol@literal{\Hnewline }% + \pgfsysprotocol@literal{"/>\pgfsys@svg@newline \pgfsys@svg@newline } + \pgfsysprotocol@literal{\pgfsys@svg@newline }% \pgf@sys@svg@gs{clip-path="url(\#pgfcp\the\pgf@sys@svg@objectcount)"} \pgf@sys@svg@clipnextfalse% \else% \pgfsysprotocol@literal{\Hnewline } + \pgfsysprotocol@literal{" #1/>\pgfsys@svg@newline } \fi% } \def\pgfsys@stroke{\pgf@sys@svg@possiblyclippedpath{style="fill:none"}} @@ -78,7 +81,7 @@ \pgfsysprotocol@literal{ \Hnewline \Hnewline } + \pgfsysprotocol@literal{"/>\pgfsys@svg@newline \pgfsys@svg@newline } \pgf@sys@svg@gs{clip-path="url(\#pgfcp\the\pgf@sys@svg@objectcount)"} \pgf@sys@svg@clipnextfalse% \else% @@ -91,7 +94,15 @@ % Transparency: \def\pgfsys@stroke@opacity#1{\pgf@sys@svg@gs{stroke-opacity="#1"}} -\def\pgfsys@fill@opacity#1{\pgf@sys@svg@gs{fill-opacity="#1"}} +\def\pgfsys@fill@opacity#1{\pgf@sys@svg@gs{fill-opacity="#1"}\def\pgf@sys@svg@opacity{#1}} +\def\pgf@sys@svg@opacity{1} +\def\pgfsys@transparencygroupfrombox#1{% + \setbox#1=\hbox{% + \pgfsys@invoke{\pgfsys@svg@newline }% + \box#1% + \pgfsys@invoke{\pgfsys@svg@newline }% + }% +} % Transformation: \def\pgfsys@transformcm#1#2#3#4#5#6{% @@ -104,11 +115,11 @@ \edef\pgf@sys@svg@thescopecount{\the\pgf@sys@svg@scopecount}% \begingroup% \pgf@sys@svg@scopecount=1\relax% - \pgfsysprotocol@literal{\Hnewline }% + \pgfsysprotocol@literal{\pgfsys@svg@newline }% } \def\pgfsys@endscope{% \loop% - \pgfsysprotocol@literal{\Hnewline }% + \pgfsysprotocol@literal{\pgfsys@svg@newline }% \advance\pgf@sys@svg@scopecount by-1\relax% \ifnum\pgf@sys@svg@scopecount>0\relax% \repeat% @@ -138,8 +149,6 @@ % Color management % -\def\XC@mcolor{\ifpgfpicture\pgfsetcolor{.}\fi} - \def\pgf@sys@svg@color@rgb#1,#2,#3\relax{% {% \pgf@xa=#1pt% @@ -257,7 +266,7 @@ \divide\pgf@x by \c@pgf@counta\relax% \pgf@sys@svg@addtostops{\pgf@sys@tonumber\pgf@x" stop-color="}% \pgf@sys@svg@shading@dorgb#3% - \pgf@sys@svg@addtostops{"/>\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{"/>\noexpand\pgfsys@svg@newline}% } \def\pgf@sys@svg@shading@dorgb#1#2#3{% \pgf@sys@svg@color@rgb#1,#2,#3\relax% @@ -277,9 +286,9 @@ {% \pgf@parsefunc{#3}% \global\advance\pgf@sys@svg@objectcount by1\relax% - \pgf@sys@svg@addtostops{\noexpand\Hnewline} + \pgf@sys@svg@addtostops{\noexpand\pgfsys@svg@newline} \pgf@sys@svg@shading@stops% - \pgf@sys@svg@addtostops{\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{\noexpand\pgfsys@svg@newline}% \pgf@process{\pgfpoint{\pgf@sys@shading@end@pos}{#2}}% \expandafter\xdef\csname @pgfshading#1!\endcsname{% \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}% @@ -287,7 +296,7 @@ width="\pgf@sys@tonumber{\pgf@x}" height="\pgf@sys@tonumber{\pgf@y}" style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount); - stroke:none"/>\noexpand\Hnewline}}% + stroke:none"/>\noexpand\pgfsys@svg@newline}}% \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}% }% }% @@ -308,9 +317,9 @@ \global\advance\pgf@sys@svg@objectcount by1\relax% \pgf@sys@svg@addtostops{\noexpand\Hnewline} + gradientTransform="rotate(90)">\noexpand\pgfsys@svg@newline} \pgf@sys@svg@shading@stops% - \pgf@sys@svg@addtostops{\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{\noexpand\pgfsys@svg@newline}% \pgf@process{\pgfpoint{\pgf@sys@shading@end@pos}{#2}}% \expandafter\xdef\csname @pgfshading#1!\endcsname{% \def\noexpand\pgf@sys@svg@sh@defs{\noexpand\pgfsysprotocol@literal{\pgf@sys@svg@thestops}}% @@ -318,7 +327,7 @@ width="\pgf@sys@tonumber{\pgf@y}" height="\pgf@sys@tonumber{\pgf@x}" style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount); - stroke:none"/>\noexpand\Hnewline}}% + stroke:none"/>\noexpand\pgfsys@svg@newline}}% \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@y}{\the\pgf@x}}% }% }% @@ -343,9 +352,9 @@ id="pgfsh\the\pgf@sys@svg@objectcount" fx="\pgf@sys@tonumber\pgf@x" fy="\pgf@sys@tonumber\pgf@y" - >\noexpand\Hnewline} + >\noexpand\pgfsys@svg@newline} \pgf@sys@svg@shading@stops% - \pgf@sys@svg@addtostops{\noexpand\Hnewline}% + \pgf@sys@svg@addtostops{\noexpand\pgfsys@svg@newline}% \pgf@xa=\pgf@sys@shading@end@pos% \pgf@xb=2\pgf@xa% \expandafter\xdef\csname @pgfshading#1!\endcsname{% @@ -355,7 +364,7 @@ cy="\pgf@sys@tonumber{\pgf@xa}" r="\pgf@sys@tonumber{\pgf@xa}" style="fill:url(\noexpand\#pgfsh\the\pgf@sys@svg@objectcount); - stroke:none"/>\noexpand\Hnewline}}% + stroke:none"/>\noexpand\pgfsys@svg@newline}}% \def\noexpand\pgf@sys@svg@pos{\noexpand\pgfpoint{\the\pgf@xb}{\the\pgf@xb}}% }% }% @@ -364,6 +373,8 @@ % Patterns +\iffalse % comment until interpage support is available + \def\pgfsys@declarepattern#1#2#3#4#5#6#7#8#9{% % Start building the pattern dictionary: \pgf@xa=#2\relax% @@ -410,6 +421,36 @@ \pgf@sys@svg@gs@color{fill="url(\#pgfpat#1)"}% } +\fi + + + + +% Fadings + +% +% Opacity masks +% +% \def\pgfsys@fadingfrombox#1#2{% +% \setbox#2=\hbox{% +% \pgfsys@invoke{}% +% \box#2% +% \pgfsys@invoke{}% +% }% +% \wd#2=0pt% +% \ht#2=0pt% +% \dp#2=0pt% +% \unskip\box#2% +% } +% \def\pgfsys@usefading#1#2#3#4#5#6#7{% +% \pgf@sys@svg@gs@color{mask="url(\#pgfmask#1)"}% +% } + + + +% + +\def\pgfutil@color{\pgfsetcolor} \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def index 4124784d999..0ad85414779 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfm.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfm.def,v 1.19 2008/05/14 16:05:56 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfm.def,v 1.21 2013/07/16 16:03:13 tantau Exp $ % Driver commands for dvipdfm @@ -23,6 +23,13 @@ \def\pgfsys@invoke#1{\special{pdf: content Q #1 q}} % ugly, but necessary... +\def\pgfsys@papersize#1#2{% +% \expandafter\gdef\expandafter\pgfsys@atbegindocument% +% \expandafter{\pgfsys@atbegindocument + \special{papersize=#1,#2}% +% } +} + % % Position tracking (needs pdftex >= 1.40.0-alpha-20051205 in dvi mode) diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def index b9669434a4a..a5806aeab78 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvipdfmx.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfmx.def,v 1.3 2009/05/22 07:25:48 jinhwancho Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvipdfmx.def,v 1.12 2013/08/28 11:00:54 tantau Exp $ % Driver commands for dvipdfmx % @@ -20,6 +20,7 @@ % \input pgfsys-common-pdf.def + % For unique object name: \newcount\pgfsys@objnum\pgfsys@objnum\@ne @@ -38,41 +39,65 @@ % To avoid this problem, we need to change the color temporarily to another. % % We assume that black is the default color when no color is specified. -\def\start@force@reset@color{% +\def\pgfsys@dvipdfmx@start@force@reset@color{% \special{pdf:bcolor [1]}% \special{pdf:bcolor [0]}% } -\def\stop@force@reset@color{% +\def\pgfsys@dvipdfmx@stop@force@reset@color{% \special{pdf:ecolor}% \special{pdf:ecolor}% } + +\def\pgfsys@dvipdfmx@suspendcontent{% + \special{pdf:code q -1 0 0 -1 0 0 cm q}% + \special{pdf: econtent}% + \special{pdf: bcontent}% + \special{pdf:code -1 0 0 -1 0 0 cm}% + \special{pdf:code q}% translate to original system + \special{pdf: econtent}% +} + +\def\pgfsys@dvipdfmx@unsuspendcontent{% + \special{pdf: bcontent}% + \special{pdf:code Q Q Q}% +} + +\def\pgfsys@hbox#1{% + \pgfsys@beginscope% + \setbox#1=\hbox{\box#1}% + \wd#1=0pt% + \ht#1=0pt% + \dp#1=0pt% + \pgfsys@dvipdfmx@suspendcontent% + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash + \pgfsys@dvipdfmx@start@force@reset@color% + \box#1% + \pgfsys@dvipdfmx@stop@force@reset@color% + \pgfsys@dvipdfmx@unsuspendcontent% + \pgfsys@endscope% +} + % We cannot use many codes in pgfsys-common-pdf-via-dvi.def. % So it is rewritten here (with some bugs fixed). \def\pgfsys@hboxsynced#1{% - {% - \pgfsys@beginscope% - \setbox\pgf@hbox=\hbox{% - \hskip\pgf@pt@x% - \raise\pgf@pt@y\hbox{% - \pgf@pt@x=0pt% - \pgf@pt@y=0pt% - % The order of `pdf:bcontent' is important here. It should be - % followed by \pgflowlevelsynccm, not reverse order. - \special{pdf:bcontent}% - \pgflowlevelsynccm% - \start@force@reset@color% - \pgfsys@hbox#1% - \stop@force@reset@color% - \special{pdf:econtent}}% - \hss% - }% - \wd\pgf@hbox=0pt% - \ht\pgf@hbox=0pt% - \dp\pgf@hbox=0pt% - \box\pgf@hbox% - \pgfsys@endscope% - }% + \pgfsys@beginscope% + \setbox#1=\hbox{\box#1}% + \wd#1=0pt% + \ht#1=0pt% + \dp#1=0pt% + \pgfsys@dvipdfmx@suspendcontent% + \pgfsys@invoke{0 J [] 0 d}% reset line cap and dash + \pgfsys@dvipdfmx@start@force@reset@color% + \pgf@sys@bp@correct\pgf@pt@x% + \pgf@sys@bp@correct\pgf@pt@y% + \special{pdf:btrans matrix \pgf@pt@aa\space \pgf@pt@ab\space \pgf@pt@ba\space \pgf@pt@bb\space + \pgf@sys@tonumber{\pgf@pt@x} \pgf@sys@tonumber{\pgf@pt@y}}% + \box#1% + \special{pdf:etrans}% + \pgfsys@dvipdfmx@stop@force@reset@color% + \pgfsys@dvipdfmx@unsuspendcontent% + \pgfsys@endscope% } % All text materials between `pdf:bcontent' and `pdf:econtent' are @@ -202,7 +227,7 @@ \def\pgfsys@markposition##1{% \pdfsavepos% \edef\pgf@temp{##1}% - \expandafter\write\expandafter\pgfutil@auxout\expandafter{% + \expandafter\pgfutil@writetoaux\expandafter{% \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% } \def\pgfsyspdfmark##1##2##3{% @@ -272,7 +297,7 @@ % Image Mask came from pgfsys-pdftex.def % generic/pgf/basiclayer/pgfcoreimage.code.tex must be modified! \def\pgfsys@defineimage{% width, height, page number - \ifx\includegraphics\relax + \ifx\includegraphics\undefined \ifx\pgf@imagewidth\pgfutil@empty\edef\pgf@imagewidth{1bp}\fi% width? \ifx\pgf@imageheight\pgfutil@empty\edef\pgf@imageheight{1bp}\fi% height? \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage}\fi% @@ -316,18 +341,32 @@ \pgf@sys@bp@correct\pgf@xc% \pgf@sys@bp@correct\pgf@yc% % Now create the pattern object: - \special{pdf:stream @pgf@patternobject@#1 (#8) - << /Type /Pattern - /PatternType 1 - /PaintType \ifnum#9=0 2 \else 1 \fi - /TilingType 1 - /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb] - /XStep \pgf@sys@tonumber\pgf@xc\space - /YStep \pgf@sys@tonumber\pgf@yc\space - /Resources << >> %<< - >>}% - \pgfutil@addpdfresource@patterns{/pgfpat#1\space @pgf@patternobject@#1}% + \pgfsys@dvipdfmx@patternobj{% + \pgfsys@dvipdfmx@stream{@pgfpatternobject#1}{#8}{% + /Type /Pattern + /PatternType 1 + /PaintType \ifnum#9=0 2 \else 1 \fi + /TilingType 1 + /BBox [\pgf@sys@tonumber\pgf@xa\space\pgf@sys@tonumber\pgf@ya\space\pgf@sys@tonumber\pgf@xb\space\pgf@sys@tonumber\pgf@yb] + /XStep \pgf@sys@tonumber\pgf@xc\space + /YStep \pgf@sys@tonumber\pgf@yc\space + /Resources << >> %<< + }% + }% + \pgfutil@addpdfresource@patterns{/pgfpat#1\space @pgfpatternobject#1}% } + +% hook for xdvipdfmx: +\def\pgfsys@dvipdfmx@patternobj#1{% + #1% +}% + +% hook for xdvipdfmx: +\def\pgfsys@dvipdfmx@stream#1#2#3{% + \special{pdf:stream #1 (#2) << #3 >>}% +}% + + \def\pgfsys@setpatternuncolored#1#2#3#4{% \pgfsysprotocol@literal{/pgfprgb cs #2 #3 #4 /pgfpat#1\space scn}% } @@ -356,6 +395,12 @@ \ht#2=0pt% \dp#2=0pt% \box#2% + \special{pdf:put @resources + << + \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi + \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi + \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi + >>}% << \special{pdf:exobj <> >>}}}\@tempa% \expandafter\xdef\csname pgfsmaskxform@#1\endcsname{\the\pgfsys@objnum}% }% @@ -364,7 +409,7 @@ } \def\pgfsys@usefading#1#2#3#4#5#6#7{% \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax% - \PackageError{pgf}{Undefined fading '#1'}{}% + \pgferror{Undefined fading '#1'}% \else% {% \expandafter\ifx\csname pgfsmask@#1\endcsname\relax% @@ -405,7 +450,16 @@ \ht#1=0pt% \dp#1=0pt% \hskip\pgf@picminx bp\box#1\hskip-\pgf@picminx bp% - \special{pdf:exobj <> >>}}}\@tempa% + \special{pdf:put @resources + << + \ifpgf@sys@pdf@extgs@exists /ExtGState @pgfextgs \fi + \ifpgf@sys@pdf@patterns@exists /Pattern @pgfpatterns \fi + \ifpgf@sys@pdf@colorspaces@exists /ColorSpace @pgfcolorspaces \fi + >>}% << + \special{pdf:exobj <> >>}% + }}\@tempa% \special{pdf:uxobj @pgftransgroup\the\pgfsys@objnum}% }% \global\advance\pgfsys@objnum\@ne% @@ -421,6 +475,13 @@ \fi \fi +\def\pgfsys@papersize#1#2{% +% \expandafter\gdef\expandafter\pgfsys@atbegindocument%% +% \expandafter{\pgfsys@atbegindocument + \special{papersize=#1,#2}% +% } +} + \endinput %%% Local Variables: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def index cec3fa14fda..3847d14a6c8 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvips.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvips.def,v 1.20 2008/04/03 17:04:45 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvips.def,v 1.23 2013/07/16 16:03:13 tantau Exp $ % Driver commands for dvips @@ -52,7 +52,8 @@ \def\pgfsys@imagesuffixlist{.epsi:.eps:.ps:} \def\pgfsys@papersize#1#2{% - \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}} + \special{papersize=#1,#2}% +}% \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument\special{papersize=#1,#2}}} \expandafter\gdef\expandafter\pgfsys@atbegindocument\expandafter{\pgfsys@atbegindocument% \pgf@sys@postscript@header{ @@ -74,10 +75,9 @@ /pgfpd{/delta globaldict /pgfdelta get def}bind def % put delta /.setopacityalpha where {pop} {/.setopacityalpha{pop}def} ifelse % install .setopacityalpha /.pgfsetfillopacityalpha{/pgffoa exch def - /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore}bind def - /pgfeofill{gsave pgffoa .setopacityalpha eofill 1 .setopacityalpha newpath eofill grestore}bind def}bind def - /.pgfsetstrokeopacityalpha{/pgfsoa exch def - /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore}bind def}bind def + /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore newpath}bind def + /pgfeofill{gsave pgffoa .setopacityalpha eofill 1 .setopacityalpha newpath eofill grestore newpath}bind def}bind def + /.pgfsetstrokeopacityalpha{/pgfsoa exch def /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def}bind def /pgffoa 1 def /pgfsoa 1 def end @@ -101,7 +101,7 @@ \def\pgfsys@markposition#1{% \pdfsavepos% \edef\pgf@temp{#1}% - \expandafter\write\expandafter\pgfutil@auxout\expandafter{% + \expandafter\pgfutil@writetoaux\expandafter{% \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% } diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def new file mode 100644 index 00000000000..6225c5abc21 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-dvisvgm.def @@ -0,0 +1,78 @@ +% Copyright 2006 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-dvisvgm.def,v 1.3 2013/08/23 09:50:22 tantau Exp $ + + +% Driver commands for dvisvgm + +% +% Load common pdf commands: +% +\input pgfsys-common-svg.def + +\def\pgfsys@invoke#1{{\let\#\pgf@sys@svg@hash\special{dvisvgm:raw #1}}} +\def\pgfsys@beginpicture{\pgfsys@invoke{}} +\def\pgfsys@endpicture{\pgfsys@invoke{}} + +\def\pgfsys@svg@newline{{?nl}} + + +\def\pgfsys@hbox#1{% + {% + \setbox#1=\hbox{\box#1}% + \wd#1=0pt% + \ht#1=0pt% + \dp#1=0pt% + \pgfsetcolor{.}% + \pgfsys@invoke{}\box#1\pgfsys@invoke{}% + }% +} + +\def\pgfsys@shadingoutsidepgfpicture#1{% + \begingroup% + #1% + \setbox\pgfpic=\hbox to0pt{% + \pgfsys@beginpicture% + \pgfsys@beginscope% + \pgf@sys@svg@sh@defs% + \pgf@sys@svg@sh% + \pgfsys@endscope% + \pgfsys@endpicture% + \hss% + }% + \pgf@process{\pgf@sys@svg@pos}% + \pgf@picminx=0pt% + \pgf@picminy=0pt% + \pgf@picmaxx=\pgf@x% + \pgf@picmaxy=\pgf@y% + \def\pgf@trimleft@final{0pt}% + \def\pgf@trimright@final{0pt}% + \def\pgf@shift@baseline{0pt}% + \pgfsys@typesetpicturebox\pgfpic% + \endgroup% +} + +\def\pgfsys@shadinginsidepgfpicture#1{% + #1% + \pgf@sys@svg@sh@defs% hmmm.... + \pgf@process{\pgf@sys@svg@pos} + \pgf@xa=-.5\pgf@x% + \pgf@ya=-.5\pgf@y% + \pgfsysprotocol@literal{}% + \pgf@sys@svg@sh% + \pgfsysprotocol@literal{}% +} + +\endinput + + +%%% Local Variables: +%%% mode: latex +%%% End: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def index 8627a611077..b9ee92c3622 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-pdftex.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-pdftex.def,v 1.26 2009/05/22 07:25:48 jinhwancho Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-pdftex.def,v 1.33 2013/07/18 10:34:44 tantau Exp $ % Driver commands for pdf @@ -52,8 +52,7 @@ \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage }\fi% \ifx\pdfximage\@undefined% old version of pdflatex \ifx\pgf@imagepage\pgfutil@empty\else% - \PackageWarning{pgf}{Page selection not supported. Ignoring - page selection}% + \pgfwarning{Page selection not supported. Ignoring page selection}% \fi% \setbox\pgfutil@tempboxa=\hbox{% \pdfimage \pgf@imageheight \pgf@imagewidth {\pgf@filename}}% @@ -81,7 +80,7 @@ \pgfmathparse{#2}% \setbox\pgfutil@tempboxa=\hbox to\pgf@max{\vbox to\pgfmathresult pt{\vfil\pgfsys@invoke{/Sh sh}}\hfil}% \pgf@process{\pgfpoint{\pgf@max}{#2}}% - \pdfxform resources {% + \immediate\pdfxform resources {% /Shading << /Sh << /ShadingType 2 /ColorSpace /DeviceRGB /Domain [\pgf@pdfparseddomain] @@ -97,7 +96,7 @@ \pgfmathparse{#2}% \setbox\pgfutil@tempboxa=\hbox to\pgfmathresult pt{\vbox to\pgf@max{\vfil\pgfsys@invoke{/Sh sh}}\hfil}% \pgf@process{\pgfpoint{#2}{\pgf@max}}% - \pdfxform resources {% + \immediate\pdfxform resources {% /Shading << /Sh << /ShadingType 2 /ColorSpace /DeviceRGB /Domain [\pgf@pdfparseddomain] @@ -121,7 +120,7 @@ \pgf@sys@bp@correct{\pgf@y}% \pgf@sys@bp@correct{\pgf@xa}% \pgf@sys@bp@correct{\pgf@ya}% - \pdfxform resources {% + \immediate\pdfxform resources {% /Shading << /Sh << /ShadingType 3 /ColorSpace /DeviceRGB /Domain [\pgf@pdfparseddomain] @@ -218,41 +217,14 @@ } -\def\pgfsys@papersize#1#2{% - \pdfpageheight#2% - \pdfpagewidth#1} - - - % XForm version, crashes ghostview. - %\def\pgfsys@defobject#1#2#3#4{% - % \pgf@process{#2} - % \setbox\pgfobjectbox\hbox{\raise-\pgf@y\hbox{\hskip-\pgf@x\relax#4}} - % \pgf@process{#3} - % \pgf@xa=\pgf@x - % \pgf@ya=\pgf@y - % \pgf@process{#2} - % \advance\pgf@xa by-\pgf@x - % \advance\pgf@ya by-\pgf@y - % \wd\pgfobjectbox=\pgf@xa - % \dp\pgfobjectbox=0pt - % \ht\pgfobjectbox=\pgf@ya - % \pdfxform\pgfobjectbox - % \expandafter\xdef\csname#1\endcsname{\the\pdflastxform} - % \expandafter\xdef\csname pgf@trans#1\endcsname - % {{\pgfget x}{\pgfget y}}} - %\def\pgfsys@useobject#1#2{% - % \setbox\pgfobjectbox\hbox{\pdfrefxform \csname#1\endcsname}% - % \dp\pgfobjectbox=0pt% - % \ht\pgfobjectbox=0pt% - % \wd\pgfobjectbox=0pt% - % \pgfsys@discardpath% - % \pgfsys@beginscope% - % #2% - % \edef\pgf@temp{{1}{0}{0}{1}\csname pgf@trans#1\endcsname}% - % \expandafter\pgfsys@transform\pgf@temp% - % \box\pgfobjectbox% - % \pgfsys@endscope} +\def\pgfsys@papersize#1#2{\pdfpageheight#2\relax\pdfpagewidth#1\relax} +\def\pgfsys@global@papersize#1#2{\global\pdfpageheight#2\relax\global\pdfpagewidth#1\relax} + +\ifx\paperheight\@undefined + \def\pgfsys@thepageheight{\pdfpageheight} + \def\pgfsys@thepagewidth{\pdfpagewidth} +\fi % @@ -261,7 +233,7 @@ \def\pgfsys@markposition#1{% \pdfsavepos% \edef\pgf@temp{#1}% - \expandafter\write\expandafter\pgfutil@auxout\expandafter{% + \expandafter\pgfutil@writetoaux\expandafter{% \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% } @@ -274,7 +246,7 @@ \pgf@marshal% } -\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfpointorigin} +\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{\hoffset}{\voffset}} % @@ -294,7 +266,7 @@ } \def\pgfsys@usefading#1#2#3#4#5#6#7{% \expandafter\ifx\csname pgfsmaskxform@#1\endcsname\relax% - \PackageError{pgf}{Undefined fading '#1'}{}% + \pgferror{Undefined fading '#1'}% \else% {% \expandafter\ifx\csname pgfsmaks@#1\endcsname\relax% @@ -342,7 +314,9 @@ \def\pgfsys@transparencygroupfrombox#1{% \pgf@sys@pdf@check@resources% \pdfxform - attr { /Group << /S /Transparency >> } %<< + attr { /Group << /S /Transparency + /I \ifpgfsys@transparency@group@isolated true \else false \fi + /K \ifpgfsys@transparency@group@knockout true \else false \fi >> } %<< resources { \pgf@sys@pdf@possible@resources } #1% \setbox#1=\hbox{\pdfrefxform\pdflastxform}% @@ -395,6 +369,10 @@ \pgfutil@addpdfresource@colorspaces{ /pgfprgb [/Pattern /DeviceRGB] } +\def\pgfsys@color@unstacked#1{% + \pdfliteral{\csname\string\color@#1\endcsname}% +} + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def index 71f819cc2bc..cc5dadb1173 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-tex4ht.def @@ -7,11 +7,9 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-tex4ht.def,v 1.23 2010/08/18 12:14:47 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-tex4ht.def,v 1.25 2013/08/06 17:46:08 tantau Exp $ -\RequirePackage{xcolor} - % Driver commands for tex4ht @@ -28,6 +26,11 @@ \newcount\pgf@sys@svg@picnum +\def\pgfsys@pictureboxsynced#1{% + \pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope% +} + + %% %% initial support of Mathml and xhtml inside svg through the svg:foreignelement tag %% @@ -83,49 +86,60 @@ % class="}{\%s}{-\%s}{x-x-\%d}{}{">}{} %} +\def\pgfsys@svg@newline{\Hnewline} + % we don't want tex4ht putting

and

tags automatically in our svg code and causing invalid xhtml in our svg pictures \newif\ifpgfsys@CssIncluded@\pgfsys@CssIncluded@false \def\pgfsys@beginpicture{% - \EndP\HtmlParOff - \pgfkeys{/tikz/tex4ht node/escape=false}% text only nodes are the default. Advantage : pure svg pictures are the default, nicer for text only nodes. - % Disadvantages : this rendering methods produce more invalid or degraded svg pictures than with the foreignelement tag + \EndP\HtmlParOff + \pgfkeys{/pgf/tex4ht node/escape=false}% + % text only nodes are the default. Advantage : pure svg pictures are + % the default, nicer for text only nodes. + % Disadvantages : this rendering methods produce more invalid or degraded svg pictures than with the foreignelement tag %% we use css to control the display of foreignelement rendered text nodes - \ifpgfsys@CssIncluded@ - \else - \Css{ - .foreignobject {% - line-height:100\%; - font-size:120\%; % this is the trick....a font of size 100% in a box scaled down to half size makes it a half size font. -% you'll have to double the size of things that you want to have a regular size in this half-scaled box though - font-family:STIXgeneral,Times,Symbol,cmr10,CMSY10,CMEX10;% can't wait for the stix font...the cmr10, etc font are available from the mozilla site, times and symbols should be okey - padding:0; - margin:0; -% background-color:\#12ff55; usefull for debugging positioning - text-align:center; % good for centered text nodes...will have to improve that later on...with more integration with tikz options for text nodes - } - }% - \Css{% - math {%, math[mode="inline"] { - vertical-align:baseline; - line-height:100\%; - font-size:100\%; - font-family:STIXGeneral,Times,Symbol, cmr10,cmsy10,cmex10,cmmi10; - font-style: normal; - margin:0; -% background-color:\#99ff99; - padding:0; - }% - }% - \pgfsys@CssIncluded@true - \fi + \ifpgfsys@CssIncluded@ + \else + \Css{ + .foreignobject {% + line-height:100\%; + font-size:120\%; % this is the trick....a font of size 100% in + % a box scaled down to half size makes it a + % half size font. + % you'll have to double the size of things + % that you want to have a regular size in + % this half-scaled box though + font-family:STIXgeneral,Times,Symbol,cmr10,CMSY10,CMEX10;% + % can't wait for the stix font...the cmr10, etc font are + % available from the mozilla site, times and symbols should be + % okey + padding:0; + margin:0; + % background-color:\#12ff55; usefull for debugging positioning + text-align:center; % good for centered text nodes...will have to improve that later on...with more integration with pgf options for text nodes + } + }% + \Css{% + math {%, math[mode="inline"] { + vertical-align:baseline; + line-height:100\%; + font-size:100\%; + font-family:STIXGeneral,Times,Symbol, cmr10,cmsy10,cmex10,cmmi10; + font-style: normal; + margin:0; + % background-color:\#99ff99; + padding:0; + }% + }% + \pgfsys@CssIncluded@true + \fi }% \def\pgfsys@endpicture{% - \HtmlParOn - \par% FIXME : was '\Par' but that seems to be undefined!? + \HtmlParOn + \par% FIXME : was '\Par' but that seems to be undefined!? }% -% this is okey for both rendering methods for text nodes (mtext or foreignelement)... +% this is okay for both rendering methods for text nodes (mtext or foreignelement)... \def\pgfsys@typesetpicturebox#1{% \global\advance\pgf@sys@svg@picnum by 1\relax% % Ok, compute width/height @@ -143,8 +157,7 @@ \pgf@xc=\pgf@x% \pgf@yc=\pgf@y% \pgfsysprotocol@flushcurrentprotocol% - \HCode{

SVG-Viewer needed.

}% \special{t4ht>\jobname-\the\pgf@sys@svg@picnum.svg}% -%%%%%%%% This is necessary to control the svg through css - \pgfkeys{% - /tikz/tex4ht node/css/.get=\pgfsys@foreignobject@css - }% - \pgfsys@invoke{\Hnewline% added that + %%%%%%%% This is necessary to control the svg through css + \pgfkeys{% + /pgf/tex4ht node/css/.get=\pgfsys@foreignobject@css + }% + \pgfsys@invoke{\Hnewline% added that \Hnewline}% added that %%%%%%%%%%%%%%% maybee I should add an option to change the css, for the whole picture \pgfsys@invoke{\Hnewline }% \wd#1=0pt% \ht#1=0pt% @@ -230,44 +244,55 @@ %% we have to use some "evil" ^^ tex4ht hackery % tex4ht hackery {% grouping necessary cause we change the catcode of ":" - \catcode`:=11\relax - %%% this is necessary to calculate the size of text nodes with inline maths - % (it is an improvement of tex4ht, got to ask eitan gurary if he could put it in the tex4ht code) - \gdef\DviMathAlt{% - \a:DviMath\leavevmode \MathClass \ht:special{t4ht@(}\hbox\bgroup{\expandafter\ifx\csname ht:everypar\endcsname\relax\expandafter\everypar\else \expandafter\ht:everypar\fi{}\leavevmode\ht:special{t4ht@)}}\DviSend - }% -% these are configures for the foreignelement rendering method of text nodes : we let tex4ht write xhtml and mathml in the svg picture -% - \gdef\pgfsys@foreignobject@configure{% - \Configure{$}{\Configure{@math}{%\a:mathml - display="inline" }\DviMathAlt}{\EndDviMath}{}%%% we REALLY need to use \DviMathAlt here instead of \DviMath see above remark - \Configure{$$}{\Configure{@math}{%\a:mathml - display="block" }\IgnorePar - \ifvmode\else \HCode{}\fi\EndP - \DviMath}{\EndDviMath\ShowPar\pgfsys@foreignobject@par{\csname HCondtrue\endcsname\noindent} - }{\DisplayMathtrue}% - \Configure{SUB}{\Send{BACK}{<\a:mathml msub><\a:mathml mrow\Hnewline>}% - \Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\TG}% - \Configure{SUP}{\Send{BACK}{<\a:mathml msup><\a:mathml mrow\Hnewline>}% - \Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\TG}% - \Configure{SUBSUP}{\Send{BACK}{<\a:mathml msubsup><\a:mathml mrow\Hnewline>}% - \Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\TG}% - \Configure{htf}{0}{+}{}{}% - }% - \global\let\pgfsys@foreignobject@par=\par % use this instead of \par -- \Configure is no \long macro (at least in one of the older versions). - -% these are the configures for the mtext rendering method of text nodes : we turn everything into regular character (don't want math modes or subsup) -% and we hope it works (it doesn't if the text nodes aren't simple) - \gdef\pgfsys@mtext@configure{% - % no configures for \(\) and \[\] those might be needed for context or Latex. Let me know ! - \Configure{$$}{}{}{}% no block maths - \Configure{$}{}{}{}%$ no inline maths - \Configure{SUB}{\HCode{}}{\HCode{}}% - \Configure{SUP}{\HCode{}}{\HCode{}}% - \Configure{SUBSUP}{}{}{}% not both sub and sup - \Configure{htf} {0}{+}{}{}% - }% + \catcode`:=11\relax + %%% this is necessary to calculate the size of text nodes with + %%% inline maths + % (it is an improvement of tex4ht, got to ask eitan gurary if he + % could put it in the tex4ht code) + \gdef\DviMathAlt{% + \a:DviMath\leavevmode \MathClass + \ht:special{t4ht@(}\hbox\bgroup{\expandafter\ifx\csname + ht:everypar\endcsname\relax\expandafter\everypar\else + \expandafter\ht:everypar\fi{}\leavevmode\ht:special{t4ht@)}}\DviSend + }% + % these are configures for the foreignelement rendering method of text nodes : we let tex4ht write xhtml and mathml in the svg picture + % + \gdef\pgfsys@foreignobject@configure{% + \Configure{$}{\Configure{@math}{%\a:mathml + display="inline" }\DviMathAlt}{\EndDviMath}{}%%% we REALLY need to use \DviMathAlt here instead of \DviMath see above remark + \Configure{$$}{\Configure{@math}{%\a:mathml + display="block" }\IgnorePar + \ifvmode\else \HCode{}\fi\EndP + \DviMath}{\EndDviMath\ShowPar\pgfsys@foreignobject@par{\csname HCondtrue\endcsname\noindent} + }{\DisplayMathtrue}% + \Configure{SUB}{\Send{BACK}{<\a:mathml msub><\a:mathml mrow\Hnewline>}% + \Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\TG}% + \Configure{SUP}{\Send{BACK}{<\a:mathml msup><\a:mathml mrow\Hnewline>}% + \Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\TG}% + \Configure{SUBSUP}{\Send{BACK}{<\a:mathml msubsup><\a:mathml mrow\Hnewline>}% + \Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\Tg<\a:mathml mrow\Hnewline>\trap:base}{\Tg\TG}% + \Configure{htf}{0}{+}{}{}% + }% + \global\let\pgfsys@foreignobject@par=\par % use this instead of \par + % -- \Configure is no \long macro (at + % least in one of the older + % versions). + + % these are the configures for the mtext rendering method of text + % nodes : we turn everything into regular character (don't want math + % modes or subsup) + % and we hope it works (it doesn't if the text nodes aren't simple) + \gdef\pgfsys@mtext@configure{% + % no configures for \(\) and \[\] those might be needed for + % context or Latex. Let me know ! + \Configure{$$}{}{}{}% no block maths + \Configure{$}{}{}{}%$ no inline maths + \Configure{SUB}{\HCode{}}{\HCode{}}% + \Configure{SUP}{\HCode{}}{\HCode{}}% + \Configure{SUBSUP}{}{}{}% not both sub and sup + \Configure{htf} {0}{+}{}{}% + }% }% % a counter to produce unique ids for each text node rendered with foreign element @@ -295,8 +320,8 @@ \def\pgfutil@endminipage{% % same thing here % -% \ifpgfsys@textonly\else\EndP\HtmlParOff\fi - \egroup\egroup +% \ifpgfsys@textonly\else\EndP\HtmlParOff\fi + \egroup\egroup }% @@ -306,71 +331,73 @@ \newdimen\pgf@t % this is the alternate hbox routine that renders text nodes through the foreignobject tag \def\pgfsys@foreignobject@hbox#1{% - % Compute box y translation (x translation is correct). - \pgf@y=-\ht#1\relax - \HCode{\Hnewline}% scaling work around (damn dumb browsers !) - % Compute box size (scaled 2 times) - % this is necessary to make the browser scale the font down 50% (the STUPID browsers won't make font-size:50% happen, - % so we have to work around this by making svg scale the things down 50%, doubling the size of the text node frame (i.e. no changement there) - \pgf@x=2\wd#1\relax - \pgf@y=2\ht#1\relax - \advance\pgf@y by 2\dp#1\relax - % this is to adjust the y translation to compensate for the differences between the TeX and the Html models for lines - \setbox\pgfsys@foreignobject@Box=\hbox{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - $abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZf_1^1\overline D)_1^1\vec i\vec j$}% - \pgf@t=\ht#1\relax - \advance\pgf@t by -\ht\pgfsys@foreignobject@Box\relax - \pgf@s=\pgf@t\relax - \advance\pgf@s by \dp#1\relax - \advance\pgf@s by -\dp\pgfsys@foreignobject@Box\relax - \ifnum\pgf@s>0\relax - \pgf@s=0pt - \pgf@t=0pt - \else - \advance \pgf@y by -2\pgf@s\relax - \pgf@t=2\pgf@t\relax - \fi - % - \HCode{}% - % this is to make use of the css, class and id options through which you can control the way things display - \pgfkeys{% - /tikz/tex4ht node/css/.get=\pgfsys@foreignobject@css,% - /tikz/tex4ht node/class/.get=\pgfsys@foreignobject@class,% - /tikz/tex4ht node/id/.get=\pgfsys@foreignobject@id - }% - \HCode{\Hnewline - \Hnewline - \Hnewline -% I'll have to look into this, perhaps there are better doctype....  aren't recognised and produces invalid svg pictures -% a workaround (not implemented yet) would be to make them into entities of the svg picture. - \Hnewline -
\Hnewline - }% - \box#1% - \HCode{% -
\Hnewline - \Hnewline -
\Hnewline - }% -% debug positioning not needed but it would be nice to let it there to control things later on -% \HCode{} - \HCode{
\Hnewline}% - \global\advance\pgf@sys@svg@nodenum by 1\relax + % Compute box y translation (x translation is correct). + \pgf@y=-\ht#1\relax + \HCode{\Hnewline}% scaling work around (damn dumb browsers !) + % Compute box size (scaled 2 times) + % this is necessary to make the browser scale the font down 50% (the STUPID browsers won't make font-size:50% happen, + % so we have to work around this by making svg scale the things down 50%, doubling the size of the text node frame (i.e. no changement there) + \pgf@x=2\wd#1\relax + \pgf@y=2\ht#1\relax + \advance\pgf@y by 2\dp#1\relax + % this is to adjust the y translation to compensate for the differences between the TeX and the Html models for lines + \setbox\pgfsys@foreignobject@Box=\hbox{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + $abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZf_1^1\overline D)_1^1\vec i\vec j$}% + \pgf@t=\ht#1\relax + \advance\pgf@t by -\ht\pgfsys@foreignobject@Box\relax + \pgf@s=\pgf@t\relax + \advance\pgf@s by \dp#1\relax + \advance\pgf@s by -\dp\pgfsys@foreignobject@Box\relax + \ifnum\pgf@s>0\relax + \pgf@s=0pt + \pgf@t=0pt + \else + \advance \pgf@y by -2\pgf@s\relax + \pgf@t=2\pgf@t\relax + \fi + % + \HCode{}% + % this is to make use of the css, class and id options through which you can control the way things display + \pgfkeys{% + /pgf/tex4ht node/css/.get=\pgfsys@foreignobject@css,% + /pgf/tex4ht node/class/.get=\pgfsys@foreignobject@class,% + /pgf/tex4ht node/id/.get=\pgfsys@foreignobject@id + }% + \HCode{\Hnewline + \Hnewline + \Hnewline + % I'll have to look into this, perhaps there are better + % doctype....  aren't recognised and produces invalid svg + % pictures a workaround (not implemented yet) would be to make + % them into entities of the svg picture. + \Hnewline +
\Hnewline + }% + \box#1% + \HCode{% +
\Hnewline + \Hnewline +
\Hnewline + }% + % debug positioning not needed but it would be nice to let it there to control things later on + % \HCode{} + \HCode{
\Hnewline}% + \global\advance\pgf@sys@svg@nodenum by 1\relax }% % the options and the code that controls it all (switches between \pgfsys@mtext@hbox and \pgfsys@foreignelement@hbox) \pgfkeys{% - /tikz/.cd, - tex4ht node/escape/.is choice, - tex4ht node/escape/false/.code={\let\pgfsys@hbox\pgfsys@mtext@hbox\pgfsys@mtext@configure\pgfsys@textonlytrue}, - tex4ht node/escape/true/.code={\let\pgfsys@hbox\pgfsys@foreignobject@hbox\pgfsys@foreignobject@configure\pgfsys@textonlyfalse}, - tex4ht node/css/.initial=\jobname, - tex4ht node/class/.initial=foreignobject, - tex4ht node/id/.initial=\jobname\the\pgf@sys@svg@picnum-\the\pgf@sys@svg@nodenum + /pgf/.cd, + tex4ht node/escape/.is choice, + tex4ht node/escape/false/.code={\let\pgfsys@hbox\pgfsys@mtext@hbox\pgfsys@mtext@configure\pgfsys@textonlytrue}, + tex4ht node/escape/true/.code={\let\pgfsys@hbox\pgfsys@foreignobject@hbox\pgfsys@foreignobject@configure\pgfsys@textonlyfalse}, + tex4ht node/css/.initial=\jobname, + tex4ht node/class/.initial=foreignobject, + tex4ht node/id/.initial=\jobname\the\pgf@sys@svg@picnum-\the\pgf@sys@svg@nodenum }% @@ -426,19 +453,26 @@ \pgfsysprotocol@literal{
\Hnewline}% } -% Protect against color.4ht evil meddling with xcolor: -\let\pgf@xcolor@declaredcolor=\@declaredcolor -\let\pgf@xcolor@undeclaredcolor=\@undeclaredcolor + +\ifpgfutil@format@is@latex + % Protect against color.4ht evil meddling with xcolor: + \RequirePackage{xcolor} + \let\pgf@xcolor@declaredcolor=\@declaredcolor + \let\pgf@xcolor@undeclaredcolor=\@undeclaredcolor +\fi \AtBeginDocument{ \let\pgfsys@invoke=\pgfsys@body@invoke \let\pgfsys@shadingoutsidepgfpicture=\pgfsys@body@shadingoutsidepgfpicture \let\pgfsys@shadinginsidepgfpicture=\pgfsys@body@shadinginsidepgfpicture - \let\pgf@texht@declaredcolor=\@declaredcolor - \let\pgf@texht@undeclaredcolor=\@undeclaredcolor - \def\@declaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@declaredcolor\else\expandafter\pgf@texht@declaredcolor\fi} - \def\@undeclaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@undeclaredcolor\else\expandafter\pgf@texht@undeclaredcolor\fi} - %\ConfigureEnv{pgfpicture}{}{}{}{} there is no environment in plain TeX and this produces errors + \ifpgfutil@format@is@latex + \let\pgf@texht@declaredcolor=\@declaredcolor + \let\pgf@texht@undeclaredcolor=\@undeclaredcolor + \def\@declaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@declaredcolor\else\expandafter\pgf@texht@declaredcolor\fi} + \def\@undeclaredcolor{\ifpgfpicture\expandafter\pgf@xcolor@undeclaredcolor\else\expandafter\pgf@texht@undeclaredcolor\fi} + \fi + \def\pgfutil@color{\pgfsetcolor} + % \ConfigureEnv{pgfpicture}{}{}{}{} there is no environment in plain TeX and this produces errors % this might be needed for context or latex though....let me know ! }% diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def index 5e3aa27258c..0645fb8c51f 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-textures.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-textures.def,v 1.5 2007/12/12 16:57:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-textures.def,v 1.6 2011/05/13 10:16:37 tantau Exp $ % Driver commands for textures driver @@ -71,10 +71,12 @@ pgffoa .setopacityalpha}bind def% save /.setopacityalpha where {pop} {/.setopacityalpha{pop}def} ifelse % install .setopacityalpha /.pgfsetfillopacityalpha{/pgffoa exch def - /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha newpath fill grestore}bind def - /pgfeofill{gsave pgffoa .setopacityalpha eofill1 .setopacityalpha newpath eofill grestore}bind def}bind def + /pgffill{gsave pgffoa .setopacityalpha fill 1 .setopacityalpha + newpath fill grestore newpath}bind def + /pgfeofill{gsave pgffoa .setopacityalpha eofill1 + .setopacityalpha newpath eofill grestore newpath}bind def}bind def /.pgfsetstrokeopacityalpha{/pgfsoa exch def - /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore}bind def}bind def + /pgfstr{gsave pgfsoa .setopacityalpha stroke grestore newpath}bind def}bind def /pgffoa 1 def /pgfsoa 1 def } diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def index 742b4a6fef3..5014f48beba 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-vtex.def @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-vtex.def,v 1.8 2007/12/12 16:57:17 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-vtex.def,v 1.10 2013/07/15 12:05:34 tantau Exp $ % Driver commands for vtex @@ -47,7 +47,7 @@ \def\pgf@sys@vtex@@setcolor#1#2#3#4#5{% \pgfsysps@color@resetnow% \expandafter\ifx\csname pgfsys@color@#4\endcsname\relax% - \PackageError{pgfbase}{Unsupported color model `#4'. Sorry}{}% + \pgferror{Unsupported color model `#4'. Sorry}% \else% \edef\pgf@colmarshal{\expandafter\noexpand\csname pgfsys@color@#4\endcsname}% \pgf@uncomma#5,,% @@ -92,6 +92,13 @@ } } +% vtex commands for changing the paper size +\def\pgfsys@papersize#1#2{\mediawidth#1\mediaheight#2} + + + + + \endinput %%% Local Variables: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def index feaa7f77bae..9d13ae1ae70 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys-xetex.def @@ -7,44 +7,68 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-xetex.def,v 1.3 2010/02/16 10:56:09 tantau Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys-xetex.def,v 1.9 2013/07/16 16:03:13 tantau Exp $ -% Driver commands for dvipdfm +\input pgfsys-dvipdfmx.def -% -% Load common pdf and pdf in dvi commands: -% -\input pgfsys-common-pdf.def -\input pgfsys-common-pdf-via-dvi.def +\def\pgfsys@dvipdfmx@patternobj#1{% + % I have NO idea why this is necessary for xdvipdfmx - but without + % it, it crashes. + \pgfutil@insertatbegincurrentpagefrombox{#1}% +}% -% -% dvipdfmx-specific stuff: -% +% XeTeX supports pdftex commands for paper size +\def\pgfsys@papersize#1#2{% + \pdfpageheight#2% + \pdfpagewidth#1} + +\def\pgfsys@global@papersize#1#2{% + \global\pdfpageheight#2% + \global\pdfpagewidth#1} + -\def\pgfsys@invoke#1{\special{pdf:literal direct #1 }} +% Xetex does not support interpolate and not mask +\def\pgfsys@defineimage{% width, height, page number + \ifx\includegraphics\undefined + \ifx\pgf@imagewidth\pgfutil@empty\edef\pgf@imagewidth{1bp}\fi% width? + \ifx\pgf@imageheight\pgfutil@empty\edef\pgf@imageheight{1bp}\fi% height? + \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{ page \pgf@imagepage}\fi% + \ifx\pgf@imageinterpolate\pgfutil@empty\else\edef\pgf@imageinterpolate{ /Interpolate\space\pgf@imageinterpolate}\fi% + \ifx\pgf@imagemask\pgfutil@empty\else\xdef\pgf@imagemask{ /SMask @\pgf@imagemask}\fi% + \edef\pgf@image{\noexpand\hbox to \pgf@imagewidth{\vbox to \pgf@imageheight{\vfil\special{pdf:image width \pgf@imagewidth\space height \pgf@imageheight\space\pgf@imagepage\space(\pgf@filename) <<\pgf@imageinterpolate\pgf@imagemask\space>>}}\hfil}}% + \else + \ifx\pgf@imagewidth\pgfutil@empty\else\edef\pgf@imagewidth{width=\pgf@imagewidth,}\fi% + \ifx\pgf@imageheight\pgfutil@empty\else\edef\pgf@imageheight{height=\pgf@imageheight,}\fi% + \ifx\pgf@imagepage\pgfutil@empty\else\edef\pgf@imagepage{page=\pgf@imagepage,}\fi% + \edef\pgf@image{\noexpand\includegraphics[\pgf@imageheight\pgf@imagewidth\pgf@imagepage]{\pgf@filename}}% + \fi% +} + +% XeTeX supports position tracking, now +\def\pgfsys@markposition#1{% + \pdfsavepos% + \edef\pgf@temp{#1}% + \expandafter\pgfutil@writetoaux\expandafter{% + \expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\pdflastxpos}{\the\pdflastypos}}% +} +\def\pgfsyspdfmark#1#2#3{% + \expandafter\gdef\csname pgf@sys@pdf@mark@pos@#1\endcsname{\pgfqpoint{#2sp}{#3sp}}% +} -\ifx\XeTeXversion\@undefined - \PackageError{pgfsys}{XeTeX is not running, but it should. Somehow - the wrong driver got selected}{} -\fi +\def\pgfsys@getposition#1#2{% + \edef\pgf@marshal{\let\noexpand#2=\expandafter\noexpand\csname pgf@sys@pdf@mark@pos@#1\endcsname}% + \pgf@marshal% +} +\def\pgf@sys@pdf@mark@pos@pgfpageorigin{\pgfqpoint{2\hoffset}{0pt}} -% -% Position tracking always on -% -\pgf@sys@pdf@dvi@tracker +\ifx\paperheight\@undefined +\else + \pdfpagewidth\paperwidth + \pdfpageheight\paperheight % this is to work around a positioning problem in xetex. +\fi -% -% Page size stuff -% -\def\pgfsys@papersize#1#2{% - \pdfpageheight#2% - \pdfpagewidth#1} \endinput - -%%% Local Variables: -%%% mode: latex -%%% End: diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex index 3cd39c48645..63a1aac41a5 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsys.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys.code.tex,v 1.37 2010/06/30 13:06:37 ludewich Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsys.code.tex,v 1.47 2013/11/30 11:35:10 ludewich Exp $ % Load key mechanism @@ -17,6 +17,10 @@ \pgfkeys{/pgf/.is family} \def\pgfset{\pgfqkeys{/pgf}} +% This is if is needed *very* early +\newif\ifpgfpicture + + % % The following conversion functions are used to convert from TeX % dimensions to postscript/pdf points. @@ -66,6 +70,28 @@ \newcount\c@pgf@countc \newcount\c@pgf@countd +\newtoks\t@pgf@toka +\newtoks\t@pgf@tokb +\newtoks\t@pgf@tokc + +% Ensure that math registers are the same (math is broken in case it +% is loaded first) +\let\pgfmath@x\pgf@x +\let\pgfmath@xa\pgf@xa +\let\pgfmath@xb\pgf@xb +\let\pgfmath@xc\pgf@xc + +\let\pgfmath@y\pgf@y +\let\pgfmath@ya\pgf@ya +\let\pgfmath@yb\pgf@yb +\let\pgfmath@yc\pgf@yc + +\let\c@pgfmath@counta\c@pgf@counta +\let\c@pgfmath@countb\c@pgf@countb +\let\c@pgfmath@countc\c@pgf@countc +\let\c@pgfmath@countd\c@pgf@countd + + % The following \if decides, whether even-odd filling and clipping is % to be used or normal the non-zero winding number rule. See the @@ -96,8 +122,7 @@ \expandafter\ifx\csname pgf@sys@fail@#1\endcsname\pgfutil@empty% \else% \expandafter\global\expandafter\let\csname pgf@sys@fail@#1\endcsname=\pgfutil@empty% - \PackageWarning{pgf}{% - Your graphic driver \pgfsysdriver\space does not support #1. This warning is given only once}% + \pgfwarning{Your graphic driver \pgfsysdriver\space does not support #1. This warning is given only once}% \fi% } @@ -131,33 +156,31 @@ % \def\pgfsys@moveto#1#2{\pgf@sys@fail{path constructions}} -% This command is used to start a path at a specific point (#1bp,#2bp) -% or to move the current point of the current path to (#1bp,#2bp) +% This command is used to start a path at a specific point (#1,#2) +% or to move the current point of the current path to (#1,#2) % without drawing anything upon stroking (the current path is % `interrupted'). % -% Here (and in the following) the coordinates are in TeX's big points -% (bp), unless the coordinate system has been scaled. A big point is -% 1/72 inches. Note that TeX's point pt is 1/72.27 inches. +% The arguments must be dimensions (like |10pt|). % % Example: % -% \pgfsys@moveto{10}{10} -% \pgfsys@lineto{0}{0} +% \pgfsys@moveto{10pt}{10pt} +% \pgfsys@lineto{0pt}{0pt} % \pgfsys@stroke % -% This will draw a line from (10bp,10bp) to the origin of the picture. +% This will draw a line from (10pt,10pt) to the origin of the picture. \def\pgfsys@lineto#1#2{\pgf@sys@fail{path constructions}} -% Continue the current path to (#1bp,#2bp) with a line. +% Continue the current path to (#1,#2) with a line. \def\pgfsys@curveto#1#2#3#4#5#6{\pgf@sys@fail{path constructions}} -% Continue the current path with a bezier curver to (#5bp,#6bp). The -% control points of the curve are at (#1bp,#2bp) and (#3bp,#4bp). +% Continue the current path with a bezier curver to (#5,#6). The +% control points of the curve are at (#1,#2) and (#3,#4). \def\pgfsys@rect#1#2#3#4{\pgf@sys@fail{path constructions}} % Append a rectangle to the current path whose lower left corner is at -% (#1bp,#2bp) and whose width/height is given by (#3bp,#4bp). +% (#1,#2) and whose width/height is given by (#3,#4). % % This command can be `mapped back' to moveto and lineto commands, but % it is included since pdf has a special, quick version of this command. @@ -306,7 +329,7 @@ % % \def\pgfsys@setlinewidth#1{\pgf@sys@fail{setting the line width}} -% Sets the width of lines, when stroked, to #1bp. +% Sets the width of lines, when stroked, to #1. \def\pgfsys@buttcap{\pgf@sys@fail{setting the line cap}} % Sets the cap to a butt cap. See \pgfsys@stroke. @@ -331,22 +354,21 @@ % Sets the join to a bevel join. See \pgfsys@stroke. \def\pgfsys@setdash#1#2{\pgf@sys@fail{setting the dashing pattern}} -% Sets the dashing patter. #1 should be a list of lengths given in big -% points (bp) separated by spaces. #2 should be a single value given -% in bp. +% Sets the dashing patter. #1 should be a list of lengths separated by +% spaces. #2 should be a single dimension. % % The list of values in #1 is used to determine the lengths of the % `on' phases of the dashing and of the `off' phases. For example, if -% #1 is `3 4', then the dashing pattern is `3bp on followed by 4bp -% off, followed by 3bp on, followed by 4bp off, and so on'. A pattern -% of `.5 4 3 1.5' means `.5bp on, 4bp off, 3bp on, 1.5bp off, .5bp on, +% #1 is `3pt 4pt', then the dashing pattern is `3pt on followed by 4pt +% off, followed by 3pt on, followed by 4pt off, and so on'. A pattern +% of `.5pt 4pt 3pt 1.5pt' means `.5pt on, 4pt off, 3pt on, 1.5pt off, .5pt on, % ...'. If the number of entries is odd, the last one is used twice, -% so `3' means `3bp on, 3bp off, 3bp on, 3bp off,...'. An empty list +% so `3pt' means `3pt on, 3pt off, 3pt on, 3pt off,...'. An empty list % means `always on'. % % The second argument determines the `phase' of the pattern. For -% example, for a pattern of `3 4' and a phase of `1', the pattern -% would start: `2bp on, 4bp off, 3bp on, 4bp off, 3bp on, 4bp off...'. +% example, for a pattern of `3pt 4pt' and a phase of `1pt', the pattern +% would start: `2pt on, 4pt off, 3pt on, 4pt off, 3pt on, 4pt off...'. @@ -509,6 +531,17 @@ % overlap will be darker than the rest. By comparison, if the circles % are part of a transparency group, the overlap will get the same % color as the rest. +% +% The following settings modify the bevahiour of a transparency group: + +\newif\ifpgfsys@transparency@group@isolated +\newif\ifpgfsys@transparency@group@knockout + + +\def\pgfsys@blend@mode#1{\pgf@sys@fail{blend mode}} +% Sets the current blend mode. See the PDF specification for details +% on blend modes. + \def\pgfsys@definemask{\pgf@sys@fail{image masks}} % This command declares a mask for usage with images. It works similar @@ -631,12 +664,36 @@ % Page size stuff % % + \def\pgfsys@papersize#1#2{\pgf@sys@fail{papersize}} -% This command sets the paper size in a portable way. +% This command sets the paper size in a portable way. It tries to do +% so "locally" for the current page, but what really happens depends +% strongly on the driver. For instance, dvips will use whatever is +% used with the first call to this command that is part of the +% shipped-out document and will ignore all other uses. In contrast, +% pdftex will use the current value of the papersize for each page +% and, additionally, setting the papersize is local to the current TeX +% group. +% #1 = width +% #2 = height + +\def\pgfsys@global@papersize#1#2{\pgfsys@papersize{#1}{#2}} +% This command does the same as the papersize command, only for +% drivers that support this, \global is used to set the papersize. % #1 = width % #2 = height +\ifx\paperheight\@undefined + \def\pgfsys@thepageheight{\the\vsize} % this is wrong, but I do not + % know how to compute the page height + % in plain tex. + \def\pgfsys@thepagewidth{\the\hsize} +\else + \def\pgfsys@thepageheight{\paperheight} + \def\pgfsys@thepagewidth{\paperwidth} +\fi + % % @@ -705,7 +762,7 @@ \def\pgfsys@transformshift#1#2{\pgfsys@transformcm{1}{0}{0}{1}{#1}{#2}} % This command will change the origin of the low-level coordinate -% system to (#1bp,#2bp). +% system to (#1,#2). \def\pgfsys@transformxyscale#1#2{\pgfsys@transformcm{#1}{0}{0}{#2}{0bp}{0bp}} % This command will scale the low-level coordinate system (and @@ -739,6 +796,20 @@ % transformation cm. This will ensure that hyperlinks ``survive'' at % least translations. +\def\pgfsys@pictureboxsynced#1{% + {% + \setbox0=\hbox{\pgfsys@beginpicture\box#1\pgfsys@endpicture}% + \pgfsys@hboxsynced0% + }% +} +% Basically, this should do the same as doing a (scoped) low level sync +% followed by inserting the box #1 directly into the output +% stream. However, the default implementation uses \pgfsys@hboxsynced +% in conjunction with \pgfsys@beginpicture to ensure that, if +% possible, hyperlinks survive in pdfs. Drivers that are sensitive to +% picture-in-picture scopes shuold replace this implementation by +% \pgfsys@beginscope\pgflowlevelsynccm\box#1\pgfsys@endscope + \def\pgfsys@beginpicture{} % Called at the beginning of a pgfpicture. Used to setup things. @@ -835,7 +906,9 @@ {% \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% \pgfsysprotocol@bufferedtrue% + \pgfsys@beginscope% #4% + \pgfsys@endscope% \pgfsysprotocol@getcurrentprotocol\pgfsys@@temp% \expandafter\global\expandafter\let\csname #1\endcsname=\pgfsys@@temp% }% @@ -897,9 +970,9 @@ \input pgf.cfg -\PackageInfo{pgfsys}{Driver file for pgf: \pgfsysdriver} +\immediate\write-1{Driver file for pgf: \pgfsysdriver} \pgfutil@InputIfFileExists{\pgfsysdriver}{}{% - \PackageError{pgfsys}{Driver file ``\pgfsysdriver'' not found.}{}} + \pgferror{Driver file ``\pgfsysdriver'' not found.}} diff --git a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex index 96fe6db490a..0b6310873ab 100644 --- a/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/systemlayer/pgfsyssoftpath.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsyssoftpath.code.tex,v 1.7 2008/07/18 19:06:58 ludewich Exp $ +\ProvidesFileRCS $Header: /cvsroot/pgf/pgf/generic/pgf/systemlayer/pgfsyssoftpath.code.tex,v 1.9 2013/09/09 10:05:41 tantau Exp $ % This package provides the pgf system path abstraction layer. This @@ -52,7 +52,7 @@ % buffers are flushed. % % Because of this buffering, it is imperative that the main path is -% accessed only vie appropriate interface macros. +% accessed only via appropriate interface macros. @@ -141,33 +141,31 @@ % Add a moveto element to the current path \def\pgfsyssoftpath@moveto#1#2{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@movetotoken{#1}{#2}% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \edef\pgfsyssoftpath@coord{{#1}{#2}}% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@movetotoken\pgfsyssoftpath@coord}% \ifpgfsyssoftpathmovetorelevant% - \xdef\pgfsyssoftpath@lastmoveto{{#1}{#2}}% + \global\let\pgfsyssoftpath@lastmoveto\pgfsyssoftpath@coord% \fi% } % Add a lineto element to the current path \def\pgfsyssoftpath@lineto#1#2{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@linetotoken{#1}{#2}% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \edef\pgfsyssoftpath@coord{{#1}{#2}}% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@linetotoken\pgfsyssoftpath@coord}% } + % Add curveto elements to the current path \def\pgfsyssoftpath@curveto#1#2#3#4#5#6{% \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@curvetosupportatoken{#1}{#2}% - \noexpand\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}% - \noexpand\pgfsyssoftpath@curvetotoken{#5}{#6}% - }}% + \noexpand\pgfsyssoftpath@curvetosupportatoken{#1}{#2}% + \noexpand\pgfsyssoftpath@curvetosupportbtoken{#3}{#4}% + \noexpand\pgfsyssoftpath@curvetotoken{#5}{#6}% + }}% \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% } + % Add rectanlge elements to the current path \def\pgfsyssoftpath@rect#1#2#3#4{% \edef\pgfsyssoftpath@temp{{% @@ -179,18 +177,13 @@ % Add closepath element to the current path \def\pgfsyssoftpath@closepath{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@closepathtoken\pgfsyssoftpath@lastmoveto% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@closepathtoken\pgfsyssoftpath@lastmoveto}% } % Add special element to the current path \def\pgfsyssoftpath@specialround#1#2{% - \edef\pgfsyssoftpath@temp{{% - \noexpand\pgfsyssoftpath@specialroundtoken{#1}{#2}% - }}% - \expandafter\pgfsyssoftpath@addtocurrentpath\pgfsyssoftpath@temp% + \edef\pgfsyssoftpath@temp{{#1}{#2}}% + \expandafter\pgfsyssoftpath@addtocurrentpath\expandafter{\expandafter\pgfsyssoftpath@specialroundtoken\pgfsyssoftpath@temp}% } % Marshallers @@ -200,6 +193,8 @@ \def\pgfsyssoftpath@curvetosupportatoken#1#2#3#4#5#6#7#8{\pgfsys@curveto{#1}{#2}{#4}{#5}{#7}{#8}} \def\pgfsyssoftpath@closepathtoken#1#2{\pgfsys@closepath} \let\pgfsyssoftpath@specialroundtoken=\pgfutil@gobbletwo +\def\pgfsyssoftpath@curvetosupportbtoken#1#2{curvetotokenb} % make sure this this \ifx-equal only to itself +\def\pgfsyssoftpath@curvetotoken#1#2{curvetotoken}% make sure this this \ifx-equal only to itself \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex index d31ddedfe26..e984ca06315 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgffor.code.tex @@ -7,17 +7,23 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgffor.code.tex,v 1.18 2010/03/23 14:47:45 vibrovski Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgffor.code.tex,v 1.25 2013/12/13 11:40:27 tantau Exp $ +% pgfmath is needed +\input pgfmath.code.tex \newdimen\pgffor@iter \newdimen\pgffor@skip \newif\ifpgffor@continue -\let\pgffor@beginhook=\pgfutil@empty -\let\pgffor@endhook=\pgfutil@empty -\let\pgffor@afterhook=\pgfutil@empty +\def\pgffor@reset@hooks{% + \let\pgffor@beginhook=\relax% + \let\pgffor@endhook=\relax% + \let\pgffor@afterhook=\relax% +} +\pgffor@reset@hooks + % Stack emulation % @@ -133,20 +139,20 @@ } \def\pgffor@iterate{% - % Must do all of these in case the internal stack is used. - \let\pgffor@last=\pgfutil@empty% + % Must do all of these in case the internal stack is used. + \let\pgffor@last=\pgfutil@empty% \let\pgffor@prevlast=\pgfutil@empty% \let\pgffor@dotsend=\pgfutil@empty% - \let\pgffor@dots@pre=\pgfutil@empty% - \let\pgffor@dots@post=\pgfutil@empty% - % - \expandafter\pgffor@scan\pgffor@values} + \let\pgffor@dots@pre=\pgfutil@empty% + \let\pgffor@dots@post=\pgfutil@empty% + % + \expandafter\pgffor@scan\pgffor@values} \def\pgffor@stop{\pgffor@stop}% \def\pgffor@dots{...}% \def\pgffor@scan{\pgfutil@ifnextchar({\pgffor@scanround}{\pgffor@scanone}} -\def\pgffor@scanround(#1)#2,{\def\pgffor@value{(#1)}\pgffor@scanned} +\def\pgffor@scanround(#1)#2,{\def\pgffor@value{(#1)#2}\pgffor@scanned} \def\pgffor@scanone#1,{\def\pgffor@value{#1}\pgffor@scanned} @@ -215,7 +221,7 @@ \pgffor@assign@before@code% \fi% % - \expandafter\pgffor@beginhook\pgffor@body\pgffor@endhook% + \expandafter\expandafter\expandafter\pgffor@reset@hooks\expandafter\pgffor@beginhook\expandafter\pgffor@body\pgffor@endhook% % Execute assign after code. \ifx\pgffor@assign@after@code\pgfutil@empty% \else% @@ -373,7 +379,7 @@ \pgffor@assign@before@code% \fi% % - \expandafter\pgffor@beginhook\pgffor@body\pgffor@endhook% + \expandafter\expandafter\expandafter\pgffor@reset@hooks\expandafter\pgffor@beginhook\expandafter\pgffor@body\pgffor@endhook% % % Perform assignments after loop body. \ifx\pgffor@assign@after@code\pgfutil@empty% @@ -448,23 +454,21 @@ % Convert the number in the macro passed as #1 to a-z or A-Z. \pgfutil@tempcnta=#1\relax% \ifnum\pgfutil@tempcnta>95\relax% - \advance\pgfutil@tempcnta by-96% - \expandafter\def\expandafter#1\expandafter% - {\pgffor@alpha\pgfutil@tempcnta}% + \advance\pgfutil@tempcnta by-96\relax% + \edef#1{\pgffor@alpha\pgfutil@tempcnta}% \else% - \advance\pgfutil@tempcnta by-64% - \expandafter\def\expandafter#1\expandafter% - {\pgffor@Alpha\pgfutil@tempcnta}% + \advance\pgfutil@tempcnta by-64 % + \edef#1{\pgffor@Alpha\pgfutil@tempcnta}% \fi% } \def\pgffor@Alpha#1{% - \ifcase#1\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M% + \ifcase#1\relax\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or K\or L\or M% \or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\else?\fi% } \def\pgffor@alpha#1{% - \ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m% + \ifcase#1\relax\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or k\or l\or m% \or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\else?\fi% } @@ -482,12 +486,12 @@ \begingroup% \escapechar=-1\relax% \expandafter\pgffor@@addiftotoks\string#1\pgffor@stop} -\def\pgffor@@addiftotoks#1#2#3#4#5\pgffor@stop{% +\def\pgffor@@addiftotoks#1#2#3#4\pgffor@stop{% \endgroup - \csname if#4#5\endcsname% - \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#4#5true\endcsname}% + \csname if#3#4\endcsname% + \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#3#4true\endcsname}% \else% - \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#4#5false\endcsname}% + \expandafter\def\expandafter\pgffor@tokstemp\expandafter{\csname#3#4false\endcsname}% \fi% \pgffor@@addcstotoks% } @@ -520,28 +524,32 @@ \let\pgffor@remember@expanded=\pgfutil@empty \def\pgffor@default@endgroup{% - \ifx\pgffor@assign@once@code\pgfutil@empty% - \else% - \global\edef\pgffor@remember@once@expanded{\pgffor@remember@once@code}% - \fi% - \ifx\pgffor@remember@code\pgfutil@empty% - \else% - \global\edef\pgffor@remember@expanded{\pgffor@remember@code}% - \fi% - \endgroup% - % - \ifx\pgffor@remember@once@expanded\pgfutil@empty% - \else% - \pgffor@remember@once@expanded% - \let\pgffor@assign@once@code=\pgfutil@empty% - \global\let\pgffor@remember@once@expanded=\pgfutil@empty% - \fi% - % - \ifx\pgffor@remember@expanded\pgfutil@empty% - \else% - \pgffor@remember@expanded% - \global\let\pgffor@remember@expanded=\pgfutil@empty% - \fi% + \ifx\pgffor@remember@once@code\pgfutil@empty + \else + \xdef\pgffor@remember@once@expanded{\pgffor@remember@once@code}% + \fi + \ifx\pgffor@remember@code\pgfutil@empty + \else + \xdef\pgffor@remember@expanded{\pgffor@remember@code}% + \fi + \endgroup + % + \ifx\pgffor@remember@once@expanded\pgfutil@empty + \else + \pgffor@remember@once@expanded% + % \let\pgffor@assign@once@code=\pgfutil@empty % Not needed anymore? (CJ) + \global\let\pgffor@remember@once@expanded=\pgfutil@empty + \fi + \ifx\pgffor@assign@once@code\pgfutil@empty + \else + \global\let\pgffor@assign@once@code=\pgfutil@empty + \fi + % + \ifx\pgffor@remember@expanded\pgfutil@empty + \else + \pgffor@remember@expanded% + \global\let\pgffor@remember@expanded=\pgfutil@empty + \fi } \let\pgffor@begingroup=\pgffor@default@begingroup diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex index 86e0499ded7..3d79735459d 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeys.code.tex @@ -25,8 +25,14 @@ % This is useful: +\newif\ifpgfkeys@csname@test% + +\def\pgfkeys@ifcsname#1\endcsname#2\else#3\fi{% + \pgfkeys@csname@testfalse% + \expandafter\ifx\csname#1\endcsname\relax\else\expandafter\ifx\csname#1\endcsname\@undefined\else\pgfkeys@csname@testtrue\fi\fi% + \ifpgfkeys@csname@test#2\else#3\fi% +}% -\def\pgfkeys@ifcsname#1\endcsname#2\else#3\fi{\expandafter\ifx\csname#1\endcsname\relax#3\else#2\fi}% \ifx\eTeXrevision\undefined% \else% \expandafter\let\expandafter\pgfkeys@ifcsname\csname ifcsname\endcsname% @@ -37,7 +43,7 @@ % This also: \ifx\PackageError\undefined - \def\pgfkeys@error#1{\immediate\write-1{Package pgfkeys: Error! #1.}}% + \def\pgfkeys@error#1{\errmessage{Package pgfkeys Error: #1.}}% \else \def\pgfkeys@error#1{\PackageError{pgfkeys}{#1}{}}% \fi @@ -180,10 +186,10 @@ % for handled keys). \long\def\pgfkeysifassignable#1#2#3{% \pgfkeysifdefined{#1}% - {#2} - {\pgfkeysifdefined{#1/.@cmd}% - {#2}% - {#3}}% + {#2} + {\pgfkeysifdefined{#1/.@cmd}% + {#2}% + {#3}}% }% @@ -286,14 +292,37 @@ \expandafter\pgfkeys@normal% \fi% } -\long\def\pgfkeys@normal#1,{% +\newif\ifpgfkeys@syntax@handlers +\def\pgfkeys@normal{% + \ifpgfkeys@syntax@handlers% + \expandafter\pgfkeys@syntax@handlers% + \else% + \expandafter\pgfkeys@@normal% + \fi% +} +\def\pgfkeys@syntax@handlers{\pgf@keys@utilifnextchar\relax\pgfkeys@syntax@@handlers\pgfkeys@syntax@@handlers}%get rid of spaces +\def\pgfkeys@syntax@@handlers{\futurelet\pgfkeys@first@char\pgfkeys@syntax@handlers@test} +\def\pgfkeys@syntax@handlers@test{% + \pgfkeysgetvalue{/handlers/first char syntax/\meaning\pgfkeys@first@char}\pgfkeys@the@handler% + \ifx\pgfkeys@the@handler\relax% + \expandafter\pgfkeys@@normal% + \else% + \expandafter\pgfkeys@use@handler% + \fi% +} +\long\def\pgfkeys@use@handler#1,{% + \pgfkeys@the@handler{#1}% + \pgfkeys@parse% +} + +\long\def\pgfkeys@@normal#1,{% \pgfkeys@unpack#1=\pgfkeysnovalue=\pgfkeys@stop% \pgfkeys@parse% } \def\pgfkeys@cleanup\pgfkeys@mainstop{} \def\pgfkeys@mainstop{\pgfkeys@mainstop} % equals only itself -\def\pgfkeys@novalue{} % equals only itself +\def\pgfkeys@novalue{} \def\pgfkeysnovalue{\pgfkeys@novalue} % equals only itself \def\pgfkeysnovalue@text{\pgfkeysnovalue} \def\pgfkeysvaluerequired{\pgfkeysvaluerequired} % equals only itself @@ -312,7 +341,8 @@ {}% no default, so leave it \fi% \ifx\pgfkeyscurrentvalue\pgfkeysvaluerequired% - \pgfkeysvalueof{/errors/value required/.@cmd}\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov% + \def\pgf@marshal{\pgfkeysvalueof{/errors/value required/.@cmd}}% + \expandafter\pgf@marshal\expandafter{\pgfkeyscurrentkey}{}\pgfeov% \else% \pgfkeys@case@one% \fi% @@ -356,30 +386,30 @@ \pgfkeys@split@path% \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{% \pgfkeys@ifexecutehandler{% - \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% + \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov - }{% + }{% % this here is necessary: /my search path/key/.code % won't be called, so \pgfkeyscurrentpath == '/my search path/key' % -> it should be one directory higher! We want to invoke the - % .unknown handler in - % '/my search path' - % - % Idea: - % set - % - path := '/my search path' - % - name := 'key/.code' - % - key = '/my search path/key/.code' - \let\pgfkeys@temp=\pgfkeyscurrentkey - \let\pgfkeys@tempb=\pgfkeyscurrentname + % .unknown handler in + % '/my search path' + % + % Idea: + % set + % - path := '/my search path' + % - name := 'key/.code' + % - key = '/my search path/key/.code' + \let\pgfkeys@temp=\pgfkeyscurrentkey + \let\pgfkeys@tempb=\pgfkeyscurrentname \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% \pgfkeys@split@path% - \let\pgfkeyscurrentkey=\pgfkeys@temp - \edef\pgfkeyscurrentname{\pgfkeyscurrentname/\pgfkeys@tempb}% - \pgfkeys@unknown - }% + \let\pgfkeyscurrentkey=\pgfkeys@temp + \edef\pgfkeyscurrentname{\pgfkeyscurrentname/\pgfkeys@tempb}% + \pgfkeys@unknown + }% }{% - \pgfkeys@unknown + \pgfkeys@unknown }% } @@ -394,37 +424,31 @@ \else % implement the 'only existing' feature here: \pgfkeysifdefined{\pgfkeyscurrentpath}{#1}{% - \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{#1}{#2}% + \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{#1}{#2}% }{}% \fi% }% \def\pgfkeys@ifexecutehandler@handlefullorexisting#1#2{% \ifpgfkeysaddeddefaultpath \pgfkeys@ifcsname pgfk@excpt@\pgfkeyscurrentname\endcsname% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentname' is an exception; processing it (on \pgfkeyscurrentpath).}% #1% ok, this particular key handler is known and be processed in any case (for example .try) \else % implement the 'only existing' feature here: \pgfkeysifdefined{\pgfkeyscurrentpath}{% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentpath' does exist. Executing '\pgfkeyscurrentname'.}% - #1% - }{% - \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentpath/.@cmd' does exist. Executing '\pgfkeyscurrentname'.}% - #1% - }{% -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): '\pgfkeyscurrentpath' does NOT exist. Skipping '\pgfkeyscurrentname'.}% - #2% - }% - }% + #1% + }{% + \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}{% + #1% + }{% + #2% + }% + }% \fi% \else -%\message{ifexecutehandler(\pgfkeyscurrentkeyRAW, path \pgfkeysdefaultpath): Fully qualified key provided. Executing '\pgfkeyscurrentname'.}% #1% ok, always true if the USER explicitly provided the full key path. \fi }% -\def\pgfkeysaddhandlyonlyexistingexception#1{\expandafter\def\csname pgfk@excpt@#1\endcsname{1}}% - +\def\pgfkeysaddhandleonlyexistingexception#1{\expandafter\def\csname pgfk@excpt@#1\endcsname{1}}% \def\pgfkeys@unknown{% \pgfkeysifdefined{\pgfkeyscurrentpath/.unknown/.@cmd}% @@ -579,10 +603,12 @@ \long\def\pgfkeysdef#1#2{% \long\def\pgfkeys@temp##1\pgfeov{#2}% \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}% + \pgfkeyssetvalue{#1/.@body}{#2}% } \long\def\pgfkeysedef#1#2{% \long\edef\pgfkeys@temp##1\pgfeov{#2}% \pgfkeyslet{#1/.@cmd}{\pgfkeys@temp}% + \pgfkeyssetvalue{#1/.@body}{#2}% } @@ -628,27 +654,27 @@ % % defnargs: % \pgfkeysdefnargs{/a}{2}{1=`#1', 2=`#2'} % \pgfkeys{ -% /a= -% {1} -% {2} +% /a= +% {1} +% {2} % } % ->defnargs: 1=`1', 2=`2' % % defargs: % \pgfkeysdefargs{/b}{#1#2}{1=`#1', 2=`#2'} % \pgfkeys{ -% /b= -% {1} -% {2} +% /b= +% {1} +% {2} % } % ->defargs: 1=`1', 2=` 2' (note the space!) % % defargs: % \pgfkeysdefargs{/b}{#1#2}{1=`#1', 2=`#2'} % \pgfkeys{ -% /b= -% {1}% -% {2} +% /b= +% {1}% +% {2} % } % ->defargs: 1=`1', 2=`2' %-------------------------------------------------- @@ -656,32 +682,30 @@ \long\def\pgfkeysedefnargs#1#2#3{\pgfkeysdefnargs@{#1}{#2}{#3}{\edef}}% \long\def\pgfkeysdefnargs@#1#2#3#4{% \ifcase#2\relax - \pgfkeyssetvalue{#1/.@args}{}% + \pgfkeyssetvalue{#1/.@args}{}% \or - \pgfkeyssetvalue{#1/.@args}{##1}% + \pgfkeyssetvalue{#1/.@args}{##1}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2}% + \pgfkeyssetvalue{#1/.@args}{##1##2}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8}% - \or - \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% + \pgfkeyssetvalue{#1/.@args}{##1##2##3##4##5##6##7##8##9}% \else - \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% + \pgfkeys@error{\string\pgfkeysdefnargs: expected <= 9 arguments, got #2}% \fi \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs - \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% + \def\pgfkeys@temp{\expandafter\long\expandafter#4\csname pgfk@#1/.@@body\endcsname}% \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% % eliminate the \pgfeov at the end such that TeX gobbles spaces % by using @@ -712,34 +736,37 @@ % Find out, whether with args or not. \pgfkeysifdefined{\pgfkeyscurrentpath/.@args}% {% Yes, so add to body and reuse args - \pgfkeysaddvalue{\pgfkeyscurrentpath/.@body}{#1}{#2}% - % Redefine code - {% - \pgfkeysgetvalue{\pgfkeyscurrentpath/.@args}{\pgfkeys@tempargs}% - \pgfkeysgetvalue{\pgfkeyscurrentpath/.@body}{\pgfkeys@tempbody}% - \def\pgfkeys@marshal{\expandafter\gdef\expandafter\pgfkeys@global@temp\pgfkeys@tempargs}% - \expandafter\pgfkeys@marshal\expandafter{\pgfkeys@tempbody}% - }% + \pgfkeysaddvalue{\pgfkeyscurrentpath/.@body}{#1}{#2}% + % Redefine code + {% + \pgfkeysgetvalue{\pgfkeyscurrentpath/.@args}{\pgfkeys@tempargs}% + \pgfkeysgetvalue{\pgfkeyscurrentpath/.@body}{\pgfkeys@tempbody}% + \def\pgfkeys@marshal{\expandafter\gdef\expandafter\pgfkeys@global@temp\pgfkeys@tempargs}% + \expandafter\pgfkeys@marshal\expandafter{\pgfkeys@tempbody}% + }% \pgfkeysifdefined{\pgfkeyscurrentpath/.@@body}{% - % support for \pgfkeysndefargs: - \pgfkeyslet{\pgfkeyscurrentpath/.@@body}{\pgfkeys@global@temp}% - }{% - % support for \pgfkeysdefargs: + % support for \pgfkeysndefargs: + \pgfkeyslet{\pgfkeyscurrentpath/.@@body}{\pgfkeys@global@temp}% + }{% + % support for \pgfkeysdefargs: \pgfkeyslet{\pgfkeyscurrentpath/.@cmd}{\pgfkeys@global@temp}% - }% + }% }% {% % No, so single argument (simple \pgfkeysdef). Redefine accordingly. + \edef\pgf@expanded@path{\pgfkeyscurrentpath}% {% \toks0{#1}% - \pgfkeysifdefined{\pgfkeyscurrentpath/.@cmd}% - {\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@\pgfkeyscurrentpath/.@cmd\endcsname##1\pgfeov}}% - {\pgfkeys@temptoks{}}% + \pgfkeysifdefined{\pgf@expanded@path/.@cmd}% + {\expandafter\expandafter\expandafter\pgfkeys@temptoks\expandafter\expandafter\expandafter{\csname pgfk@\pgf@expanded@path/.@body\endcsname}}% + {\expandafter\pgfkeys@temptoks\expandafter{\expandafter\pgfkeyssetvalue\expandafter{\pgf@expanded@path}{##1}}}% \toks1{#2}% \xdef\pgfkeys@global@temp{\the\toks0 \the\pgfkeys@temptoks \the\toks1 }% }% - \expandafter\def\expandafter\pgfkeys@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% - \pgfkeyslet{\pgfkeyscurrentpath/.@cmd}\pgfkeys@temp% + \def\pgf@temp{\pgfkeyssetvalue{\pgf@expanded@path/.@body}}% + \expandafter\pgf@temp\expandafter{\pgfkeys@global@temp}% + \expandafter\long\expandafter\def\expandafter\pgfkeys@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% + \pgfkeyslet{\pgf@expanded@path/.@cmd}\pgfkeys@temp% }% } \pgfkeys{/handlers/.prefix code/.code=\pgfkeys{\pgfkeyscurrentpath/.add code={#1}{}}}% @@ -780,7 +807,8 @@ {% \ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% \else% - \pgfkeysvalueof{/errors/value forbidden/.@cmd}\pgfkeyscurrentkey\pgfkeyscurrentvalue\pgfeov% + \def\pgf@marshal{\pgfkeysvalueof{/errors/value forbidden/.@cmd}}% + \expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkey\expandafter}\expandafter{\pgfkeyscurrentvalue}\pgfeov% \fi% }{}}} @@ -799,23 +827,32 @@ \pgfkeys@ifcsname#1#2\endcsname% \csname#1#2\endcsname% \else% - \pgfkeysvalueof{/errors/boolean expected/.@cmd}\pgfkeyscurrentkey{#2}\pgfeov% + \def\pgf@marshal{\pgfkeysvalueof{/errors/boolean expected/.@cmd}}% + \expandafter\pgf@marshal\expandafter{\pgfkeyscurrentkey}{#2}\pgfeov% \fi } \pgfkeys{/handlers/.is choice/.code=% \pgfkeys{% \pgfkeyscurrentpath/.cd,% - .code=\expandafter\pgfkeysalso\expandafter{\pgfkeyscurrentkey/##1}, - .unknown/.style={/errors/unknown choice value=\pgfkeyscurrentkey\pgfkeyscurrentvalue}}} + .code=\def\pgfkeys@was@choice{##1}\expandafter\pgfkeysalso\expandafter{\pgfkeyscurrentkey/##1}, + .unknown/.code={% + \def\pgf@marshal{\pgfkeysvalueof{/errors/unknown choice value/.@cmd}}% + {\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\the\expandafter\pgfkeys@pathtoks\expandafter}\expandafter{\pgfkeys@was@choice}\pgfeov}% + }% + }% +} % Repeatedly setting a key \pgfkeys{/handlers/.list/.code=% {% + \ifx\foreach\@undefined% + \pgfkeys@error{You need to load the pgffor package to use the .list key syntax.}% + \fi% % Use foreach to unfold the list - \let\pgf@keys@temp=\pgfutil@empty% + \def\pgf@keys@temp{}% \foreach \pgf@keys@key in{#1}% {\expandafter\expandafter\expandafter\gdef% \expandafter\expandafter\expandafter\pgf@keys@temp% @@ -825,10 +862,16 @@ \expandafter\expandafter\expandafter{\expandafter\pgf@keys@list@path\expandafter}\pgf@keys@temp\pgf@stop% }% } -\def\pgf@keys@do@list#1{\pgfutil@ifnextchar\bgroup{\pgf@keys@do@list@item{#1}}\pgfutil@gobble} +\def\pgf@keys@do@list#1{\pgf@keys@utilifnextchar\bgroup{\pgf@keys@do@list@item{#1}}\pgf@keys@gobble} \def\pgf@keys@do@list@item#1#2{\pgfkeysalso{#1={#2}}\pgf@keys@do@list{#1}} +% Forwarding + +\pgfkeys{/handlers/.forward to/.code=% + \pgfkeys{\pgfkeyscurrentpath/.add code={}{\pgfkeys{#1={##1}}}} +} + % Inspection handlers @@ -836,6 +879,9 @@ \pgfkeys{/handlers/.show code/.code=\pgfkeysgetvalue{\pgfkeyscurrentpath/.@cmd}{\pgfkeysshower}\show\pgfkeysshower} % inspect the body of the command +% First char syntax handlers +\pgfkeys{/handlers/first char syntax/.is if=pgfkeys@syntax@handlers} + % Path handling % Prepares the .unknown handler used by '.search also'. @@ -844,22 +890,23 @@ \global\def\pgfkeys@global@temp##1\pgfeov{}% \pgfkeys@searchalso@parse#1,\pgfkeys@mainstop {% - \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}% - \toks1={\def\pgfutilnext{\pgfkeysvalueof{/handlers/.unknown/.@cmd}##1\pgfeov}\pgfutilnext}% - \xdef\pgfkeys@global@temp{% - \noexpand\ifpgfkeysaddeddefaultpath - \noexpand\pgfkeyssuccessfalse - \noexpand\let\noexpand\pgfkeys@searchalso@name=\noexpand\pgfkeyscurrentkeyRAW - \the\toks0 % one or more /.try things; one for each path. The last element won't have a /.try - %\noexpand\ifpgfkeyssuccess - %\noexpand\else - % \the\toks1 % invoke /handlers/.unknown handler - %\noexpand\fi - \noexpand\else - \the\toks1 % invoke /handlers/.unknown handler - \noexpand\fi - }% - \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% + \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}% + \toks1={\pgfkeysalso{/handlers/.unknown/.@cmd/.expand once=\pgfkeys@searchalso@temp@value}}% + \xdef\pgfkeys@global@temp{% + \noexpand\def\noexpand\pgfkeys@searchalso@temp@value{####1}% + \noexpand\ifpgfkeysaddeddefaultpath + \noexpand\pgfkeyssuccessfalse + \noexpand\let\noexpand\pgfkeys@searchalso@name=\noexpand\pgfkeyscurrentkeyRAW + \the\toks0 % one or more /.try things; one for each path. The last element won't have a /.try + %\noexpand\ifpgfkeyssuccess + %\noexpand\else + % \the\toks1 % invoke /handlers/.unknown handler + %\noexpand\fi + \noexpand\else + \the\toks1 % invoke /handlers/.unknown handler + \noexpand\fi + }% + \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% }% }% @@ -876,36 +923,36 @@ \pgfkeys@spdef\pgfkeys@temp{#1}% {% \toks0=\expandafter{\pgfkeys@global@temp##1\pgfeov}% - \toks1=\expandafter{\pgfkeys@temp}% - \toks2={##1}% - \xdef\pgfkeys@global@temp{% - \the\toks0 % the space is important! - \noexpand\ifpgfkeyssuccess\noexpand\else - \noexpand\pgfqkeys{\the\toks1 }{\noexpand\pgfkeys@searchalso@name - \ifx\pgfkeys@searchalso@nexttok\pgfkeys@mainstop\else/.try\fi={\the\toks2 }}% - \noexpand\fi}% - \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% + \toks1=\expandafter{\pgfkeys@temp}% + \xdef\pgfkeys@global@temp{% + \the\toks0 % the space is important! + \noexpand\ifpgfkeyssuccess\noexpand\else + \noexpand\pgfqkeys{\the\toks1 }{\noexpand\pgfkeys@searchalso@name + \ifx\pgfkeys@searchalso@nexttok\pgfkeys@mainstop\else/.try\fi /.expand once=\noexpand\pgfkeys@searchalso@temp@value}% + \noexpand\fi}% + \expandafter\gdef\expandafter\pgfkeys@global@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}% }% \pgfkeys@searchalso@parse#2% } \pgfkeys{% - /handlers/.is family/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}},% - /handlers/.cd/.code=\edef\pgfkeysdefaultpath{\pgfkeyscurrentpath/},% - /handlers/.search also/.code={% - \pgfkeys@searchalso@prepare@unknown@handler{#1}% + /handlers/.is family/.code=\pgfkeys{\pgfkeyscurrentpath/.ecode=\edef\noexpand\pgfkeysdefaultpath{\pgfkeyscurrentpath/}},% + /handlers/.cd/.code=\edef\pgfkeysdefaultpath{\pgfkeyscurrentpath/},% + /handlers/.search also/.code={% + \pgfkeys@searchalso@prepare@unknown@handler{#1}% %\message{I prepared the '\pgfkeyscurrentpath/.unknown' handler \meaning\pgfkeys@global@temp\space for '#1'.}% - \pgfkeyslet{\pgfkeyscurrentpath/.unknown/.@cmd}{\pgfkeys@global@temp}% - } + \pgfkeyslet{\pgfkeyscurrentpath/.unknown/.@cmd}{\pgfkeys@global@temp}% + } }% % Value expansion \pgfkeys{/handlers/.expand once/.code=\expandafter\pgfkeys@exp@call\expandafter{#1}} +\pgfkeys{/handlers/.expand two once/.code 2 args=\expandafter\expandafter\expandafter\pgfkeys@exp@call\expandafter\expandafter\expandafter{\expandafter#1\expandafter}\expandafter{#2}} \pgfkeys{/handlers/.expand twice/.code=\expandafter\expandafter\expandafter\pgfkeys@exp@call\expandafter\expandafter\expandafter{#1}} \pgfkeys{/handlers/.expanded/.code=\edef\pgfkeys@temp{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfkeys@temp}} -\def\pgfkeys@exp@call#1{\pgfkeysalso{\pgfkeyscurrentpath={#1}}} +\long\def\pgfkeys@exp@call#1{\pgfkeysalso{\pgfkeyscurrentpath={#1}}} % Try to set a key and do nothing if not define @@ -938,20 +985,20 @@ {% \pgfkeys@split@path% \pgfkeysifdefined{/handlers/\pgfkeyscurrentname/.@cmd}{% - % in the standard configuration, this check here is redundand - % because pgfkeys@ifexecutehandler === true. - % It is only interesting for 'handle only existing'. + % in the standard configuration, this check here is redundand + % because pgfkeys@ifexecutehandler === true. + % It is only interesting for 'handle only existing'. \pgfkeys@ifexecutehandler{% - \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% + \pgfkeysgetvalue{/handlers/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}% \expandafter\pgfkeys@code\pgfkeyscurrentvalue\pgfeov \pgfkeyssuccesstrue% - }{% - \pgfkeyssuccessfalse - }% }{% - \pgfkeyssuccessfalse + \pgfkeyssuccessfalse }% - }% + }{% + \pgfkeyssuccessfalse + }% + }% }% } @@ -962,49 +1009,111 @@ % Errors -\pgfkeys{/errors/boolean expected/.code 2 args=\pgfkeys@error{% - Boolean parameter of key '#1' must be 'true' or 'false', not - '#2'. I am going to ignore it}} -\pgfkeys{/errors/value required/.code 2 args=\pgfkeys@error{% - The key '#1' requires a value. I am going to ignore this key}{}} -\pgfkeys{/errors/value forbidden/.code 2 args=\pgfkeys@error{% - You may not specify a value for the key '#1'. I am going to ignore - the value '#2' that you provided}} -\pgfkeys{/errors/unknown choice value/.code 2 args=\pgfkeys@error{% - Choice '\pgfkeyscurrentname' unknown in key - '\pgfkeyscurrentpath'. I am going to ignore this key}} -\pgfkeys{/errors/unknown key/.code 2 args=\pgfkeys@error{% - I do not know the key '#1' and I am going to ignore it. Perhaps - you misspelled it}} +\pgfkeys{ + /errors/boolean expected/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \pgfkeys@error{% + Boolean parameter of key '\the\toks1' must be 'true' or 'false', not + '\the\toks2'. I am going to ignore it% + } + }, + /errors/value required/.code 2 args=% + { + \toks1={#1} + \pgfkeys@error{% + The key '\the\toks1' requires a value. I am going to ignore this + key% + } + }, + /errors/value forbidden/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \pgfkeys@error{% + You may not specify a value for the key '\the\toks1'. I am going to ignore + the value '\the\toks2' that you provided% + } + }, + /errors/unknown choice value/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \pgfkeys@error{% + Choice '\the\toks2' unknown in choice key '\the\toks1'. I am + going to ignore this key% + } + }, + /errors/unknown key/.code 2 args=% + { + \toks1={#1} + \toks2={#2} + \def\pgf@temp{#2}% + \pgfkeys@error{% + I do not know the key '\the\toks1'\ifx\pgf@temp\pgfkeysnovalue@text\space\else, to which you passed + '\the\toks2', \fi and I am going to ignore it. Perhaps you + misspelled it% + } + } +} \pgfkeys{/handlers/.unknown/.code=% {% - \let\pgfkeys@orig@key=\pgfkeyscurrentkey% - \pgfkeysalso{/errors/unknown key=\pgfkeys@orig@key{}}% - } + \def\pgf@marshal{\pgfkeysvalueof{/errors/unknown key/.@cmd}}% + {\expandafter\expandafter\expandafter\pgf@marshal\expandafter\expandafter\expandafter{\expandafter\pgfkeyscurrentkey\expandafter}\expandafter{\pgfkeyscurrentvalue}\pgfeov}% + }% } \pgfkeys{ - /handler config/.is choice, - /handler config/all/.code={% - \let\pgfkeys@case@three=\pgfkeys@case@three@handleall - \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleall - }, - /handler config/only existing/.code={% - \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted - \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleonlyexisting - }, - /handler config/full or existing/.code={% - \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted - \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handlefullorexisting - }, - /handler config/only existing/add exception/.code={\pgfkeysaddhandlyonlyexistingexception{#1}}, + /handler config/.is choice, + /handler config/all/.code={% + \let\pgfkeys@case@three=\pgfkeys@case@three@handleall + \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleall + }, + /handler config/only existing/.code={% + \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted + \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handleonlyexisting + }, + /handler config/full or existing/.code={% + \let\pgfkeys@case@three=\pgfkeys@case@three@handle@restricted + \let\pgfkeys@ifexecutehandler=\pgfkeys@ifexecutehandler@handlefullorexisting + }, + /handler config/only existing/add exception/.code={\pgfkeysaddhandleonlyexistingexception{#1}}, }% -\pgfkeysaddhandlyonlyexistingexception{.cd}% -\pgfkeysaddhandlyonlyexistingexception{.try}% -\pgfkeysaddhandlyonlyexistingexception{.retry}% -\pgfkeysaddhandlyonlyexistingexception{.lastretry}% -\pgfkeysaddhandlyonlyexistingexception{.unknown}% +\pgfkeysaddhandleonlyexistingexception{.cd}% +\pgfkeysaddhandleonlyexistingexception{.try}% +\pgfkeysaddhandleonlyexistingexception{.retry}% +\pgfkeysaddhandleonlyexistingexception{.lastretry}% +\pgfkeysaddhandleonlyexistingexception{.unknown}% +\pgfkeysaddhandleonlyexistingexception{.expand once}% +\pgfkeysaddhandleonlyexistingexception{.expand two once}% +\pgfkeysaddhandleonlyexistingexception{.expand twice}% +\pgfkeysaddhandleonlyexistingexception{.expanded}% + + +% Utilities for self-containment +\def\pgf@keys@gobble#1{} +\long\def\pgf@keys@utilifnextchar#1#2#3{% + \let\pgf@keys@utilreserved@d=#1% + \def\pgf@keys@utilreserved@a{#2}% + \def\pgf@keys@utilreserved@b{#3}% + \futurelet\pgf@keys@utillet@token\pgf@keys@utilifnch} +\def\pgf@keys@utilifnch{% + \ifx\pgf@keys@utillet@token\pgf@keys@utilsptoken + \let\pgf@keys@utilreserved@c\pgf@keys@utilxifnch + \else + \ifx\pgf@keys@utillet@token\pgf@keys@utilreserved@d + \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@a + \else + \let\pgf@keys@utilreserved@c\pgf@keys@utilreserved@b + \fi + \fi + \pgf@keys@utilreserved@c} +{% + \def\:{\global\let\pgf@keys@utilsptoken= } \: + \def\:{\pgf@keys@utilxifnch} \expandafter\gdef\: {\futurelet\pgf@keys@utillet@token\pgf@keys@utilifnch} +} \input pgfkeysfiltered.code.tex diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex index c46e418ddad..ef7411da924 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfkeysfiltered.code.tex @@ -132,7 +132,7 @@ % #1: old value of default path. % #2: key-value-list. -\def\pgfkeysfiltered@@install#1#2{% +\long\def\pgfkeysfiltered@@install#1#2{% \pgfkeys@install@filter@and@invoke{% \let\pgfkeysdefaultpath\pgfkeys@root% \pgfkeys@parse#2,\pgfkeys@mainstop% @@ -162,7 +162,7 @@ } % #1 = options -\long\long\def\pgfkeysalsofiltered#1{% +\long\def\pgfkeysalsofiltered#1{% \pgfkeys@install@filter@and@invoke{\pgfkeysalso{#1}}% }% @@ -922,7 +922,7 @@ % #1 the code to invoke after init and before cleanup -\def\pgfkeys@install@filter@and@invoke#1{% +\long\def\pgfkeys@install@filter@and@invoke#1{% \ifpgfkeysfilteringisactive \pgfkeys@error{Sorry, nested calls to key filtering routines are not allowed. (reason: It is not possible to properly restore the previous filtering state after returning from the nested call)}% \fi diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex index 6a0a1be016d..4f9d167e7bb 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfrcs.code.tex @@ -15,10 +15,8 @@ % prints out a message to the log. -%\def\pgfversion{2.00-cvs} -%\def\pgftypesetversion{\oldstylenums{2}.\oldstylenums{00}--\textsc{cvs}} -\def\pgfversion{2.10} -\def\pgftypesetversion{\oldstylenums{2}.\oldstylenums{10}} +\def\pgfversion{3.0.0} +\def\pgftypesetversion{\oldstylenums{3}.\oldstylenums{0}.\oldstylenums{0}} \ifx\pgfrcsloaded\undefined @@ -89,9 +87,13 @@ \def\ProvidesFile#1[#2]{\wlog{Loading file #1 version #2.}} \fi -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgfrcs.code.tex,v 1.24 2010/10/25 20:57:06 ludewich Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/utilities/pgfrcs.code.tex,v 1.28 2013/12/20 14:44:47 tantau Exp $ \catcode`\@=\pgfrcsatcode \fi + +% Local Variables: +% coding: undecided-unix +% End: diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex new file mode 100644 index 00000000000..26529cd5e37 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common-lists.tex @@ -0,0 +1,159 @@ +% Copyright 2013 by Christian Feuersaenger +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Public License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 +% +% This list here is a general re-implementation of the list used in +% the PGF system layer. +% It employs two collect-buffers to reduce the runtime. +% +% - It has preasymptotical runtime O(N), but is O(N^2) asymptotically. +% - It requires only 5 macros per list. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Usage: +% \pgfapplistnewempty\macro +\def\pgfapplistnewempty#1{% + \expandafter\let\csname pgfapp@#1\endcsname=\pgfutil@empty + \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}% + \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}% +}% + +% #1: the item to append +% #2: the list as macro name +\long\def\pgfapplistpushback#1\to#2{% + \begingroup + \c@pgf@counta=\csname pgfapp@#2@smallbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfapp@#2@smallbuf@c\endcsname=\pgf@glob@TMPa + \ifnum\csname pgfapp@#2@smallbuf@c\endcsname<40 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2@smallbuf\endcsname{\the\t@pgf@toka}% + \else + \pgfapplistpushback@smallbufoverfl{#1}{#2}% + \fi +}% +\long\def\pgfapplistpushback@smallbufoverfl#1#2{% + \begingroup + \c@pgf@counta=\csname pgfapp@#2@bigbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfapp@#2@bigbuf@c\endcsname=\pgf@glob@TMPa + % + \ifnum\csname pgfapp@#2@bigbuf@c\endcsname<30 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2@bigbuf\endcsname{\the\t@pgf@toka\the\t@pgf@tokb}% + \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}% + \else% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#2\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#2@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#2@smallbuf\endcsname#1}% + \expandafter\edef\csname pgfapp@#2\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + \expandafter\let\csname pgfapp@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfapp@#2@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#2@bigbuf@c\endcsname{0}% + \fi% +}% +\def\pgfapplist@flushbuffers#1{% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfapp@#1\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfapp@#1@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfapp@#1@smallbuf\endcsname}% + \expandafter\edef\csname pgfapp@#1\endcsname{\the\t@pgf@toka\the\t@pgf@tokb\the\t@pgf@tokc}% + \expandafter\let\csname pgfapp@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfapp@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfapp@#1@bigbuf@c\endcsname{0}% +}% + +\def\pgfapplistlet#1=#2{% + \pgfapplist@flushbuffers{#2}% + \expandafter\let\expandafter#1\csname pgfapp@#2\endcsname +}% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% A variant of applist which has the same runtime requirements, but +% does PUSH FRONT only. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% Usage: +% \pgfprependlistnewempty{list} +\def\pgfprependlistnewempty#1{% + \expandafter\let\csname pgfpPRP@#1\endcsname=\pgfutil@empty + \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}% + \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}% +}% + +% #1: the item to append +% #2: the list as macro name +\long\def\pgfprependlistpushfront#1\to#2{% + \begingroup + \c@pgf@counta=\csname pgfpPRP@#2@smallbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfpPRP@#2@smallbuf@c\endcsname=\pgf@glob@TMPa + \ifnum\csname pgfpPRP@#2@smallbuf@c\endcsname<40 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}% + \t@pgf@tokb={#1}% + \expandafter\edef\csname pgfpPRP@#2@smallbuf\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}% + \else + \pgfprependlistpushfront@smallbufoverfl{#1}{#2}% + \fi +}% +\long\def\pgfprependlistpushfront@smallbufoverfl#1#2{% + \begingroup + \c@pgf@counta=\csname pgfpPRP@#2@bigbuf@c\endcsname\relax + \advance\c@pgf@counta by1 + \xdef\pgf@glob@TMPa{\the\c@pgf@counta}% + \endgroup + \expandafter\let\csname pgfpPRP@#2@bigbuf@c\endcsname=\pgf@glob@TMPa + % + \ifnum\csname pgfpPRP@#2@bigbuf@c\endcsname<30 + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@bigbuf\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2@smallbuf\endcsname}% + \t@pgf@tokc={#1}% + \expandafter\edef\csname pgfpPRP@#2@bigbuf\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}% + \expandafter\let\csname pgfpPRP@#2@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#2@smallbuf@c\endcsname{0}% + \else% + \pgfprependlist@flushbuffers{#2}% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#2\endcsname}% + \t@pgf@tokb={#1}% + \expandafter\edef\csname pgfpPRP@#2\endcsname{\the\t@pgf@tokb\the\t@pgf@toka}% + \fi% +}% +\def\pgfprependlist@flushbuffers#1{% + \t@pgf@toka=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1\endcsname}% + \t@pgf@tokb=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@bigbuf\endcsname}% + \t@pgf@tokc=\expandafter\expandafter\expandafter{\csname pgfpPRP@#1@smallbuf\endcsname}% + \expandafter\edef\csname pgfpPRP@#1\endcsname{\the\t@pgf@tokc\the\t@pgf@tokb\the\t@pgf@toka}% + \expandafter\let\csname pgfpPRP@#1@smallbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@smallbuf@c\endcsname{0}% + \expandafter\let\csname pgfpPRP@#1@bigbuf\endcsname=\pgfutil@empty + \expandafter\def\csname pgfpPRP@#1@bigbuf@c\endcsname{0}% +}% +\def\pgfprependlistlet#1=#2{% + \pgfprependlist@flushbuffers{#2}% + \expandafter\let\expandafter#1\csname pgfpPRP@#2\endcsname +}% diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex index 7b3c34a0510..cdf0cfe821d 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-common.tex @@ -27,17 +27,40 @@ \catcode`\@=11\relax +% Which format is loaded? +\newif\ifpgfutil@format@is@latex +\newif\ifpgfutil@format@is@plain +\newif\ifpgfutil@format@is@context + + % Simple stuff -\long\def\pgfutil@ifundefined#1{% +% \pgfutil@ifundefined{} +% {}{} +% +% This will let #1 to \relax if it undefined. +% +% This macro is expandable. +\def\pgfutil@ifundefined#1{% \expandafter\ifx\csname#1\endcsname\relax \expandafter\pgfutil@firstoftwo \else \expandafter\pgfutil@secondoftwo \fi} -\def\pgfutil@firstofone#1{#1} -\def\pgfutil@firstoftwo#1#2{#1} -\def\pgfutil@secondoftwo#1#2{#2} + +% A variant of \pgfutil@ifundefined which will NOT let #1 to \relax it +% is undefined. However, this macro is not expandable. +\def\pgfutil@IfUndefined#1{% + \begingroup\expandafter\expandafter\expandafter\endgroup + \expandafter\ifx\csname#1\endcsname\relax + \expandafter\pgfutil@firstoftwo + \else + \expandafter\pgfutil@secondoftwo + \fi +} +\long\def\pgfutil@firstofone#1{#1} +\long\def\pgfutil@firstoftwo#1#2{#1} +\long\def\pgfutil@secondoftwo#1#2{#2} \def\pgfutil@empty{} \def\pgfutil@gobble@until@relax#1\relax{} \def\pgfutil@gobble#1{} @@ -51,6 +74,7 @@ \xdef#1{\the\pgfutil@toks@}% \endgroup} \newif\ifpgfutil@tempswa +\newif\ifpgfutil@tempswb % pgfutil@ifnextchar @@ -111,12 +135,13 @@ \expandafter\pgfutil@fornoop \else #4\relax\expandafter\pgfutil@iforloop\fi#2\@@#3{#4}} \def\pgfutil@tfor#1:={\pgfutil@tf@r#1 } -\long\def\pgfutil@tf@r#1#2\do#3{\def\pgfutil@fortmp{#2}\ifx\pgfutil@fortmp\space\else +\long\def\pgfutil@tf@r#1#2\do#3{\def\pgfutil@fortmp{#2}\ifx\pgfutil@fortmp\pgfutil@space\else \pgfutil@tforloop#2\pgfutil@nil\pgfutil@nil\@@#1{#3}\fi} \long\def\pgfutil@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\pgfutil@nnil \expandafter\pgfutil@fornoop \else #4\relax\expandafter\pgfutil@tforloop\fi#2\@@#3{#4}} +\def\pgfutil@space{ } % pgfutil@IfFileExists @@ -170,6 +195,19 @@ \let\pgfutil@insertatbegincurrentpage=\relax +% Ragged left and ragged right + +\def\pgfutil@raggedright{\rightskip\z@ plus2em \spaceskip.3333em \xspaceskip.5em\relax} +\def\pgfutil@raggedleft{\leftskip\z@ plus2em \rightskip\z@ \spaceskip.3333em \xspaceskip.5em\parfillskip0pt\relax} + + +% Error Messages +\def\pgfutil@packageerror#1#2#3{\errhelp{#3}\errmessage{Package #1 Error: #2}} +\def\pgfutil@packagewarning#1#2{\immediate\write17{Package #1: Warning! #2.}} +\def\pgferror#1{\pgfutil@packageerror{pgf}{#1}{}} +\def\pgfwarning#1{\pgfutil@packagewarning{pgf}{#1}} + + % Library files inclusion @@ -196,20 +234,28 @@ \def\use@@pgflibrary#1{% \edef\pgf@list{#1}% \pgfutil@for\pgf@temp:=\pgf@list\do{% - \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% - \ifx\pgf@temp\pgfutil@empty - \else - \expandafter\ifx\csname pgf@library@\pgf@temp @loaded\endcsname\relax% - \expandafter\let\csname pgf@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% - \expandafter\edef\csname pgf@library@#1@atcode\endcsname{\the\catcode`\@} - \expandafter\edef\csname pgf@library@#1@barcode\endcsname{\the\catcode`\|} - \catcode`\@=11 - \catcode`\|=12 - \input pgflibrary\pgf@temp.code.tex - \catcode`\@=\csname pgf@library@#1@atcode\endcsname - \catcode`\|=\csname pgf@library@#1@barcode\endcsname - \fi% - \fi + \expandafter\pgfkeys@spdef\expandafter\pgf@temp\expandafter{\pgf@temp}% + \ifx\pgf@temp\pgfutil@empty + \else + \expandafter\ifx\csname pgf@library@\pgf@temp @loaded\endcsname\relax% + \expandafter\let\csname pgf@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% + \expandafter\edef\csname pgf@library@#1@atcode\endcsname{\the\catcode`\@} + \expandafter\edef\csname pgf@library@#1@barcode\endcsname{\the\catcode`\|} + \expandafter\edef\csname pgf@library@#1@dollarcode\endcsname{\the\catcode`\$} + \catcode`\@=11 + \catcode`\|=12 + \catcode`\$=3 + \pgfutil@InputIfFileExists{pgflibrary\pgf@temp.code.tex}{}{% + \pgferror{I did not find the pgf library + '\pgf@temp'. I looked for the file named + pgflibrary\pgf@temp.code.tex, but could not find it in in + the current texmf trees.} + }% + \catcode`\@=\csname pgf@library@#1@atcode\endcsname + \catcode`\|=\csname pgf@library@#1@barcode\endcsname + \catcode`\$=\csname pgf@library@#1@dollarcode\endcsname + \fi% + \fi }% } @@ -240,11 +286,14 @@ \expandafter\let\csname pgf@module@\pgf@temp @loaded\endcsname=\pgfutil@empty% \expandafter\edef\csname pgf@module@#1@atcode\endcsname{\the\catcode`\@} \expandafter\edef\csname pgf@module@#1@barcode\endcsname{\the\catcode`\|} + \expandafter\edef\csname pgf@module@#1@dollarcode\endcsname{\the\catcode`\$} \catcode`\@=11 \catcode`\|=12 + \catcode`\$=3 \input pgfmodule\pgf@temp.code.tex \catcode`\@=\csname pgf@module@#1@atcode\endcsname \catcode`\|=\csname pgf@module@#1@barcode\endcsname + \catcode`\$=\csname pgf@module@#1@dollarcode\endcsname \fi% }% } @@ -258,8 +307,6 @@ % Guess the driver: % -\def\pgfutil@guessdriver{\edef\pgfsysdriver{pgfsys-\Gin@driver}} - \begingroup \catcode`\"=12 \edef\pgf@loc@TMPa{"}% @@ -461,4 +508,51 @@ \let\pgfutil@write=\write \let\pgfutil@read=\read +% curtesy for latex: +\let\pgfutil@protect\relax + + +% new tempdims: +\newdimen\pgfutil@tempdima +\newdimen\pgfutil@tempdimb + + +% luatex stuff +% We assume luatex version > 0.39: +% - \directlua will work +% - \directlua is the only luatex primitive that we can assume +% accessible without being prefixed by the format via +% tex.enableprimitives. +% Ideas taken from the ifluatex package (Heiko Oberdiek) +\let\pgfutil@ifluatex\iffalse +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname directlua\endcsname\relax +\else + \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname + \csname iftrue\endcsname +\fi + +\pgfutil@ifluatex + \let\pgfutil@directlua\directlua + \pgfutil@directlua{% + tex.enableprimitives('pgfutil@',{'luaescapestring'})} +\else + \def\pgfutil@directlua#1{} + \def\pgfutil@luaescapestring#1{} +\fi +% End of luatex stuff + +% Advances a number stored in a macro and writes the result back into +% the macro. +% #1 is a macro containing a number. +\def\pgfutil@advancestringcounter#1{% + \begingroup + \c@pgf@counta=#1\relax + \advance\c@pgf@counta by1 + \edef#1{\the\c@pgf@counta}% + \pgfmath@smuggleone#1% + \endgroup +}% +\input pgfutil-common-lists.tex + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def index 202778f5802..22c2a291417 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-context.def @@ -1,4 +1,4 @@ -% Copyright 2006, 2011 by Till Tantau +% Copyright 2006 by Till Tantau % % This file may be distributed and/or modified % @@ -8,6 +8,7 @@ % See the file doc/generic/pgf/licenses/LICENSE for more details. +\pgfutil@format@is@contexttrue % The aux files, needed for reading back coordinates @@ -16,6 +17,7 @@ \csname newwrite\endcsname\pgfutil@auxout \csname openout\endcsname\pgfutil@auxout\jobname.pgf } +\def\pgfutil@writetoaux#1{\write\pgfutil@auxout{#1}} % XColor-like support for ConTeXt @@ -138,23 +140,30 @@ \def\pgfutil@emu@select#1#2#3#4#5{#5} - +% The cmyk part is from Joseph Wright. +% See tex.stackexchange.com/questions/27952/cmyk-context-colors-in-tikz \def\pgfutil@registercolor#1{% \edef\pgf@temp{\PDFcolor{#1}}% - \edef\pgf@marshal{\noexpand\pgfutil@in@{ g}{\pgf@temp}}% - \pgf@marshal% - \ifpgfutil@in@% - \expandafter\pgfutil@context@parse@gray\pgf@temp\pgf@stop{#1}% - \else% - \edef\pgf@marshal{\noexpand\pgfutil@in@{ rg}{\pgf@temp}}% - \pgf@marshal% - \ifpgfutil@in@% - \expandafter\pgfutil@context@parse@rgb\pgf@temp\pgf@stop{#1}% - \else% - \PackageError{pgf}{Color #1 has an unsupported color model.}{}% - \pgfutil@definecolor{#1}{gray}{0} - \fi% - \fi% + \edef\pgf@marshal{\noexpand\pgfutil@in@{rg}{\pgf@temp}}% + \pgf@marshal + \ifpgfutil@in@ + \expandafter\pgfutil@context@parse@rgb\pgf@temp\pgf@stop{#1}% + \else + \edef\pgf@marshal{\noexpand\pgfutil@in@{g}{\pgf@temp}}% + \pgf@marshal + \ifpgfutil@in@ + \expandafter\pgfutil@context@parse@gray\pgf@temp\pgf@stop{#1}% + \else + \edef\pgf@marshal{\noexpand\pgfutil@in@{k}{\pgf@temp}}% + \pgf@marshal + \ifpgfutil@in@ + \expandafter\pgfutil@context@parse@cmyk\pgf@temp\pgf@stop{#1}% + \else + \pgferror{Color #1 has an unsupported color model.}% + \pgfutil@definecolor{#1}{gray}{0}% + \fi + \fi + \fi } \def\pgfutil@context@parse@gray#1 g#2\pgf@stop#3{% @@ -165,6 +174,15 @@ \pgfutil@definecolor{#5}{rgb}{#1,#2,#3} } +\def\pgfutil@context@parse@cmyk#1 #2 #3 #4k#5\pgf@stop #6{% + \pgfutil@definecolor{#6}{cmyk}{#1,#2,#3,#4}% +} + +\def\pgfutil@emu@cmyk#1#2,#3,#4,#5\@nil{% + \expandafter\def\csname\string\color@#1\endcsname + {\xcolor@{}{}{cmyk}{#2,#3,#4,#5}}% +} + % Make this command available in general: \let\colorlet=\pgfutil@colorlet @@ -253,12 +271,18 @@ \newbox\pgfutil@tempboxa -\newdimen\pgfutil@tempdima -\newdimen\pgfutil@tempdimb - \newbox \pgfutil@voidb@x \newtoks \pgfutil@toks@ +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempcnta\pgfutil@tempcnta +\let\pgfmath@tempcntb\pgfutil@tempcntb + +% From LaTeX +\newskip\pgfutil@flushglue +\pgfutil@flushglue=0pt plus 1fil + % Module stuff \def\pgfutil@usemodule#1{\usemodule[#1]} @@ -332,9 +356,9 @@ % The following is still messy and needs to be cleanup up (everything % prefixed by pgfutil@): -\def\PackageInfo#1#2{} -\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% -\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% +%\def\PackageInfo#1#2{} +%\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% +%\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% \long\def\AtBeginDocument#1{#1}% \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def index f9681aa4a56..c990a3730a4 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-latex.def @@ -10,12 +10,21 @@ \catcode`\@=11\relax +\pgfutil@format@is@latextrue + \let\pgfutil@auxout=\@auxout +\def\pgfutil@writetoaux#1{\if@filesw\write\pgfutil@auxout{#1}\fi} + \let\pgfutil@tempcnta=\@tempcnta \let\pgfutil@tempcntb=\@tempcntb \let\pgfutil@voidb@x=\voidb@x \let\pgfutil@toks@=\toks@ +\let\pgfutil@packageerror=\PackageError +\let\pgfutil@packagewarning=\PackageWarning + +\def\pgfutil@protect{\protect} + \def\pgfutil@definecolor{\definecolor} \def\pgfutil@color{\color} @@ -38,6 +47,11 @@ \pgf@next{#2}{#3}% } +\let\pgfutil@raggedleft\raggedleft +\let\pgfutil@raggedright\raggedright + +\let\pgfutil@flushglue=\@flushglue + \def\pgfutil@font@tiny{\tiny} \def\pgfutil@font@scriptsize{\scriptsize} \def\pgfutil@font@footnotesize{\footnotesize} @@ -59,13 +73,30 @@ \let\pgfutil@tempboxa=\@tempboxa -\let\pgfutil@tempdima=\@tempdima -\let\pgfutil@tempdimb=\@tempdimb +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempcnta\pgfutil@tempcnta +\let\pgfmath@tempcntb\pgfutil@tempcntb -\AtEndDocument{\the\pgfutil@everybye} + +\AtBeginDocument{\AtEndDocument{\par\vfil\penalty-10000\relax\the\pgfutil@everybye}} \def\pgfutil@insertatbegincurrentpagefrombox#1{% - \global\setbox\pgfutil@abb\hbox{\unhbox\pgfutil@abb#1}% + \edef\pgf@temp{\the\wd\pgfutil@abb}% + \global\setbox\pgfutil@abb\hbox{% + \unhbox\pgfutil@abb + % + % the order in which \pgfutil@insertatbegincurrentpagefrombox + % matters unless we make the following -shift! + % To see this, consider writing two such statements. The second + % one will (naturally) be placed more to the right, although there + % is no apparent reason why it should. + % + % CF observed problems when placing patterns in XObjects without + % this skip (dvipdfmx driver for pgfplots shader=interp) + \hskip-\pgf@temp\relax + #1% + }% } \newbox\pgfutil@abb% \def\pgfutil@insertatbegincurrentpage#1{% @@ -82,14 +113,14 @@ % Add at begin page stuff \setbox\@cclv=\vbox{% \setbox\z@=\hbox{\pgfutil@abe\unhbox\pgfutil@abb\pgfutil@abc\global\let\pgfutil@abc\pgfutil@empty}% - \wd\z@=\z@ - \ht\z@=\z@ - \dp\z@=\z@ - \box\z@ + \wd\z@=\z@% + \ht\z@=\z@% + \dp\z@=\z@% + \box\z@% % if TeX changes into vertical mode, it inserts \parskip and % \lineskip. Disable it here: - \nointerlineskip - \ifvbox\@cclv \unvbox\@cclv \else\hsize=\wd\@cclv \unhbox\@cclv \fi% + \nointerlineskip% + \ifvbox\@cclv \unvbox\@cclv \else\hsize=\wd\@cclv \noindent\unhbox\@cclv \fi% %\box\@cclv % using \box instead of \unhbox or \unvbox % has the advantage that glue settings won't be @@ -98,4 +129,30 @@ }% } +% Preview hack: preview.sty hacks into \shipout (which is ok), but +% does not honour everyshi.sty (which is not ok). This causes everyshi +% material to get lost. + +\AtBeginDocument{ + \@ifpackageloaded{preview}{% + % Ok, package loaded. Swap definitions of everyshi.sty's shipout + % and preview.sty's shipout: + \let\pgf@temp\pr@shipout% This is the original shipout + \let\pr@shipout\@EveryShipout@Shipout% This is what preview.sty should call + \let\@EveryShipout@Org@Shipout\pgf@temp% Everyshi should now use the original one + }{}% +} + + +% Guess the driver: + +\def\pgfutil@guessdriver{ + \ifx\HCode\@undefined% + \edef\pgfsysdriver{pgfsys-\Gin@driver}% should be right + \else% + \def\pgfsysdriver{pgfsys-tex4ht.def}% should be right + \fi% +} + + \endinput diff --git a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def index c09cf21fe0f..31d0d21d10c 100644 --- a/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def +++ b/Master/texmf-dist/tex/generic/pgf/utilities/pgfutil-plain.def @@ -9,6 +9,7 @@ +\pgfutil@format@is@plaintrue % The aux files, needed for reading back coordinates @@ -17,7 +18,7 @@ \csname newwrite\endcsname\pgfutil@auxout \csname openout\endcsname\pgfutil@auxout\jobname.pgf } - +\def\pgfutil@writetoaux#1{\write\pgfutil@auxout{#1}} % XColor-like support for plain TeX @@ -147,7 +148,7 @@ \def\pgfutil@minipage[#1]#2{% \hbox to#2\bgroup% \hsize=#2\relax% - \vbox\bgroup\leavevmode% + \vbox\bgroup\noindent% } \def\pgfutil@endminipage{\egroup\egroup} @@ -159,14 +160,18 @@ \ifx\pdfoutput\relax\alloc@0\count\countdef\insc@unt\pdfoutput\fi \def\pgfutil@guessdriver{ - \ifcase\pdfoutput% - \ifx\XeTeXversion\@undefined - \def\pgfsysdriver{pgfsys-dvips.def}% hopefully - \else - \def\pgfsysdriver{pgfsys-xetex.def}% should be right - \fi + \ifx\HCode\@undefined% + \ifcase\pdfoutput% + \ifx\XeTeXversion\@undefined + \def\pgfsysdriver{pgfsys-dvips.def}% hopefully + \else + \def\pgfsysdriver{pgfsys-xetex.def}% should be right + \fi + \else% + \def\pgfsysdriver{pgfsys-pdftex.def}% should be right + \fi% \else% - \def\pgfsysdriver{pgfsys-pdftex.def}% should be right + \def\pgfsysdriver{pgfsys-tex4ht.def}% should be right \fi% } @@ -206,9 +211,14 @@ \newbox\pgfutil@tempboxa -\newdimen\pgfutil@tempdima -\newdimen\pgfutil@tempdimb +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempdima\pgfutil@tempdima +\let\pgfmath@tempcnta\pgfutil@tempcnta +\let\pgfmath@tempcntb\pgfutil@tempcntb +% From LaTeX +\newskip\pgfutil@flushglue +\pgfutil@flushglue=0pt plus 1fil % Module stuff @@ -228,8 +238,7 @@ -% Hack shipout. Should perhaps use atbegshi? Not in standard distribution, currently... -% Code inspired (but patched...) from everyshi.sty: +% Hack shipout. Now use atbegshi \def\pgfutil@insertatbegincurrentpagefrombox#1{% \global\setbox\pgfutil@abb\hbox{\unhbox\pgfutil@abb#1}% @@ -244,39 +253,34 @@ } \let\pgfutil@abe\pgfutil@empty% -\def\pgfutil@@EveryShipout@Shipout{% - \afterassignment\pgfutil@@EveryShipout@Test - \setbox255= % -} -\def\pgfutil@@EveryShipout@Test{% - \ifvoid\@cclv\relax - \aftergroup\pgfutil@EveryShipout@Output - \else - \pgfutil@EveryShipout@Output - \fi% -} -\def\pgfutil@EveryShipout@Output{% - \setbox255=\vbox{% - \setbox0=\hbox{\pgfutil@abe\unhbox\pgfutil@abb\pgfutil@abc\global\let\pgfutil@abc\pgfutil@empty}% - \wd0=0pt% - \ht0=0pt% - \dp0=0pt% - \box0% - \unvbox255% - }% - \pgfutil@@EveryShipout@Org@Shipout\box\@cclv% -} -\let\pgfutil@@EveryShipout@Org@Shipout\shipout -\let\shipout\pgfutil@@EveryShipout@Shipout - - +% Code by Heiko Oberdiek on ctt +\input atbegshi.sty\relax +\AtBeginShipout{% + \setbox\AtBeginShipoutBox=\vbox{% + \setbox0=\hbox{% + \begingroup + \pgfutil@abe + \unhbox\pgfutil@abb + \pgfutil@abc + \global\let\pgfutil@abc\pgfutil@empty + \endgroup + }% + \wd0=0pt\relax + \ht0=0pt\relax + \dp0=0pt\relax + \box0 % + \nointerlineskip + \box\AtBeginShipoutBox + }% +}% +% End of HO code % The following is still messy and needs to be cleanup up (everything % prefixed by pgfutil@): -\def\PackageInfo#1#2{} -\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% -\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% +%\def\PackageInfo#1#2{} +%\def\PackageWarning#1#2{\immediate\write17{Package #1: Warning! #2.}}% +%\def\PackageError#1#2#3{\immediate\write17{Package #1: Error! #2.}}% \long\def\AtBeginDocument#1{#1}% \endinput diff --git a/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty b/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty index ad5c9b2ad4f..22eb6a92941 100644 --- a/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty +++ b/Master/texmf-dist/tex/latex/pgf/basiclayer/pgf.sty @@ -10,7 +10,7 @@ \RequirePackage{pgfrcs} -\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/latex/pgf/basiclayer/pgf.sty,v 1.12 2008/01/15 17:17:22 tantau Exp $ +\ProvidesPackageRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/latex/pgf/basiclayer/pgf.sty,v 1.14 2013/12/18 15:01:45 tantau Exp $ \def\pgf@draft{} \DeclareOption{draft}{\def\pgf@draft{\pgf@draftmodetrue}} diff --git a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex index e507d30e85c..ba9ed33e243 100644 --- a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex +++ b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.pdflinks.code.tex @@ -82,6 +82,9 @@ /pdflinks/codeexample links/.is if=pgfmanualprettyenabled, /pdflinks/codeexample links/.default=true, % + % How to render a hyperlink + /pdflinks/render hyperlink/.code=#1, + % % whenever an unqualified key is found, the following key prefix % list is tried to find a match. /pdflinks/search key prefixes in/.initial={/tikz/,/pgf/}, @@ -123,6 +126,12 @@ /pdflinks/internal link prefix/.initial=pgf, } +\begingroup + \catcode`\_=12 + \gdef\pgfmanualpdf@underscore{_}% + \catcode`\ =13\relax\gdef\pgfmanualpdf@install@active@space{\def {\space}}% +\endgroup + \gdef\pgfmanualpdf@installreplacements{% \def\marg##1{{##1}}% \def\oarg##1{[##1]}% @@ -132,10 +141,15 @@ \def\\{\textbackslash}% \def\space{:}% \edef\ {\space}% + \edef\SPACE{\` \relax}% + \ifnum\the\catcode`\ =13 % + \pgfmanualpdf@install@active@space + \fi \edef\#{}% \def\printanat{@}% \def\protect{}% \def\textasciicircum{o}% + \def\_{\pgfmanualpdf@underscore}% \expandafter\edef\pgfmanual@verb@activebar{\pgfmanual@verb@bar}% }% @@ -216,7 +230,11 @@ \fi \expandafter\gdef\csname pgfd@lbl@\pgfmanualpdflabel@@\endcsname{w}% 1. remember the label AND remember that we "w"rote it into the pdf. \edef\pgfmanualpdflabel@@{\pgfkeysvalueof{/pdflinks/internal link prefix}.\pgfmanualpdflabel@@}% - \expandafter\hypertarget\expandafter{\pgfmanualpdflabel@@}{#2}% + \ifvmode% + \expandafter\hypertarget\expandafter{\pgfmanualpdflabel@@}{#2}% + \else% + {\setbox0=\hbox{\raise1em\hbox{\expandafter\hypertarget\expandafter{\pgfmanualpdflabel@@}{}}}\ht0=0pt\box0}#2% + \fi% \else #2% \fi @@ -262,7 +280,7 @@ }% \def\pgfmanualpdfref@#1#2{% \pgfkeysgetvalue{/pdflinks/internal link prefix}\pgfmanual@temp - \expandafter\hyperlink\expandafter{\pgfmanual@temp.#1}{#2}% + \expandafter\hyperlink\expandafter{\pgfmanual@temp.#1}{\pgfkeysvalueof{/pdflinks/render hyperlink/.@cmd}{#2}\pgfeov}% \ifpgfmanualshowlabels \pgfkeysvalueof{/pdflinks/show labels code/.@cmd}{#1}\pgfeov \fi diff --git a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex index 85482fedaaf..3c4f5c28fbc 100644 --- a/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex +++ b/Master/texmf-dist/tex/latex/pgf/doc/pgfmanual.prettyprinter.code.tex @@ -191,6 +191,10 @@ % #1: the coordinate system name (*without* the leading brace). % The leading brace must be re-inserted by this style. /codeexample/prettyprint/point with cs/.code 2 args={(#1:#2},% + % + % The font / color command to use for comments. Will be set at + % the beginning of a comment + /codeexample/prettyprint/comment font/.initial=,% % the same with specialised code: %/codeexample/prettyprint/point with cs//.code 2 args={(#1:#2},% % @@ -285,12 +289,12 @@ % \def\pgfmanual@pretty@installcommenthandler{% \expandafter\def\pgfmanual@pretty@activepercent{% - \begingroup + \begingroup% \pgfmanualprettycommentactivetrue \expandafter\let\pgfmanual@pretty@activenl=\pgfmanual@pretty@recoveraftercomment \expandafter\def\pgfmanual@pretty@activepercent{\%}% - %\tt - \% % + \pgfkeysvalueof{/codeexample/prettyprint/comment font}%\tt + \%% }% }% \def\pgfmanual@pretty@recoveraftercomment{% diff --git a/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex b/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex index 9fe775dc8a8..c3000401b0b 100644 --- a/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex +++ b/Master/texmf-dist/tex/latex/pgf/frontendlayer/libraries/tikzlibraryexternal.code.tex @@ -22,9 +22,19 @@ % It replaces \tikzpicture/ \endtikzpicture and \tikz and invokes \beginpgfgraphicnamed ... \endpgfgraphicnamed % commands if necessary. +% load this package in order to get \pdf@mdfivesum . +% \pdf@mdfivesum is available for pdftex and lualatex and computes the +% md5 sum. Note that pdftex has \pdfmdfivesum, but lualatex does not +% have it. +\usepackage{pdftexcmds} + % source generic implementation: \input tikzexternalshared.code.tex +\pgfutil@IfUndefined{pdf@mdfivesum}{}{% + \let\tikzexternal@mdfivesum=\pdf@mdfivesum +}% + \def\tikzexternal@TEXDIALECT@begpicture{\begin{tikzpicture}} \def\tikzexternal@TEXDIALECT@endpicture{\end{tikzpicture}}% @@ -52,6 +62,7 @@ \noexpand\endgroup \noexpand#1{\the\t@tikzexternal@tmpa}% }% + \t@tikzexternal@tmpa={}% release memory. \else \t@tikzexternal@tmpa=\expandafter{\the\t@tikzexternal@tmpa #2\end{#3}}% \def\tikzexternal@TEXDIALECT@collectpicture@next{% @@ -61,8 +72,30 @@ }% \def\tikzexternal@laTeX@collect@until@end@tikzpicturetikzpicturestring{tikzpicture}% +\def\tikzexternal@handle@landscape{% + \ltx@ifpackageloaded{pdflscape}{% + % Work around a bug in conjunction with pdflscape and + % external: without this optimize-away-instruction, the + % externalized image would be rotated - and it will be rotated + % once more again when it is included. + % + % if we "optimize it away", the landscape stuff will be + % omitted. I hope this is enough... might not be entirely + % fool-proof; perhaps we need to set it to \relax. For now, it + % will probably do the job + \tikzset{ + external/.cd, + optimize command away=\landscape, + optimize command away=\endlandscape + }% + }{% + }% +}% + \AtBeginDocument{% \pgfutil@ifundefined{tikzexternalrealjob}{% \global\let\tikzexternalrealjob=\jobname }{}% + \tikzexternal@handle@landscape }% + diff --git a/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty b/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty index b8092306e25..f079db528ea 100644 --- a/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty +++ b/Master/texmf-dist/tex/latex/pgf/math/pgfmath.sty @@ -7,6 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. +\RequirePackage{pgfrcs,pgfkeys} \input{pgfmath.code.tex} \endinput diff --git a/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty b/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty index 2e2eab766e2..6f9c2b8b932 100644 --- a/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty +++ b/Master/texmf-dist/tex/latex/pgf/systemlayer/pgfsys.sty @@ -9,6 +9,10 @@ \RequirePackage{pgfrcs} +\DeclareOption{dvisvgm}{\def\pgfsysdriver{pgfsys-dvisvgm.def}} + +\ProcessOptions + \input{pgfsys.code.tex} \input{pgfsyssoftpath.code.tex} \input{pgfsysprotocol.code.tex} diff --git a/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty b/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty index dc04e9aeea2..c0de8c134ad 100644 --- a/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty +++ b/Master/texmf-dist/tex/latex/pgf/utilities/pgffor.sty @@ -9,6 +9,7 @@ \RequirePackage{pgfrcs} \RequirePackage{pgfkeys} +\RequirePackage{pgfmath} \input{pgffor.code.tex} diff --git a/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty b/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty index 9e1ebc3035e..2144e9c7005 100644 --- a/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty +++ b/Master/texmf-dist/tex/latex/pgf/utilities/pgfpages.sty @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesPackage{pgfpages}[2004/11/05 ver 0.01] +\ProvidesPackage{pgfpages}[2011/01/05 ver 0.02] \RequirePackage{pgfcore,calc} @@ -790,10 +790,11 @@ \else% \pgflowlevel{\pgftransformyscale{\csname pgfpages@p@\the\pgf@cpn @yscale\endcsname}}% \fi% + \pgfscope% \expandafter\ifx\csname pgfpages@p@\the\pgf@cpn @rotation\endcsname\relax% - \pgfscope% \else% - \pgflowlevel{\pgftransformrotate{\csname pgfpages@p@\the\pgf@cpn @rotation\endcsname}}% + \pgflowlevel{\pgftransformrotate{\csname + pgfpages@p@\the\pgf@cpn @rotation\endcsname}}% \fi% \pgfutil@tempdima=\csname pgfpages@p@\the\pgf@cpn @width\endcsname\relax% \pgfutil@tempdimb=\csname pgfpages@p@\the\pgf@cpn @height\endcsname\relax% @@ -855,11 +856,14 @@ \@parboxrestore% \pgfpages@originalshipout% \vbox{\hbox{% - \hskip-1in% - \vbox to \pgfphysicalheight{% - \vss\box\pgfpages@shipoutbox% - \vskip1in% - }}}% + \pgfsetupphysicalpagesizes% + \hskip-1in% + \vbox to \pgfphysicalheight{% + \vss\box\pgfpages@shipoutbox% + \vskip1in% + }}% + \pgfsetupphysicalpagesizes% + }% \endgroup% } @@ -896,8 +900,13 @@ % \pgfhookintoshipout \newcommand\pgfhookintoshipout{ - \let\pgfpages@originalshipout=\shipout - \let\shipout=\pgfpages@interceptshipout + \ifx\CROP@shipout\undefined + \let\pgfpages@originalshipout=\shipout + \let\shipout=\pgfpages@interceptshipout + \else + \let\pgfpages@originalshipout=\CROP@shipout + \let\CROP@shipout=\pgfpages@interceptshipout + \fi } \def\pgfpages@interceptshipout{% @@ -1005,37 +1014,15 @@ % \pgfsetupphysicalpagesizes \newcommand\pgfsetupphysicalpagesizes{% - % The following code was send to me by Rolf Niepraschk - \ifx\Gin@driver\pgfutil@empty\else% - \filename@parse{\Gin@driver}\@tempswafalse% - \def\reserved@a{dvips}% - \ifx\filename@base\reserved@a\@tempswatrue\fi% - \def\reserved@a{dvipdfm}% - \ifx\filename@base\reserved@a\@tempswatrue\fi% - \if@tempswa% - \AtBeginDvi{% - \special{papersize=\the\pgfphysicalwidth,\the\pgfphysicalheight}}% - \fi% - \def\reserved@a{pdftex}% - \ifx\filename@base\reserved@a - \pdfpagewidth\pgfphysicalwidth\pdfpageheight\pgfphysicalheight% - \fi% - \def\reserved@a{vtex}% - \ifx\filename@base\reserved@a - \mediawidth\pgfphysicalwidth\mediaheight\pgfphysicalheight% - \fi% - \fi + \pgfsys@global@papersize{\the\pgfphysicalwidth}{\the\pgfphysicalheight}% } % % Start/End setup % -\AtBeginDocument -{ - \pgfhookintoshipout - \pgfsetupphysicalpagesizes -} +\pgfhookintoshipout + \AtEndDocument { \clearpage -- cgit v1.2.3