From e01e46b7728cbf52a79f46b873fce009a8291f12 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 5 Oct 2011 04:09:10 -0400 Subject: [PATCH] Removed the `plot' collection, in preparation for adding the new one instead. --- collects/meta/dist-specs.rkt | 3 +- collects/meta/props | 20 +- collects/mzlib/struct.rkt | 2 +- collects/plot/demos/demo-1.rkt | 724 ------- collects/plot/demos/demo-10.rkt | 25 - collects/plot/demos/demo-2.rkt | 4 - collects/plot/demos/demo-3.rkt | 4 - collects/plot/demos/demo-4.rkt | 5 - collects/plot/demos/demo-5.rkt | 7 - collects/plot/demos/demo-6.rkt | 8 - collects/plot/demos/demo-7.rkt | 8 - collects/plot/demos/demo-8.rkt | 14 - collects/plot/demos/fit-demo-1.rkt | 24 - collects/plot/demos/fit-demo-2.rkt | 79 - collects/plot/extend.rkt | 18 - collects/plot/fit-low-level.rkt | 56 - collects/plot/fit.rkt | 54 - collects/plot/fonts/plstnd5.fnt | Bin 6424 -> 0 bytes collects/plot/fonts/plxtnd5.fnt | Bin 58808 -> 0 bytes collects/plot/info.rkt | 5 - collects/plot/main.rkt | 155 -- collects/plot/math.rkt | 39 - collects/plot/plot-extend.rkt | 112 - collects/plot/plot.rkt | 78 - collects/plot/plot.scrbl | 638 ------ collects/plot/plplot.rkt | 408 ---- collects/plot/renderer-helpers.rkt | 58 - collects/plot/renderers.rkt | 180 -- collects/plot/view.rkt | 354 ---- collects/tests/plot/3d-mesh.png | Bin 53977 -> 0 bytes collects/tests/plot/contours.png | Bin 18256 -> 0 bytes collects/tests/plot/dashed-line.png | Bin 6306 -> 0 bytes collects/tests/plot/mix.png | Bin 54263 -> 0 bytes collects/tests/plot/red-identity.png | Bin 6634 -> 0 bytes collects/tests/plot/run-tests.rkt | 113 - collects/tests/plot/shade.png | Bin 15757 -> 0 bytes collects/tests/plot/size.png | Bin 1230 -> 0 bytes collects/tests/plot/vector-field.png | Bin 31779 -> 0 bytes src/Makefile.in | 16 +- src/configure | 19 - src/get-libs.rkt | 6 +- src/plot/Makefile.in | 67 - src/plot/build.bat | 2 - src/plot/build.rkt | 32 - src/plot/dllexport.h | 6 - src/plot/fit/fit.c | 752 ------- src/plot/fit/fit.h | 62 - src/plot/fit/matrix.c | 315 --- src/plot/fit/matrix.h | 75 - src/plot/plplot/dc_drv.c | 266 --- src/plot/plplot/disptab.h | 92 - src/plot/plplot/drivers.h | 81 - src/plot/plplot/metadefs.h | 72 - src/plot/plplot/nan.h | 33 - src/plot/plplot/pdf.h | 107 - src/plot/plplot/pdfutils.c | 917 --------- src/plot/plplot/plConfig.h | 9 - src/plot/plplot/plDevs.h | 2 - src/plot/plplot/plargs.c | 2213 -------------------- src/plot/plplot/plbox.c | 1352 ------------ src/plot/plplot/plbuf.c | 724 ------- src/plot/plplot/plcdemos.h | 36 - src/plot/plplot/plcont.c | 1296 ------------ src/plot/plplot/plcore.c | 2833 -------------------------- src/plot/plplot/plcore.h | 253 --- src/plot/plplot/plctrl.c | 1745 ---------------- src/plot/plplot/plcvt.c | 205 -- src/plot/plplot/pldebug.h | 97 - src/plot/plplot/pldtik.c | 209 -- src/plot/plplot/plevent.h | 205 -- src/plot/plplot/plfill.c | 341 ---- src/plot/plplot/plfreetype.h | 126 -- src/plot/plplot/plgridd.c | 843 -------- src/plot/plplot/plhist.c | 180 -- src/plot/plplot/plimage.c | 235 --- src/plot/plplot/plline.c | 927 --------- src/plot/plplot/plmap.c | 312 --- src/plot/plplot/plmeta.c | 707 ------- src/plot/plplot/plot3d.c | 2087 ------------------- src/plot/plplot/plpage.c | 282 --- src/plot/plplot/plplot.h | 1774 ---------------- src/plot/plplot/plplotP.h | 872 -------- src/plot/plplot/plsdef.c | 335 --- src/plot/plplot/plshade.c | 1115 ---------- src/plot/plplot/plstripc.c | 318 --- src/plot/plplot/plstrm.h | 681 ------- src/plot/plplot/plsym.c | 1084 ---------- src/plot/plplot/pltick.c | 139 -- src/plot/plplot/plvpor.c | 444 ---- src/plot/plplot/plwind.c | 178 -- src/plot/plplot/plxwd.h | 108 - src/racket/configure.ac | 11 - 92 files changed, 6 insertions(+), 30387 deletions(-) delete mode 100644 collects/plot/demos/demo-1.rkt delete mode 100644 collects/plot/demos/demo-10.rkt delete mode 100644 collects/plot/demos/demo-2.rkt delete mode 100644 collects/plot/demos/demo-3.rkt delete mode 100644 collects/plot/demos/demo-4.rkt delete mode 100644 collects/plot/demos/demo-5.rkt delete mode 100644 collects/plot/demos/demo-6.rkt delete mode 100644 collects/plot/demos/demo-7.rkt delete mode 100644 collects/plot/demos/demo-8.rkt delete mode 100644 collects/plot/demos/fit-demo-1.rkt delete mode 100644 collects/plot/demos/fit-demo-2.rkt delete mode 100644 collects/plot/extend.rkt delete mode 100644 collects/plot/fit-low-level.rkt delete mode 100644 collects/plot/fit.rkt delete mode 100644 collects/plot/fonts/plstnd5.fnt delete mode 100644 collects/plot/fonts/plxtnd5.fnt delete mode 100644 collects/plot/info.rkt delete mode 100644 collects/plot/main.rkt delete mode 100644 collects/plot/math.rkt delete mode 100644 collects/plot/plot-extend.rkt delete mode 100644 collects/plot/plot.rkt delete mode 100644 collects/plot/plot.scrbl delete mode 100644 collects/plot/plplot.rkt delete mode 100644 collects/plot/renderer-helpers.rkt delete mode 100644 collects/plot/renderers.rkt delete mode 100644 collects/plot/view.rkt delete mode 100644 collects/tests/plot/3d-mesh.png delete mode 100644 collects/tests/plot/contours.png delete mode 100644 collects/tests/plot/dashed-line.png delete mode 100644 collects/tests/plot/mix.png delete mode 100644 collects/tests/plot/red-identity.png delete mode 100755 collects/tests/plot/run-tests.rkt delete mode 100644 collects/tests/plot/shade.png delete mode 100644 collects/tests/plot/size.png delete mode 100644 collects/tests/plot/vector-field.png delete mode 100644 src/plot/Makefile.in delete mode 100644 src/plot/build.bat delete mode 100644 src/plot/build.rkt delete mode 100644 src/plot/dllexport.h delete mode 100644 src/plot/fit/fit.c delete mode 100644 src/plot/fit/fit.h delete mode 100644 src/plot/fit/matrix.c delete mode 100644 src/plot/fit/matrix.h delete mode 100644 src/plot/plplot/dc_drv.c delete mode 100644 src/plot/plplot/disptab.h delete mode 100644 src/plot/plplot/drivers.h delete mode 100644 src/plot/plplot/metadefs.h delete mode 100644 src/plot/plplot/nan.h delete mode 100644 src/plot/plplot/pdf.h delete mode 100644 src/plot/plplot/pdfutils.c delete mode 100644 src/plot/plplot/plConfig.h delete mode 100644 src/plot/plplot/plDevs.h delete mode 100644 src/plot/plplot/plargs.c delete mode 100644 src/plot/plplot/plbox.c delete mode 100644 src/plot/plplot/plbuf.c delete mode 100644 src/plot/plplot/plcdemos.h delete mode 100644 src/plot/plplot/plcont.c delete mode 100644 src/plot/plplot/plcore.c delete mode 100644 src/plot/plplot/plcore.h delete mode 100644 src/plot/plplot/plctrl.c delete mode 100644 src/plot/plplot/plcvt.c delete mode 100644 src/plot/plplot/pldebug.h delete mode 100644 src/plot/plplot/pldtik.c delete mode 100644 src/plot/plplot/plevent.h delete mode 100644 src/plot/plplot/plfill.c delete mode 100644 src/plot/plplot/plfreetype.h delete mode 100644 src/plot/plplot/plgridd.c delete mode 100644 src/plot/plplot/plhist.c delete mode 100644 src/plot/plplot/plimage.c delete mode 100644 src/plot/plplot/plline.c delete mode 100644 src/plot/plplot/plmap.c delete mode 100644 src/plot/plplot/plmeta.c delete mode 100644 src/plot/plplot/plot3d.c delete mode 100644 src/plot/plplot/plpage.c delete mode 100644 src/plot/plplot/plplot.h delete mode 100644 src/plot/plplot/plplotP.h delete mode 100644 src/plot/plplot/plsdef.c delete mode 100644 src/plot/plplot/plshade.c delete mode 100644 src/plot/plplot/plstripc.c delete mode 100644 src/plot/plplot/plstrm.h delete mode 100644 src/plot/plplot/plsym.c delete mode 100644 src/plot/plplot/pltick.c delete mode 100644 src/plot/plplot/plvpor.c delete mode 100644 src/plot/plplot/plwind.c delete mode 100644 src/plot/plplot/plxwd.h diff --git a/collects/meta/dist-specs.rkt b/collects/meta/dist-specs.rkt index 7f717ca421..286d4dba28 100644 --- a/collects/meta/dist-specs.rkt +++ b/collects/meta/dist-specs.rkt @@ -648,8 +648,7 @@ mz-extras :+= (- (package: "swindle") (cond (not dr) => (srcfile: "tool.rkt" "swindle*.png"))) ;; -------------------- plot -plt-extras :+= (package: "plot" #:src? #t) - (lib: "lib{plplot|fit}*") +plt-extras :+= (package: "plot") ;; -------------------- mzcom plt-extras :+= (- (package: "mzcom" #:src? #t) diff --git a/collects/meta/props b/collects/meta/props index 57c1bfbda6..4688dd43ea 100755 --- a/collects/meta/props +++ b/collects/meta/props @@ -1151,24 +1151,7 @@ path/s is either such a string or a list of them. "collects/plai" responsible (jay) "collects/plai/private/gc-gui.rkt" drdr:command-line (gracket "-t" *) "collects/planet" responsible (robby) -"collects/plot" responsible (eli) -"collects/plot/demos/demo-1.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-10.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-2.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-3.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-4.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-5.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-6.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-7.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/demo-8.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/fit-demo-1.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/demos/fit-demo-2.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/extend.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/main.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/plot-extend.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/plot.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/renderers.rkt" drdr:command-line (gracket-text "-t" *) -"collects/plot/view.rkt" drdr:command-line (gracket-text "-t" *) +"collects/plot" responsible (ntoronto) "collects/preprocessor" responsible (eli) "collects/profile" responsible (eli) "collects/r5rs" responsible (mflatt) @@ -1574,7 +1557,6 @@ path/s is either such a string or a list of them. "collects/tests/planet/test-docs-complete.rkt" drdr:command-line (raco "make" *) "collects/tests/planet/thread-safe-resolver.rkt" drdr:command-line (raco "make" *) drdr:timeout 1000 "collects/tests/planet/version.rkt" drdr:command-line (raco "make" *) -"collects/tests/plot/run-tests.rkt" drdr:command-line (gracket-text "-t" *) "collects/tests/r6rs" responsible (mflatt) "collects/tests/racket" responsible (mflatt) "collects/tests/racket/all.rktl" drdr:command-line #f diff --git a/collects/mzlib/struct.rkt b/collects/mzlib/struct.rkt index eb54208080..9e3e79bfbe 100644 --- a/collects/mzlib/struct.rkt +++ b/collects/mzlib/struct.rkt @@ -150,7 +150,7 @@ "expected a parenthesized sequence of property--value pairings after fields" stx)])) - ;; Finally, parse optional inspector expr, again exploting + ;; Finally, parse optional inspector expr, again exploiting ;; `parse-define-struct'. (define (parse-at-inspector id sup-id fields props rest) (let-values ([(_ __ ___ inspector-stx) diff --git a/collects/plot/demos/demo-1.rkt b/collects/plot/demos/demo-1.rkt deleted file mode 100644 index 0319f552af..0000000000 --- a/collects/plot/demos/demo-1.rkt +++ /dev/null @@ -1,724 +0,0 @@ -#reader(lib"read.ss""wxme")WXME0108 ## -#| - This file uses the GRacket editor format. - Open this file in DrRacket, or DrScheme version 4 or later - to read it. - - http://racket-lang.org/ -|# - 45 7 #"wxtext\0" -3 1 6 #"wxtab\0" -1 1 8 #"wxmedia\0" -4 1 8 #"wximage\0" -2 0 34 #"(lib \"syntax-browser.ss\" \"mrlib\")\0" -1 0 16 #"drscheme:number\0" -3 0 44 #"(lib \"number-snip.ss\" \"drscheme\" \"private\")\0" -1 0 36 #"(lib \"comment-snip.ss\" \"framework\")\0" -1 0 43 #"(lib \"collapsed-snipclass.ss\" \"framework\")\0" -0 0 19 #"drscheme:sexp-snip\0" -0 0 33 #"(lib \"bullet-snip.ss\" \"browser\")\0" -0 0 29 #"drscheme:bindings-snipclass%\0" -1 0 36 #"(lib \"cache-image-snip.ss\" \"mrlib\")\0" -1 0 25 #"(lib \"matrix.ss\" \"htdp\")\0" -1 0 22 #"drscheme:lambda-snip%\0" -1 0 8 #"gb:core\0" -5 0 10 #"gb:canvas\0" -5 0 17 #"gb:editor-canvas\0" -5 0 10 #"gb:slider\0" -5 0 9 #"gb:gauge\0" -5 0 11 #"gb:listbox\0" -5 0 12 #"gb:radiobox\0" -5 0 10 #"gb:choice\0" -5 0 8 #"gb:text\0" -5 0 11 #"gb:message\0" -5 0 10 #"gb:button\0" -5 0 12 #"gb:checkbox\0" -5 0 18 #"gb:vertical-panel\0" -5 0 9 #"gb:panel\0" -5 0 20 #"gb:horizontal-panel\0" -5 0 33 #"(lib \"readable.ss\" \"guibuilder\")\0" -1 0 56 -( - #"(lib \"hrule-snip.ss\" \"macro-debugger\" \"syntax-browse" - #"r\")\0" -) 1 0 18 #"java-comment-box%\0" -1 0 23 #"java-interactions-box%\0" -1 0 45 #"(lib \"image-snipr.ss\" \"slideshow\" \"private\")\0" -1 0 26 #"drscheme:pict-value-snip%\0" -0 0 38 #"(lib \"pict-snipclass.ss\" \"slideshow\")\0" -2 0 55 -( - #"(lib \"vertical-separator-snip.ss\" \"stepper\" \"private" - #"\")\0" -) 1 0 18 #"drscheme:xml-snip\0" -1 0 31 #"(lib \"xml-snipclass.ss\" \"xml\")\0" -1 0 21 #"drscheme:scheme-snip\0" -2 0 34 #"(lib \"scheme-snipclass.ss\" \"xml\")\0" -1 0 10 #"text-box%\0" -1 0 32 #"(lib \"text-snipclass.ss\" \"xml\")\0" -1 0 15 #"test-case-box%\0" -2 0 1 6 #"wxloc\0" -00000000000 1 77 0 1 #"\0" -0 75 1 #"\0" -0 11 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 0 9 -#"Standard\0" -0 75 11 #" Monospace\0" -0 14 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 2 24 -#"framework:default-color\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 150 0 150 0 0 0 -1 -1 2 15 -#"text:ports out\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 150 0 150 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 93 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 15 -#"text:ports err\0" -0 -1 1 #"\0" -1 0 -1 -1 93 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 175 0 0 0 -1 -1 2 17 -#"text:ports value\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 175 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 27 -#"Matching Parenthesis Style\0" -0 -1 1 #"\0" -1 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 37 -#"framework:syntax-color:scheme:symbol\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 38 -#"framework:syntax-color:scheme:keyword\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 194 116 31 0 0 0 -1 -1 2 -38 #"framework:syntax-color:scheme:comment\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 194 116 31 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 41 128 38 0 0 0 -1 -1 2 37 -#"framework:syntax-color:scheme:string\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 41 128 38 0 0 0 -1 -1 2 39 -#"framework:syntax-color:scheme:constant\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 41 128 38 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 132 60 36 0 0 0 -1 -1 2 42 -#"framework:syntax-color:scheme:parenthesis\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 132 60 36 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 36 -#"framework:syntax-color:scheme:error\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 36 -#"framework:syntax-color:scheme:other\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 81 112 203 0 0 0 -1 -1 2 -38 #"drscheme:check-syntax:lexically-bound\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 81 112 203 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 68 0 203 0 0 0 -1 -1 2 31 -#"drscheme:check-syntax:imported\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 68 0 203 0 0 0 -1 -1 2 35 -#"profj:syntax-colors:scheme:keyword\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 139 0 139 0 0 0 -1 -1 2 37 -#"profj:syntax-colors:scheme:prim-type\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 139 0 139 0 0 0 -1 -1 2 38 -#"profj:syntax-colors:scheme:identifier\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 38 38 128 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 34 -#"profj:syntax-colors:scheme:string\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 35 -#"profj:syntax-colors:scheme:literal\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 34 139 34 0 0 0 -1 -1 2 35 -#"profj:syntax-colors:scheme:comment\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 194 116 31 0 0 0 -1 -1 2 -33 #"profj:syntax-colors:scheme:error\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 35 -#"profj:syntax-colors:scheme:default\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 37 -#"profj:syntax-colors:scheme:uncovered\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 -1 -1 2 35 -#"profj:syntax-colors:scheme:covered\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 139 0 139 0 0 0 -1 -1 4 1 -#"\0" -0 70 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 4 4 -#"XML\0" -0 70 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 8 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 8 24 -#"drscheme:text:ports err\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 4 1 -#"\0" -0 71 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 4 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 255 0 0 0 -1 -1 4 1 -#"\0" -0 71 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 255 0 0 0 -1 -1 4 1 -#"\0" -0 71 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 100 0 0 0 0 -1 -1 0 1 -#"\0" -0 75 11 #" Monospace\0" -0 11 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 0 1 -#"\0" -0 75 1 #"\0" -0 12 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 0 1 -#"\0" -0 75 11 #" Monospace\0" -0 15 90 -1 90 -1 3 -1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 2 -14 #"Html Standard\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 0 1 -#"\0" -0 75 1 #"\0" -0 10 90 -1 90 -1 3 -1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 0 1 -#"\0" -0 75 12 #"Courier New\0" -0 10 90 -1 90 -1 2 -1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 40 25 15 0 0 0 -1 -1 2 30 -#"drscheme:check-syntax:keyword\0" -0 -1 1 #"\0" -1 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 40 25 15 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 248 20 64 0 0 0 -1 -1 2 39 -#"drscheme:check-syntax:unbound-variable\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 248 20 64 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 36 36 140 0 0 0 -1 -1 2 37 -#"drscheme:check-syntax:bound-variable\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 36 36 140 0 0 0 -1 -1 2 32 -#"drscheme:check-syntax:primitive\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 36 36 140 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 51 135 39 0 0 0 -1 -1 2 31 -#"drscheme:check-syntax:constant\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 51 135 39 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 165 0 0 0 0 -1 -1 2 32 -#"drscheme:check-syntax:tail-call\0" -0 -1 1 #"\0" -1 0 92 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 165 0 0 0 0 -1 -1 2 27 -#"drscheme:check-syntax:base\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 132 60 36 0 0 0 -1 -1 2 1 -#"\0" -0 70 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 71 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1 1 1 80 80 248 0 0 0 -1 -1 2 1 -#"\0" -0 71 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 1 0 0 0 0 0 0 0 0 1 1 1 80 80 248 0 0 0 -1 -1 2 1 -#"\0" -0 71 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 0 100 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 94 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 255 0 0 0 0 0 -1 -1 2 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 200 0 0 0 0 0 -1 -1 0 1 -#"\0" -0 -1 1 #"\0" -1 0 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1 1 1 200 0 0 0 0 0 -1 -1 -00000000002 0 00000000000 3 00000000000 125 0 26 3 12 #"#lang scheme" -0 0 4 29 1 #"\n" -0 0 22 3 1 #"(" -0 0 14 3 7 #"require" -0 0 4 3 1 #" " -0 0 14 3 4 #"plot" -0 0 22 3 1 #")" -0 0 4 29 1 #"\n" -0 0 4 29 1 #"\n" -0 0 22 3 1 #"(" -0 0 14 3 4 #"plot" -0 0 4 3 1 #" " -0 0 4 29 1 #"\n" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 6 #"points" -0 0 4 3 1 #" " -0 0 4 29 1 #"\n" -0 0 4 3 2 #" " -0 0 22 3 1 #"(" -0 0 14 3 3 #"map" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 15 3 6 #"lambda" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 1 #"x" -0 0 22 3 1 #")" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 6 #"vector" -0 0 4 3 1 #" " -0 0 14 3 1 #"x" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 6 #"random" -0 0 4 3 1 #" " -0 0 14 3 1 #"x" -0 0 22 3 3 #")))" -0 0 4 3 1 #" " -0 0 17 3 25 #"; a random list of points" -0 0 4 29 1 #"\n" -0 0 4 3 7 #" " -0 0 22 3 1 #"(" -0 0 14 3 10 #"build-list" -0 0 4 3 1 #" " -0 0 20 3 2 #"30" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 15 3 6 #"lambda" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 1 #"x" -0 0 22 3 1 #")" -0 0 4 3 1 #" " -0 0 22 3 1 #"(" -0 0 14 3 4 #"add1" -0 0 4 3 1 #" " -0 0 14 3 1 #"x" -0 0 22 3 5 #")))))" -0 0 4 29 1 #"\n" -0 0 4 3 1 #" " -0 0 22 3 1 #"#" -0 0 22 3 6 #":x-max" -0 0 4 3 1 #" " -0 0 20 3 2 #"30" -0 0 4 3 1 #" " -0 0 22 3 1 #"#" -0 0 22 3 6 #":y-max" -0 0 4 3 1 #" " -0 0 20 3 2 #"30" -0 0 22 3 1 #")" -0 0 4 29 1 #"\n" -0 0 4 29 1 #"\n" -0 0 17 3 1 #";" -0 0 17 3 1 #" " -0 0 17 3 1 #"p" -0 0 17 3 1 #"r" -0 0 17 3 1 #"o" -0 0 17 3 1 #"d" -0 0 17 3 1 #"u" -0 0 17 3 1 #"c" -0 0 17 3 1 #"e" -0 0 17 3 1 #"s" -0 0 17 3 1 #" " -0 0 17 3 1 #"s" -0 0 17 3 1 #"o" -0 0 17 3 1 #"m" -0 0 17 3 1 #"e" -0 0 17 3 1 #"t" -0 0 17 3 1 #"h" -0 0 17 3 1 #"i" -0 0 17 3 1 #"n" -0 0 17 3 1 #"g" -0 0 17 3 1 #" " -0 0 17 3 2 #"li" -0 0 17 3 1 #"k" -0 0 17 3 1 #"e" -0 0 17 3 1 #" " -0 0 17 3 1 #"t" -0 0 17 3 1 #"h" -0 0 17 3 1 #"i" -0 0 17 3 1 #"s" -0 0 17 3 1 #" " -0 0 17 3 1 #"-" -0 0 17 3 1 #" " -0 0 17 3 1 #"t" -0 0 17 3 1 #"h" -0 0 17 3 1 #"e" -0 0 17 3 1 #" " -0 0 17 3 1 #"p" -0 0 17 3 1 #"o" -0 0 17 3 1 #"i" -0 0 17 3 1 #"n" -0 0 17 3 1 #"t" -0 0 17 3 1 #"s" -0 0 17 3 1 #" " -0 0 17 3 1 #"a" -0 0 17 3 1 #"r" -0 0 17 3 1 #"e" -0 0 17 3 1 #" " -0 0 17 3 6 #"random" -0 0 4 29 1 #"\n" -0 0 17 3 1 #";" -0 3 00000000037 4 1 #"\0" -2 -1 -1 0 0 0 00000000013 500 -( - #"\211PNG\r\n\32\n\0\0\0\rIHDR\0\0\3 \0\0\2X\b\2\0\0" - #"\0\25\24\25'\0\0\30\24IDATx\234\355\335K\223\252\320\31\206" - #"\321>)\a\374\377_\313\300A\6\246\214%\b\210/\267\375\255U\31" - #"$\236\356\210[\204\247\271\270\377\365\367\376\17\0\200\234\377" - #"\34\275\0\0\0\255\21X\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201" - #"\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\2" - #"\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26" - #"\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000" - #"\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a" - #"\2\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4" - #"\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0" - #"\2000\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X" - #"\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302" - #"\4\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t," - #"\0\2000\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23" - #"X\0\0a\2\v\0 L`\1\0\204\t,\0\200\260\333\321\v\260\267" - #"\356\326}\372\247\376\336O\374\374\350\277\2\0\f\375\323\r" - #"\177\177\177\335\255\373TW\317\307\37\245e\270\0\200Y\2kQ]" - #"\315\3760\0\300S\365k\260\276\252\253\277\277\277\376\336O\234d\4" - #"\0\370\23X\0\0q\245\3\353\333\303W\0\0K\224\273\213\360\351q\246" - #"\317M\202\0@\\\335\300z+*G\255\0\200\224\272\201\265\5\327\277" - #"\3\300\n\355\35\343\20Xa+V\221\335\16\236" -) 500 -( - #"\355y\224\256\275\27\325\336\23\355\371\\\236\350\22\317\325" - #"\336\23\355\371\\\236\350\307\347\332\347\211\366T\372\"\367O|" - #"\27\3\0\360\v\201\5\0\20V(\260\34\224\2\0\366Q(\260&N" - #"\374\r\37\377\364\303n6\4\0f\325\272\310\375\221M\257\20541" - #"\205\363\333\17\233\354\31\0X\250\342d\317\257\207\246f_\376W\337" - #"D\352\370\326\223\241\340\225\365\201W\326\a\3364\271J\324:\202" - #"\365\360\325\273\330\336[\16\0l\255\3205X\0\0\373\20X\0\0a\2" - #"\v\0 L`\1\233s-#\257\254\17T \260\0\0\302\4\26\0@\230\300" - #"\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201\5\0" - #"\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 " - #"L`\1\0\204\335\216^\200\326t\267\356\355\221\376\336\37\262${" - #"\32\276\352\341\203\25\306\1\200Y\243\273\214\366\b\254\260" - #"\232\0311|\325\335\255\2539\24\0L\e\335e\34\262$\233r\212\20\0" - #" L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26\0@\230" - #"\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201\5" - #"\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\2\v" - #"\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26\0@" - #"\230\300\2\0\b\23X\0\0a\267\243\27\2405\335\255{{\244\277\367" - #"\207,\311\236\206\257z\370`\205q\0`\326\350.\243=\2+\254fF\f_uw" - #"\353j\16\5\0\323Fw\31\207,\311\246\234\"\4\0\b\23X\0\0a" - #"\2\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4" - #"\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0" - #"\2000\201" -) 500 -( - #"\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\2" - #"\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26" - #"\0@\330\355\350\5hMw\353\336\36\351\357\375!K\262\247\341\253" - #"\36>Xa\34\0\2305\272\313h\217\300\n\253\231\21\303W\335\335" - #"\272\232C\1\300\264\321]\306!K\262)\247\b\1\0\302\4" - #"\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0" - #"\2000\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X" - #"\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302" - #"\4\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t," - #"\0\2000\201\5\0\20v;z\1Z\323\335\272\267G\372{\177\310\222\354" - #"i\370\252\207\17V\30\a\0f\215\3562\332#\260\302jf\304\360Uw\267" - #"\256\346P\0000mt\227q\310\222l\312)B\0\2000\201\5\0\20&\260\0\0" - #"\302\4\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204" - #"\t,\0\2000\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0" - #"\b\23X\0\0a\2\v\0 L`\1\0\204\335\216^\200ct\267\356\371" - #"\337\373{\277\344'\247\177\f\0\340\251b`u\267\356\265\226\336\376" - #"\347\247\237|\224\226\314\2\0f\225;E8\314\251\376\336\277\36\320" - #"\372\364\223\375\275\377\364\223\0\0\257j\5\326\247\203U\303rZ" - #"\376\223\0\0oj\5\26\0\300\16j\5\326\222k\255\206\377\23\0" - #"\340+\265\2\v\0`\a\2\313\361*\0 \254z`\251+\0 \256\342\367`" - #"=mQW\263\367\30\266\321sKn\245\234\376\2316\306\1\200Y5\357\276" - #"\257\eX\e\35\273*\322\r\263/\323\241A\0\36\226\3542" -) 500 -( - #"\366Y\222=\25=E8\275\373\367eW\0\300/*\6\226\203+\0\300\246\312" - #"\235\"\\XW\217\203X\303\237\24g\0\227\360z\"\302v\373[F" - #"\357w\265\2\353\253\255\3425X\0@\334\272/6j\265\275\34" - #"\301\2\0\bs\4+l\266\304\3338\367\274\360[\304&\376\265\215" - #"q\0\340\351\323\251\300\307\203\317\177j\365\220\325\e\201\25V" - #"\244\eV\177\317\5\0m\30\375\336\242\351\257l\370\373\374\255" - #"\r[,\341\261\234\"\34Q\363r<\0 E`\1\0k\254\230h\274\316" - #"!\f\2015n\342D\2623_\0\260\304\350\236\264Hc\271\6\353\243" - #"\267\263\313\346L\205\306|\332\364\357\277$E|\332\247^z\314\255E" - #"\317Z\32N\366\3747yIV\363{U\2015\345\265\262\e^\t\240\240OG" - #"\243\35\245\336\310\304\300^w\314\255E\17\353f\31\37\376Vc" - #"\376\225Z\t" -) 500 -( - #"\266V\355C5\301Ppf\323\353\247\2657nvH\2578\346\326\242\240&\207" - #"\3135X@-\263\233\362\"\27\210\354f\335|\300'g-b\226\300\2\nY" - #"\370\207\262\275#\23\254E,!\260\0\330\212\371\200)K`\1\325" - #"\331\257\357\254\273u\355\215y{\257\210\37\t,\240\264\267Y\322" - #"\330MKcn-bH`\1\245=N`\265w\a\323\371\2654\346\326\"\206\4" - #"\26P\235\375\342vF\257\254\352\357\375\350t\277\227~#.\275\360lA`" - #"\1\0\204\t,\240\220\205\267\252]\375h\312\251\254\230\17" - #"\370\344\254E,!\260\200Z\246\367\216\217\e\334\354\27\367t" - #"\305k\303\255E\3142\27!P\316\304\364\264v\212[\3704\257\353" - #"\245\307\374\227\265\310\24\321\25\b,\240\242u\323\323\262\332s" - #"x[\32\363uk\221)\242\213\20X@]\366g\373ko\314\277zE\23\25" - #"\3658$\326\336\370\224\345\32,\0\330\203)\242K\21X\0\2609G\247" - #"\252\21X\0\260-\223^\27$\260\0\340\0MNz\315\223\300\2\200" - #"\303h\254V\271\2130lt\326\255C\226dO\243\e\210\267\a+\214\3" - #"\300\267\nn\e\2134\345\277\202o\355v\\\303\370d(\0^-\334*" - #"\326\334x6\371\252\235\"\4\0\b\23X\0\260\271\366&\275f\232" - #"\300\2\200=\370\n\206R\\\344\16\0\37\257\274\316\36R\232" - #"\230\17\307\341\253\306\b,\0\252\233\210\233x\367|:\216\245\256" - #"\32#\260\0(m:\241\266\230\203YKU\340\32,\0\352Z\22O\256\235b\5" - #"\201\5\0\20&\260\0(\312\34\314lG`\1\300\377\231\203\231\b" - #"\201\5\0\377\363L+\215\305\217\4\26\0\374\317\363\214\241\e" - #"\375\370\221\300\2\240\250\321+\253\372{?\254+\337\2\312\267" - #"\4\26\0@\230\300\2\240.s0\263\21\201\5\0\20f\252\34\340" -) 500 -( - #"t^\217(T>r`\34\3661=\31\216\303W\254#\260\200\23y$\305\353" - #"\376l\370H\5\306ag\23'\n\2159\353\b,\340,F\17\25<\36)\225" - #"\27\306\341\20F\225,\327`\1\2470}\"\346q\347|\205\357~4\16" - #"\320\6\201\5\34o\341e.\315\267\205q\200f\b,\0\2000\201\5" - #"\234\224\2034\17\306\1\256H`\1g\364\250\nma\34\340\242\334E" - #"\0306:\255\325!K\262\247\321\255\377\333\203\25\306\1\200YE" - #"\376`\20Xa53\302\304\250\304Y\177\36\214\3\355\31\335e\34\262" - #"$\233r\212\20\0 L`\1\307[\370\275\3\315\37\0315\16\320" - #"\f\201\5\234\302l[\24\251\n\343\0mp\r\26\\[K\363" - #"\1O\314\271[\252*\214\3\243\3349t-\2\v\256\352\323|\300" - #"\177W\336\362\16\333\242\346\354{\306\201W\243\357\276U\342\344" - #"\4\26\\\322\304|\300\177\27\337\362\276\235#\273\350\253\370" - #"\235q\340\341\323aK\363\177\237\234\300\202\353\231=O\364\334\362" - #"^t\263{\321\305\2163\0164\377ao\230\213\334\1\0\302\4\26" - #"\\\314\362?U\27\336\363\17\234\223\17\373\245\t,hAw\353l^" - #"\241\2\37\366\253\20Xpy\266\266P\204\17\373\205\b,\0\2000w" - #"\21\302\305\f\277!\351\323U\32n,\202K\363a\2774G\260\0\0\302" - #"\4\26\0@\230\300\202\353YrK\266S\6\320\0\37\366\353r\r\26" - #"\234Hjj\24\267\32A\21>\354\247%\260\340\24>\315\334\374)\263" - #"\236\177\32766\3313\360f\364\303\376g\26\302\323\23Xp\260O[" - #"\311\331\231\\_\177\340\365\21\2401\303\17\373\237\317\373\351" - #"\t,8\322\3573\271\332\310B\21>\354\327\342\"w\0\2000\201\5" - #"\2071\223+@\253\4\26\234\213\231\\\1\32 \260\340\2144\26" - #"\300\245\t,\0\2000w" -) 500 -( - #"\21\206\r\17\232\300\202q\263\263\245" - #"j\254S\361^\300(\37\215\243\270\310\35F\230E\30\200_\b,\0" - #"\2000\201\5\357\314\"\f\300\217\\\203\5\363L\225\n\300W" - #"\34\301\2\0\b\23X0\317\201+\0\276\"\260\340\335\350\225U" - #"\375\2757\2475\0\v\t,\0\2000\201\5#\314\"\234\345^K^Y" - #"\37\250@`\301\32\366\20\0L\3605\rSF/\3049dI\32\366\251T\246" - #"\207z\364\267f\337\235\257~\353\227Y\204\327-\336\231\375\37665\363" - #"U\27\355\275\271\353\30\a\230&\260>\32=\1\344\254P\326\304x" - #"\256\370\247\351wg\305o\255\233Ex\335\342\235\331\357o\323\247\377~" - #"9\355\275\271\353\30\a\230\345\24\341\270O\233\t\337\334\35" - #"\264d6\345\257~k\342\335Y\367[\317\37x\375\317\304O\376\370D" - #"\347\264\347\333trM\276\250\25\214\3,!\260\216\267\333\366" - #"\350T\e\276u\263)\17\177kxxi\3702g\237k\341%\355\323?\260\347" - #"\23\245D.\344_\3626\315\376J\312v\243\367\366\242F\257\37\270\334" - #"\213Z\361D\a\276\271\353\234j\364P\201\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000" - #"\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a" - #"\2\v\0 L`\1\0\204\t,\0\2000\201\5\0\20v;z\1Z\323\335" - #"\272\267G\372{\177\310\222\354i\370\252\207\17V\30\a\0f\215\356" - #"2\332#\260\302jf\304\360Uw\267\256\346P\0000mt\227q\310\222l\312)B\0" - #"\2000\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X" - #"\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302" - #"\4\26\0@\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t," - #"\0\2000\201\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23" - #"X\0\0a\2\v\0 L`\1\0\204\335\216^\200\326t\267\356\355\221" - #"\376\336\37\262${\32\276\352\341\203\25\306\1\200Y\243\273\214" - #"\366\b\254\260\232\0311|\325\335\255\2539\24\0L\e\335e\34\262" - #"$\233r\212\20\0 L`\1\233k\362\317SV\263>P" -) 500 -( - #"\201\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t\254\343\355" - #"v\275g\223\27\226\2667z{\276M\355\255\22\336\246K<\321\236\332" - #"\e\275\366\236\250U\2\v\0 L`\1\0\204\t,\0\2000\201\5\0" - #"\20&\260\0\0\302\376\231\2217\310=\27\0\260B{5\"\260\0\0\302" - #"\234\"\4\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201" - #"\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\267" - #"\243\27\200\326<'d4\vSY\335\255\233~\367_g\355\264\236\264\352mn" - #"\326\205\253\204\365\241I\23\23\365\216\276\343m\254\17\2\213" - #"\244\327=\353\343\23r\351\217\a\337Z2\337\371[~YO\2324\214" - #"\354O\331\375\266\2X\37\232\364\351\255\237}\374\322\353\203S" - #"\204\304\274}Z\372{\337\337\373%{\\\332\360X\1f\17T\274\375" - #"\200\365\244\210\321wy\270\316X\37\212ki?\"\260\310\370\364\267" - #"\310u?\e|e\366\264 uX\31\2305\272\2224\266\37\21X@\200\35*" - #"\260P\221\4\27X\300N&\266\252\27\375\v\225Q\v\367\235\326" - #"\a\332&\260\0\200\235<\322\271\273u\3157\264\273\b\1\330\\" - #"\221\263B\314z\273\211\270\341\265\302\21,\0\266\325\366~\224\325" - #"\332>\27,\260\0\330\220\272\242&\201\5\300V\324\25e\t,`'\23" - #"\247\3\354\206\2334\375\266Z\37h\233\300\2 O$\3610q\225U\333+" - #"\211\300\"\343\323\37\243m\177~\370\326\304|)\207,\17\eY\370" - #"\236Z\37*\e\276\365\215\355G\4\0261o\237\215\307\327\234\\" - #"\361S\301\236\32\276\207\250\254o?\370o\333\215\r\226\210#\r" - #"\263\351\271w\30\256'-\355G\376]t\2719\255\347g\303\252U\326" - #"\354\6\361u\3j=i\314l!\215\276\343\266\e\315\373\352" -) 221 -( - #"S\337\306\372 \260\0\0\302\234\"\4\0\b\23X\0\0a\2\v\0 L`" - #"\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26\0@\230" - #"\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201\5" - #"\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\2\v" - #"\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26\0@" - #"\230\300\2\0\b\23X\0\0a\2\v\0 L`\1\0\204\t,\0\2000\201" - #"\5\0\20&\260\0\0\302\4\26\0@\230\300\2\0\b\23X\0\0a\2" - #"\v\0 L`\1\0\204\t,\0\2000\201\5\0\20&\260\0\0\302\4\26" - #"\0@\230\300\2\0\b\373/+T\1\37\252S\336\263\0\0\0\0IEND\256B`" - #"\202" -) 0 00000000000 diff --git a/collects/plot/demos/demo-10.rkt b/collects/plot/demos/demo-10.rkt deleted file mode 100644 index cfc52e1477..0000000000 --- a/collects/plot/demos/demo-10.rkt +++ /dev/null @@ -1,25 +0,0 @@ -#lang scheme -(require plot) - -(require mzlib/class plot/plot-extend) -; (number -> number) mumbo-jumbo -> 2d-renderer -(define-plot-type dashed-line - fun 2dview (x-min x-max) ((samples 100) (segments 20) (color 'red) (width 1)) - (let* ((dash-size (/ (- x-max x-min) segments)) - (x-lists (build-list (/ segments 2) - (lambda (index) - (x-values - (/ samples segments) - (+ x-min (* 2 index dash-size)) - (+ x-min (* (add1 ( * 2 index)) dash-size))))))) - (send* 2dview - (set-line-color color) - (set-line-width width)) - (for-each (lambda (dash) - (send 2dview plot-line - (map (lambda (x) (vector x (fun x))) dash))) - x-lists))) - ; - -(plot (dashed-line (lambda (x) x) (color 'red))) -(plot3d (surface (lambda (x y) (* (sin x) (sin y))))) diff --git a/collects/plot/demos/demo-2.rkt b/collects/plot/demos/demo-2.rkt deleted file mode 100644 index 8fb82521d9..0000000000 --- a/collects/plot/demos/demo-2.rkt +++ /dev/null @@ -1,4 +0,0 @@ -#lang scheme -(require plot) - -(plot (line (lambda (x) x) #:color 'red)) diff --git a/collects/plot/demos/demo-3.rkt b/collects/plot/demos/demo-3.rkt deleted file mode 100644 index 130080fe9f..0000000000 --- a/collects/plot/demos/demo-3.rkt +++ /dev/null @@ -1,4 +0,0 @@ -#lang scheme -(require plot) - -(plot (line sin #:color 'red)) diff --git a/collects/plot/demos/demo-4.rkt b/collects/plot/demos/demo-4.rkt deleted file mode 100644 index 942d036319..0000000000 --- a/collects/plot/demos/demo-4.rkt +++ /dev/null @@ -1,5 +0,0 @@ -#lang scheme -(require plot) - -(plot (vector-field (gradient (lambda (x y) (* (sin x) (cos y)))) #:samples 25) - #:title "gradient field of F(x,y) = sin(x) * sin(y)") diff --git a/collects/plot/demos/demo-5.rkt b/collects/plot/demos/demo-5.rkt deleted file mode 100644 index 973c03327e..0000000000 --- a/collects/plot/demos/demo-5.rkt +++ /dev/null @@ -1,7 +0,0 @@ -#lang scheme -(require plot) - -(define (trig x y) (* (sin x) (sin y))) -(plot (shade trig) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "shdade of F(x,y) = sin(x) * sin(y)") diff --git a/collects/plot/demos/demo-6.rkt b/collects/plot/demos/demo-6.rkt deleted file mode 100644 index 9153c84880..0000000000 --- a/collects/plot/demos/demo-6.rkt +++ /dev/null @@ -1,8 +0,0 @@ -#lang scheme -(require plot) - -(define (trig x y) (* (sin x) (sin y))) - -(plot (contour trig) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "contours of F(x,y) = sin(x) * sin(y)") diff --git a/collects/plot/demos/demo-7.rkt b/collects/plot/demos/demo-7.rkt deleted file mode 100644 index 49d1623022..0000000000 --- a/collects/plot/demos/demo-7.rkt +++ /dev/null @@ -1,8 +0,0 @@ -#lang scheme -(require plot) - -(define (trig x y) (* (sin x) (sin y))) - -(plot (vector-field (gradient trig) #:samples 25) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "gradient field of F(x,y) = sin(x) * sin(y)") diff --git a/collects/plot/demos/demo-8.rkt b/collects/plot/demos/demo-8.rkt deleted file mode 100644 index d5b01982ed..0000000000 --- a/collects/plot/demos/demo-8.rkt +++ /dev/null @@ -1,14 +0,0 @@ -#lang scheme -(require plot) - -(define (trig x y) (* (sin x) (sin y))) - -(plot (mix (shade trig) - (contour trig) - (vector-field (gradient trig) #:samples 25)) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "gradient field +shdade + contours of F(x,y) = sin(x) * sin(y)") - -(plot3d (mesh3d trig) - #:x-min -3.5 #:x-max 3.5 #:y-min -3.5 #:y-max 3.5 #:z-min -1.0 #:z-max 1.5 - #:bgcolor '(0 0 0) #:fgcolor '(255 0 0)) diff --git a/collects/plot/demos/fit-demo-1.rkt b/collects/plot/demos/fit-demo-1.rkt deleted file mode 100644 index 7462fe27f0..0000000000 --- a/collects/plot/demos/fit-demo-1.rkt +++ /dev/null @@ -1,24 +0,0 @@ -#lang scheme -(require plot) - -(define x-vals (build-list 15 (lambda (x) x) )) -(define errors (build-list 15 (lambda (x) 1))) - -(define (fun x) - (* 3 (exp (* x -1 1.32)))) -(define z-vals (map fun x-vals)) - -(define (gues-fun x a b) - (* a (exp (* x -1 b)))) - -(define params - (fit gues-fun - '((a 1) (b 1)) - (map vector x-vals z-vals errors))) - -(plot (mix - (points (map vector x-vals z-vals)) - (line (lambda (x) - (apply gues-fun x (fit-result-final-params params))))) - #:x-min -1 #:x-max 20 - #:y-min -1 #:y-max 10) diff --git a/collects/plot/demos/fit-demo-2.rkt b/collects/plot/demos/fit-demo-2.rkt deleted file mode 100644 index f09802ce1c..0000000000 --- a/collects/plot/demos/fit-demo-2.rkt +++ /dev/null @@ -1,79 +0,0 @@ -#lang scheme - -;; This is data from the Cavendish experiment -(define raw-data - '((0.0 -14.7 3.6) - (1.0 8.6 3.6) - (2.1 28.8 3.0) - (3.1 46.7 3.4) - (4.2 47.4 3.5) - (5.2 36.5 3.4) - (6.2 37.0 10.3) - (7.2 5.1 3.4) - (8.2 -11.2 3.4) - (9.1 -22.4 3.5) - (10.0 -35.5 3.6) - (11.0 -33.6 3.9) - (12.0 -21.1 3.9) - (12.9 -15.0 4.2) - (13.8 -1.6 2.7) - (14.9 19.5 3.2) - (15.9 27.5 2.8) - (17.0 32.6 3.5) - (17.9 27.5 2.7) - (18.9 20.2 3.3) - (20.0 13.8 3.4) - (21.0 -1.3 4.2) - (22.0 -24.5 6.7) - (23.0 -25.0 3.3) - (24.0 -25.0 3.1) - (25.0 -20.2 3.6) - (26.0 -9.9 3.2) - (27.0 5.8 3.2) - (28.0 14.7 3.0) - (29.0 21.8 3.5) - (30.0 29.8 2.7) - (31.0 21.4 4.1) - (32.0 24.6 2.7) - (32.9 25.8 12.0) - (33.8 0.6 2.9) - (34.7 -16.6 3.2) - (35.7 -24.0 3.7) - (36.6 -24.6 3.8) - (37.7 -19.8 3.5))) - -; first column is time data, second is result, third is error. to parse them out... -(require mzlib/math) - -(define times - (map car raw-data)) -(define vals - (map cadr raw-data)) -(define errors - (map caddr raw-data)) - -(define experemental-data (map list->vector raw-data)) - -(require plot) - -(plot (mix (points experemental-data #:sym 'circle) - (error-bars experemental-data)) - #:x-min 0 #:x-max 40 - #:y-min -40 #:y-max 50 - #:width 400 #:height 300) - -(define (theta x a tau phi T theta0) - (+ theta0 - (* a (exp (/ x tau -1)) (sin (+ phi (/ (* 2 pi x) T)))))) - -(define result - (fit theta '((a 40) (tau 15) (phi -0.5) (T 15) (theta0 10)) experemental-data)) - -(plot (mix (points (map vector times vals) #:sym 'square #:color 'black) - (error-bars experemental-data) - (line (fit-result-function result) #:color 'green)) - #:x-min -5 #:x-max 40 - #:y-min -40 #:y-max 50) - -(fit-result-final-params result) -;(pretty-print result) diff --git a/collects/plot/extend.rkt b/collects/plot/extend.rkt deleted file mode 100644 index ab0c053c65..0000000000 --- a/collects/plot/extend.rkt +++ /dev/null @@ -1,18 +0,0 @@ -#lang scheme/base - -(require "plot-extend.rkt" - "renderer-helpers.rkt" - "view.rkt") - -(provide (except-out (all-from-out "plot-extend.rkt") - define-plot-type) - plot-view% - - sample-size - scale-vectors - x-values - normalize-vector - normalize-vectors - make-column - xy-list - zgrid) diff --git a/collects/plot/fit-low-level.rkt b/collects/plot/fit-low-level.rkt deleted file mode 100644 index 82415aeb12..0000000000 --- a/collects/plot/fit-low-level.rkt +++ /dev/null @@ -1,56 +0,0 @@ -(module fit-low-level racket/base - (require mzlib/foreign mzlib/runtime-path - (for-syntax racket/base)) - (unsafe!) - - (define-runtime-path libfit-path '(so "libfit")) - - (define libfit (ffi-lib libfit-path)) - - (define do-fit-int - (get-ffi-obj "do_fit" libfit - (_fun (func : (_fun _int _pointer -> _double)) - (val-num : _int = (length x-values)) - (x-values : (_list i _double*)) - (y-values : (_list i _double*)) - (z-values : (_list i _double*)) - (errors : (_list i _double*)) - (param-num : _int = (length params)) - (params : (_list i _double*)) - -> (_list o _double* param-num)))) - - (define (do-fit callback x-vals y-vals z-vals errors params) - (do-fit-int (lambda (argc argv) - (let ([args (cblock->list argv _double argc)]) - (apply callback args))) - x-vals y-vals z-vals errors params)) - - (define get-asym-error - (get-ffi-obj "get_asym_error" libfit - (_fun (len : _?) ; len is only used for list conversion - -> (_list o _double* len)))) - - (define get-asym-error-percent - (get-ffi-obj "get_asym_error_percent" libfit - (_fun (len : _?) ; len is only used for list conversion - -> (_list o _double* len)))) - - (define get-rms - (get-ffi-obj "get_rms" libfit - (_fun -> _double*))) - - (define get-varience - (get-ffi-obj "get_varience" libfit - (_fun -> _double*))) - - (define (fit-internal f-of-x-y x-vals y-vals z-vals err-vals params) - - (let* ([len (length params)] - [fit-result (do-fit f-of-x-y x-vals y-vals z-vals err-vals params)] - [asym-error (get-asym-error len)] - [asym-error-percent (get-asym-error-percent len)] - [rms (get-rms)] - [varience (get-varience)]) - (list fit-result asym-error asym-error-percent rms varience))) - - (provide fit-internal)) diff --git a/collects/plot/fit.rkt b/collects/plot/fit.rkt deleted file mode 100644 index 437c8eab22..0000000000 --- a/collects/plot/fit.rkt +++ /dev/null @@ -1,54 +0,0 @@ -(module fit mzscheme - (require plot/math) - (require plot/fit-low-level) - - ; a structure contain a the results of a curve-fit - (define-struct fit-result ( - rms - variance - names - final-params - std-error - std-error-percent - function - ) (make-inspector)) - - ; fit-int : (number* -> number) (list-of (symbol number)) (list-of (vector number [number] number number)) -> fit-result - (define (fit-int function guesses data) - (let* ((independent-vars (- (procedure-arity function) (length guesses))) - (f-of-x-y (cond - [(= 1 independent-vars) - (lambda (x y . rest) - (apply function x rest))] - [(= 2 independent-vars) - function] - [else - (error "Function provided is either not of one or two independent variables or the number of - guesses given is incorrect")])) - (x-vals (map vector-x data)) - (y-vals (if (= 1 independent-vars) - x-vals - (map vector-y data))) - (z-vals (if (= 1 independent-vars) - (map vector-y data) - (map vector-z data))) - (err-vals (if (= 1 independent-vars) - (map vector-z data) - (map (lambda (vec) (vector-ref vec 4)) data))) - (result (fit-internal f-of-x-y x-vals y-vals z-vals err-vals (map cadr guesses)))) - (if (null? result) - null - (begin - ;(display result) - (make-fit-result - (list-ref result 3) - (list-ref result 4) - (map car guesses) - (car result) - (cadr result) - (caddr result) - (lambda args (apply function(append args (car result))))))))) - - (provide fit-int - (struct fit-result (rms variance names final-params - std-error std-error-percent function)))) diff --git a/collects/plot/fonts/plstnd5.fnt b/collects/plot/fonts/plstnd5.fnt deleted file mode 100644 index 51923d998d88877ae37f0ebaa29fde4bdd0fa7d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6424 zcmb_gYmjC~S$_N8ea@NLZ+EjP^{_u}zrOJ{&{;({`#;r=3Dz~iNHQAZ@=KId+bLsZ!KIhx)Y&Msz za%QUMoW8#OzE3~z)8}v5J@mWuQTjOj27Qd~p%2sF&}Zq_={M;kc)OQ=hdx2SMZb;b zPtvF8_vrWO59kl+kLZu-FX=P%0R0u+NKpVs z^sV|%{b7Bten9`D{uli}ni*%VFh|VG&GqIj=4Nw?d7t@&`J}nee9nBq{Jr@n^Ck1| z=A=1o*6mB|hJC$#lYOhb)xO7mz}{^iun*b)v}f$n23xr2yKCHQ+|BNT?tb@W_up>Y ztrssYURu1ecysZ#;2sp zJk|CRV9V?Q~9t#K}>d;$*x-G@jF$MecPn@$WA5ve8Jj2 zubnN(wV~?E)_K#&Ci=c@`zF-9mW^&rZ=;pQXeUcvg=)7a&&Nq=p*UxrjjLS7e8f7l zc$!(K=zBzg__W(1MLSv2l^zzis*{5d3>*~AfL9 zS32)&_smT_Mtk{8XuhO{m&WFzyqtIrTwH|c)w$k{+g&zik6$isYnS6ndByWyzAS53 zn8?x0=W&IUr*hFQjHk7Uk8G8=Vin_y5r=-pySD7Ap$cVmNS0|WaF#ArB`RJr)QzYb zv6=|3RbF^%LpOw;_iE6=kP%ub%|U<{Vi4<2$R0=6x&b}5tc!h!0~=&e5mc|Nc6u6D z4|N+n_qug`87o%FQahs!*Fmh1T4)6}Ajy; z^^iD~W%g?GIjr5Y%~Thid2R?NS(XQ39bcEK9iszF5w34(WG@T;<_kR>Ze#wj|L*y*WO)y1Ww1#XP1 z7)+549o$M5lt`7X2bn&!yn1)s2~Ww=NR$ zq8n7tyU;e6pG2i9Qy`B5K|+v#t9oXpXnNmetx^{aZzT?X!hm4J`h)|k za7GELU_Oj^au=Mbs^-}|I66EYF|0bayNrF)Wn zFA-rO*_1n&3RoqfW&l%UzwL_K%6ADJ$R^xOmUz`+?_yhR8u%Cp6Nt`}X=Lm{OzrV4Gf z#;({(4=j;CbcMr+dkm5{G^#%Dq}Kb4*(LbG2MgqhN=)-AoP<_%Ijc(f^dr;$;h}W* zv8{k&0MhA6Z5uR$F_NH>J2u`Tk~U3Dz0$C^x?| zg@}pialAZBUjX_x;sI>eqnc?PB8G?5uhsZX1^&iyWPNXXvSTY1EzuI0wn*>rjtim@ zL+m`HiN`%2PA4~wG(a$UeE&-C&?^vk@L^JT`TbI!g>uAs>{%ZNq(at<0Tm3FSp0+f zVFR*bKoWww5D^idp9FqHTtk$8fM{4JrE_)P`=Fj5TY0pdh?iIIY%UI>vR)@ssy zr+Ld|M;dF;ShhSp_ldVj=2B-?Mbgj#z1x5v{Ns4lFb0=~i+xDc80jVDoDTTxLQ&vI zvMj`i0*{QLNS=B|pJY!a9fll`ZZ^Y!1kXCrBL_f$K~NzNj(q-HF@OwRc12^CYQYy_ ziHy}P10L1VHbsXcr z^ytBp`yN?4;T{$b4=3tJ<|m(c^z>t=PCa(|(I-yMAE{3aXmBUi9@%&D;G>5gJACTM z>7!2^n;)++jX3U(tsUKW`A+6)hFoW78uo=o>CTA!&S1bf} zL#>zzl>JPgt>45m#x;h|;#w$zMSuk31F-;LccBT(I8UQ!J(kfBa0@Bu#-ADpIfJC$_}jo&@+1CNk_J|F`?FVRt>KpWs(mGfXV}SKa;7kNCJpQ9*zNWc@OvGN5CFojksm&+8 zu|bpL=-mm(r=;uCjWdsFd5t?f{G}QiFs7OK7h_ro!o;`(HHmZ4kWb4_<*LMbeU&_i zi<0tL+%{!fp{`_wEKKR3c2p1p?;t91PqB@|Ro+ZrQRnOGykO`d&C_`a6U%@XkgxDb z0n8J6%wiH1>E8AQCND*yLAOQ9?O6@seAId=mdF&isNsGA&6mEYdJEgNNzzp3`^tPh z^#?^yz46I%>TBC#C@IZsvu4P5WyCe772*sZ4aeIMCx#zRnGLqrlO}20QZK|JF8juJ cby)JHs;!6EicijmFOv91N6Vy9OXR8l1JpVom;e9( diff --git a/collects/plot/fonts/plxtnd5.fnt b/collects/plot/fonts/plxtnd5.fnt deleted file mode 100644 index 88ec784ba9853d6be9aef654b7e2f2fd3fa4117a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58808 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

>KVM9vB?#AM73I?dyMQ_|5S*i*Hr?>I2RaP|j`j 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 number - ; computes the magnituded of the vector by using pythegorean theorem - (define (vector-magnitude vec) - (sqrt (foldl (lambda (item total) (+ (sqr item) total)) 0 (vector->list vec)))) - - ; shortcuts to avoid writing ugly vector-ref code - (define (vector-x vec) - (vector-ref vec 0)) - - (define (vector-y vec) - (vector-ref vec 1)) - - (define (vector-z vec) - (vector-ref vec 2)) - - ; make-vec : (number number -> number) (number number -> number) -> (vector -> vector) - (define (make-vec func1 func2) - (lambda (point) (vector (func1 (vector-x point) (vector-y point)) (func2 (vector-x point) (vector-y point))))) - - ; derivative : (number -> number) [number] -> (number -> number) - (define derivative - (opt-lambda (func [h .00000001]) - (lambda (x) (/ (- (func (+ x h)) (func x)) h)))) - - ; gradient : (number number -> number) [number] -> (vector -> vector) - (define gradient - (opt-lambda (func-3d [h .00000001]) - (lambda (point) (vector ((derivative (lambda (x) (func-3d x (vector-y point))) h) (vector-x point)) - ((derivative (lambda (y) (func-3d (vector-x point) y)) h) (vector-y point)))))) - - (provide (all-defined))) diff --git a/collects/plot/plot-extend.rkt b/collects/plot/plot-extend.rkt deleted file mode 100644 index 08bb3ef957..0000000000 --- a/collects/plot/plot-extend.rkt +++ /dev/null @@ -1,112 +0,0 @@ -(module plot-extend mzscheme - (require mzlib/class plot/view plot/renderer-helpers) - - (define-syntax (define-plot-type stx) - (define (join-identifier prefix ident) - (datum->syntax-object - ident - (string->symbol - (string-append (symbol->string prefix ) - (symbol->string (syntax-e ident)))) )) - (syntax-case stx () - [(_ name data view ((var default) ...) body) - #'(r-lambda-internal name data view ((var default) ...) () body)] - [(_ name data view (field ...) ((var default) ...) body) - (let ((accessors (map (lambda (f) (join-identifier 'get- f)) (syntax-e #'(field ...))))) - (with-syntax (((getter ...) accessors)) - #'(r-lambda-internal name data view ((var default) ...) ((field getter) ...) body)))])) - - #| - (define-syntax r-lambda-internal-test - (syntax-rules () - [(_ name data view ((var default) ...) ((value accessor) ...) body) - (define-syntax name - (lambda (stx-2) - (define (find-val sym lst) - (cond - [(null? lst) #f] - [(eq? (car (syntax-object->datum (car lst))) sym) - (cadr (syntax-object->datum (car lst)))] - [else - (find-val sym (cdr lst))])) - - ;; there is probably a better way to do this - (define (subst-names original overrides) - (map - (lambda (default-pair) - (let ((pair-id (car (syntax-object->datum default-pair)))) - (cond - [(find-val pair-id overrides) - => (lambda (new-val) - (datum->syntax-object - default-pair - (list pair-id new-val)))] - [else - default-pair]))) - original)) - - (syntax-case stx-2 () - [(_ val) - #'(let ((var default) ... - (data val)) - (lambda (view) - (let ((value (send view accessor)) ...) - body)))] - [(_ val (override-name override-value) (... ...) ) - - (let ((new-defaults (subst-names - (syntax-e #'((var default) ...)) - - (syntax-e #'((override-name override-value) (... ...)))))) - (with-syntax ((((def new-def-val) (... ...)) new-defaults)) - #'(let ((def new-def-val) (... ...) - (data val)) - (lambda (view) - (let ((value (send view accessor)) ...) - body)))))])))])) -|# - (define-syntax r-lambda-internal - (syntax-rules () - [(_ name data view ((var default) ...) ((value accessor) ...) body) - (define-syntax name - (lambda (stx-2) - (syntax-case stx-2 () - [(_ val) - #'(let ((var default) ... - (data val)) - (lambda (view) - (let ((value (send view accessor)) ...) - body)))] - [(_ val (override-name override-value) (... ...) ) - (let ((overrides - (map - (lambda (stx) - (let ((pair (syntax-e stx))) - (list - (syntax-e (car pair)) - (cadr pair)))) - (syntax-e #'((override-name override-value) (... ...)))))) - (let ((new-defaults - (map - (lambda (a-default) - (let ((def-name (syntax-e (car (syntax-e a-default))))) - (cond - [(assq def-name overrides) => - (lambda (new-val) - (datum->syntax-object - a-default ; ... - (list (car (syntax-e a-default)) - (cadr new-val))))] - [else a-default]))) - (syntax-e #'((var default) ...))))) - (with-syntax ((((var-new default-new) (... ...)) new-defaults)) - #'(let ((var-new default-new) (... ...) - (data val)) - (lambda (view) - (let ((value (send view accessor)) ...) - body))))))])))])) - (provide - define-plot-type - (all-from-except plot/view plot-view%) - (all-from plot/renderer-helpers))) - diff --git a/collects/plot/plot.rkt b/collects/plot/plot.rkt deleted file mode 100644 index 81410a9d74..0000000000 --- a/collects/plot/plot.rkt +++ /dev/null @@ -1,78 +0,0 @@ -#lang mzscheme - -(require mzlib/list mzlib/etc mzlib/class - "math.rkt" "view.rkt" "renderer-helpers.rkt" "renderers.rkt" "fit.rkt") - -;; plot : plottable (option value)* -(define-syntax plot - (syntax-rules () - [(_ ren ) - (instantiate 2d-view% () (renderer ren))] - [(_ ren (option value) ...) - (instantiate 2d-view% () (renderer ren) (option value) ...)])) - -(define-syntax plot3d - (syntax-rules () - [(_ ren ) - (instantiate 3d-view% () (renderer ren))] - [(_ ren (option value) ...) - (instantiate 3d-view% () (renderer ren) (option value) ...)])) - -;; mix-int : renderer renderer -> renderer -;; creates a renderer that will renderer both of the inputs -(define (mix-int renderer1 renderer2) - (lambda (view) - (send view reset-to-default) - (renderer1 view) - (send view reset-to-default) - (renderer2 view))) - -;; mix : renderer+ -> renderer -;; combine any number of renderers -(define (mix r1 . the-rest) - (if (empty? the-rest) - r1 - (mix-int r1 (apply mix the-rest)))) - -;; make-2d-renderer : (2d-view% -> void) -;; provides a user with the ability to create their own renderers -;; without providing the implementation -(define custom identity) - -;; -(define-syntax fit - (syntax-rules () - [(_ func ((param guess) ...) data) - (fit-int func '((param guess) ...) data)])) - -(provide - - ;; fitting - fit - (struct fit-result - (rms variance names final-params std-error std-error-percent function)) - ;; to make plots - plot - plot3d - - ;; to combine/create renderers - mix - custom - - ;; 2d-renderers - error-bars - points - line - vector-field - contour - shade - ;; 3d-rendereres - surface - mesh3d - - ;; from math-tools - derivative - gradient - make-vec - - ) diff --git a/collects/plot/plot.scrbl b/collects/plot/plot.scrbl deleted file mode 100644 index d5e4950384..0000000000 --- a/collects/plot/plot.scrbl +++ /dev/null @@ -1,638 +0,0 @@ -#lang scribble/doc -@(require scribble/manual - (for-label scheme - scheme/gui/base - plot - plot/extend)) - -@title{PLoT: Graph Plotting} - -@author["Alexander Friedman" "Jamie Raymond"] - -PLoT (a.k.a. PLTplot) provides a basic interface for producing common -types of plots such as line and vector field plots as well as an -advanced interface for producing customized plot types. Additionally, -plots and plot-items are first-class values and can be generated in -and passed to other programs. - -@table-of-contents[] - -@section{Quick Start} - -@subsection{Overview} - -PLoT (aka PLTplot) provides a basic interface for producing common -types of plots such as line and vector field plots as well as an -advanced interface for producing customized plot types. Additionally, -plots and plot-items are first-class values and can be generated in -and passed to other programs. - -@subsection{Basic Plotting} - -After loading the correct module using @racket[(require plot)] try - -@racketblock[(plot (line (lambda (x) x)))] - -Any other function using the contract @racket[(real? . -> . real?)] -can be plotted using the same form. To plot multiple items, use the -functions @racket[mix] and @racket[mix*] to combine the items to be -plotted. - -@racketblock[ - (plot (mix (line (lambda (x) (sin x))) - (line (lambda (x) (cos x))))) - ] - -The display area and appearance of the plot can be changed by adding -brackets argument/value pairs after the first argument. - -@racketblock[ - (plot (line (lambda (x) (sin x))) - #:x-min -1 #:x-max 1 #:title "Sin(x)") - ] - -The appearance of each individual plot item can be altered by adding -argument/value pairs after the data. - -@racketblock[ - (plot (line (lambda (x) x) - #:color 'green #:width 3)) - ] - -Besides plotting lines from functions in 2-D, the plotter can also -render a variety of other data in several ways: - -@itemize[ - - @item{Discrete data, such as - @racketblock[(define data (list (vector 1 1 2) - (vector 2 2 2)))] - can be interpreted in several ways: - @itemize[ - @item{As points: @racket[(plot (points _data))]} - @item{As error data: @racket[(plot (error-bars _data))]}]} - - @item{A function of two variables, such as - @racketblock[(define 3dfun (lambda (x y) (* (sin x) (sin y))))] - can be plotted on a 2d graph - @itemize[ - @item{Using contours to represent height (z) - @racketblock[(plot (contour 3dfun))]} - @item{Using color shading - @racketblock[(plot (shade 3dfun))]} - @item{Using a gradient field - @racketblock[(plot (vector-field (gradient 3dfun)))]}] - or in a 3d box - @itemize[ - @item{Displaying only the top of the surface - @racketblock[(plot3d (surface 3dfun))]}]} - - ] - -@subsection[#:tag "ex-curve-fit"]{Curve Fitting} - -The @racketmodname[plot] library uses a non-linear, least-squares fit -algorithm to fit parameterized functions to given data. - -To fit a particular function to a curve: - -@itemize[ - - @item{Set up the independent and dependent variable data. The first - item in each vector is the independent variable, the second is the - result. The last item is the weight of the error; we can leave it - as @racket[1] since all the items weigh the same. - - @racketblock[ - (define data '(#(0 3 1) - #(1 5 1) - #(2 7 1) - #(3 9 1) - #(4 11 1))) - ] - } - - @item{Set up the function to be fitted using fit. This particular - function looks like a line. The independent variables must come - before the parameters. - - @racketblock[ - (define fit-fun - (lambda (x m b) (+ b (* m x)))) - ] - } - - @item{If possible, come up with some guesses for the values of the - parameters. The guesses can be left as one, but each parameter must - be named.} - - @item{Do the fit; the details of the function are described in - @secref["curve-fit"]. - - @racketblock[ - (define fitted - (fit fit-fun - '((m 1) (b 1)) - data)) - ] - } - - @item{View the resulting parameters; for example, - - @racketblock[ - (fit-result-final-params fitted) - ] - - will produce @racketresultfont{(2.0 3.0)}. - } - - @item{For some visual feedback of the fit result, plot the function - with the new parameters. For convenience, the structure that is - returned by the fit command has already the function. - - @racketblock[ - (plot (mix (points data) - (line (fit-result-function fitted))) - #:y-max 15) - ]}] - -A more realistic example can be found in -@filepath{demos/fit-demo-2.rkt} in the @filepath{plot} collection. - -@subsection{Creating Custom Plots} - -Defining custom plots is simple: a plot-item (that is passed to plot -or mix) is just a function that acts on a view. Both the 2-D and 3-D -view snip have several drawing functions defined that the plot-item -can call in any order. The full details of the view interface can be -found in @secref["extend"]. - -For example, if we wanted to create a constructor that creates -plot-items that draw dashed lines given a @racket[(real? . -> . real?)] -function, we could do the following: - -@racketblock[ - (require plot/extend) - - (define (dashed-line fun - #:x-min [x-min -5] - #:x-max [x-max 5] - #:samples [samples 100] - #:segments [segments 20] - #:color [color 'red] - #:width [width 1]) - (let* ([dash-size (/ (- x-max x-min) segments)] - [x-lists (build-list - (/ segments 2) - (lambda (index) - (x-values - (/ samples segments) - (+ x-min (* 2 index dash-size)) - (+ x-min (* (add1 (* 2 index)) - dash-size)))))]) - (lambda (2dview) - (send 2dview set-line-color color) - (send 2dview set-line-width width) - (for-each - (lambda (dash) - (send 2dview plot-line - (map (lambda (x) (vector x (fun x))) dash))) - x-lists)))) - ] - -Plot a test case using @racket[dashed-line]: - -@racketblock[ - (plot (dashed-line (lambda (x) x) #:color 'blue)) -] - -@; ---------------------------------------- - -@section[#:tag "plot"]{Plotting} - -@defmodule[plot] - -The @racketmodname[plot] library provides the ability to make basic -plots, fit curves to data, and some useful miscellaneous functions. - -@subsection{Plotting} - -The @racket[plot] and @racket[plot3d] functions generate plots that can be -viewed in the DrRacket interactions window. - -@defproc[(plot [data ((is-a?/c 2d-view%) . -> . void?)] - [#:width width real? 400] - [#:height height real? 400] - [#:x-min x-min real? -5] - [#:x-max x-max real? 5] - [#:y-min y-min real? -5] - [#:y-max y-max real? 5] - [#:x-label x-label string? "X axis"] - [#:y-label y-label string? "Y axis"] - [#:title title string? ""] - [#:fgcolor fgcolor (list/c byte? byte? byte) '(0 0 0)] - [#:bgcolor bgcolor (list/c byte? byte? byte) '(255 255 255)] - [#:lncolor lncolor (list/c byte? byte? byte) '(255 0 0)] - [#:out-file out-file (or/c path-string? output-port? #f) #f]) - (is-a?/c image-snip%)]{ - -Plots @racket[data] in 2-D, where @racket[data] is generated by -functions like @racket[points] or @racket[lines]. - -A @racket[data] value is represented as a procedure that takes a -@racket[2d-view%] instance and adds plot information to it. - -The result is a @racket[image-snip%] for the plot. If an @racket[#:out-file] -path or port is provided, the plot is also written as a PNG image to -the given path or port.} - -@defproc[(plot3d [data ((is-a?/c 3d-view%) . -> . void?)] - [#:width width real? 400] - [#:height height real? 400] - [#:x-min x-min real? -5] - [#:x-max x-max real? 5] - [#:y-min y-min real? -5] - [#:y-max y-max real? 5] - [#:z-min z-min real? -5] - [#:z-max z-max real? 5] - [#:alt alt real? 30] - [#:az az real? 45] - [#:x-label x-label string? "X axis"] - [#:y-label y-label string? "Y axis"] - [#:z-label z-label string? "Z axis"] - [#:title title string? ""] - [#:fgcolor fgcolor (list/c byte? byte? byte) '(0 0 0)] - [#:bgcolor bgcolor (list/c byte? byte? byte) '(255 255 255)] - [#:lncolor lncolor (list/c byte? byte? byte) '(255 0 0)]) - (is-a?/c image-snip%)]{ - -Plots @racket[data] in 3-D, where @racket[data] is generated by a -function like @racket[surface]. The arguments @racket[alt] and -@racket[az] set the viewing altitude (in degrees) and the azimuth -(also in degrees), respectively. - -A 3-D @racket[data] value is represented as a procedure that takes a -@racket[3d-view%] instance and adds plot information to it.} - - -@defproc[(points [vecs (listof (vector/c real? real?))] - [#:sym sym (or/c character? integer? symbol?) 'fullsquare] - [#:color color plot-color? 'black]) - ((is-a?/c 2d-view%) . -> . void?)]{ - -Creates 2-D plot data (to be provided to @racket[plot]) given a list -of points specifying locations. The @racket[sym] argument determines -the appearance of the points. It can be a symbol, an ASCII character, -or a small integer (between -1 and 127). The following symbols are -known: @racket['pixel], @racket['dot], @racket['plus], -@racket['asterisk], @racket['circle], @racket['times], -@racket['square], @racket['triangle], @racket['oplus], @racket['odot], -@racket['diamond], @racket['5star], @racket['6star], -@racket['fullsquare], @racket['bullet], @racket['full5star], -@racket['circle1], @racket['circle2], @racket['circle3], -@racket['circle4], @racket['circle5], @racket['circle6], -@racket['circle7], @racket['circle8], @racket['leftarrow], -@racket['rightarrow], @racket['uparrow], @racket['downarrow]. } - - -@defproc[(line [f (real? . -> . (or/c real? (vector real? real?)))] - [#:samples samples exact-nonnegative-integer? 150] - [#:width width exact-positive-integer? 1] - [#:color color plot-color? 'red] - [#:mode mode (one-of/c 'standard 'parametric) 'standard] - [#:mapping mapping (or-of/c 'cartesian 'polar) 'cartesian] - [#:t-min t-min real? -5] - [#:t-max t-max real? 5]) - ((is-a?/c 2d-view%) . -> . void?)]{ - -Creates 2-D plot data to draw a line. - -The line is specified in either functional, i.e. @math{y = f(x)}, or -parametric, i.e. @math{x,y = f(t)}, mode. If the function is -parametric, the @racket[mode] argument must be set to -@racket['parametric]. The @racket[t-min] and @racket[t-max] arguments -set the parameter when in parametric mode.} - - -@defproc[(error-bars [vecs (listof (vector/c real? real? real?))] - [#:color color plot-color? 'black]) - ((is-a?/c 2d-view%) . -> . void?)]{ - -Creates 2-D plot data for error bars given a list of vectors. Each -vector specifies the center of the error bar @math{(x,y)} as the first -two elements and its magnitude as the third.} - - -@defproc[(vector-field [f ((vector real? real?) . -> . (vector real? real?))] - [#:width width exact-positive-integer? 1] - [#:color color plot-color? 'red] - [#:style style (one-of/c 'scaled 'normalized 'read) 'scaled]) - ((is-a?/c 2d-view%) . -> . void?)]{ - -Creates 2-D plot data to draw a vector-field from a vector-valued -function.} - - -@defproc[(contour [f (real? real? . -> . real?)] - [#:samples samples exact-nonnegative-integer? 50] - [#:width width exact-positive-integer? 1] - [#:color color plot-color? 'black] - [#:levels levels (or/c exact-nonnegative-integer? - (listof real?)) - 10]) - ((is-a?/c 2d-view%) . -> . void?)]{ - -Creates 2-D plot data to draw contour lines, rendering a 3-D function -a 2-D graph cotours (respectively) to represent the value of the -function at that position.} - -@defproc[(shade [f (real? real? . -> . real?)] - [#:samples samples exact-nonnegative-integer? 50] - [#:levels levels (or/c exact-nonnegative-integer? - (listof real?)) - 10]) - ((is-a?/c 2d-view%) . -> . void?)]{ - -Creates 2-D plot data to draw like @racket[contour], except using -shading instead of contour lines.} - - -@defproc[(surface [f (real? real? . -> . real?)] - [#:samples samples exact-nonnegative-integer? 50] - [#:width width exact-positive-integer? 1] - [#:color color plot-color? 'black]) - ((is-a?/c 3d-view%) . -> . void?)]{ - -Creates 3-D plot data to draw a 3-D surface in a 2-D box, showing only -the @italic{top} of the surface.} - - -@defproc[(mix [data (any/c . -> . void?)] ...+) - (any/c . -> . void?)]{ - -Creates a procedure that calls each @racket[data] on its argument in -order. Thus, this function can composes multiple plot @racket[data]s -into a single data.} - - -@defproc[(plot-color? [v any/c]) boolean?]{ - -Returns @racket[#t] if @racket[v] is one of the following symbols, -@racket[#f] otherwise: - -@racketblock[ -'white 'black 'yellow 'green 'aqua 'pink -'wheat 'grey 'blown 'blue 'violet 'cyan -'turquoise 'magenta 'salmon 'red -]} - -@; ---------------------------------------- - -@subsection[#:tag "curve-fit"]{Curve Fitting} - -PLoT uses the standard Non-Linear Least Squares fit algorithm for -curve fitting. The code that implements the algorithm is public -domain, and is used by the @tt{gnuplot} package. - -@defproc[(fit [f (real? ... . -> . real?)] - [guess-list (list/c (list symbol? real?))] - [data (or/c (list-of (vector/c real? real? real?)) - (list-of (vector/c real? real? real? real?)))]) - fit-result?]{ - -Attempts to fit a @defterm{fittable function} to the data that is -given. The @racket[guess-list] should be a set of arguments and -values. The more accurate your initial guesses are, the more likely -the fit is to succeed; if there are no good values for the guesses, -leave them as @racket[1].} - -@defstruct[fit-result ([rms real?] - [variance real?] - [names (listof symbol?)] - [final-params (listof real?)] - [std-error (listof real?)] - [std-error-percent (listof real?)] - [function (real? ... . -> . real?)])]{ - -The @racket[params] field contains an associative list of the -parameters specified in @racket[fit] and their values. Note that the -values may not be correct if the fit failed to converge. For a visual -test, use the @racket[function] field to get the function with the -parameters in place and plot it along with the original data.} - -@; ---------------------------------------- - -@subsection{Miscellaneous Functions} - -@defproc[(derivative [f (real? . -> . real?)] [h real? .000001]) - (real? . -> . real?)]{ - -Creates a function that evaluates the numeric derivative of -@racket[f]. The given @racket[h] is the divisor used in the -calculation.} - -@defproc[(gradient [f (real? real? . -> . real?)] [h real? .000001]) - ((vector/c real? real?) . -> . (vector/c real? real?))]{ - -Creates a vector-valued function that the numeric gradient of -@racket[f].} - -@defproc[(make-vec [fx (real? real? . -> . real?)] [fy (real? real? . -> . real?)]) - ((vector/c real? real?) . -> . (vector/c real? real?))]{ - -Creates a vector-values function from two parts.} - -@; ---------------------------------------- - -@section[#:tag "extend"]{Customizing Plots} - -@defmodule[plot/extend] - -The @racketmodname[plot/extend] module allows you to create your own -constructors, further customize the appearance of the plot windows, -and in general extend the package. - -@defproc[(sample-size [sample-count exact-positive-integer?] - [x-min number] - [x-max number]) - real?]{ - -Given @racket[sample-count], @racket[x-min], and @racket[x-max], returns the -size of each sample.} - - -@defproc[(scale-vectors [vecs (listof vector?)] [x-sample-size real?] [y-sample-size real?]) - (listof vector?)]{ - -Scales vectors, causing them to fit in their boxes.} - - -@defproc[(x-values [sample-count exact-positive-integer?] - [x-min number] - [x-max number]) - (listof real?)]{ - -Given @racket[samples], @racket[x-min], and @racket[x-max], returns a -list of @racket[x]s spread across the range.} - - -@defproc[(normalize-vector [vec vector?] [x-sample-size real?] [y-sample-size real?]) - vector?]{ - -Normalizes @racket[vec] based on @racket[x-sample-size] and -@racket[y-sample-size].} - - -@defproc[(normalize-vectors [vecs (listof vector?)] [x-sample-size real?] [y-sample-size real?]) - (listof vector?)]{ - -Normalizes @racket[vecs] based on @racket[x-sample-size] and -@racket[y-sample-size].} - - -@defproc[(make-column [x real?] [ys (listof real?)]) - (listof (vector/c real? real?))]{ - -Given an @racket[x] and a list of @racket[_y]s, produces a list of -points pairing the @racket[x] with each of the @racket[_y]s.} - - -@defproc[(xy-list [sample-count exact-positive-integer?] - [x-min real?] - [x-max real?] - [y-min real?] - [y-max real?]) - (listof (listof (vector/c real? real?)))]{ - -Makes a list of all the positions on the graph.} - - -@defproc[(zgrid [f (real? real? . -> . real?)] - [xs (listof real?)] - [ys (listof real?)]) - (listof (listof real?))]{ - -Given a function that consumes @racket[_x] and @racket[_y] to produce -@racket[_z], a list of @racket[_x]s, and a list of @racket[_y]s, produces a -list of @racket[_z] column values.} - -@; ---------------------------------------- - -@defclass[plot-view% image-snip% ()]{ - -@defmethod[(get-x-min) real?]{ - Returns the minimum plottable @racket[_x] coordinate.} - -@defmethod[(get-y-min) real?]{ - Returns the minimum plottable @racket[_y] coordinate.} - -@defmethod[(get-x-max) real?]{ - Returns the maximum plottable @racket[_x] coordinate.} - -@defmethod[(get-y-max) real?]{ - Returns the maximum plottable @racket[_y] coordinate.} - -@defmethod[(set-line-color [color plot-color?]) void?]{ - Sets the drawing color.} - -@defmethod[(set-line-width [width real?]) void?]{ - Sets the drawing line width.} - -} - -@; ---------------------------------------- - -@defclass[2d-view% plot-view% ()]{ - -Provides an interface to drawing 2-D plots. An instance of -@racket[2d-view%] is created by @racket[plot], and the following -methods can be used to adjust it. - -@defmethod[(set-labels [x-label string?] - [y-label string?] - [title string?]) - void?]{ - -Sets the axis labels and title.} - - -@defmethod[(plot-vector [head (vector/c real? real?)] - [tail (vector/c real? real?)]) - void?]{ - -Plots a single vector.} - - -@defmethod[(plot-vectors [vecs (listof (list/c (vector/c real? real?) - (vector/c real? real?)))]) - void?]{ - -Plots a set of vectors.} - - -@defmethod[(plot-points [points (listof (vector/c real? real?))] - [sym (or/c character? integer? symbol?)]) - void?]{ - -Plots points using a specified symbol. See @racket[points] for -possible values for @racket[sym]} - - -@defmethod[(plot-line [points (listof (vector/c real? real?))]) void?]{ - -Plots a line given a set of points.} - - -@defmethod[(plot-contours [grid (listof (listof real?))] - [xs (listof real?)] - [ys (listof real?)] - [levels (listof real?)]) void?]{ - -Plots a grid representing a 3-D function using contours to distinguish levels.} - -@defmethod[(plot-shades [grid (listof (listof real?))] - [xs (listof real?)] - [ys (listof real?)] - [levels (listof real?)]) void?]{ - -Plots a grid representing a 3-D function using shades to show levels.} - -} - -@; ---------------------------------------- - -@defclass[3d-view% plot-view% ()]{ - -Provides an interface to drawing 3-D plots. An instance of -@racket[3d-view%] is created by @racket[plot3d], and the following -methods can be used to adjust it. - - -@defmethod[(plot-surface [xs (listof real?)] - [ys (listof real?)] - [zs (listof real?)]) void?]{ - -Plots a grid representing a 3d function in a 3d box, showing only the -top of the surface.} - - -@defmethod[(plot-line [xs (listof real?)] - [ys (listof real?)] - [zs (listof real?)]) void?]{ - -Plots a line in 3-D space.} - - -@defmethod[(get-z-min) real?]{ - Returns the minimum plottable @racket[_z] coordinate.} - -@defmethod[(get-z-max) real?]{ - Returns the maximum plottable @racket[_z] coordinate.} - -@defmethod[(get-alt) real?]{ - Returns the altitude (in degrees) from which the 3-D box is viewed.} - -@defmethod[(get-az) real?]{ - Returns the azimuthal angle.} - -} diff --git a/collects/plot/plplot.rkt b/collects/plot/plplot.rkt deleted file mode 100644 index fd065f6d20..0000000000 --- a/collects/plot/plplot.rkt +++ /dev/null @@ -1,408 +0,0 @@ -#lang racket/base -(require mzlib/etc - racket/list - ffi/unsafe - racket/runtime-path - racket/class - (for-syntax racket/base)) - -(define-runtime-path plplot-path '(so "libplplot")) -(define-runtime-path font-dir "fonts") - -(define libplplot (ffi-lib plplot-path)) - -(define plplotlibdir (get-ffi-obj "plplotLibDir" libplplot _string)) - -;; set the lib dir to contain the fonts: -(let ([path font-dir]) - ;; free current pointer, if any: - (let ([p (get-ffi-obj "plplotLibDir" libplplot _pointer)]) - (when p (free p))) - ;; install new value: - (set-ffi-obj! "plplotLibDir" libplplot _bytes - ;; malloc the string, since the GC won't see the static variable: - (let* ([gced-bytes (path->bytes path)] - [len (bytes-length gced-bytes)] - [p (malloc (add1 len) 'raw)] - [malloced-bytes (make-sized-byte-string p len)]) - (bytes-copy! malloced-bytes 0 gced-bytes) - ;; set nul terminator: - (ptr-set! p _byte len 0) - malloced-bytes))) - -(define-cstruct _dc_Dev - ([user_data _pointer] - [drawLine _fpointer] - [drawLines _fpointer] - [fillPoly _fpointer] - [setWidth _fpointer] - [setColor _fpointer] - [setColorRGB _fpointer] - [startPage _fpointer] - [endPage _fpointer] - [endDoc _fpointer])) - -(define _PLINT _int) - -(define _plflt _double*) -(define _plint _int) - -;; While an array generated from a list is passed to an -;; plot library function, we might perform a GC through -;; the back-end drawing operation. So, arrays must be -;; allocated as non-moving objects -(define-fun-syntax _list/still - (lambda (stx) - (syntax-case stx (i) - [(_ i ty) #'(_list/still i ty 'atomic-interior)] - [(_ i ty mode) - #'(type: _pointer - pre: (x => (list->cblock/mode x ty mode)))]))) - -(define-fun-syntax _matrix-of - (lambda (stx) - (syntax-case stx (i) - [(_ ty) - #'(_list/still i (_list/still i ty) 'interior)]))) - -(define (list->cblock/mode l type mode) - (if (null? l) - #f ; null => NULL - (let ([cblock (malloc (length l) type mode)]) - (let loop ([l l] [i 0]) - (unless (null? l) - (ptr-set! cblock type i (car l)) - (loop (cdr l) (add1 i)))) - cblock))) - -(define-syntax define* - (syntax-rules () - [(_ (name . args) body ...) - (begin (provide name) (define (name . args) body ...))] - [(_ name expr) - (begin (provide name) (define name expr))])) - -(define* pl-setup-page - (get-ffi-obj "c_plspage" libplplot - (_fun (xp : _plflt = 0.0) - (yp : _plflt = 0.0) - (xleng : _plint) - (yleng : _plint) - (xoff : _plint = 0) - (yoff : _plint = 0) - -> _void))) - -(define* pl-set-device - (get-ffi-obj "c_plsdev" libplplot (_fun _string -> _void))) - -(define* pl-set-output-file - (get-ffi-obj "c_plsfnam" libplplot (_fun _string -> _void))) - -(define* pl-init-plot - (get-ffi-obj "c_plinit" libplplot (_fun -> _dc_Dev-pointer))) - -(define* pl-finish-plot - (get-ffi-obj "c_plend" libplplot (_fun -> _void))) - -(define* pl-set-plot-environment - (get-ffi-obj "c_plenv" libplplot - (_fun _plflt _plflt _plflt _plflt _plint _plint -> _void))) - -(define* pl-set-labels - (get-ffi-obj "c_pllab" libplplot - (_fun _string _string _string -> _void))) - -(define* pl-plot-line - (get-ffi-obj "c_plline" libplplot - (_fun _plint (x : (_list/still i _plflt)) (y : (_list/still i _plflt)) -> _void))) - -(define* pl-plot-segment - (get-ffi-obj "c_pljoin" libplplot - (_fun _plflt _plflt _plflt _plflt -> _void))) - -(define* pl-set-background-color - (get-ffi-obj "c_plscolbg" libplplot - (_fun _plint _plint _plint -> _void))) - - -(define* pl-select-colormap0-index - (get-ffi-obj "c_plcol0" libplplot - (_fun _plint -> _void))) - -(define* pl-set-colormap0-index - (get-ffi-obj "c_plscol0" libplplot - (_fun _plint _plint _plint _plint -> _void))) - -(define* pl-set-line-width - (get-ffi-obj "c_plwid" libplplot - (_fun _plint -> _void))) - -(define* pl-write-text - (get-ffi-obj "c_plptex" libplplot - (_fun _plflt _plflt _plflt _plflt _plflt _string -> _void))) - -;;(define* pl-2d-countour-plot ...) -;;(define* pl-2d-shade-plot ...) - -(define* pl-x-error-bars - (get-ffi-obj "c_plerrx" libplplot - (_fun _plint (_list/still i _plflt) - (_list/still i _plflt) - (_list/still i _plflt) -> _void))) - -(define* pl-y-error-bars - (get-ffi-obj "c_plerry" libplplot - (_fun _plint (_list/still i _plflt) - (_list/still i _plflt) - (_list/still i _plflt) -> _void))) - -(define* pl-plot-points - (get-ffi-obj "c_plpoin" libplplot - (_fun _plint (x : (_list/still i _plflt)) (y : (_list/still i _plflt)) _plint - -> _void))) - -(define* pl-fill - (get-ffi-obj "c_plfill" libplplot - (_fun (n : _plint = (length x-values)) - (x-values : (_list/still i _plflt)) - (y-values : (_list/still i _plflt)) - -> _void))) - -(define* pl-world-3d - (get-ffi-obj "c_plw3d" libplplot - (_fun - _plflt _plflt _plflt _plflt _plflt _plflt _plflt _plflt _plflt _plflt _plflt - -> - _void))) - -;; bit-masks for some of the functions.. -(define-values (DRAW_LINEX DRAW_LINEY MAG_COLOR BASE_CONT TOP_CONT SURF_CONT DRAW_SIDES DRAW_FACETED MESH) - (apply values (build-list 9 (lambda (s) (arithmetic-shift 1 s))))) - -(define DRAW_LINEXY (bitwise-ior DRAW_LINEX DRAW_LINEY)) - - -(define* pl-plot3d - (get-ffi-obj "c_plot3d" libplplot - (_fun - (x-values : (_list/still i _plflt)) - (y-values : (_list/still i _plflt)) - (z-values : (_matrix-of _plflt)) - (nx : _int = (length x-values)) - (ny : _int = (length y-values)) - (draw-opt1 : _int = DRAW_LINEXY) - (draw-opt2 : _int = 0) - -> _void))) ;; these are documented in the plplot ref manual, and will be obseleted. - -(define* pl-mesh3d - (get-ffi-obj "c_plot3d" libplplot - (_fun - (x-values : (_list/still i _plflt)) - (y-values : (_list/still i _plflt)) - (z-values : (_matrix-of _plflt)) - (nx : _int = (length x-values)) - (ny : _int = (length y-values)) - (draw-opt1 : _int = DRAW_LINEXY) - -> _void))) - -; ;; this function needs to go. -; (define* pl-plot-points -; (get-ffi-obj "c_plpoin" libplplot -; (_fun -; (nx : _int = (length x-values)) -; (x-values : (_list/still i _plflt)) -; (y-values : (_list/still i _plflt)) -; (code : _int)))) - -(define* pl-box3 - (get-ffi-obj "c_plbox3" libplplot - (_fun - (x-ops : _string) (x-title : _string) (x-spacing : _plflt) (x-ticks : _int) - (y-ops : _string) (y-title : _string) (y-spacing : _plflt) (y-ticks : _int) - (z-ops : _string) (z-title : _string) (z-spacing : _plflt) (z-ticks : _int) - -> _void))) - -(define* pl-line3 - (get-ffi-obj "c_plline3" libplplot - (_fun - (n-points : _int = (length x-values)) - (x-values : (_list/still i _plflt)) - (y-values : (_list/still i _plflt)) - (z-values : (_list/still i _plflt)) - -> _void))) - - -(define* pl-poly3 - (get-ffi-obj "c_plpoly3" libplplot - (_fun - (n-points : _int = (length x-values)) - (x-values : (_list/still i _plflt)) - (y-values : (_list/still i _plflt)) - (z-values : (_list/still i _plflt)) - (draw-mask : (_list/still i _int)) - (direction : _int) - -> _void))) - -;; need the CStruct PLcGrid ; -;; PLFLT *xg, *yg, *zg; -;; PLINT nx, ny, nz; -(define-cstruct _PLcGrid ((xg _pointer) - (yg _pointer) - (zg _pointer) - (nx _int) - (ny _int) - (nz _int))) - -(define pl-2d-contour-plot-int - (get-ffi-obj "c_plcont" libplplot - (_fun - (matrix : (_matrix-of _plflt)) - (nx : _int = (PLcGrid-nx grid)) - (ny : _int = (PLcGrid-ny grid)) - (t1 : _plint = 1) - (t2 : _int = (PLcGrid-nx grid)) - (t3 : _plint = 1) - (t4 : _int = (PLcGrid-ny grid)) - (levels : (_list/still i _plflt)) - (nlevels : _int = (length levels)) - (pltr : _fpointer = (get-ffi-obj "pltr1" libplplot _fpointer)) - (grid : _PLcGrid-pointer) - -> _void))) - -(define* (pl-2d-contour-plot z-vals x-vals y-vals levels) - (let ((grid-obj (make-PLcGrid (list->cblock x-vals _plflt) (list->cblock y-vals _plflt) #f - (length x-vals) (length y-vals) 0))) - (pl-2d-contour-plot-int z-vals levels grid-obj))) - - - -(define pl-2d-shade-plot-int - (get-ffi-obj "c_plshades" libplplot - (_fun - (matrix : (_matrix-of _plflt)) - (nx : _int = (PLcGrid-nx grid)) - (ny : _int = (PLcGrid-ny grid)) - (null-val : _pointer = #f) - (x_min : _plflt = 0) - (x_max : _plflt = 0) - (y_min : _plflt = 0) - (y_max : _plflt = 0) - (levels : (_list/still i _plflt)) - (nlevels : _int = (length levels)) - (fill_width : _int = 1) - (cont_col : _int = 1) - (cont_width : _int = 0) - (fill_fun : _fpointer = (get-ffi-obj "c_plfill" libplplot _fpointer)) - (rectan : _int = 1) - (pltr : _fpointer = (get-ffi-obj "pltr1" libplplot _fpointer)) - (grid : _PLcGrid-pointer) - -> _void))) - -(define* (pl-2d-shade-plot z-vals x-vals y-vals levels) - ;; this can prolly be inlined above.. - (let ((grid-obj (make-PLcGrid (list->cblock x-vals _plflt) (list->cblock y-vals _plflt) #f - (length x-vals) (length y-vals) 0))) - (pl-2d-shade-plot-int z-vals levels grid-obj))) - - -;; set up color map numbers -(define plscmap1n - (get-ffi-obj "c_plscmap1n" libplplot - (_fun _int -> _void))) - -;; set up the map -(define plscmap1l - (get-ffi-obj "c_plscmap1l" libplplot - (_fun - (itype : _plint) - (npts : _int = (length intencity)) - (intencity : (_list/still i _plflt)) - (coord1 : (_list/still i _plflt)) - (coord2 : (_list/still i _plflt)) - (coord3 : (_list/still i _plflt)) - (rev : _pointer = #f) - -> _void))) - -(define pl-mesh3dc-int - (get-ffi-obj "c_plmeshc" libplplot - (_fun - (x-values : (_list/still i _plflt)) - (y-values : (_list/still i _plflt)) - (z-values : (_matrix-of _plflt)) - (x-len : _int = (length x-values)) - (y-len : _int = (length y-values)) - (opts : _int) - (levels : (_list/still i _plflt)) - (n-levels : _int = (length levels)) - -> _void))) - -(define* (pl-mesh3dc x-vals y-vals z-vals contours? lines? colored? sides? levels) - (let ((opts (foldl - (lambda (mask use? current) (bitwise-ior current (if use? mask 0))) - 0 - (list DRAW_LINEXY MAG_COLOR BASE_CONT DRAW_SIDES) - (list contours? lines? colored? sides?)))) - (plscmap1n 256) - (plscmap1l 0 '(0.0 1.0) '(240 0) '(.6 .6) '(.8 .8)) - (pl-mesh3dc-int x-vals y-vals z-vals opts levels))) - -(define (dc-draw-line dest x1 y1 x2 y2) - (send (ptr-ref dest _racket) draw-line x1 y1 x2 y2)) -(define (dc-draw-multi dest xs ys n go) - (let ([xs (cast xs _pointer (_vector o _short n))] - [ys (cast ys _pointer (_vector o _short n))]) - (go (ptr-ref dest _racket) - (for/list ([x (in-vector xs)] - [y (in-vector ys)]) - (cons x y))))) -(define (dc-draw-lines dest xs ys n) - (dc-draw-multi dest xs ys n - (lambda (dc l) (send dc draw-lines l)))) -(define (dc-fill-poly dest xs ys n) - (dc-draw-multi dest xs ys n - (lambda (dc l) (send dc draw-polygon l)))) -(define (dc-set-width dest w) - (send (ptr-ref dest _racket) set-width w)) -(define (dc-set-color dest index) - (send (ptr-ref dest _racket) set-index-color index)) -(define (dc-set-color/rgb dest r g b) - (send (ptr-ref dest _racket) set-rgb-color r g b)) -(define (dc-start-page dest) - (send (ptr-ref dest _racket) start-page)) -(define (dc-end-page dest) - (send (ptr-ref dest _racket) end-page)) -(define (dc-end-doc dest) - (send (ptr-ref dest _racket) end-doc) - (free-immobile-cell dest)) - -(define draw_line (function-ptr dc-draw-line - (_fun _pointer _short _short _short _short -> _void))) -(define draw_lines (function-ptr dc-draw-lines - (_fun _pointer _pointer _pointer _PLINT -> _void))) -(define fill_poly (function-ptr dc-fill-poly - (_fun _pointer _pointer _pointer _PLINT -> _void))) -(define set_width (function-ptr dc-set-width - (_fun _pointer _int -> _void))) -(define set_color (function-ptr dc-set-color - (_fun _pointer _short -> _void))) -(define set_color_rgb (function-ptr dc-set-color/rgb - (_fun _pointer _short _short _short -> _void))) -(define start_page (function-ptr dc-start-page - (_fun _pointer -> _void))) -(define end_page (function-ptr dc-end-page - (_fun _pointer -> _void))) -(define end_doc (function-ptr dc-end-doc - (_fun _pointer -> _void))) - -(provide init-dev!) -(define (init-dev! dev obj) - (set-dc_Dev-user_data! dev (malloc-immobile-cell obj)) - (set-dc_Dev-drawLine! dev draw_line) - (set-dc_Dev-drawLines! dev draw_lines) - (set-dc_Dev-fillPoly! dev fill_poly) - (set-dc_Dev-setWidth! dev set_width) - (set-dc_Dev-setColor! dev set_color) - (set-dc_Dev-setColorRGB! dev set_color_rgb) - (set-dc_Dev-startPage! dev start_page) - (set-dc_Dev-endPage! dev end_page) - (set-dc_Dev-endDoc! dev end_doc)) diff --git a/collects/plot/renderer-helpers.rkt b/collects/plot/renderer-helpers.rkt deleted file mode 100644 index 50d8ab6d19..0000000000 --- a/collects/plot/renderer-helpers.rkt +++ /dev/null @@ -1,58 +0,0 @@ -(module renderer-helpers mzscheme - - ; Contains the helpers for the plot-renderers package - ; useful for building your own renderers - - (require mzlib/list mzlib/math plot/math) - - ; sample-size: number number number -> number - (define (sample-size samples x-min x-max) - (/ (- x-max x-min) (- samples 1))) - - ; scale-vectors : listof-posn number number -> listof-posn - ; scales vectors, causing them to fit in their boxes - (define (scale-vectors deltas x-sample-size y-sample-size) - (let* ((x-max-value (apply max (map vector-x deltas))) - (y-max-value (apply max (map vector-y deltas))) - (x-div-const (/ x-max-value x-sample-size)) - (y-div-const (/ y-max-value y-sample-size))) - (map (lambda (point) (vector (* (/ (vector-x point) x-div-const) 9/10) - (* (/ (vector-y point) y-div-const) 9/10))) deltas))) - - ; x-values : number number number -> listof-number - (define (x-values samples x-min x-max) - (let ((ss (sample-size samples x-min x-max))) - (build-list samples (lambda (x) (+ x-min (* x ss)))))) - - ; normalze-vector : posn number number -> posn - (define (normalize-vector vec x-sample-size y-sample-size) - (let* ((size (vector-magnitude vec))) - (if (zero? size) - (vector 0 0) - (vector (* (/ (vector-x vec) size) x-sample-size 9/10) - (* (/ (vector-y vec) size) y-sample-size 9/10))))) - - ; normalize-vector : listof-posn number number -> listolf-posn - (define (normalize-vectors deltas x-sample-size y-sample-size) - (map (lambda (vec) (normalize-vector vec x-sample-size y-sample-size)) deltas)) - - ; make-column : number listof-number -> listof-points - (define (make-column x-val y-values) - (map (lambda (y) (vector x-val y)) y-values)) - - ; xy-list : number number number number number -> listof-posn - ; make a list of all the positions on the graph - (define (xy-list samples x-min x-max y-min y-max) - (let* ((x-vals (x-values samples x-min x-max)) - (y-vals (x-values samples y-min y-max))) - (apply append (map (lambda (x) (make-column x y-vals)) x-vals)))) - - ; zgrid : (number number -> number) listof-number listof-number -> listof-listof number - (define (zgrid func x-vals y-vals samples) - (map (lambda (x) (map (lambda (y) (func x y)) y-vals)) x-vals)) - - (provide (all-defined)) - - (require mzlib/class mzlib/etc) - - ) diff --git a/collects/plot/renderers.rkt b/collects/plot/renderers.rkt deleted file mode 100644 index ea6ef9d62a..0000000000 --- a/collects/plot/renderers.rkt +++ /dev/null @@ -1,180 +0,0 @@ -(module renderers mzscheme - (require plot/math plot/renderer-helpers mzlib/class plot/plot-extend) - - ;line : (number -> number) [number] [symbol] [number] -> (2dplotview -> nothing) - (define-plot-type line - func 2dplotview (x-min x-max) ((samples 150) (color 'red) - (width 1) - (mode 'standard) - (mapping 'cartesian) - (t-min -5) (t-max 5)) - (let* - ((t-min (if (or (eq? mapping 'polar) (eq? mode 'parametric)) - t-min x-min)) - (t-max (if (or (eq? mapping 'polar)(eq? mode 'parametric)) - t-max x-max)) ; maybe let-values? - (points - (case mode - ((standard) (map (lambda (x) (vector x (func x))) - (x-values samples x-min x-max))) - ((parametric) (map func (x-values samples t-min t-max)))))) - (send* 2dplotview - (set-line-color color) (set-line-width width) - (plot-line - (case mapping - ((cartesian) points) - ((polar) (map - (lambda (point) ; convert to cartesian from theta, r - (vector - (* (vector-y point) (cos (vector-x point))) - (* (vector-y point) (sin (vector-x point))))) - points))))))) - - ; error-bars : (listof (vector x y err)) [symbol] -> (2dplotview -> nothing) - (define-plot-type error-bars - errs 2dplotview () ((color 'red)) - (let* ((y-list (map vector-y errs)) - (e-list (map vector-z errs)) - (y-mins (map (lambda (y e) (- y e)) y-list e-list )) - (y-maxs (map (lambda (y e) (+ y e)) y-list e-list ))) - (send 2dplotview set-line-color color) - (send 2dplotview plot-y-errors (map vector (map vector-x errs) - y-mins y-maxs)))) - - - ; field : (vector -> vector) [number] [symbol] [number] [symbol] -> (2dplotview -> nothing) - ; plots a vector field - ; styles are - ; scaled -> vector field with scaled vectors - ; normalized -> all vectors same size, indicates direction - ; real -> all vectors drawn to scale - (define-plot-type vector-field - vfun 2dplotview - (x-min x-max y-min y-max) - ([samples 20] [color 'black] [width 1] [style 'scaled]) - (let* ((points (xy-list samples x-min x-max y-min y-max)) - (results (map vfun points)) - (new-results - (case style - [(real) results] - [(scaled) (scale-vectors results - (sample-size samples x-min x-max) - (sample-size samples y-min y-max))] - [(normalized) (normalize-vectors - results - (sample-size samples x-min x-max) - (sample-size samples y-min y-max))] - [else (error (string-append "Unknown vector field style passed to field-renderer: " (symbol->string style)))]))) - (send* 2dplotview - (set-line-color color) (set-line-width width) - (plot-vectors points new-results)))) - - ; contour : (nubmer number -> number) [number] [symbol] [number] [number u listof-number] -> (2dplotview -> void) - ; renders a contour plot given function and contour levels - (define-plot-type contour - fun3d 2dplotview - (x-min x-max y-min y-max) - ((samples 50) (color 'black) (width 1) (levels 10)) - (let* ((x-vals (x-values samples x-min x-max)) - (y-vals (x-values samples y-min y-max)) - (grid (zgrid fun3d x-vals y-vals samples)) - (z-max (apply max (map (lambda (row) (apply max row)) grid))) - (z-min (apply min (map (lambda (row) (apply min row)) grid))) - (c-levels (if (list? levels) levels (x-values levels z-min z-max)))) - (send* 2dplotview - (set-line-color color) (set-line-width width) - (plot-contours grid x-vals y-vals c-levels)))) - - ; shade : (number number -> number) [number] [symbol] [number] [number / listof-number] -> (2dplotview -> nothing) - ; renders a shade plot given function and shade levels - (define-plot-type shade - fun3d 2dplotview (x-min x-max y-min y-max) - ((samples 50) (levels 10)) - (let* ((x-vals (x-values samples x-min x-max)) - (y-vals (x-values samples y-min y-max)) - (grid (zgrid fun3d x-vals y-vals samples)) - (z-max (apply max (map (lambda (row) (apply max row)) grid))) - (z-min (apply min (map (lambda (row) (apply min row)) grid))) - (c-levels (x-values levels z-min z-max))) - (send* 2dplotview - (plot-shades grid x-vals y-vals c-levels)))) - - ; points : (listof vector) [symbol] -> (2dplotview -> nothing) - ; plots a set of points using a specific character - (define-plot-type points - lop 2dplotview ((sym 'fullsquare) (color 'black)) - (send* 2dplotview - (set-line-color color) - (plot-points lop - (cond [(and (integer? sym) (<= -1 sym 127)) sym] - [(and (char? sym) - (char<=? (integer->char 32) - sym - (integer->char 127))) - (char->integer sym)] - [(assq sym point-syms) => cadr] - [else (error "Symbol not found in table!")])))) - - ; the symbol-> char table - (define point-syms - '((pixel -1) - (dot 1) - (plus 2) - (asterisk 3) - (circle 4) - (times 5) - (square 6) - (triangle 7) - (oplus 8) - (odot 9) - ;; (??? 10) - (diamond 11) - (5star 12) - ;; (square 13) - ;; (??? 14) - (6star 15) - (fullsquare 16) - (bullet 17) - (full5star 18) - ;; (square 19) - (circle1 20) - (circle2 21) - (circle3 22) - (circle4 23) - (circle5 24) - (circle6 25) - (circle7 26) - (circle8 27) - (leftarrow 28) - (rightarrow 29) - (uparrow 30) - (downarrow 31))) - - - ;; 3D PLOTTERS - ; plot a surface - (define-plot-type surface - fun3d 3dplotview (x-min x-max y-min y-max) - ((samples 50) (color 'black) (width '1)) - (let* ((x-vals (x-values samples x-min x-max)) - (y-vals (x-values samples y-min y-max)) - (grid (zgrid fun3d x-vals y-vals samples))) - (send* 3dplotview - (set-line-color color) (set-line-width width) - (plot-surface x-vals y-vals grid)))) - - (define-plot-type mesh3d - fun3d 3dplotview (x-min x-max y-min y-max z-min z-max) - ((samples 50) (width '1) (levels 10) (color #t) (lines #t) - (contours #t) (sides #f)) - (let* ((x-vals (x-values samples x-min x-max)) - (y-vals (x-values samples y-min y-max)) - (grid (zgrid fun3d x-vals y-vals samples)) - (c-levels (if (list? levels) levels (x-values levels z-min z-max)))) - (send* 3dplotview - (set-line-width width) - (plot-3dmesh x-vals y-vals grid lines color contours sides c-levels)))) - - (provide (all-defined))) - - diff --git a/collects/plot/view.rkt b/collects/plot/view.rkt deleted file mode 100644 index 8d31beea9e..0000000000 --- a/collects/plot/view.rkt +++ /dev/null @@ -1,354 +0,0 @@ -(module view mzscheme - (require plot/plplot plot/math mzlib/class mzlib/file - racket/draw racket/snip - mzlib/math) - - ;; including suggested fix from Doug Williams - - ; macro for creating a field in a class with a getter and a setter - (define-syntax (fields-with-accessors stx) - (define (join-identifier prefix ident) - (datum->syntax-object - ident - (string->symbol (string-append (symbol->string prefix )(symbol->string (syntax-e ident)))) )) - (syntax-case stx () - [(_ (field init) ... ) - (let ((accessors (map (lambda (id) (join-identifier 'get- id)) (syntax-e #'(field ...)))) - (setters (map (lambda (id) (join-identifier 'set- id)) (syntax-e #'(field ...))))) - (with-syntax (((accessor ... ) accessors) - ((setter ...) setters)) - #'(fields-with-accessors-helper (accessor setter field init) ...)))])) - - ; for accessors - (define-syntax fields-with-accessors-helper - (syntax-rules () - [(_ (accessor setter field init) ...) - (begin - (init-field (field init)) ... - (define (accessor) field) ... - (define (setter val) (set! field val)) ...) ])) - - - ; base class for a plot view - ; - (define plot-view% - (class* image-snip% () - (public - set-line-color - set-line-width - set-plot-environment - reset-to-default - get-x-min - get-x-max - get-y-min - get-y-max - - get-x-label - get-y-label - get-title - start-plot - finish-plot - - get-renderer - - get-height - get-width) - - (init-field - renderer) - - (fields-with-accessors - (height 300) - (width 400) - (out-file #f) ;; if file is not #f, keep the file - (x-min -5) - (x-max 5) - (y-min -5) - (y-max 5) - (x-label "X axis") - (y-label "Y axis") - (title "") - (device 'dc) - (fgcolor '(0 0 0)) - (bgcolor '(255 255 255)) - (lncolor '(255 0 0))) - - (define x-size 400) - (define y-size 300) - (define bitmap (make-bitmap width height)) - - (inherit - set-bitmap - load-file) - - (define (get-renderer) renderer) - - ; set the initial environment - (define (set-plot-environment x-min x-max y-min y-max just other) - (pl-set-plot-environment x-min x-max y-min y-max just other)) - - ; changes the *initial* colormap to match the colors - ; this should probably be done dynamically - (define (init-colors) - (apply pl-set-colormap0-index 0 bgcolor) ; 0 to white - (apply pl-set-colormap0-index 1 fgcolor) ; 1 to black - (apply pl-set-colormap0-index 15 lncolor)) ; 15 to red - - ; these are the colors to whitch the plot will be initialzed - (define colors '((white 0) (black 1) (yellow 2) (green 3) - (aqua 4) (pink 5) (wheat 6) (grey 7) - (brown 8) (blue 9) (violet 10) (cyan 11) - (turquoise 12) (magenta 13) (salmon 14) (red 15))) - - ; set-line-width : number -> nothing - (define (set-line-width width) (pl-set-line-width width)) - - ; reset-to-default : void - ; resets some of the state to default - (define (reset-to-default) - (init-colors) - (set-line-color 'black) - (set-line-width 0)) - - ;set-line-color : symbol -> nothing - (define (set-line-color color) - (let ((index (cond [(assq color colors ) => cadr] - [else (error (format "color ~v not found" color))]))) - (pl-select-colormap0-index index))) - - ; start the plot - ; does housekeeping/setup for plplot - (define (start-plot) - (cond - [(eq? device 'dc) - (init-colors) - (pl-setup-page width height) - (pl-set-device "dc") - (let ([dev (pl-init-plot)]) - (init-dev! dev (let ([dc (make-object bitmap-dc% bitmap)]) - (send dc set-origin 0 height) - (send dc set-scale 1 -1) - (send dc set-smoothing 'aligned) - (send dc set-background (apply make-object color% bgcolor)) - (send dc clear) - (new (class object% - (define/public (draw-line x1 y1 x2 y2) - (send dc draw-line x1 y1 x2 y2)) - (define/public (draw-lines points) - (send dc draw-lines points)) - (define/public (draw-polygon points) - (send dc draw-polygon points)) - (define/public (set-width n) - (send dc set-pen (send (send dc get-pen) get-color) n 'solid)) - (define/public (set-index-color i) - (let ([color (case i - [(0) (apply make-object color% bgcolor)] - [(1) (apply make-object color% fgcolor)] - [(15) (apply make-object color% lncolor)] - [else (make-object color% (symbol->string (car (list-ref colors i))))])]) - (send dc set-pen color (send (send dc get-pen) get-width) 'solid) - (send dc set-brush color 'solid))) - (define/public (set-rgb-color r g b) - (let ([color (make-object color% r g b)]) - (send dc set-pen color (send (send dc get-pen) get-width) 'solid) - (send dc set-brush color 'solid))) - (define/public (start-page) (void)) - (define/public (end-page) (void)) - (define/public (end-doc) - (send dc set-bitmap #f)) - (super-new)))))) - (set-line-color 'black) - (set-line-width 0)] - [else - (error "Incorrect device specified")])) - - ; finish the plot.. loads the file - (define (finish-plot) - (cond - [(eq? device 'dc) - (pl-finish-plot) - (when out-file - (send bitmap save-file out-file 'png)) - (set-bitmap bitmap)] - [else - (error "Incorrect device specified")])) - - (super-instantiate ()))) - - ;; a 2d plot view - (define 2d-view% - (class* plot-view% () - (public - set-labels - plot-y-errors - plot-vector - plot-vectors - plot-points - plot-line - plot-contours - plot-shades - fill) - - ; set-labels : string string string -> nothing - ; sets the x, y and title lables - (define (set-labels x-label y-label title) - (pl-set-labels x-label y-label title)) - - ; plot-contours: listoflistof number, listof-number, listof-number, listof-number - (define (plot-contours z x-vals y-vals levels) - (pl-2d-contour-plot z x-vals y-vals levels)) - - ; plot-shades: listoflistof number, listof-number, listof-number, listof-number - (define (plot-shades z x-vals y-vals levels) - (pl-2d-shade-plot z x-vals y-vals levels)) - - ; plot-line : (listof vector) -> void - ; plots a line with the given points - (define (plot-line points) - (pl-plot-line (length points) - (map vector-x points) - (map vector-y points))) - - ; plot-points : (listof vector) -> void - ; plots given points with a . symbol - (define (plot-points points sym) - (pl-plot-points (length points) - (map vector-x points) - (map vector-y points) - sym)) - - (define v-head-ratio 1/4) ; size of the vector head - (define rot (* 5 pi 1/6)) - - ; plot-vectors: (listof (list vector vector)) - > void - (define (plot-vectors from delta) - (for-each (lambda (f d) (send this plot-vector f d)) from delta)) - - ; plot-vector : vector vector -> nothing - (define (plot-vector from delta) - (unless (= 0 (vector-magnitude delta)) - (let* ((x (vector-x from)) (x2 (+ x (vector-x delta))) - (y (vector-y from)) (y2 (+ y (vector-y delta))) - (ang (atan (vector-y delta) (vector-x delta))) - (len (vector-magnitude delta)) - (x3 (+ x2 (* len v-head-ratio (cos (+ ang rot))))) - (x4 (+ x2 (* len v-head-ratio (cos (- ang rot))))) - (y3 (+ y2 (* len v-head-ratio (sin (+ ang rot))))) - (y4 (+ y2 (* len v-head-ratio (sin (- ang rot)))))) - (plot-line (list from - (vector x2 y2) - (vector x3 y3) - (vector x4 y4) - (vector x2 y2)))))) - - ; fill : (list-of number) (list-of number) -> void - (define (fill xs ys) - (pl-fill xs ys)) - - ; plot-y-errors (listof (vector x y-min y-max)) ->nothing - ; plots y error bars given a vector containing the x y and z (error magnitude) points - (define (plot-y-errors errlist) - (pl-y-error-bars (length errlist) (map vector-x errlist) (map vector-y errlist) (map vector-z errlist))) - - - - (inherit start-plot set-plot-environment finish-plot - get-x-min get-x-max get-y-min get-y-max get-renderer - get-x-label get-y-label get-title) - (define (plot) - (start-plot) - (set-plot-environment (get-x-min) (get-x-max) (get-y-min) (get-y-max) 0 1) - (set-labels (get-x-label) (get-y-label) (get-title)) - (with-handlers ((exn? (lambda (ex) (finish-plot) (raise ex)))) - ((get-renderer) this)) - (finish-plot) - this) - - (super-instantiate ()) - (plot))) - - ; 3d view - ; for making meshes and stuff - - (define 3d-view% - (class* plot-view% () - (public - plot-polygon - plot-line - plot-surface - plot-3dmesh - get-z-min - get-z-max - get-alt - get-az) - - - (fields-with-accessors - (z-min -5) - (z-max 5) - (alt 30) - (az 45) - (z-label "Z-Axis")) - - ; set-labels : string string string -> nothing - ; sets the x, y and title lables - (define (set-labels x-label y-label title) - (pl-set-labels x-label y-label title)) - - ; define the 3d world - (define (world3d x y z xmin xmax ymin ymax zmin zmax alt az) - (pl-world-3d x y z xmin xmax ymin ymax zmin zmax alt az)) - - ; set up the axies box - (define (box3d - xopts xlabel xticks nxsub - yopts ylabel yticks nysub - zopts zlabel zticks nzsub) - (pl-box3 xopts xlabel xticks nxsub - yopts ylabel yticks nysub - zopts zlabel zticks nzsub)) - - ; draw a simple 3d surface plot - (define (plot-surface x y z) - (pl-plot3d x y z)) - - ; plot-3dmesh - (define (plot-3dmesh x y z lines? colored? contours? sides? levels) - (pl-mesh3dc x y z lines? colored? contours? sides? levels)) - - (inherit start-plot set-plot-environment finish-plot get-x-min - get-x-max get-y-min get-y-max get-renderer get-x-label get-y-label - get-title) - - (define (plot) - (start-plot) - (set-plot-environment -1 1 -1 1 0 -2) - (world3d 1 1 1 (get-x-min) (get-x-max) (get-y-min) (get-y-max) z-min z-max alt az) - (box3d - "bnstu" (get-x-label) 0 0 - "bnstu" (get-y-label) 0 0 - "bnstu" z-label 0 0) - (set-labels "" "" (get-title)) - (with-handlers ((exn? (lambda (ex) (finish-plot) (raise ex)))) - ((get-renderer) this)) - (finish-plot) - this) - - ; plot a polygon in 3 space - (define (plot-polygon x y z draw ifc) - (pl-poly3 x y z draw ifc)) - - - ; plot a line in 3 space - ; x y and z are lists of equal length - (define (plot-line x y z) - (pl-line3 x y z)) - - - (super-instantiate ()) - (plot))) - - (provide - plot-view% - 2d-view% - 3d-view%)) diff --git a/collects/tests/plot/3d-mesh.png b/collects/tests/plot/3d-mesh.png deleted file mode 100644 index 8ae38eff293a4f3d0c57aa3ad2beee8764600b38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53977 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

5?VNH?G74 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 X^b3V0aYw-8XOQG&lF8TkKSTX;=R diff --git a/collects/tests/plot/dashed-line.png b/collects/tests/plot/dashed-line.png deleted file mode 100644 index 83d4149a9ee964b4cea7d413b81a6d649043f4df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6306 zcmc(k2Q-{pyT^whj82e3ltiLSlxWe3-WiOZNVE|d(Mu4Wm=HvC61@xw2BSw1En;+{ zA4&8UopHDGo%7wVto7Zq?pk-_bWj&QMQgr-FgxzJ`ht52`a{^;x5I(Fx`>Qc!mJssiSs5T3||9^dzZ1CgsMUwrKLl7+WV%vaGJ z!X3WtP3g($-tDdy#t^ySI!z`BM4r|JGRRgADUi1&&<$=T%pwUQmZKyj54=po2oWXa zgE-RsKVPtR+d?jvuUp81Fjm~S%+eWwC^>QEA8~hT8l*9WT?$axh%6SFSkht+z1)=| z4i!xhMP6{^a+>2Bq>=O>BPfU~X@+AE$(v&^7jRClWeCjS9v9} zn>>xsi>Sdek&-?2{u}IF?TLqhT=6ye3`=e`5+o@8(HS{T&=Bn%cN1wgs-}g zw$^g45`|@A7V5f4@t;&#h}yJYzdlFOe|XlgsNW@LP0$(Nt!9<^0@W2pnWw=`9YlQn z#dswhA-O7JuLCC$V=P(%|;Gk zJjpcG(wV2D+`+MM_1Y8@0|NCEg$& zMhwYyfR6U!w|YvsaJu3g#t?F(d4V(`+C7 zc+w!ea5cD_iaaTY+jaYU@5gg!PQFyJ=LPKespKMdDl-$g<2GddJSSUu;OA?ljf&O; z{rBJpG$wK(aj@!Z<$(nprHtS=RWQ867e8!dF^+0yi0|vhIJ>UAadUek@Q{`wj$%ei zSQt0Sf1XN7xU@(Al)K}6mA=ShB${_}5;uH9Q87=W_F8a5bZhdOoFDUDE+)aQjq*iF z4zT_lt^ct8N=ORwh%j?)AD`bok(oA4xpDU^TNBVWt5LMjm;^fH7+Ehh6>i?c78Dn6 zhc(IBj$x#wq?Q9h+tqGd3l8p=jcft(tfdWa#^G;Xr;izkrdJ`z68T@10Wir~4)9H2 zw3wdb5EBBwH12<^@w2?+EM%dyf7~F!!98->h7!`aINyJBIY zO4bAnY^9FT&4jO`DvKlt$xY~RT|~q|3*y>NPQ?#ROG``hwbO+xsN~?6-m#Tqu~-zV z>>76M^Ji5%yZlAhSg)K!38=tJlj_Hl$-;KfmrR!QG=02x>ExW|Re9ev3{>JYb#(Fv z7M(`W2UdgFshb&H?Qt-U`<0$h4>IYdqsjFQ|6S7oBep`-Vp83w{Mqy3Dk$cIm5M$_ zy#16lle@e7l=#I6(g}>6o!yUyf)b?fURVD+GR}nlT?=chpUaSxkcPvQNE1c`T3Pvi-Gph()dZ01Vepan0W{in|`sXP7 z?eK5~7a~2P`StX|%X8(S#0fE*D0hzX*t_7rJqRngR)cpyPEK?t{ zD~V{AiGK^3E3KZA48Z%DJmuA}QRQoI)o+o_)BoDOu#KA*oSzrvqE_Z(?k?F?AT9a+ z{kyT1e-#@2xGjnSHGg;W6a9Mqw)R2=C5qZnxgG&MfpN0dyN9a_w68c?G0)*evZ{3=QlRW_uRa^yyn|u68jj*l;N{q6vRts z1p^K=jEzUaS)c76O`qaxe`H)?IXg=IFsd9lsB&n9!yX9Y@@5C?>G5`7zcxvn z3CT*|-y*r&X}_-)K2+hCz5Q73P0Qm)aXN&~YC7un*t2E`iE=}t_6Lel7?I~@$pgdO+_PGoFK_y-28AY5!@?vaS!>XsBP52(} zPPn*?mS=B`F&=Mco|-rM)$X|+Y%L574B*KW4(J(+aEM|RWXnw*?CR>;r;vVEb%SH7 z<>aSoda{s8@El=bVN8}@*&A+s8PZ~pzj-Yr8rPF`ji+OrrDlk6Mk&raH-_O)%AJcz z84#6WA8w#6TS#8ogqF|j?(UW~9(J8IQ|K}R*WTW~{iCnU_IJ!e#fXaJ*Q| z9*Mak_VJKaP{aNj%15V_1?e^=GgB}9DO5wScu+U*#ph3Y1=%H$?{pPS=~c4-yaAh} z^4i+5E1#r)5ge~I>`fgW9wP2Y$;f2%K3ZO0K5-ys)BAX-dHsj%ske=F@|Q1PzMkJW z`Zb`V{M-AEtMqYxGFF`>uldawwY3;}Fg{>n5-8e(Qjcpis~~e&S3eP>J!G+|*fMml zMfA;6wQs5nfQE$lwK)@*2IJd2NhMZwoy~%eUpV3Ck$7h`26GH#2pC_O`iR((BC`J&)dS+ zCMR8I>>Jj6%j8c&1?TRC0eksG@JX-UnsQkrW-u#z}f z1QQ`|qblzwsvrh~9ELend20#O!1&qWvoy#(P{kz=XU}{4>?%w{qZ^Poez&@*7F`E4 zH#<9vLQxGUD_?O4-H$q4pj{p=m3sPJbN2nbxP^shz#3lHQaVje- zBR==^yf{@JK03w4!xZL4u9Xv-{&K$Ga2imAQ@2lhMB;0Q&+?T_$1tkq4{YCf%A8+Y z>)kKWb2J%(Dyuvr_{(FJTVeWJq%j8f`=^rM&Kn3Mb?@x#fOhlPWP`f%jBvHflw52Q z4X>9%uB#88i>@S`i9CFCkRs|NU|usLt(B{9U|@hJ8~q!{SBGeH_>=+ikA7hC7dvx| zI1vn?V&Dq$LX(MB$mI!VBy#@#nFo9Oj6RBO&RZ=-?74mYw|ei2jX)=|q2KcXIr=e* z-FcqnT$Q}FGPMKoH-aFB+c^wR?1*3qu`oG3BA6{0xQSpQV1O(&!BMT%^FRg@H#$&i zD&dRzjyI`dGPwab$)0sD6DJY6EJ8CP(cFmNKjiUpYO>?|Z=i%ozJOxD;6kJgE& zEuu$Tf?YS?Qc$O&&wUMQ7V7v1vdKEvQBKjhkdv>Xoff;Ztd&FvTzWDPe)B6D6Hyg7 zfkrMq^|DJ&G!`rAvLCH_#xu9x-@HBgH@H{Uny2ggKfwB4KAFrUt<)YqIQs;K{Df{k zMltyhtiL5uqW?S3U*eU!;!+|5kfj6MfoOr1gC=^9tg+a7ft0VIMlf3&sK0=p(5bMd zm`(R7Ft3jxo(x2qY~@`Y{#b}2X^BuAEKq_7CZWpP%tgq13kSUw(+mx(B;=6Ovewep zz9S;?#`KN@u~IOqIVCl9d3Ckn*$Fo2VLVLE_9tn{$Lod~B+W>PsRki*BGf2Z5P<+ZYP!^2qeG?5$hnjzdK$0&gk_-*)&}=MFeH z1-VID>^s=lJ?TKPD1X1T?%8_D%3^U20J`>_!IB)NeBVk`a1VnZRzvU-Vo^ z(vqxq+!82TA<;ro&)+D~*ITZH+i!rn?@J*d#TO*tv~`arR8P!hitp|WT)`bIkC7rX zrd<6&{R1{eIvSH41{x+LH6IQd5odCq(Si7rhTmBh-oKf5<}{Ew_~HfSMwY%m3c92u z1w$xKyi{H=OqHsy=Y^YRchEU7h3t~-!eesZk;Jvf4o>me*-$&D35;h-8gvN?s}9Xw zV>yEluz4XodAd9!U+bk87S5YFu(EScj4Pyw zL!hJl@AdwW!@y`!a^k}yvj%_x=ZKB#!niIVVn582lAFF>$hdoH<9gW4(bU7$TooIz zzoR?+&&2SxaQfr;jgQ>Mata009}lg%4_V_3^12~(3rj=AF)=Y!R_McK!dT`dPcnk* z=l>o0<^K>HnuDeT2{$`Cbkd{d4zB(SJ?3?jkn5*EAYvIbGsu-o_|04UItJE_VoaLAYUgFWI`3Xx;QsiS?STEN19AqfB;t=?d`p0Lz$pD zdn;p40gxM8dbc5rT6)R9ea6+{7*(tjZ-HFt@9!TO+3OMRvp=xkQ7WJDPBnz%Po=jB z#ZnB*D%+408o(D+$w{UQ9J`(3PXJ>}d92(r%dy&gE{&QO5fi&ocni(kA>sPlXTV2V zO!^8$#^YaWxRwA1W$vMJ^|=R>6Fs(m>jcmm8A&z}+EeYjw`Ni2;jQDj_N~^g?`rT4 z5z|<;8+$IVGtK*P^O8IKW+S!c=&~{wH#axMUt!<$e7;I|xi}!1k;zKYs#y@ViSY z+B#svpqmcF@^w}D$CeDnWL3=FJ+ca7iU|;12&_r zG_|$YrW%eqWbvCSto|2V7rzESFd>zjE$$KTf#fJI!mJ%H9b2y-0qWQ?J|!2+Vzu) zdu}E-$?|YfC%|WU80;~-Ok#IFUwe6$e4Z&@2*gU`(b`jHI|QP~?1YL{CQUoP34gd; z)`SQCiB-mLbcdxCgx=o8rEkGC>RygQB8^Fb;f?s@w6tFt8Nm9?hO-I?os5o}0K5T* zO$~Cy9Te%iGBTE4;Hwd!{)js;N_88?_2+g~Z=h_zraXY2|GYzg%$k1=G*~g|4e+M} OL`_*+39VrL{J#LRMc%Ri diff --git a/collects/tests/plot/mix.png b/collects/tests/plot/mix.png deleted file mode 100644 index def30152c5bdb8818505d319c47968913b6550ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54263 zcmc$FW0xdN)NQrxX>;1P-96K`?P=S#rfu7{&1u`VZR6JS-u3=~`{`z_s)$vUx$;Cr zWt_dw*(Xe1Rty0a2NnPTAV`S+Rs;Y*V*h(Xg95)n+RV!UHjsu=V!r|3|Gjd%N)iA7 zB7nqiA!WDBi!4_+CFA$u9tv~S=dBrt&BhCz5cs^2Vt5FJkcgj@u$|P`a(YmdpyBW+ z@`A}K8j8(70!FOzoMt!YlCIcwB+@gt38{V-a#7^Ttcgw^@9kM6@Jw?_B-myjb3H$I z!^D&J_4fAa!`5=Yfnx!WhhP+1NJz*8|Nmc2W%S_mwA^c8OiWBym$#N^t}x{fZca|h zfs4yaZ*T7$XV$Dxc>*$0(u1`oOKy^!(-~3kTzN`(L`0iSBQ2qd>4aS>@sQ|Wk8gTi z9&D79rF10n29}mIKVXvtpdcX1e3pD!y|+l4o0~H@Y@3^!7O`KYL)o{$E-x;u{^z*3 zxX^UnFb#gK#0C%e(|+WH2R^&Btal7O?F3!b_ZFEOX+A!0{%EB2EXc#tp;RIpN6KYB zS2#8{ri%BhVgA0I4l)s6>%6kQjs`A-926KB7#bRSCn_KyaCkX3+T%dC#4P>k^2nqj z1*zf({M91v@bc2y+Pcas(c-q$3wl!XmwU=t;sVKHj_`O9-lBv>FsTH6ilwFHdXuHv z;)pVhc2tVU=L}s=t_Ner2nuU=~TqD%VkBraLB4Y966y+$_I+o_=$-L z6cSNRE-pH~?o86ry*)!XIJkIH;0T+BJl)-`SL;QbPlN&?XL*IHN`xNYDxfO9E04L9 zvh2o5sHb21gW(7W2wbnX$RzHrHamcQOa@)$?2@x5Hp`_-?KZ{z4~ey&`ZxQY8A37FSOY$Xml1-i_~VuhNum6aRs)?AU){r&x7%-kJ}1s_8CvR+ngEn_*F zowKudvEvf8FAhh!lh~(qZoF;OvGDzm1tcNoj;t)5am*V%P!jd&iH7cVvwqDlX*RZ8 z-yaBXUPq4t66v9orU<|rQg7z%&K8JCrO-P&ITfZ^ow?sB*9f5Fu;_VDy=p*6@kyVb zHYwDO3^NeL3|qEDKxTo9)@Ea;ljV7&3MB`f(U3=pS3y~a@k{k5i_Q8}pxE_#T|j8CFG zMc8?*{JZQyc;8sTXQXT@;f%Gh`%9U`GWRPnX`k|2O%0^Hr0mw=^h2ubyPV!mIYwpk zWM@Z^M13rjQe?8P&mXu}?u-G8IElDS?Ck8qdGe1Y7Hywp1jRlzXD*8$!uz`}E-q(U zQaI1ec;QC_qThmtZL?6NIe(-Q4FJl&sFX6z{wN>kIcJAVVJ7PisvK8p%Tf8N_%=QA znkp{ql^;4PEZ-)_EVe2_<^Y`!jqi>=P4-ZccM)LpI1Zs%o2x_^D!}I=)D#MaQyJr(lV64Y9O#Ycbej)Wh z9o)i0;1i>x4CdqS16$iLLjmVaZcwl^!Y~sPRSXJ#__Glpw@xzcjImCAmPcNhXjOzd3yf+?ZjkaVrMslGGH<=hq}1PZJ5k3 zyw#Ox0PgSe3E27a7ANI4Y;^eM?;l{ZVd-(M_)(k7(;y24M@dWV;OuPu{VT((_}v#~ zS4#c!XZ8FbCy_5R`$He0l;ATAir@xR35KCLzEz6w`*9S41}5q2UNys&=uR#cA{~iF zYzI*V94cSz9C}#SZ75cBd9BA*pwvDdpZ$?ogo zEji^RKpD!CT4TlR#FX^x&22BFN@{TBplG^n!AM&i>-nQk1$Yxgw**unFK)ATzA`cO zk&g(gdMgaYXZ`{k`h7RC4Zi2y&}s2F=d+YG@*(E0p0XfLCvXX5E~zJRZ7;w> zj$|wXT{Jy%?;<)BlHra1*gPsUqt(h`g_@YnHlnHNC6jFzgsm++PEfb^Ph|P1L>8kE z*Xit&Wu)ZfHIkwzT<8=J&HfZGj#&%rul03dh5~M>^orSx3mP=xvKO~ zyxh?yB%^VPoc}hQ1lZDomPJSzi@oj5WL*dA0xTUkjgyAmlvan?0<7SQ)@B4nH7)it zIYEj)A$I~zS=nsl`6AqU^K2Qq-;6x1){tIP`RxcwJ0l;F$pn#Fwbecm;O%OwtH5&E z2O}g0W->A&V{3tRd}kjg191)^K@T+@kFD~Ln9%w9uJ>lBL%h1O>+o<<%-!*R&8em} z2tbxje2IeAzT&Dj=<*b&MckN~&i?k+1CIg4@6SJ2@2M*96C+#SlIkg}0Q8ANat=0Z zuN7bFiDFMrr9e`Odt{?XZDr5p^`;mmQ5$@1#1a`Kj`QE!#on2jS4+#dMhD1n5u|*Y zXiSs_;1ykEiDbAEwRbev1sz!fGpJUYwt0R5UXY?Q*nIw9^Q24-IW^D{AcY(}!-?&@fJW;dk)thgR*#&wOwA z%U+d4`BQ?0{n5D6RER!hG`-LoJFi}J@c4fA>>r}gP1^?Q+i!5bSgIe2ZJkkpfE^fc z(RSW{hxgcRbA+O`Yv=(Cnk6ZF%;}*Ai7{ za=nUnJcf7Xw-&Q#3|y`W;)y)xwCh;xYBIx zsq}Mfjyb(ezLYRhzlkOWXX<@5nqzLqMQt^IdXvyCNiJ1DX}ja+SlOJOKz zRyB>}=qer@CgH$TJd?07BvuhDth(ef+13%@Rwy6u0pX(Bt*?q?Z3RgQs%n)ijYD84 zNXI)(IK8@zGM~R0!gWeRh`=oHbj4rF+}qOt_t*3Nm&#OICuBr&b|$a2{^9HGeLwwt z^^*q|4ue%d(%sXVZqV@Wzw%V6Gm`N?v64R%gow?*gvbNMgU&31g89PY#M8g2jD8a< ztC+9BkfGAVdj($|>bnJu!Y!#m>xEh(Y)9f8i>)GAVox{;;aU9##ALIQryBO#xIJy&9|!+Z{?(N>qt@R%)=Us* z&BDCxAcz*x!pr{>v`wFMuYo=P`=)_*fS{f$V67ig%C+%kBl6vys7H4}|8!P=SJU=% z)(rT02<&rnn)vAU!Y2iap}Qz=EjT}~GxMmWb%`YeM@={XL;q!pE~7=_d;_h^H&ZD| z+VBkAnItdy5}AN!3HgM7o1)G0bE@F7vbsI?ih=tZ4D4LMQ&64OIfGH9r-+20SEoXp4( z+Q8!F6`PGnfHWfbZx}2E zjviB06*(fKD@ZavVRiwWpoVK`4EE`1WYj-qTIo0?6TS_PSC?o8`i4pmF~mfAOUf-F z)gDeMC{+rL1(HWhe_O1z7_bRJLO578RA{~O3@9iytd!@6e;3<_0?@Kv_HHGEmar-y z2|F=XlNz;_e*})~2~vF@JouRb@I<=goGX2erJu_i0CSf^@2Wa;^27j>aM9_t4F1JB zezv-5=jRBze(!RlBCGLFAyefzE5$Qa-0d4PXImF@LJc}U#pk}QGO_g5WM5fhfAdr8MlAm^bI)la_Gp#h;LZR_CsU_94`f45M4G`#aZLYm;S^JIWaA-=8!k z`N)2QRT*=>M&$Iz${3C`u$)Q%#;|Ne{5Q9IKw?{8NG~Qp8BM4aoUaMS#^kl(aR6r&kp%HM(m44 zQ;mLUK9{q^te|+>Zyky@x&AX9rKhDCwuP zD6LM`TP}Y!9hj*u<%Nf%!3Hxya==EuwmEx+e%k8)^oEC7LcGub+k6G5`uhUPRI}@x z6<0mN8&Nb|7eZbPqPl#u=j8Rq=fajp-|_UIyiTYUk_7Vse7Zlwdjxh{B1{^|F$9J^ z+|Z}BG^&K|bwvuQf>|W;`{wwjeKo71S`@=ha)MQ3oX!epyoE(eePq7QFg}SSQM-LD zC?)k|Ey}OzfNOdBRNMV7o6~?Z+x4FG;S~s-98qOmFbhsLxA^$4zMi^wNgV2>ME@=z zDd2BQTro=})~2dpObl#nz~7{q%PUQ|F8(1vVu8y2l=ChEdMcNEu=lzYgB14SkI2cr za^K@qplvi^8g){k-fL%}H0A~OZSJw`?>V7R5LNG=&&@e7fSXtC0y0ANv<#%5f3--t z{^y3hg=~#zNu4xX%_NZ=-P#7VQbDKg_IY1m>zv}aS<{n&jjP|hjEpz*-b{+0DA189 zJh1vfZLjG2QD1WYD3vb4q%oHkY@G$u!VG_8Q2D2Uy?#dZl@)RLT{3V%rR4=8_?CtU z<2f;Bpwsc}We+UO_c3C3e(1_#e^T~Llx4N6~MhXWwW;nAF$w5Sam((I>{Qjly9605d zk1-ZB^#%<5gw7vyqd)frpQxB8D5P9Mvf~gmwjaA4FL;N-8p18$X7G=;XUBJ}?erFMM?xTb(#sJqQ+BK#u?VcN~=UfMIEJ` zSXotr5fI!Spr5aQrOBV=Uh@3P!7BUF)<#JK76WB_jqfCPx*a`A5$)ozf;VD}+MQO1 znhJvvPnf00{hFHx$?M{CTt?`yXgga%WiZYN#94%d59gt$^C;LbG!{J`7Sy^PFi=SB z)3t+!$|`yJpeibq48C{wX)J#u2AZuCnE<5mBIf4FNl6(Y@IvlfzljqQ1xbaC$u2H- z_CNvJS7`SQ+R<~0KhX0^p@V|~J6DL7mM?GATHInGL7kt=dX!W`8rX%3oSa0A$X4v} z33*#E8uViBZP8eOs3=O>-zw!DNHv-2{m}ZPMHJug$+fS-1aI0I8I={ScK|`)onwY=_GECYIaf^6QnfEx4*4 z9t==!f$&8rPy;)^Iz`~`A1m(ESpIzbv%X=pS5R5GcZ;C8dGecwvv&#O`<;-Mw$_CX z6zq04bj_&yo51@`|4ezWX<6LWmGXz3y?+E;X4dY`jP|4Yz=ziZC7`tp=+mpKHQzSX`4XkC_c#;#r`SrvinJ4BH3-lWQU9Q8>Cg;rFQNV*4`PkrJYFG6koYF8g zfb;XzwnX>89Qu8Xt}wzwRU2M$9I5#x^S|XS4{%Q@p+m4%u&qSjS9IHL*v5!9L1r0f zXS6>aQ(j8T&f9K{{+2>3b8Q%nSRO z`$8D9mY-T&9}rIjt){QaXJvj7#JfP(A8*qNgUo7xI6^p@#;5Yc0Tpg}RWar6D}sKy z63fnJB&2q$m*hnlg#*t$Ah~i}edP7kcR^8%C}h3c8W>1xahF@6Iq(AZd0xfq0G1E? zK|a;$1cA#S3M8j0KaturnwaTh zcP^=V&%|$G5_MxxUv{dl)88oZ;iy!ex^~$=J*^Qg^en&+qP>7CtO- zH#0Mb4iB^BDW%H_^*VsQ1uKGB)~PmO7Wd#FdC1w3C0Qg+hz6{~iAiz&jRN_1VwX3o z(Y!gxeK=OIMK@#5SN$!{0i}76cy(-@I%Ed9)E`6oVSq*fc!eWrG=IpnNrd^^DlZ8J z1_pC*ey<&v1=-xdzFhELx3V-ZIK&3m|dzv1w{Aw3|i?`UeW;=Mgw}!him9 zNlL`3S%{2>mYZgvqdP|ZeLOW{p@!AR%=o&L0im6tOJ9TiE|`WeJm5X7m7&BMX^!ry zDEExS;TNXaS8h-z`29ct( zt3om=3~zBVS>OGkS23mQN_+dbH#Otm^)NCvEg_Pi?+_tB>h|VzM=dK$)ch5{(g2mg zVf1Vh<(cp0m7jD)7!Mu_7WcQ_K5dSAWdWQWx4V1INcriaWHJOiqNz%&CC0y}G-tC1 z7C3tnm0lN_xmY~ih)A(Q;&l9kS4JB$pQ?_;N6V$B^XvSw3ytQpzUJ?x-Jk5;AE?4V zHOc2I3Yf(+S}3zhSp^!@M@IY7SU6YuBQ+HKEthLOITG)geP#5N3wwNRoShr$G|F6` zp3(y;i_ZGM0Laig*EM`SdZfY*%$b?J`{wBg{x;3cm{!(lNad&r(*tL`BNHs@QM5+3 zI#h8DgW%Bo%dr`6dyoS^l0ocl@BR(EH?gwLSIBjx3voN#9lS~0@thF@| zXJyvJG6`6Uv^feDI?w^lAAh%QZwjJFPiVW~6!%!t_a-Dmx{z29pg*qxUJW~_UjE^l;A}h|P*4Dhq$g)QCN8Dhv z#4u)`p)N*#3#6x#rG7)_QQQ)I$}8Q9FjjkoG_W##+FSihuI{^(Z_E61Z#npxc+HPIo2xPto3pmxZ8CGG=T(O*5E7L z&=FSi6wFm7ADKqEJbjj+{t*HRk5EvDjw^lr4gkdyKs-59`fe0TM}}^E$-%{`^j@H*1U>J4DJif2~`E zj!|?Z8Rxd^^+%7Gt)6Ci9cd$#+^x*oafTCsl&X|Q@~VZ}CddV>z=OxLu4+5%A2t!= zwUo>{OG*9=^QCAD!u+jMQ%JH|V}q?y&RYpn;x{$|!eFO6WTPM$vQ&{Qj|(eKiMzKH zGY+n&fE)6FA;Kkmk}0=1hqMm^1Dv;)eF{H0`mZ8naFS&HN|+5a^-oBQ%Yf#ppkche z5}BQ@D6R|?c)=qdrlZ-+lwU?{PituS`99F-Pn0}wvY9n%QBRSFRvB?T{a0HK-jmtk}ZIIsiC0a3)Yh5n8^ug5*QU~)hQ{nVw($@+tY|H2*Bu^kO-c*&6`ByCS zR+03RNmxyYhCW3GIqi~+aP#G3WoKs<_Fs{2o$>I2sd`aR3|F}xgmsy=KJEkTJLH#* zI20qA6GH@>WRHIjL^-iFgLZ|lvFeP3TEvzn$#&Pd5zS~`4KCQuweO-@p3T`WGtoO{k9mCWG$h2f_c7~Hlfj<-7U1FX{0 z)_I_S(~=c*fE|iuHKqn5$3Z~KtPPGf}1pQ)Hu2r!7s zOYM9=AMZG}8xLo7lzdc~$HqMHcvoh0c{C)0h-ZT~Hn3)v?%Am)2$IVLkz-xk+?oug z#`Eef%Txg?&BVxzm6{+UR6Q63oD1?65Mby776fB6%TT9Nhw+)>L!0PmfaIDh z32*;DvS!ccRdD+<HjlHC+$2pZ7j@pz_J`lj7XVhFdpI^@Hbc`O1!&~RXe z)4k@eRfH=R#K5c^YU)gIG#LDbTW@7vl4XDZkJLkh%J-^cx^5aj7>&QuiS7ApfmB)r z5egE{ZFW~03uRv_=pE$9Q2lvDz3ZAq%WO&c#% zR-)X#S~DtmdK#^fEA({tpqJj&;({mQ8~TKzAq9xlSv^i+xq*T58m^989N<*P5w&f`*` z!oYRfS!s$@t8Kw-Z_|6Iz)Ki2L9}E-qsV+5UeM2KO9SYnUWKr_DII%1&o;bqn*!RTp;7X zy1F`@f+EEn5mr{!{ef}0vZ`JZH1gT113R83VL}lMZ(`&BK-Sf@a|i&EW;|qMKN>ZC z1CS)9n*k&R6$sDw5<^AB^sH&guXjCU@Q=@!2K9u3d~ju%b|BheXUF2a343+-iJ;$R zVzP4_=yb>N&f7+Ue$gadTPT79{4wqug52x~{G!&?CFtxtISK>Z-R~ZYm8b%!X?Bk> z`}Y4iv?VYzKh>!ha0hx1L#Ij;U?sYF!nAq zl$B5H_1mLa;lNmwv$ILhs5+?VK2v{ehCFp64MwQRelZ89hzL zytJI2I}8IJ^-aMAvH|@RQd?6W$El#|2=DTS6vyzDB3qf7 zSdq337v{ttXBq8r1}K?Hms@x1so^t&fR7)cTy||DBqra$&Xn8q@>7TkXY2K_`U5pzR8&A-lBR56-||VzPgGUZKLz^Sb^tq z-OBAhX)NVrCWQmkf5nT&(UIFXI{(P)nEMp_#XIyoWS;daY!`W4mvhZ)%iNtv&5x{W zKIeJ0yjm3?j!g04BJ#t^uDZlZ5lQf*u6?Hd`r*MHoHD|H!4dBnYFK<#wT3*(p&~-h zd0EObb&%RqL!-axRsf;(Ms-_2O?rKIw1#1pIX&t4Qb7yIo}hb+c@NvRhj@-H?X|~S zRk?&1bkiIvM?9sono`mlpAOGw=^SxzcmwZ_t9rhFWd{s^>3?G$s%Tb0nqPVjFIP7W zy;e5;HpRsvAh3Cv2pO)#;&zggkSH$SvWMCoJ+wi9mp-2bJ30dC6`)cW{{tRDZQqEs zsU0Wuy&??G>c0#j!OEn~Py3-LfUJ$Tc(d%=U)_{QjjqC5gKIN>RNP(r#;&6fI?uno zCh4FjgCm1RZj|=D=SwA*20pogc$9fcJx47QBSSyp%b&Vl_4U3$Qn!Q(*L~L5)=3AdfLjJcH`}GwO6GG zg#^GGp#Mut3!k~VbM0GGSU4!CDu$pvG06ds$H~E>v;~7fpAFi#6dU^x8|#QSrBAe& z%U~pCz#Nd2Sg2z&WUwxeH}`4>v6ACA_2^L==S@E?_N2QVVg7<00Cxy7eW}-EA zB2B=Y>_>t5uB=y#L?ZODdiYK4&W~W?LU%1wx@|Spf{p!!0|@K&UnB*w-ozs7p{;m% z<-2>abb9enw!fAOfqCGN72p>fY~UzH=hk^xAXd}kIP7Ose(%xa zvjp0gJf}z!^)a)`|m-20}{Wx@dLYx zK}bRb!Pf_Y`-I@Cx?^Ma-8~xygUzn0U;vB3wXHR@G>RW%^urc-I+7w-sUa{}uBAw5Roi4dKC`W1s%8`qUWH>$9hqir7L7sO84gZ+ro63y= z%6^E5l$HuIOlE^g;utfNlHMHN#ev&LkYWNX{Zws6U1M!hKkA!t=(!gq(TnvX#wX{s3{!1h*!&Z3Drt!??Wwf-Wnb6xn>qPkxFRJvC}elL0iLvvL@5$%bL+(03|~fB4~-REo7gX% zeAOqK;#Jjab#<%38@gNove*?`x+XMzG~7))wX|%$mG&cTq(AH!%~FHlgM% z-!}=%l0~3l#{T}eKt3z)7YUE=ou`GB!G;pndw53qaB%`nfW*4kO-;#9f8pg9 zLtY)%^E_h0fUvH>)NF0sKN{kv@UM#-?%tw+m0%Z6H*hDr4584nYYiXl0Yiq36Gsl? zhK6|Az66>w&i z($!THT_9qD6<+F)>pvcpg(D1?7AHdJgzu@i=HkUVXxgE)=@nYmr zwN&f?VH)y4?#+4^_Rm}Ag9Z<1=@@RM(IY^>Z;m%!&00uI9r zl5(74qhncnL?{Dmca}uE4HRHBw6n(6SjnlWwC}YyXlHv}+uu*fnW+F&8VRUq8nFOk zN$VSSPbErzzYQ)d0@V~%ESR?^L?Zsd6)HmXf_k9-Cd@^WcmfgT zmgSW8na?scxiljk;k1TMW)iGRQj%ckB8X3Z-`ilYM4LsUZM=J($%wj8cHs%-_v%!MUD zj3yxg)Dg6_G-|bMpi#6>XTB!ZwdH{z5$t?sRXUMHppy7pKN&&v;L1!`B0=WdzcH&-eSodQ`z}`>*h8?8 zWIF}8eeLYL?CM#tt(Ic>=K6ZPSYjKjEz!ozGKx1?|E}@LFA|H+J~9pNEhl#ZD$xE^ zeFNg}7t}l)*`EJGE2~=!o|lCZv>3B z9)TQYaip&kyImI$J*gPHcEjxQ_4@=YjRKK1nTkR6^Fei? zsZYpjJNp~PcT2JQl&dlXoVP+fS@W{u*Vmb!fSX4M5ky7+G`OAfzrH{>kLV}m>&$ZM zO08#U>zp$64%h#@cCEKlBXN1nb+@UUwEm8~@I0URRbGq zuHO3b%S*C_F)v60I3{%8GT?X$PAl4HWynAIQ{qYLT9CMV-b7A6DJL{4L_ zqQB_5DJ(QJGn>QQ)lZd7QE}suD+|(`9ZF#HMdM2$a&Q&5(HIL5OWO<#&pBOKmgVT? z!AO0bC6B#YIaH?ddy5GRzvI#LPhUU$McJR5lZ4OGdcWQ!BvRLPiQ;--VouH-$yWpB z4_mI#^$_ZVuOfZq}u(wnh1PM)oDmKvdzlN%M>esX3Kw(Ku7oYqp&_}deACdQy4 z{-oz0=8cZfDeAKS+)6)f?j2H=!E5qoaY;+5^LhYpMc=-|mW~HQB)^sPmG6s;$^&qC zKyqkbEtd~l5qG3Vuj@kMxeO@7@>tO46nGyS*pk|GoSF@t#VTCIt9&)NSo-FX6A-SD z@N_By)*j&WDQ}Rb=oPP)+u|NCRpZY`Tc@c;V%>I$H_~#n?4;>Z{-+)I8&eX25`jV} zSHfnhUtk?pimpw<1kH?UQg<37&IuKmi7zFkBBYLud!gb zA@S+3&&!q(IRUnpT1n#m{$9hRMzuvgOrDNVhAwcHhF&P7>ASD(Io6{^&!XuRe+m(mN*X`$4g<&Sce0TqY zz1z^5PM*uclx7_l5`&?EFi)CSUbcWtka!VHe**SF~U=AkanSjpKQfkUFCByl+?LCl0ia6~9(Y+>O>C{|V?CKPS@ z{sAhevQj}2i1t}y6i|GZq#5Oeew71Fv6I9+Q`q%|jOr_$b(GQIP(o=>TTyAxa&!O{ z!~Q~1SI_l~g6!M&Xm}XfX9~T}Tt&)ugKFR`wJ468M}EB`3q|(i)n?1Jfxmu#k<>CT z-+;JcXq^UaNEMw~vH#IQAt}1)o^KCIMN!WedFQW{zp3n$A@Kna5F=v& zRaF=bKao*TQPHp^4i5R8Tp*KHk^Pjz>zQBP=Kdun&7ynCD=Op_6k!3x>;-5vP-+z&9qw*$NoPx&N+pWheYPJa zQiYb64`p#R^p2WGWn_eg=u(!b88oU@SCsee`*-iU7?V|2_02uHo^418|ECYC`|U<# z@KHOX#z8OJP+&7<#hckll*H!IKIdFv!vmY2Jo9RhE2dQjN%>=BTFm6gFh22ebDWB9 zkysQJCO#e+bJ;7eN{zwIV=sy$8>h1p-gKIn9mB^bl?#o}qw(R{<$Ug+7X9#S0VBt7 z1cRcgynMx=;H&n70u7+Ww!l)2lShn`N1(A~+wRq2ClJb%6_(~aQ?N z$)ukgBx)j(DG;%sux9P<#VDpw<4Eb^JVMM6)St3K{w#vremDWmwJM6Z;AP) z*w_Ag3DHZ1^iv{()jJq1qnDUyWzW^?Im-PD9TaM`_nTHHyr#RKp{I8p_qsE%zn=mO z0_qo$+gXly5Izs%lllGY$!sb!1dj`RQ-c%*^l#Drd9?8q0rdOZ;mOPW?|VY8XM7C$ z!DPC0rP?T51)V4){@%4FXt;uMQ9C~(Wtlq_NR*j9Xjs>}+Q*-w3Zvxn`0I7k^U)&^rN-zt)yckRWGSy6e2U zxX+MYe8Xtg6q07{NT7l6wrV7uG1q^`5!DbZ21%J)9e+Ym9`<CEX1 z>bQZYaB3?bGkF;j9#NA|aDZqsenE?DXl*O1E=&L}cXVx*_|xU~z?Hwrl&7^`;Om40 zKqT?^_sFP_E`ft%Tt)<+CqSnN$82-K1D+x8{< zpy6PLKEK{U#fI6gt_ZRkK&VO7t4L<;P2vY4fpKkCrtZZQ(Zj0uyiml1Tz&)aAHd>` zFRmNqy5Oe;9vB*dYLh^*xoT(abC&z-HO*OX1ti{<)Ma@e=ers@Q_*Q06Y>f|rz4e$ za%mqOdti21)X@|$%b~i)BalQTNqG>R^5nAm%->NRE*h5j;5MG4mq_n?RzB|lt$#wR zYpf90Hp_qD%*BOhU=UT_UNH3Ml4D!^?2H|uq=M*=)t#j!$H(V$_Q63gJ-wy2HmmC% z4{{p3goG2e!O-BrbFGD2Hv62|0~2KBl3;-I_H9vi(Rl6I!R$wUR(Gvs`z#==4Lm+`~HWg`C>d32lI916^~Y?t!DDlQM(TVXt{ z%W3LAV1B{73=)9UTykm@t4f?C83hcE(`IIpULHbgFxeY+B-!Qm&(ArWr!twtVfK%W zoqv6fzcqTW{;ks}`Ke&eenBLySKFGs6z}zhHK1zw*VU)V^mN+lZd6a18na{>pIe2| z*>~dw=uD;vyEdoh?sW$-`GN^&XyP`cV>iC}whKSm52+pufB|o^>-ya2Ekp_Rg@fI? z819PBHpXA$oP1JjGX>q2Iyy9a^Lk3QJfI-JoJML3FZ3_h-2Q%HK+1u?d8XIe0!vc7eORGY!jV7-P_f5SC>FH-Ge@`EP3 zn_Vt1Qd6aXRhanY%@`>RM$6UBgTG(ibDA0(l_=GTN|Pqk_g}ptsr+U5!i8A z(YW6t8A*)pJk^sx1$>kak3UZp5mX0X*Evj(i3D(@pZ`3BM2Ne z7n9?-mX^52rW~_NOOk1ADs#gZ2%q=K z>!{x4eJ5zDGell(5AVFuhdZ^U)>7em1WifQ_>F@s`JapB)pdsBqod#M_n|IIG!h9| zL{U|$0PTQ4kiSu?$ijip6ci|-ESC#q7Uc*>CuTqh&b`*9KuE~R>DL|oK9jd|dtxXl zrJxrxnsB=pk!@q6RU%8L+elfi)p9Z>8RPk!Zn;1iHOXoLk=vYHZCM#Vm33-!$5Ppq zS9h;SEP!3g!_auiT7P$~Y}K0G?D{z2czL0_gob+X)R2Img||#s&~$;5Sn>S)>HU3B z6N=b8P-hZ}%R$ELWrKU(8%vr@3#{09x-5v4kmxhb$*a3vyt!Em2|0m5V+Bi3w|k&; z<5gBO+7-SG{9{VOj^TJbS7aDZib(K#yW2^|uUZ=%R#a1=IhgbxrV{c{iP-k+E#rgE*LDA< z&fZ@0SeXXU-*`Rt&)ss%Y&VaEJmo7qo6B1h$fPXZ9!_vMoWN&!azuzffLh7AI2)71 z_yCyI<}TpY4wy?^uXrkfw*4D zbLU8)9#8Eq>!F|rgMiiAWIYL?q5`Xk)jKe{yWMsn;C5!h(YyHHD0`=DBA53e+m~y8 z5%<9*;x7VrHn<*6@&;5$;&$GgrPG8l6S5F+aaR;{lW!YazL_bZwQaU~{Ywb=Bd5mF zGt%7Y8SNs6aFl3^?{Uj=P)XFY2tjwC0oA7JLlOV01>o#DTL{cQ85A=WSL`ERA)IVm z`&!i36!JLzhfkrm`u&(Cxb0E}*@qU38a8;QalU0PVyPtDhPS#ZE-Pw59UrfLdaAk9 zE}8ZAZc9q`lk|7QJ+`0_NV9cd6au@A6@6X4s@4&VWRqqCWVf8=eFzl9=IhJ8gr0ZP z_3N>i^JRGAkHR8@C#&``C>R(si+(>4?(93GdlnsO2j+m&cq0H29fFXMYIHOMH+MJZ zpTCS0rWavo4)LVW#B)>hV^cQyQBf+^bVfc`Zd+mVIzjsGUa@Jy@7?BTgK6==Ou`!&cn3sM=^fYa~1VhAbaX;)5*R%_TYKR*%1% zM3B8LGZ?)8ho)~1j^zEmp4hfGw(SizcCxXpjcuD7+qP}n+Ss=J&gWb2uWD+l=8vg< z`swc5_nvd^xlU9b&%={xz{}a;YGp4VlJUyTjse6}5!pT1fKv9JPe{N*2`Q7E?!G;<>#GT$4~;bXS#fj^u~i96F~p9`;JKqq|4wbFn10GUN?6mP*} zWBDE|Nbu>iOHTWt79D!W1}HrQ-j=s<&$&%V*^&s91A&vT*TQn2ggZ=|;xg@_ zGP=91*AR{0l23O;c>Imm<+XT&%`Nh4IQEDAs(s5Xkzvv17(AQCl3z^oZEzouy~)a|1xtUpQd^JNNw~>Uy@Xa~9R)+KuZ`HAQgZz)|pP)HM-H42k@JSg zBFmbwas58@%@3!|GHO=BDZEv0^WyALu`n_c&*9rNJ#OH!N?}Y16V1@|X#=(_1+*3x zQd)^5{3_BmlaeNfg-H3K>u9gBfA$6+^GmE&QxdMvLxq$tm9JTHuJj{mYLAWr!&~wd z&w6Y0W=KUc8_=m7>sEx{#`4HDH8*MexZvW#{iK;3CH{<1Geb6!_cA@YO_8Y?M}{(c zN%ulV1mE4oe00c5miH=KszQ4xHS76q$ZGFC{N6J!ldJyMBd4n74vw(C5TPswt}GE6 zAfJeFb9>*J4-W*#DlF(y^n9BlqYA^B>GBVZul>Q+>Af4t?U4v&-rlSd7AxO?YN@c- z`<#D8me!Mu^qY3qTSyujsKJJ0Lil83*?tbnfis3W(9mw>x%#2$Io~h=Cc}H97*o>% z9FYSgtJmT>&=)L;Khj-|E`GT}W$8G12>d~l>IFi-AO2rG3@CG5y3laQ@;B8M(jpKcI?P;BJr2k&D z%?2uK6n3Z#`~~ zu_Y|R?s`D|ed`8j^}ukwCSgGZ0ZA0+wg*Lp5f(D2E#*CAFeCnk7c}2sMS{;9)yi!wZieJqc*gD{)gg6J6 zEV>i7W@K=48U2t@`7R=u*2-x-dfHaqmg3`C5k?Zxigi0wo4^`i;<}&QVh@Qgcro{Tq!BKaR_bvcwTviN^=1tF{h>VcE^a8R`$n;=Jl3IIK&nf zi2=?}*7u8L^{Cm|01{9zJh2!r8nLyt%0Q;qilDb#eMhScus;)oCsA~cL^~=koZd42 z+oH!GR`}sD^&o8^ieJwzv*!tmxL8f zud}~$5>zq{2siNvyGCRX8A)%8kU~V zCvBm=9a3>6+EVYzH?Eu{Ls44^0arQKhQmra09F3mKQKUR$G{Q>Tg`fZa4H*2cXuj# zB+F5fnp0*t^Q#(kavK*>Z>c!}!pYRotG1+bkMzXJfbI)((7HOaa|)8T`e51GMX{I; zgn^y+hkQGu4_JS=_@K+CWWWcn**cWqQ^w6kC*umfW9`y|d{`hUp;t+PKu}&-_seTN z=QeKneR(HJSSqv8+G5$IN}E3@r`hp7W0zB2d;4~t$T}KoBV*hHGhQ}7TpIjCxV3Vz z-_){!L}QD%FQ)}PQnG{ks3jK1)40{d8M8%kgwJJi z?pXVd;T*n$u&pQDs*F`;CV+`N8^u>Hw#)^39;exJdJJI%lJZFR#asL>>ed#g$t*=~ z)%4|cMTa)!9NBfh&TzAx;CLG67C=qy_UYUX_)FIPHeTN?@aO)>@fB#jL%77UG=FLd z2}Cj~E2%#Dr9??y-p<0PY3A)wn#*8*|8CEyT3$L$Lf#hoKm(^`^key!7<;@GtV3^) z{H>e%Xr>8lKug4~({X*P^`Mt?4bc~3|l-dpTe3x~z*;4yQp?Vox z)zDd2S4Tj@rm(wrxw(1W{shAo}y^N$izApf(UESdB-&#OPE!OSyCJI4F{W{NX+ z&F$|*odue(NK(i2zpGB6WK?w4 zXgZrlUcU>|7 zy?Ku&=gbj^<~p8FUAHWj>53}S%0uH|b%sp=qvOIU3_Q4HXVmIE?_~K6*9Mj4s{v_Y12o&1?%sMvS(J5+R7Vi-b@KW57hem1}The-vePowVq+Tv$|8 z^uAnyZa9gy)eQw;{pa>5LvvVCdSFG*=)+AW8$RG?kB_DyK)XHY{khHnY!mk~R#4w2 zX0AYM3vI5&_QLm@_Y{bpI5^(l-ObY@d*Ed_529n7rjCP9QP1hX!%hC39hG?%YI$|P zv+)gB{C%a_Q!D8iuz()H>!Uh)AIkWD^xBQZnsMXjz#U7iD* zU2VkYMlXE2l7Hw0-r+SgfRBOoT7Yf$+}GS@7vBAm!8kfW$FJj={Y_VAFGJg{!Tet; z`wxiFT%DG`cLzeZ#>N6{d%B7ZUYB>)qNfs1(8U90yY>-#H!>L>Rl)`Ku|s`@i{EFi zPu*Zyn>(`q%Q}QdbRQosub3IP^JZjYH@2UTRtXNP(YI#+|4ieKZWPFRUS6N4Lhxq5 ztTbf*cB-A$%V*78I=wjRonfs=U>^FEyQ^wH&rq5$ZmXejM3_?f^bOdYmn=hyA24i5 ztr4_0=O0xZ3lkl3U#tb*?l&Q+DEbFN)wwbPN&aTr6`h2ig2xSzRx6e9#%8XGH42nK z8J*m}T7&IY`vRE-I@uA5_UFP|rdOO~0k+hRn{y{@8vvVnd&bJV4-x2LwKsmm_3X$2 zq^LW8RB^22Rm(W#tC|1XE_5%?cT2~_vQ7HOS~=;s#_!w2--vaBjx;CJ<;EB14vtnS z%IJ6u06&lItAjQlV0`yN%~v4RWOz9F|X)K)@lzi|pxY?8j9zo%X96e;|d#Sbqqfhk%fMuqsI}5jedMVEA<_? zZ&|93w|N}WjP1JXF=g`Y3mg~2sOGhWDk7H2^QR{DueiA$=-vI&Fn9(nsj)MxvvZP` zn)+&2UwJvq1x(yD6`t3r%O73T@-?SFN2%cTDKwC2dRRn?{0hM&z;se+jp&TGvmPDM zg&YV4QVEI4N`s}gdYx{H4d;apsTpbB^Bt})m+OygUmXJtIvwJ~#7xZg8%?w~<4G6w z^~0SR7uFXWl4m;Viv9$=KW#=+lf^7SRcBt9z@;ZLHSG~|g-bAMGEc1IW@;U%1IUle z4;yjxvoIx#$0#-a2CNpif*yZbg0YX)Rh31W2BqSzXbLc;8N+dUDeE`uWVA!tiOfmJb`9* zNff02+fs{36V+1dZk#IM_kIDzLTQDtf1EG-xlC!b!Rc1EHX(_tz^CQWGLI5@sQOB4 zuVd$e{J z?sNAoE$!cYjh3?qZI)-gy5CxPDoedP(~?yWZYCL0OZsK@5xNTbxPC#~gxdlPk=ycT zycNhSJHLF+I&DL>mx6LwkJ)#^p z``C1epNb?ujJ^oVD7umv4Lpans8B>CivAM$W;{%cCq?hMPz*R8jOratXSG@+h|>IN zt>`8egRQkl=zk5X?(Y6RnH%Z({yJ#1z@VlE1ZikULES!!SEw?v6&BJp+Qte6N*tLn zUB!1?Ifbf4(=}!aMw?{pgtJdbqA$VCe3j^N zP=GLupul-=OeASZ4CfCgg zO3$<|MoMG^tk)gPFY~**lj)2PFR`I3S?p_(qW3}eN*3>q+O*SgXq&kSHX69mO>%&7 z%i~-}7ehrAWAG7^N(~eD!dh%EH}6$|&|+cpOtqZmz@7t}M;p@Z+ooTAn*$grshf4%1L<29){<&n{-wbnJylHiN6QnzZy8=kG04e_ReQ-68&w{jC?(8P zyYcbd;^i;|Ta|!kp<0?I`Wnw`Qsh(#c)vlL$SUQ5zwM003xuI&yi_*%Wy50eT<%M+ zWy6?9dW^n46ScPq7+VB0QZ=>ebWru*&2@9lj%Jt{-t^=}jBPGn)A&*eZ+nK&!DJ1@ ze!gG+MdZnhl=cjIAtjVWwE~n-*3F$dxz#Z-JuNLgEu3V3KT6~|#eX?}-OJm0zUKg) z8I_eWQ^}YQj#Rz}U8oQNRj2ct zkaxp_1<6oA^zND)o11TLXIfj!!8%=Y)#&WK zaZ#r>*{Yp`-*1_@J7prQj3Wa)mEO7dDxrx`_{&GUvXc72$j#5+FmtJ92 zB{k{?7;2yt6a;qKv~tZK1_S^ri8~QC%vzHX#OJF`&&EIN&yQP7QXaD_L;EA@GHZi_ z_s0)n@DLC(Rq=~jhIO;;&RNHN>n$}`lT`7>MMYyiZ)40PK=V3~++jn6h8CjZ0~Oc9 z(qb_UxQRZp@I3OW-OIfE#*qH{%J7~Jr+C;LDN$<w+r*&GaRr zHsE=hPJdN((w`=bJKH~-DKFoxCm@m&EXz_ko+j}+3A|4KX_-b(Z}bs((gF>Y%n#g+ z-sj*wCa-RzXCa|il3}>Az<4v-YgZ3X{z}Mah3iSfw0|h|%t9{WQ6>!bO$G(A*&bf1 zfQA8y{AF>dgcKGTc~2nVb=~O>#_MFhBh86x%mNKwTDpUUCBD^$=5f7M*4RiB9#l|F z@mH$N`l)9m<{CN=`TaQ|qW=sHm;fMbF1)s1Pj_65A5=~t%`;LKf08Ch4WY*KWGLT{ z?wXTXoeCmt6wEn8C&rq+uUEqIwsgv){~GKP&e+BZi_+}E{$=T2L*)DKZN?=0oT^!L zYeDq*y6fuFjl{??(SGq2g5bExvv!w3BdYS5aZWZuPS;*i!zKzJ@%(cs($R#Gs6`Ep zR-pn{finpg&%VXxH3qlIb*mGYUU58iEeg`mqM!#w<5~Tt@BGW8qH4pqAz&JZ9ZhvMyO& zmXWYOzg{5nT}=Sl=z7+7Xx=&I^f7jPxPvpaDH+UHZ02fSvgN^&vRJWp@{f4`M5IhF zL32xl;*xKH!&$>P_>bA%<-p-Oh&#~?%>{3EuK~-Lq2!?4wx?tx0(%1?s-{Q-?Q51< zqd^Lm9*?&Nuy{N0wAu?3@NE7LLrH={au|Eopb$iyyTSox8ZL01(2G|7%jyp39EN2v%6v9m8FKDbG%wQdWJAYRJVj6^0xG{ z&>LEGHa5JP{TX@VY}_~g2y<4OTcEpP5r8_jdS(%c=$gJS`h+Lt)}CVat>5J%O#q#^+g4u(d8A}+Z(nmQ8?&>y>uh_&Q=Fs);Ie0Y02TdGm3 z`36Z9B$~;A;^l_;en^0!)Z>WI+y$#U3WKL#ls?fFj?W`cp;6}`VAm@w50|h& z5LU)Z;}IuSvpDR+e+4VS)q71K&wD5@uXSCKizF9k4}+g9!sXM&G;yX_W-V$CnWo}l zecdT{2(I&*LSB)}#_us02!=w!-Tj9|WH<~zt}7pnjgqTie)iMHE53xxNh`);VYZDG zS_)i$fdYVzSmn~Adusrl+|6B*%AhVRBJFU24oKr^nI8{Mk(9Kea=pmA51YT!ogJ4n z|5v=P9pOA@(S{|h@{3)f1nP5a&|1PAVd`in_{OQWKl;fO?z!8WG=?ar)BQepQ1o}q z#GrMnJ8MLQ$`7#wiaaZ|h_EQUP@m6QQ-pA3ZFn#+)I9E;0c1Kbv4A0C$x-@I(47bV zqI3T1Q?Pdgv@*j%YWK2uX^X(ojUS&3rXtnFY&@qc@?al`Ko69y(j@#VAlAfZrw=sw z(wfOKYBZ{#Id-hkHD7>~9PB@`-=FQ^{1p`uadHSPGg$hoHXXV>+SobULga@!(aZA7 zcutmSd_)P)RK272sg>O^xQ2;#^5ep&tQup%LmA`M5tv`6FVYWwb3tcKGERw}?4lBf zPCDuI#~$63e8xfnw^{H7qb-8$>}+aDNi#zJGvLdeh5H+8a~2>v`-2anTD2vG2Az00#MO-Hh->a=Zq12jzshNywpM@O!rQqC1YY5C@PxW-%VoC zrQW|^uLVudaB!f{WXXg8-JYh8$EEnZrLHkXMQdTH~Fx716^K;7@|#!J^O-FWIt%3_aa(iXg`{w>uu zl5ygjBqg2V;+;3!Of4@srU~lVmplA|_?wXQ2~xkeqM}RC)x}m0b2g*Z=w~tu}h^P6#a(vy0Riprw=i z+r@PE&adKlhBJ_WHVwW?Q!zrt$nXbd!aw;j<5V6D@3&IhZ9-6)&toDz!JaOEe`o1k z+ikItm{|pd;%COa{ZsnHguk=h{J~&91occ<>5}Zy`O-h(Y3&EPXyByo&0yr8zn0O* z-cgHgVyMsrHZize`x_OfjC}b?!E(Gn31i8`uo(9mX6&x;$GV@_ZQY(KDMI?X)M^5u z5MRDN9CwI(7c~jL?vYB{&~I-~gzZiC`oKJpJOIJLiS?Eu-CK@TQX+$`lQke0vOc%Y!`B6`j?K)hZ zHI3+K^x*gNF32dzY>zY>gv-6WVFr$&Z8-tryDQ@J=g*QW(z`<M|2PUoP%KLR;rf|pfQ ziFsX%H#(sByDZnnx{z1P}SPl-zW0UT$JUV=E!JiLJjZ<{b~xN$l2qwKiMb zutDibS4k9je_V+}kSdgl35K)3`9ZGTH-+&2WN@KA&nK;hwLiQ&1Q&tLj-bB&FXZD^ zT*`~j$;oo6IUU8pfyoM!Cfw15BI$W(D3v>*zs)&P0HKD{3ps$?RP}TkoCI>|<`9uk z(;^W&gaykqV5vLjDsaMBF8m$&lNa_b@(`{!mhxY@RTvr?+SK>k#LEbgqMSA#E{?&A z-NUI!Ta|z}(D17D^Hc@V%JV(0%k!{)$#j`c>QqD|fQF3)r`hJ05Qt$?&pDw0FeE;V zds3+8`JP;_zYRbUtCN5^%Eeo@TeGl9SSdqHw54!>_0c$-Kw?mkimz(?pPw?7 z!f9!RYUemaA^Oa$f~|!!bx@2~e?h}5^nm3u%EZM?@t1x90kqIFoqLx;ct)%2Qy&Gj|g;qyL z=*OelbONQ`*_mZh(j`2+aWu|A29uEe5FZ+|AxoA}{9~>uIbF*b??u6^ z*Rj`9Dh-pO+*YoOQG;*${YFTn;epU=p_R5_aT$1g$!=O5ut1l!H2|i|HN(V=;QNYR zpzn)6yQxf*TTyYq07zu;?f|nsKqo3S7kJvZD*98mkB`w&QIk_skN5Xl^~PhXbw;uH z-19BA1MEF#Y!flarn45wSz=pg0D@zl?d|*rv>6i%J;2-Zw3)27WUHz@ClN4hQweNb zfVDmQa~!2^?Z$fHe4dYs_wP-~+o;SxO|&No5fHCV=PT)0_}o@n`phDgxBEYtcAV6O z0uHjDT90EJuSrq$3=MZeKV`TM^fc38N% zX8K@Yw!*7~4WlfV5DE)k(c0Q-yWJg$NuSPUp`@S?2OM?~8!NAfV&ao0tkQTX<;HH* zCoq!KeQ{@4Kc479Souhnx6wzs;>qCuR6O1Z(h|rY zfvsSF#T_mWO7z@RaEdaDfVYb4IZQ+fha1L=3=Mbd~lCX*k2O{V-m$) zZBl18vcczJpT?)b;AONEar;S7$wUE%Z@AyfSzkO!r`UjQ*zc=bT5b^%`tW+TH6%XXoh6&FsyM zg;t9yOfWu&7Fql#QQO(stF;SvBv3GJYBV0e?E7&x9uLuM!>|3 zDSW;g9ZE&?$Zx%_O~)8+Yc#{tN_Ip5;xgbE8DS|I5JM3axd7^P4yBlYle2tTJlK(0 zWL4FNi6$#3OzD-44c{Y~?=;qmoWwB&MgMx1#AMT=;=2+#XYKYzVY0p2HGn8844^G@ zcS(yGI3c|@nm`fNCzSYS|AE3GU0Tijwjp} z&d2=xXl?CmfjH@OR>HWTtlre3g4WS!thV!G8j)|O@q;<7xA#2az{woKW5QDZ`b=$9 zR1|Pb!~DVm0Y3iOg)VU1MM=?I!i`Gs6{*I!v4n_-(Qu;$&CGmHk^|8fF7^ z%{^caps%4p44iGC&cQJ{SqPmR2u3Ja4843Z$K?gAq^_>QqKlxH!%(1M^WlFRad_EY z@X8Xldw6{1cpueNx)SFgadKwzLV0@5Q!z9Dg+c3PXR=G>@0i|eJerdr2{&rcQk+pb zhqBcRH8C`-x7`*1SXfxp|1+0p0{u}@iGKGAO9U}A1Wc|fwA5$UVM~#dlilRXLPDF^ zOE-~kq-saa*D)9MT3a{`4XNZ%04^@-bpZnC2`A6bW7ex-JNLk#Hl&c00tE#n6(FpF zo-H_Xu~rBgnTjowIqLK3P*hfyTPUikK}|>NdCzRN)v1c=(XP$EdkH~HPF_U(T)qWU zT#SGlW?-T5M~u9899Bc)+o#OBV`3OmK1V5}zNG{%IT`cqQA7njxY-CwXU!Q12QdUM zfKr5o`)3gxX5rw3Usz{y3GG$t0ZWTIAO3Jhpx@}I@oKXyHRX@oH*ZfM5_Wvv$vu-v ztW%nu7a-+|gcM6E9<%7>elUuHbeEpLJJ%avVjzS?XLYU_P-NYZD~tCAKhfvUpbpsE z2O8w;UTnzq(cTaDr3^UoK@63U98<-4V0r&P$0CEHP+^O zMjd*ptCUtOl>8DB;&P4gX>PK@l98dx6!5mo*<1UX?Guekm2pp$H9Pysz;=K{-xd(Z zs(<*qDJdx|l5{Se5BQ!Y;C1Qres=*52&z!6+S}W^+Gtz2ji&o2CI$wFnLrL)-~Nle z)0t?AB0pG%OW$zFVu4T$CbJSuY8Xlab!`2q48dq{2;X8T_);NzVp394V&cj9ITjYy zeOb8lH;RUahQGi6+uIxPdriia+_rx*3LT@+!RwPfKcC9*;1U5K5~>tpSTA9q7h4{uUXI4FNTiouA`K{%-S%k4m3Uz=OmlNuJEhJ%Wx1!{ncsG$LT?(EPhw3>3Mg&+bj z@bGwDE>_bSM`8%@q@f4CW7V51mp)$at-65^zjl-5ZynUOlc)Qc3OL3ww%6F3e@OX& zzP{Rq0X<*EWj%Vs#a{jSdi35Ztw%2+`cl`@-gF}qlgCb%tU_4YP2k)eVEmYxoIKDw zIywT*lLB6Y&j~wwAt$yWvZQ24J-v-qq5Rv|lTEyp8rD1Dn)-ImfJOQ6{@kaM3>OW4 zIgGAcQ_G@6vH-?pEe#D#enG(@`xS6n5>P?E(cyaCfi!{cdOc4*+y@dKj-Fo4aJ6l# zSV0jAUo;m*{{qMZ?fVP$GWNZ_uyB8~J0Kt+a4k@Y@4W2itQrPrI0Ouk2bPCe7Plz9gSP(Ws*?8&{2@5D;9RpI4L*&hc3F^3aOD9%>yO%U(HLT}^fU zycGc#32fxsZi;V5E7uP((brd4a1%ZR@d2J|dU`tWrgFX7fPsex2K34zReEzbrdOvw ziWMQ?X!7~x@bdr?($lYHk3d*(S`re&)mj5OAWvfW`tnlB*Lw||#RLdJB!Jx^WZ!Fs zutjh{&_vK2EbYq`mM3uxbn@UC`+=~t$~<5381+otTQf!I zvRKA}e0Minfn~GtBdLc@BS6phmjbfSmj?C7P?3l8asy>qW|J~yVX+d|^z@Q)iOZz~ zk+g&6JwLg%kdd&im;57H^PhD?4r?x^vT|E}c@mMphtc@eo*b6&Vi(GC`9^3}G)Q1p zeInWE+cRWc3OYF0I~2?yrlFC_5#4WaBKhz%jHUOHqUFWOW{14sD;}v|hAX>}unJ0p zosPiDdWuOTBJy$Vi!LV&Di+<}>5h(@aDar7@9!x4#j6Pp2iQ4*b{FKL5EjY4Yji`+ z_>mf>sDVS;ke7nh{hck0$Ad0R{8@cgI86hdz$Af@|Em@k)EL5mB?|^NpoFql#(Y#c zyXBsYCQ8Bvh4i=o7%n}Tr~zePyZ+zY8M0Me+yDEcumLh!la346UKesD3aLa5OWL&8 zm-}NG)Y^|J<8fg7nfZG1JjKi;us^4XBPsn|;}2>7TH1U8h+jC2W&0O3*nj|m4C+G~ zxK^OXnYFSyDn}9L@j9Gpi_IqPB5Nu5DbOU$YT3@&Nu6&iBNo@g132(%s7gzj1aol_ z*hY?zPenhPCgZNj7hWC^30L$x9UlXO%Q>Q7qZ_}hv3U#r-HAzZ)@=S9deT(AN^_2v zsSKHdA|HzpG%%3;;ZcK+P)$v3*JxmK2G8xiI|vF9ADh?3+Rg0+cn2ZC!>hQ-f5SY5 zA|BFsMh}hCP-}QUl*-A;E%o}#v`h3)RuLn7iIA0M+C232S44t!b@ak*Uf zhoQ9kWI1%V8Gs=Y6<79cZq^w=eMZQ%b2k5p9EqjgXF{i=V5J+D78b}M!ok4scrbqn zN2_Teud#rq18Z$>KhW(DF}xMQlqMPOI;U>ORZS|Y9Cv6chgIF=ULFAc*`r85m|J2By@N%GdjA97L~he ztNbgebZIm*x!ofqB*c7MfL2`mdZo1thhwI85~BCYOyG1$M3qZxj;fzy_p* zUfjkH@9xSW0ssO;U{Fc{MTUm8);J7$6!r&K=4ZBkV+vjZA&9{GhD`1^29RZm(N6vL{?xs*D?5-u4St1{V)}JRxzA|Gf?)M``))|LhZ!(#u4=U%$^*3Mr>7&7Jo?oi758 zT0`kshG`b!1v>J+yxYQ>O=9zultM>hC8Ymg-tUxR;TAkQ@gg!6+gWPriO1Yh0 z5Y!T1-%9N@rKcf$_JjguvuPEWU*FW`hV!vyV|GkKgP#LS662P zp-SjA$&#dkf64=MlNbViK0ZF+4YFMn$rGyVS~)56*0!`iVrQ3YXJ|xCJr4jTS$QIf zX}Erj-MuwEN?ZppbD;?F5{WN22G-iz*4kdyULRfWFiPQ~(NlzMJNv|7AIUS@B@_#4 zwcws+=ACXAcYnSMo$X1yi`GCg_cosTbO;#*l$K)-AUIlahP~Ig6cOCS`*?i6J`$;w zNk~Z2yEH+l7(%+cVYz<&Vq){Ux6mP+>9N)O#?^XBWnM3qjg*z{aNO;GBH*>*_la7; zOa*YAo%QoTUDBy;-s57zSy(jvJL?<+LH=Jc*K)ZF0tSYSqiB9~l;{|a*$MfY9slud zg=tTy!`JR~akMu()p2cY)quE1BRAEPT3fl?;+j220enYk2yhJn*+IThDe$yK8)-nx zk9893sfIDD#5%hEWxEJnuIdL_9bBQ-(z!>4{?A3uE#2BJTA&?-woHxz^DY%iCFicG z)w!t^9+RE^Cf4F&uc=iO;pajow_%#~>(?iMjh$^ei*Kz(K1Wj~4c@}S&Y}EqG6NcE zB#Aarm<$cgdRwmNG@0UY9EAXFpWUf6w_NIrTwEt>$S~;`M(S>r{MFKg+_GM+jQ+ok z)oZ1!j>Ur6N>%NFwE1E^CJNzuyFwQd0IpRbX_U{hLDho~(A9Cwq;Yx(ZzB$>z(`xa z#>{CSIN#R1oN%=E`r2{b4b+j&dgiN|gZC-HmZ6g26^nZN2-s1AG(Oe`B z&ePalA1-3sTPHG6sH9>S#3z+cGrp-+{m7X>7ifW2reS7}D|fu$lqE(!peaa@;h|yX z?`UXT_z4)JEr4l!*CI@EAT>#ul>ZpkswDe)jk$C8pd5grIqR+q5# z9tXca-hXv0EH>-~go$Ry!~prbalLRkIl_x;M&xjg(lQ7Tq^hc_$Vg`xsega_a#0Ts z^TcB#vUmqzVPo+5UEU^7Y4Q|AMD}-LSP9mjssxhIeqR1+zO6KP-OfU#%E4q-!~u|i z!R3WN?vopUPk++K;``pYbGt$M-|wuv1Augmq+8v$$J$gVX4<<5woZ}tfA zY!44&9-c(2O_6$T(F4jteJp&=nxJJWoqU;zI~>R_Oe@%gCu zytsUyZF=Oggr6^2Z8v%B?hY;}1VrMomp~&S2(r$!e*k`}KHc~3=sV(Nh=j%> zoSnP!(_OzQ#$Tj1UW8U0!K93-(f$u^7LrwvD+Vh5jL-0+H=IDli>Ip^9d=EWR3Cu! zqg4lX`b#w-vNx!ueKyG4#l?IfveP%1(P%IIj3V%dp}=4c(o-IF8Cmo>BN4C~8(5Ot}9 zPR_@O{ryxid<@Tr^F_ZFik(kq^EwkT9>tH2jhb;z)O#f9PVee`@Q19Xu4nZ)Z($Fs z{aB8(dB)KDfOfjGQjz42qGDC8G#LgOb`e?}o97s+sweZoqWUaZ1|)2JgdDaZ!9(jC z#`{7HTK{baqpOo6TqYND#@Xf{SUcz7B636`ieJDAF3|B9sJtgH-x!5fF4iA_G^tUW zDL0*x;$-RJHhwzx(TaLNmq@}VzY;n5KYjucxDwqcQ+2jJrOUqxT_z#FdypfAraDrk zdFsnTR3dtRV%U+PjzeOKAOdp`56I%5K#Y<)b6n~?iMGO|qJDmEfYfd{>Vi{58Wr`V zNS&GaWIIPRZVZ?g3cQ64+B-wUik~8S-&1hd49*o`b3} z=D8##ODhXS*-y?4H@NV*185tYe&+}{J?E$4Fld+FYdgtANgq$6qL8>0P2)BV{Tyi@ z-?-Yf98VN4FH2}V;)pKDYD})b1^-!|m(&_Ff1o%#m+QECwkRSASS*DEu&_6m1CuB= z-##S_6=NSU1LCgM##}$$3Wy)nFqiAfT(`H07|cMyo4a?0JcE{+&xifT%Pp2%HaH*+ zp4Bwh*H@`rC4~VR8psR&IDm!#_Z#RdQ?6|)+E6mu{}_ry6L_cFtBG9jYCf}~)&ck^ z=&RlF%G*v=7Y?>qcDil&5Hm}53e5c%=}L;Rip$mYAlY$b500v%p+^Ul`@vksS7VPOT;Vc$2loS760tAt_q z+kn68D+k00W6jp5{vnpE2#|8S-lu`ao4hb=c#FD>Qs?e&@ zT^R-Gn?jpoX5M^zBH%n*IBXbbSJ1c?sOY_vnOC{3FOy8o1B{ zB1sYl--&{~>H(!5#FAkq^oNX8-YBOV2ixO?^%1;=a5>--gagxZj%P-q@!T-Faw@V3i6`Cg0f04q?k z72!CU&%x{a>}#x<)Rv_lTOYng1$l~j?|2U)a(|yELKd^}A#>$3Jo{>GBX?~yEfbYG zu(`}(IQDmJp+paw^0JeIG_%Leemn}NgCoQuGU=+uHFG7VTolj>p@E1;@t6CzX){aA zaKWM3SR+u)>=@zLl+DH+=mey`gmP)_S-B78YS+h?(2Um|owSqlF zsQok}XS)gJmvZm6yStCkFqNk>e`FK#>doG-!M&l+tSl&CvRB~ki9nF0S#qt@K|&Hh z!sh+9vrNATLtPC9gn-(Is6z5!fTDWdJasQ>8cV-U3zvppz}QeCb9A%b^2|pe&F-8y zM^m*9Q@PGvNst0e&{&%1d%~cIC70iOn)#Z~P8T18B99Oe8lm;nR$cjCx9*_ioHfqU z9@l7aGMuVOI3?85*3q~e0-fBo{!&FoY1&_9D!lwvAajdzV14R4T!l)Z|7(OPH7HU| zfGI5+G-vFmKy~2I1}?`h1o5XE7l#fr1hFc~N*4-PoO`uePNw3KlczM)GnkoeyM1Ys zBt;Y|#iXZy%t_F6A%0vPajZ;Cl>er^ahshFC^n^6tf(AJ(c4SWJCVyhifw&x+Fq)7 zzS`oSov5h0{sp70t)LXJs&4X|;BII~BrRleP|nyqzWau8-khauL0;gusY@EGWDfb+ zM?lQ|KmJuaHRHm@#31q{r_BA-<`X6jAwc7M`AX!R9+s5Pez7%NZ2BYKi}GK^)?AC`)|hWpz3P9xk=l*Yh5J8KM>PFO6u*R3@ru zD^zFB^FPeL0!*x7b@7J$wAtL%@@xD7_G=5D+)dBl*9ajiswqc{zj9 z>^jO|#&vowvY*F}-M0$)g&ylkRv0^auwR!Z`W9f=&Oh}k!Yf7-=qC1i%mt(;Q{^|t z!6&D!7dkwzZq>wL@Uuc!tbO$2T4N4;m*paxHd*-Xy`2j-U_rjmsz%|M^H%od!Uuo< zPm|fCc)Vp&_RUQ?q>$0bU!#%DYb{^WbF8Eq98IM@<%=Xul2@7}6C(JPi)b{pAI#@X zlPaj!Y?o)(2fEfD{Muml&dn7xJcL81(Vxy^Rd9i4s z9-{$0iVYh;Vfw$*J}96EK**npub2RJ|}u{Ge%;o}j@bh%0OABWzBD%1Qki!j6KR}Cx3`77 z?wk^2f4je*ebGJy&M(r8XMiMFHZ<+`z1Ri^g2rgxs zZbTfL)TO0<$(UJBcjPkE?2M*GMds_OH{}WXPBvFNL_Tq#Th-M*T^_Fwrv(*N(T$Bf zzW1=eu7fTr^xne>^dyu>`z!qJ&*VXBy1}K2M3*TkpjB|CKUnN`>+N%;#{P8n5M|Cz ztYG373mE8+Boc-gV~n$f65S=(-jFzCex1*5h8*dw4i|ikq>q#J_~V*T-B|u1!@6Z( z=V{FvTX*8Z@sjszB2DmfjJx~Okb{kl6;^ltsVUmynPa%%_|wxoEC!kNrV1&NHHZyG z<#T=OkJm61I%o2ptwi((@}_$TKT7%Dx=tM%h; z1MeVeybQ%YuuZ}VcfO))+o{IeQdq|VD;sKXG=KrJVn}h4<|F)wx zc4Ibn8r!yQJ86stO{2zXY}>YN+di?)XYb#<@64H|*y)io4)}a-x zr=VmcRfi`qsIvC-V}x+ru-K%>!aqk&EguXFA8c$YejmrD$2dPhlOMDiAJ{B|0}B}9 z;)ZoLJ_^!s5D-*Lt=>49nelud#Z=O;0Ddhk18bB9rl<;qjxIc*p#vX&gh87Q2rCky z7N4$e9{Af|BmO0tm~0KV?XHB+Zy{GT6JoJBZMW-<)vl;fG!!a93}dw+kc-#xF8#`a zPB2fvEKy55_p*`G^(*))URQ28_1Cf8X+dkB_vPiZk2SBPNLn|Cs*3EqJ5H!Kz2 z-^PI4U#`5O&(^kavklbfYLg(^YgX5xr~CHu_y|OFCk=_nBQ4vG+RBpvG>3XQvE$)X zh@xZ(!Pw}Z66%6KS-MHcU{@}VN|3W?X!zW&xv_Zg!0il>1gqHIWX3U(%TU*sVT>2w zOoz>C>U0MSv?q&;e<(F#4T&0q)pvCS!%iG3QGu1+#X)Ib7Ej?SRb26>qbc{8N@=Qp zWn+`}SM%-s(-Mn@1fRUtQuj8_qRdvS^;MuMbXdHKi@?wolrV%@_qg2G zr~^+qc0MBX)w+zWhcArojNh=sXt*~&O{Txc($|O^4{OwW;lp;{aScdRsKhD_uyme2 zqx++?v+PX`0Ky`#FLC7G`w;1zozaXg_0##_P=)oZIr# z$e*5UzrB&1z}i>LxJ`jIMtwfT<38GV>sb_M~~G+PEL;X5;bF{k+vJUiE01>TeX#7VC8I7OJClufDiu z7OPaWQr~AFD5oeMRS2PIW=?xx`N3s)v#Un>`egO>bHC1Z^}BrNuSt`?25DWv3JMG5 z<5-UI++kqp>E4fv+w_B6cW+N{8S1i$P6?}+sRweaGEe$2m_7CF7RZ_W12rbg9cle7 zZiwy|F`Vq|RJ0<(5Y!btBe2TUV9IL%x?*IA!s=}Pakk>SxCksE$1p5)n*No`J5#;hq0##Q zD($}sdcequ@t_yR7mUWq2w%&8%59sWTJG-aj%?AjVbJwP+B}QxGvGkiFo0i?&JI~V zM>4{pZab^gM3q2an9rvApULp(5BW4ZNDW|>d;+SK*D=>C(!|=tR}hYGevC`t_wyHY03wl-=LoncZ%bflBcuQVufnd=>Hf z3I@o)VWsOOA?^6MM90FL;+}HPv|6(x3+JYfwLF$#Yp8qkBb!5OERbP!r6Z99Rlu&X z5Yh`+;QJ^VF$n7mEv{zx^Rw7O9iZ(UUw6LEUaY=Xx+-cxJ!=S7vXTA08mi zid|GJF)2|KSFk~`OlcagJ|PO^JFC>osX{g|i2XavMJlcsX#V1YfDJ})pyI-SrBW38 zRSC+5AS34Eoux>@A}N7uG6S#KM8eHz#}7Bhe`l%A;)qH4%w0rqGhd$!0>$fY*-)X2 zgZfzLRqQJ!1`;8iF|1YZLqv#xo?QnBz9X>Jr`y_pz>C=;mw5IZUOb9%2 z$Hu@TlVuMMa5)7*I_J>fgnvMqC|4a^nt z_Yu-bFYHP<_zAuUC#sDcS{LnqRpcRpYkxF0XG=TvnLKaWB-mI{HEnD{?k@ez&X%vc z-kf%jd?*`~vd8wmc>SukKij%^OQ#0}p3UOo*`_Ivr0;6s=7F)e3v`n2OLNk!bcjrik<^@}z zDGP!L0+`iaR2Ue1cl5Y`&CR~W@)`mbip{A@+?AWyI7sUfpxmf47vBm}(1n$J{yQ~n z*GCv*C(O!uux`Y|8L(l-}r z@z}^2hFv=<1^Ae!1I1Of{5l)v(BuxSy_idgBt_@dq# zUM1D96!^mh`1%jpXk~x+9-*41i@^GN*k8)2#h}F@F)Kz%e9<=FXLje(p2a;Ony(M8 zWd=fOa9F7J_V>4U#lluNY2jyPl7IO3dp@C9Sphg!e`xejI9B$dXC~*huuR!n9OW<2 zB*D=|!7EmoqL=qFn9K9*-^MsE_`#-r;)r_V`_8 zksCIy3ivNqy91|(76Xz}LTzr}0P!`s8eI2W(eOk= zI`4CK-R*RPO&%uw$!no`1}8W@pw|e}jA*c#smfArfP?ET$|9kGqr+4$S3LWN1naLF z_61)5v&BRAqQPeAWpO+ox9=I>=bbxxh?d@x#(Dr^H!inJm+xe#MQI)FF)1FinBD`A zHNo%9OH>O-rHAAfY>!}dX(^x@B-cMYkWp2qiHa}vmkln{m?=V@U*M}Kmyg2U>2N!5 z;BM0fR2}erK$b`}~ zoYr6-p1+7bX-kg-%lawBpewLj=LJUN3$iOqk4@$q+0C_FZ2p;hUJRf2yF2*oLZX!4 zI4RQ$Bi`I#PgD3(qMOhf9Qri4|sImno2xFT6|Is)5v~TI5o^t*@0%;l7vE)xF%_-j6^qHOt8c z6A6wPtf}u`GElMixHSj7U1*k0EuIQ^=Ro#vQc+2XR_y1NOC$dk84s7C)a9xBWJOwn zv>I*JMkOL6Q~M2m(Nl#fQ3Jj*n|zgu%5b{+vC_Qb2{O@dLnbXWW+~(BN@({pL34@$ z(GDLT8k(Q!9^n9Neur#>>Xb3`R;|$g;Bu&|^4Fxc7wZr$Nfj}pL5qHhCSbq+2|*wqvKm+>3SAaR~N@s2 zuI5XKmv>H}iIDMdZ{DRue7uZMaWW1$7efn`VLWY)xRH87;Wv1B_C6@2c85;E$9|V~lgT@oHm-NMm)SBp4$7}w0 zwsHmoT%)H&dsS7vYfvR>AGwI2k@qR`~ zIQ)~`^%u=j-M>;tm$11p1j(#sHvSWcaC<-=JDl(FMCUcJrLUYKN>WitWm4uSiB)F7 z`q`^Qh=*48ZN=Sj^iS}Cc*Dz{sxfx-Z4 zFc@j_?R_&IB`FDnN7(szI|YpvCVYy+>-Ra1$1z@9U{NYE6N=tqGISIDuh6yPk**d% z_RLluW0TvA4`9pFSq?A%h5ut-w$I3!Wb}AD*lI#!@a?i1CF%OB z?&V6mCtGLol6e*VLf053u{ydB^UU9-2bk+8tVC7|PMq#-*re3Xz?A3IU6lrk?JAeQ|?pCVkYv&dWTUV=ta zJwB=2YLxo|ltP;Y5Jxv%D z9lp6W_vA{;GmVCe+rxBqb@BFg=RStbJ8@IOHZJvsNyL$!AWmWCQCAs!qhpnpOCL*bpF#TowvG(8D`%{qIgG5<(j1&-{W%unRD4Qd-yv6{`T(N(|3KcN0K!bs2j4aHV8S~__Yfd~wBGKQr;JP> zp`m$wBes0|{-QeIMl-+!DIk*x=sWQmNti1+2=txi$d4rux&Urkm83w7yDUjLhDn0P z?c<0T_O^foRQnB{&jE+Js>t=F#~G_$PG+|IQ;~;d@^`6D{NFr~?Df(DVu$T{LfXXp z27VrfCd-mtqyfy%dxy5{9sjUT@-H9Fs*JPLcaU&Ds>(2a^Hv~bKNo}VTQvYucU(Hm zR(DF^J|`nr;*N#bz6A)WtpW1de6srDBUPn;suU)5njrCrBOQ}GrGy$TX0*aWV#eKm zV|>ov7aLLys^0ua1ijlm)eUN`?5dj!&jzLzCS#aKrzVSZ*x2)4$2%gnTT$v2G0A@) z&S%Q7THPw<^r@W3vGKr6hH`y=H8*!JV7R%thOeqFf3+pM7tKKhl{z=wQ_wyi_bVRG^UB(5bMsMY|MJ@%_00{H*a=vrK}ZR; zRD~!>U`XGDT&BU1y}8@;THDrY!&294rG?z1V6FBz4!8r3|uY`2{E~oXYbC!;9$k+Z0m%V{mu3R{Vh5Ex&DPxFN+hU zqX0_KAriNR;)2H8C?9z~{Yn~q>St^WTuw}hVTaPoeo5JDt_+rd&-?UH^xDU>g^||_ zR%qx79O=P+Hg1}MGh3WJ1u3MJRX+CD6oexAo^|}H1y&Djt@DSQ)MhIcDMz4g{pT*! ze@TqxF7^po(c6XqsF*-|eLWP`Q~;U+wDr7vuyS~at*$&j+WcQ^g2cpqc`d1GumZ!B zwAG&mMt9(c-VZDbdHaf#l!m8P-M{}l@dE0g<*GIi?aB_Y_OFFQKC84l6ab)5hRpbz zRHab*O9=^Cu2_60LM*Cr^47d9GTGIjj z_Y*u2L%O@OZL?zb3M zcy?xt^7K?pAwvajY|fo!Zs#>P3?P)xi9KHE`Wr1F71~}~@0DR`iJh8a)%nYP`+9GM zi)*=y2o-gDAt)zjRw%wX_0$OtZa7F1s_r|O9TKQJ=KG@XP6O5*12v65L-dew&CN-d zqqx03Vfeu8{^H)2IM|&XZJ^MrkH%9UHT+R?iSWFEDRUVRH_5M*}ES zbgrpTQMq%|FBltTLgw`f! z{MI^Yp*EVGT|9AJK}N&~8j4WFl|R`SXnaIO*qtpd|bAW_;Q@}w=9_;_ULbXrZ;3;CfM4%n(&wVMJ(6NlGb@)m5 zEE+CuH8DH<%zR*6TKq*M?sdS*;!G5^qA+vQ155Vh|e2m1x@3OWIX5;lR-VDv;TEvU3GIY(bSc5^;Pa zZui17XV(+a&0mz`RAoXQhGXB^^XprLZ+0 zY;nYbpJ=<|yQY@$ToK!^&p+LK4IAfKLNc26ut8#XhL* z?Rtpq#=1Te_3raL!(CIw;&bpaF6K)hBDfMe+@IWH&XU!g#a25Eo_TAm3b%HGt|p(g zPCEm;ibl1vMR_|L9qrR%&M%2eK*7VP}WrR+d>4%A_7{XSz2j6 zH)_|5`O)bNgT=0_*n-BmpVm2!=G7fx^b>)I0WQ6~LO#DAmx>qX&e&^kgMDJj8Cgi? zFkj8CEc}$)p}WcXDZEu@=cG*7ah{LR3mHC)`yyWM-+0g}f9Dl82`_zS=PVYW* zg*K}u0|HDX8|gLm&t&5fEg-bv{fevkiH#=#M1-+-Bt zv~*yc3Rs6u`$9G7y72XxezlE*gqXP7wqN{_DrN-EwDvVZ{1_P5Dw?Y82^P~fnTa@% z{NDTr#Z^^_Ng)dg6sZ9DN@K?3LerKPCv>C}j%}7trKe%>5YaC(2?2~m5ZH99R~&oO zCk5N97-!Ziy~(LrMP1VVQ6soO$HYvrDx}EWAEZJ(ubd9sN#{}_k+Q<7Ij-iHbKgPg z^CQp5mjg!QEuWJ>NRDD3rjZ(I*vzRJD~f&r?LCZzqa%yEG-9sx*>0}9Pu(iimid;n z^@<|KF)Hb0PnUz>7RmwkDNk121XleCcV?eJ?CltOqZ`O$`!P#vm?Ki!u1+c~ITaHl z9B^5xH5!jRcX{@^Pn<-ph|sLa?75yZ+5Cb5?@0CV2!s=(e8Fk~D$AZ4laZxL*Wwz* zH(l*8qKV{v5+1xQKZRTG{E(sJY~m1i*;e@a*sN#*o~zw(3i#1cpyFWDXXyt4H!b|> z(%x#r0gc+zPM>D$w}1csUI1y#-H^*I=*&17Pc3rK-cx*FK>Ww!X5Za$bJap03llXp zv#ry>ThapB=lT+|-bPB=yLkI3t)$c4-1pDptJiYZSlx}3GFKeptY+3zAFIjJkiY}3 zfKQv3J4~TrN;;{}CupHDpI1RX3T89Hu3k$_%B8n(_a$;X_@ldfPH30835;SCoas=}K*8)H{`UsaQjyF4+ zEc^zq+Wb|;!M0E<`lhQJflhg~9Y7JC6GsM=Wa<+VdQY3)1nB~ii$)fpgfyLxF-CDX zR@`*{$T-TJ1>*->+0=QVKO)pweSMD4%)b{^LDfHCR?o@#?!T3m{xFYN>@(@R-dl^t zXWE4o!Ofja<*>I6A&Oc&`FJz4KDFH5GJi?QKa5 zQ6LA!v8&A%EdzKxDEJM=OpF^_IaQYI=YsLkX>R zp?2*dlFPuYbG5k%A#z%y;8$gNxf0=K`BjQDL&>W{%x(%-W}SKOwc*FF-{Q7|siz(YATLr%08()YP!#y0e1>b?x{H!#o=7 z&+oN|l=iQ1AdJZ$m(~WukF$MYbJ4MUOS`O7+M-yljNFKVV^VYV7CG5StCozljgU-g zettT|NU!ayKiI{Ei%OBr(jOh|RBxX=h4jA;Rw?sZ6mo2NJAKEw?o^&A?+%yNeQmr@ z)q5YW5`b0cX7d+cF~ed2OI~MmyL=<4sL8$4O{?lmsi*?4V0NNw(%00q9lEK?LHi!{ z1Du7fPNvtb*L)ACi=~A2?!4Y02|F~OUr6~k&&m-%Ov1~HCL&BIEz5iVxD~9837k%% zF7I7f+vVS8E|1lbXk?fIJWl(AnK%B&2Hw96_hz+fyfMztzZH%EtD57{jsz)M#cIV_ zL#RuzJfUVI%;(apgj=tdSOCYYZ{}CrG@Xclv>yY34p%kB$ zJlt75mEKu(t3H2R`tCD$U~i@+!Chq88&BF+lIWEVMUaHaBzs+cOJsvPP@co%^Fz92 zef)qaP?VS$?3BP;;Cc`*4vS&FzKQ*;c13-NF`e0Nb@I{ga4e6&1lfPUd-jH>k+V9zBh-Q<3tjtR8X9k$LaMfbvRZg_HcLUBRHy z=IPnvGx{Aj_Gk>OAMwLCrq?_7-8HF2w{~eg>D8|7#VZ>&&jCNDg212GQxN$gvv zfLlX6yEy8ljz;E|4tG|` zYvh7b0JNZnjr{{#5H|lyLQp@?+>)%e$;lap*@7aI<;j_Ygml;^Gh6DYypzX7WEbW; z|M9R$rdW||f?mnQ!y@Y$?DOuw_9BQAxkPY9M*=_CO%BFSDINL^g5Plle2feBh%N|29!_k4840!!fjrP#!VD-9l2Tdj2&ky2&<>x0m)^b=Z z2%_G2)l0m&#g3s{kfCbt#WtN@W>ls&HV*XIJ!xUyeJqt*6MaI*1+a4+^2|7qG6kF#AS+#(8tq3LA=>q_!18 zs2_hzz(acds+;lJP?z2N1Ag1=u4tKnPH}=B(tDL#c%b zdkqL6;&myG-7HCg)eY)h=nJ-Er=f3GIXS6zqd#&!QBg)gHxUTs*Eahs=!4x2sBFdLhhzGmDsb4)0!P8{u)3OhypF$VHiQ zl9J5=oY+W6G159V!or3whewyul9K!A)TB2=TFIxmOgPt ziL%-;eoA=-7fA&&ZC0&Mmd=>(cibUklp7x}>WW&)Eyv|Ob#aMdonCo=RXxC})#3v) zw)WNC9+stBEuXT>44@1)oaqknUMGX3u*eWNJ+nqgVh0}RCo=!=)P$JP_qR6`%;2k^P|#bQLf3b5#pQu<=z|gdZ9KfZ z+5(LNq&NF<#g)M!&?F?q7MFl?cF%oFY$9#xqoLJmfmlu|h2Q<+mYaM zgv`VuzprbaXzTOR%IOej)e`5{{le%jzp<1$Pd7y!u-jG2mf26LvMyX*?q_nU+`R@D zkpD#>MwBG|%eqY?bpi&FJOE-u4F_>^g}QRjFB-#~XIRDdC(vRu2U2Wd9~@X({$Pn( z!JXR(+cj313p+bAwXo12M0N(@W>yrX&csu5x+8%V%358T%ths=dgu|Cw3>F3E2;~?-mh~0FABxZ+G<-~#k+Eh*0G^GlxHLDMz|LM= zJuwGko?t<@?W?RH1sy$KiLzLg_QA!rp{5`ksXy4v3=A@dFWqf8 zW42=V7(6nc>An_R0W)Y{YS^@A%g3U&&}MlV*xTbbIE78en0uAruNH*PvX$~e10D4>7#F44HC>YyR`=) zkp0eI|Bdx>{o>+glFY`*R)9M}yqF9&`@OCHsSGAjzuH_{%Er86?Z2(2py0s4VQMN^ zRTK`9Cr_`gk;YmBIlaE#3da%@iKwl8^lm|nVmM9Q+{|0G@YSHB73dvP{`oTmLMHW} z+27~4FFid&%F4z^=am=VPGy(Vz9Ddw_d7%9Nif!9XwIBGiifgZuO5;(%iJoP!T;S%eCA;)$_e@$pTWb3>phVuEPVBCPBJLWlk26 zDua0959)74n1DlLK~u8a-0}6Gh`-r?zUe5$5%P#*jjh@xLVX#?$Y~Q>V0*gbTGPXh z8B$?meiP?QK*M5NZf~y~Q^Y%`mFRygiG0B9C~e+xQ65=)oh`a(=ghCcWC>0Gci+`Q zo9OJaJGFiKSGq1hQ`4OMLkqDi(!ZNM`>RJd*+F-g3wKdCmYljyF1o4q7CJqq3LkCN zthPgx*2hQD%`L5sO$t%!F^r`edK?R#XU17?gMbK`dB2yQxO$pQi>{PyYpv@*xsJ$d z?F1;}lg2|vD^l=a?e^~G#{#?mMPud+;=rxZ$Jg*6V5;+Dr7Kb8j{h)KNkV~$1IOA{ z5k!Px)O{*1FTbQ)%^TQ7_VzZ8B3#h2$RIzwH6bPC__#x_>$3*bT#>&QEgQyDN&SGy zd)I2JAzJYQ=_`a4U&)%Q%RxIT(B<6X_1-@A5^lb$*Hfz^psYaahmx0dB> zd6mkU+7Ey~^pUcFX8m;jOhyhZSkpa%W<`-CQrMu`umy+Ss!;)uEOV^*CFFedj3+sLh9HY#%wnB9%(rMCf825R~y~uB0{+oad=!-a!NR3fyw5_K+6-G(VWPE%)4h?GwfN29%9pJ z3~&sX8&L+I$onH`#MAK@{npGOoAaX&dRl&V1&5CH( zx97MCzcQsCa@$y_xkK9}1?REV*?+{CE7)9u^;SUivhdxsh77?eRr7IktS-cHZssaV z^-a!yoy4K=v$WG4yhHsF=QYJ%&Oan*h$m$ZsYoSUsVjAHjkYm9Us{El0@t zV}>|+)v0(H6b1AAHp*URIcAIfbIS+7q0G!O2Bt7-rNIqgvbUc*ymI)!lH!|ls-mJb zPw}2+`eL^PYR32_>eILs*%5Gb7%jT)p?}A4T*CX9wGV~rtq(5tJz5=yt`8^pF@!n% z#Bs8ebDN1F@8sCUJbPeUZJ~h{C(=sr-08G~&KhQ;jhS@5!Yf&lw*9lDN3geIdE+1m zFY%N3=#+Kjgt98CphkQe_3d567f1cwL=1NH7WB_qiFG<*iKG`IW zrP&@&;k4rSX_h7*a+=j(PIE*GDKO?3DrjCGvhj8J&GP;D@uMpaLsd{vP+wpFbqXag zROY-Ew#rO*-wAYlzxDF63EG($7CQ@V5YHyH@R^6eQuOu zmY4YJMwQYGAE1O^cYT5js$;U-i<*$?`!x8-$tnGdoqD9Fh5Vf(qNHf}wz?XgrJ{T_ zud-YNiHP`h7xZ>`_(&-s|ErletUF++6=y#&8p3h zTQ`_yA>*i-;yW4c{g2}5#WlN6aB-DscM!*ypXDTIhHK$}8U!7#- z$#9%UNamH`WXq-{ea=_zfUK-_Ra?TH2-jHXfc8zF-ktQJLl1(*jR;%6qF&TmtePh| z=U*qnRG$GQRsQlHc90XFC+bXOL_e!OvsmTj#0k67R!S?sUHJKM)bv{-~q~ffJIF-RmvGW&Jg!cld8&9cvIP zeA=dE0=Srn>dY0KBQC+o6&<9UmxIkvmA9d;awYd=^Fo={DqOht4~45Fepdf`60X3+ z!MVE5NrmzDo>r2fl9r=SV;kcl{}S+ZXAm(k*mxYf&#-1z`RxI(UK^;ZV*Li>WKk;d zT-`5a_m4P(fbRB(hyKNie1ASnwmxZ@K8viBH($9WlyEE-a!NAM+}kduXUs@#!Lwf} z&yN5^W!nextrBJO%-oC0Ze8f;^>8#%uzjl4?&X(b{egr%19&2ZdQ?6>g85=k*vLY& ziT5_bXtuA3QHVL0J^Ecdxma<(ed`{Awzto~yB?aHY`ngnKJD4t`6m%!K};xsRDo&C zq+Z3oGMYr!69hjzC83CN4-1~OHa~B=<~s;F30o-Rfv$Dyc0mjX*?5-Cvf93ug%@t? z`EP#WaS31(Zv!_-{I0f>!9?E`{ zE_rw)^Pb6L{1vt1>xGH8sF8$nch8#=$Wi=RjK0s#PJym-tb-8L!B;3hFkfPq_4npZ zw$sIGwLkQ*Ympf{BG-^T=R;ckW?IlWD%xGXqL!8X_7y~7nlnVH$u_Zs4C1#ROBmld z_=#sVmvaI4GNIQSfxt2(;swUIO)NEdbZ;^{7q>>MU92zS{PdS5+npJk2|`JUwe3C~ zl~n)s!S_3F`gQ&SH6(Oqr&mG``0E+Msqx_Pk56g@BuP|1-&?*No4@9?(j}3~K)U$N zNixdysN{fy?!v}a#dI{TI*~tE=FG9YGbi%FVP@<`EiA{9%{Z3kpqIi_M#`W9tXs$k zBs9e=l))C4k6Um;VkYPEn5>r}7N@J3MtsrEHIj{rV%C+;L*MPXLR&mv#nOGhyuHD1 zJ59as%0+7mvG8GGv1ZJ-3*+B+oVWz_+4SyIu&_Y~u8sBe^(MO_?ni0=O;2>Bp!B9> zBaniY9Rqk&CtlBtUUst(uDj0;UoKH-*oUd^G9UUz(MZddtXp<#UV+Z%S0 z$lA5XXIR+F(UL(5ZneW?bthl7?+=o44WlzOZ#idHcd8H2n{ z3I`NBnQjFhDP=8sK4aeo85=xJ?ClvFh~xycTThk29#%(ZYWY}qZn~f@D=-n&9W&C^ z#J@qz3q2f9h6Ex0D}a$3>cFdxfN%YDRJ&5?J_pk;>f!}U`>FYx!iy3X%+F+m$Yb`* zQvHve<_5WP)z;Jw-SEhW$$WlLFfkrpOnxtJsqN`dGj0z=$M+_!ozy##>A^2XcqEpi z<8b+G6JS5={O)4H*Mv@dYLWlOQ;_$>J0LWPbr>dH4(DqS><5S3tKoi;#3#5GiTuG? zd=brdJhQ{*h(GJ`D*526#el$z-E3hy5CuGC*%LIh_fg(QhVi5z4StdMD7zdNK2*q6 zjz+e1{tRA<4x~ft{%UG3l#bauB*3W1tkdLte@m(e15LbVYz(kq z%BRFR2l>{td>+3e_Z0Y2m29`L@$%A|7G*Q+B4&PRya>K}G;ET(OtP!Zm=xT3PRTLILAqBdnxqF6{nf4XBz6vQid4SxV|-{^Prc#%PB=xAEU z`^;C>tEAI3aF2M&Ap(Oq^qR#6l7)^lgx{s$=%vsRWrRQE8A9iswLvbu;wyJV6q%Zi z;?uh5G1qp2gPr2gS#Q-6@FGOBFzI0Vre`u^T)cgJQBW{PkSCw`1`nZ4H@)Q1LzABT zdW=_0FXw2)eb&Ay`cF=gKc135F;glW&jU48_yP2i$L_#E$Uq}hSW@{>?j`?6(Gb4O zVnY_>O3s7dU+zE+dH>1F&o6Y;J=0m&>~e^|wVueZEd+XeQ&Yk6`9j%z_sL)W2Nfp! zLz$!WvtlJ-Wuz-A8Hq2`#pM(Zj#EQN7P1{oCu1K`w!BFM?KZ)p9|cVe4onpkJnbRV z86fc!dGT3W6UXJ$-k94nNTKj=c{}So|W-%j*+R}W9m>95rq|a>R`q1oL z83L+z{cdT4+?nn18ah2mNjKKC9yiL7YuTrl& z7CX)&bXK%}^VX~fMy1YsVq_x7elAvaUU`gbf$1QP<1vKd1R@C;LE}Rf<}RGW?c8~HbfjOLp-tpdyy8v# zB$7R8rS32G#Hjm34n|!$-w}Fe7<`Q@q#pn*PSx0?$dXX%@IlzT%Rj&x5JxZlhXS&) zuAh`kgKw;2B#Hm6s}m@{WE%Bl&sdh0TGP<9^YWo$E($Hnl2=q}f+vhNKc%4Ip+S8` z_$?i@s?Eux!l=5pz3qOLZT#umKiEiMJkRQ#Z96yF+9bB)r39sW=-=<1Fy&R#uw^(5{jE0*?zp zR<}d#WUUO7c@SM5AFRve>UGgqF+^@pB(K))^;IB_fqkR@7InE^QLIn;FFO}vb93;W z@EhDW%-$aGg@vEaA|A~~XI}~~r4*p0ZuImloH%D+FR}2BJpNaso zLFkm(3xCFfltXb?wog_mY+b&@$7>y}IW(1~8hDNDySI6=D63pQZWWgUN%CJ6CJFgo zrmMOJc|SN4>FbVkKl(#6+Aw|xNJNdN&QPb<$XM3Xn71WJ=YjprJXRk-RE`ndI#%z1 zS*uR&$4S=La4)H3m?l1mIbl;%!{(m%m@O6dKeIh@`T4WE+Gr5ni;4*)D>?=RMKng+ z=ji1gJ0Mt$ykd22Zzm*jiqFJ2CM){PmX#G7i=LgMZ(^eTMvF|?g*7)XlE1}tx1R_J z|F7p8kmf)~e9`SM=B)1Gj6(Y_(fP;tFL~tl7~O6My_0o7wQ!{ljjzaH7F2q?#y zV)8E(Cr4*;ku!8IobbNF8{uL0l|$kK@IU}PUfq8@m8h8iM~FTd6EXR z^;SDE)lqUy!Ab@RCfq&QNRfh5Jy?hS6o@&SN}kvKr}vXE9)n4t&wXU=_^yDDZAF6Z z@?gtN1-qAoL%~0UOg{?SK4WZ%WuaIH4mR?p=TseNrX)Pte?Rc#Ysfe`qm0IudIGjqT|R&o8&Osfln~t_7CNw~ z|Em@|MlTkh*l4qH{`dF^r-EG77rI9+;6;Gm9Nh1pX=VaqT_GoDIs>)QPr**5u4jgb zzUkQN*8s5U8Y5;>%CdcznAiA5KW0AGKgZl0y;W9(w~we;0Mf+$unKJxf_B2B1-uwT><} zlZ80bz09NYJz9ECknZ)+NA}=LJt|*bi>{l&Tw?FJJ#MmV`+G`ZqZ+PA3=a{r116aI zQwb)dt7q|PXK8-KOX}Y-RR)~%M|yRf4uqG2vMj6xdnmJt{XSN5X8|3pQiJNy zZd4yUJW1i>qhp61Asm`@{AKpHHrh{D4S>MFef!|GH_?0WlUMwI=P!K;`L->?%S;mpJ!&7lG=l0P7RCa2MQP4XGr(;%9TqB%MXNQK&{rs~mDwWxl zvqiVG_TG{)W|CS?syTWdw{2l(F`Yoy-S+1>lYiyTtq}#^*wGk!CI)?6zRf74p3)65 z`rO)g?;{jq0Q`!sL<>u4ni1;W2o8xPLFyBWbt6c z4tk)J8jF1>Vqfp{>@4o_<|g*K4GXc zYb^?8TKlkT;o;G}pjK}ZGP{zpw*0q{g8SN8=d3Oiw?_oIB$^0lj-a6tbSA2^3pSG_ zrvD!i=W0H`8SEcCX?DZC5^(y~>5-Z8tAr+U_xPN!D$1sD^K#;s1*eP$jq;c`J6k~Y z$dq2e6bBuuA}02cuJWHm%;uJ!v9Z5Th0WL)7~9u^C_v&_TN`Q@G&)=O?ad)F4jPM_ zElARWRO5C*qqqwCx7A!Rl3C2j%j*9%cAZg8bXyw`X%b2Vq=*y|q)6|AR28IyV1QR4 zQex;Ws1zwuqzgg_(g~pmp-2@0ktQ7hfj|gB=|~eoL_)da`>pTa{c+EaSubZ_ckjnpB!?XMx2K- z;-IB5sF0jGran=Y;c2vQU$E0a3%{_Ajp^}fvCloAvNfk_;Pvtn#YCp#UXKDnH9C;| zwy9H*Yh0Z_;QF8f>JzhHU048;Lf#lw7-cq2MMZxmwE5E=99f_rwFfZDw1!8VTW^8BADKjli& zYAF=12)S>rb3-?--B?{PIE&Wpv|}6%%k)b2u}4232Sf&F0lOj1&p~N(Gq+~*;9k{C zS>eRSVIl~Xwh|D=#>dzGw$KCQUQI7E5O_XSGgpxC$&t^-Oi;)$O(Yv-CC(>1IQC25 z1myJQYTD+hc__?~L3=R#i#%2FrM$}`HAqaN&9p(}H=Ey2A_G1FV^&k2LkA)={b*?U z-9b

QCD@S-JbfENDah6V%3%UG8kJ8&bX}-dP4;t3G9u&eaG#V6!sVt8eJC;c+wN3xMlwd>xc!kjvn8&WLheC%|M*S9LxegY_jSQN8}okB^v8C$@r!cNq6nd&8D zg;j-N2QwlB{HXsP%K>c2He#^$2Xv(KNMCH&c^`4+0qn~463>mKIfI7#W3~&03`=;Y zIJ|czY;6f`dF{0#ttj81va@vQ5Ft+3r?om3b+_F4ubg>%j?b1Od90PGh;-}znZ`lR z?g8=gJ!-Y;@*LyX0#GF_RdbOu=VO(w#NX$_vD|KPdpsSm-3-A|j~UZLh-!fnAV^jy zy_Dc9CmVb(*iSWs8M`RTdKrbvb}xA);(M%`7drKAAFEKA&XIW8P=&?QG!)M~2yUW7 z`;q~VZ{bUIWBbIwq7idna#3%5qbjB4P8R6PuJ+Ew=_2&NQ=GfxF>jg&DS)mH00*_G zz>;Lny36dlKz}}K|I)pZlh!&rIp;t18FW9Tb8e z#ejco)-aT>IK>&r^G`pYY^A|heIIw5L)BQ^C&%uwR%7%8bZ4kZ=g4usCFD!+%b&^U zH}+j-w)?G0a@$EpdO{Bq5H8&E9Hk0!f4rp(yXIC*Z=Mvsz7;nagrhR(n4Ng0&v*$H zj&NTyBIU~~Vc1iRCQM%O8H1}M7-YsNf)k-`H%F$qqra3r3Y4VwvJaMDJ z_?KM4;n5#>NGkLqU^dz{lV%aHj!Dui9^Y!OcaI53J@>o;2Af+@XE9q_mz8N-b4o}W zSz7Vyi9HOH>HoiRA^r=Grcd zbhr2F2qUK=`+lK8i$H#`&?+Ja{YRj)MTx|7WY$IVnx3|$rE`*#g@r#L^=j!1m@m}tA@?z2XXK+)pC=`Sb?oAsQZNiYkm_p zK|>%-X@sS*v8Ew9mtS8PH=`q102GxPAMY1|TOQ8=DwFaL#6avtdkD|Rr&n*ayQ>|n zU4PN|75h1y(TLW;+fkIsc{#TGlNjV@<}yK{8%!!C>MOrH70^*NUthbf+!sy9#v8xq zcRiyd&>vv6-1GZ3Db!JXb1RfKRe(L>IAjO~ZGGGmKZRR;C!w(${)_kST`5~|6XK_{ znb{j6o#&>)d15ae3k&Z3dHcq%>C^!<@JAm%M#UG7J)OmV9dobGmgRPT5`L$20o?gw zvN{L^D6;Ey5qb>`a$a6BX68cWist9*mClR6?;IQV+=`7twT z4iRsmbq2dXTa-8|tF~yWEYY9n`#(uawzY%qfXUa5!kh2Jq&J813FSM?^zR)eU#~6$ zGbGMz&LNy9yZ`vigkMeoG)#*81=YgZDFL?^4znZnTEXOA?@wDJ4B5(IHGWV5znJ&) zX|mPi;^2fytDPMdKoz22QG=)IeV|XAi|}Gv)1!H9`)gy{i8Yi#8RXDr6@praZOVQ? zj^6NHWp+^5bcb?fUJO+|bKI$VN~PaV~c}@?ZL3+XOdE!u_ zU4UDM#6<{yIWj&wJK-s^B)|}MBBUg3kCC3eEsKs(dL{*7Z za*K}1J_x4sTIo)^Bor_`7wMcKFk)zW?n4PZPy&04+Fhps<^*;o2}^qQr1!mj)+Rh7 z8WoVS`3%4wl=9q5%bKe7uKltH+Q*cBd1L7S}m@< zvaZ-&FO{8@#Ak|UxVnje`<4qFs%!H#)wuBU$;hhcuw*o)!cOqwLiNAC2M~`gi0^q(kEoG^zr?;Ey zw~PRM?C*3hUSS~Z&eY`vNZdcpPe{B_LcA&FrhZ#{q2dGRiE?w zjt=c*thQ}%Fy;6-gf(S*wr?(@#yf8W82Dm>4CK|hffx{FCI0L~YGnZq4vV zF~>85MraM4B1GtYKuqXn$58WEY?z!Zj(=d4riU=TMr#%Hfg^sz~Hz5(1}U7L1z_y>P+kQ$#Mbwx))}hl}ay z>>T%Y|%w!hrMArOfc~@a>c?Kb6nQQpoN1e#-+W z6nCyEy>{sY_MZ>HWd=cDYGT5FXTFUf5WDOZ*=E!?{?H&TNA534)WoBZUp>RwDqO) zXpT%yNJ;rkCQAdvF%lBIvX0szAt4l4XlSU`>7mnxuchVq;jcyP9;k*yk1Gq}a(&|A z!NEYAl$1nr0m#yFo0ecBIXnPC&eQFG(nRuuw?AYlz#78>iS3~mE=dE@2?aQi&}j5% zj#}3)rj8_l)0E<(>l+%%k#`vY5&UU z%B7Y^)nbO0)zfC#%AWfx!zJ-=($ZR6TZ=8>mX?-yJiyr(3h>of|J#5QfEV#9ehZ4h zV4epD1HTQ(JrkIppNGTYQ)hXQqwBz|TbI5lYTP$G>`8%{nvQhGU4(A{&%Dh4x1Agx zmyIU!D2OU4Wd!BCeXH&|#GNJ*%fdhV$7oi0)Als0CKw_mC3QmgKThiZGUJc67Kg~} T&H=7)DxewOHr21vb&UKEaFFWu diff --git a/collects/tests/plot/red-identity.png b/collects/tests/plot/red-identity.png deleted file mode 100644 index f2e29615c5c3516e546d4df0660670969ade03bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6634 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 CN~Br< diff --git a/collects/tests/plot/run-tests.rkt b/collects/tests/plot/run-tests.rkt deleted file mode 100755 index 680d9433b2..0000000000 --- a/collects/tests/plot/run-tests.rkt +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/sh -#| -*- scheme -*- -exec gracket "$0" "$@" -|# -#lang scheme -(require plot file/md5 scheme/runtime-path - racket/draw) - -(define-runtime-path here "./") - -(define (read-file file) - (with-input-from-file file (lambda () (read-bytes (file-size file))))) - -(define-syntax run-test - (syntax-rules () - [(_ description (plot args ...) file-name) - (let* ([result-file-name - (build-path here (string-append file-name "-out.png"))] - [expected-file-name - (build-path here (string-append file-name ".png"))]) - (plot args ... #:out-file result-file-name) - (printf "testing \"~a\" ... " description) - (let* ([bm1 (read-bitmap result-file-name)] - [bm2 (read-bitmap expected-file-name)] - [w (send bm1 get-width)] - [h (send bm1 get-height)] - [s1 (make-bytes (* 4 w h))] - [s2 (make-bytes (* 4 w h))]) - (send bm1 get-argb-pixels 0 0 w h s1) - (send bm2 get-argb-pixels 0 0 w h s2) - (if (and (= (send bm2 get-width) w) - (= (send bm2 get-width) h) - ;; The generated and target images can be a little different, - ;; but not much --- less than 1/255 difference average difference - ;; over all RGB components (which is really pretty close) - ((/ (for/fold ([diff 0]) ([i (in-range (* w h 4))]) - (+ diff (abs (- (bytes-ref s1 i) (bytes-ref s2 i))))) - (* w h 4)) - . <= . - 1.0)) - (begin (display "passed\n") (delete-file result-file-name)) - (begin - (printf "failed! expected results in ~a, plot produced results in ~a\n" - expected-file-name - result-file-name)))))])) - -(run-test "Line" - (plot (line (lambda (x) x) #:color 'red)) - "red-identity") - -(run-test "Vector Field" - (plot (vector-field (gradient (lambda (x y) (* (sin x) (cos y)))) - #:samples 25) - #:title "gradient field of F(x,y) = sin(x) * sin(y)") - "vector-field") - -(define (trig x y) (* (sin x) (sin y))) - -(run-test "Shading" - (plot (shade trig) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "shdade of F(x,y) = sin(x) * sin(y)") - "shade") - -(run-test "Contours" - (plot (contour trig) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "contours of F(x,y) = sin(x) * sin(y)") - "contours") - -(run-test "Mix of all three" - (plot (mix (shade trig) - (contour trig) - (vector-field (gradient trig) #:samples 25)) - #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5 - #:title "gradient field & shade & contours") - "mix") - -(run-test "3d mesg" - (plot3d (mesh3d trig) - #:x-min -3.5 #:x-max 3.5 - #:y-min -3.5 #:y-max 3.5 - #:z-min -1.0 #:z-max 1.5 - #:bgcolor '(0 0 0) #:fgcolor '(255 0 0)) - "3d-mesh") - -(require plot/plot-extend) - -; (number -> number) mumbo-jumbo -> 2d-renderer -(define-plot-type dashed-line - fun 2dview (x-min x-max) ((samples 100) (segments 20) (color 'red) (width 1)) - (let* ((dash-size (/ (- x-max x-min) segments)) - (x-lists (build-list (/ segments 2) - (lambda (index) - (x-values - (/ samples segments) - (+ x-min (* 2 index dash-size)) - (+ x-min (* (add1 ( * 2 index)) dash-size))))))) - (send* 2dview - (set-line-color color) - (set-line-width width)) - (for-each (lambda (dash) - (send 2dview plot-line - (map (lambda (x) (vector x (fun x))) dash))) - x-lists))) - -(run-test "Simple plot-extend" - (plot (dashed-line (lambda (x) x) [color 'red])) - "dashed-line") - -(run-test "canvas sizing" - (plot (line sin) #:height 100 #:width 100) - "size") diff --git a/collects/tests/plot/shade.png b/collects/tests/plot/shade.png deleted file mode 100644 index 1079df9222d93e34c38f74280dad74cc1f0078e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15757 zcmbWeWmH^E)HO(OhXBFdrEw>?1ql+gad!yr?!he(oB+YyT^bFN27eACt*%?tJymDd*?UK+Du2L0B}RpTfx(cMlU9R)d6W3>8yOb(3)X6W7Vrbn zRPlo}%i~0DI z>;9}p3ETcsy+_43L^)CTQjHlo)n%q+ELP(M`9JNfx;(7djkg3J#LtUeHi^H$(*7tM zsG%Ed{yZ0lL#Nic-nNsxl5rJ4Xxp@AkgRwrXayY??NQlr@!mT=9uLgD%HA*F91_Qd z-$ZmPVE}%9VxtAaOSB^5fI=ws;ZX1;u&aaNVP8QP`M0;?@3^Fb+ryWzKBvICjZXz0FM?d z%(P#xH+Mwf>An<}XEh%A0lC$3wPm(h?H~*0= zg@uL1&&zvrd#lAICwRQrVAWsv^~yO+*{fgv_WGKKm$ynx-ljx@SFYBppx&4cC+eo= zEE$QIoIGBdI+em-s_m=P1H~`|#qnNgkdA;t?a8qQL!4+BPv{?Z&!0O z-(BK(pldf9ZOX_Ba#d9o-3Mrw*qzU*)2<4r1@Z9DAKfDgMbtT?=UJn!%Tbm#BP#k=j=UdQK-G@692<)G(yEQvIyQ8yzFGmLl|Ff<;R7CIFMXU9IM~BCKSa)zB zEZwTm5o4e3zSyf%Tj9Rp`pmG7Ro~<7$$OU_w_4z|qJ1ek?Izrwy1OI3!HJ`^`wZF4l~Xh@p@sdL8I& z-=*@Qx{An6O5W3taU!48^2c7%Hus~sB$^K)5aX9*j#mu2vy>_nt&D&;u6&k57AV=aLg_R#WYQ?0(PA#Q)rSGG9s%?I=HzoY^Y5 zjc)U=k=w=5EmN2Gl_hhkLdmoRbh1KY6=`pL!RH|NY6u750fCYVM6p#<@H(xVNX*KcL9$i_cd9}@z1us zz~&0GBkLtX3pimkuu=H&xMBTij~{I=ba#Bx_rJRxPM0h%Eh%RUTwLY73hzgOk8s9E zl)5?U-fx+{^4|GCej>nrtI^+8sr33h_|;De(!8|n*aNI_5x#$~xz*JiSMA;PjI+)w zWo>QkVDCYHMZ5khqsx6RG0Ym2`PtdUBS^AJybHM_-@i7luC5TDL=TjxUsKc5xCz7C z7hb2A%w9WtubI9L4rq7@s+YeIY8X;Rp88Y8>bBb6HO!G*e*0wSP_eu2d)D*Xy?!=f z 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 use as Racket executable to build Racket @@ -1986,13 +1984,6 @@ if test "${enable_futures+set}" = set; then enableval=$enable_futures; fi -# Check whether --enable-plot was given. -if test "${enable_plot+set}" = set; then - enableval=$enable_plot; -else - enable_plot=yes -fi - # Check whether --enable-float was given. if test "${enable_float+set}" = set; then enableval=$enable_float; @@ -2312,7 +2303,6 @@ show_explicitly_enabled "${enable_xonx}" "Unix style" show_explicitly_enabled "${enable_shared}" "Shared libraries" show_explicitly_disabled "${enable_gracket}" GRacket -show_explicitly_disabled "${enable_plot}" Plot if test "$LIBTOOLPROG" != "" ; then echo "=== Libtool program: $LIBTOOLPROG" @@ -8802,14 +8792,6 @@ fi makefiles="$makefiles foreign/Makefile" ac_configure_args="$ac_configure_args$SUB_CONFIGURE_EXTRAS" -if test -d "${srcdir}/plot" && test "${enable_plot}" = "yes" ; then - makefiles="$makefiles - plot/Makefile" - MAKE_PLOT=plot -else - MAKE_PLOT=no -fi - if test "${enable_gracket}" = "yes" ; then makefiles="$makefiles gracket/Makefile @@ -9581,7 +9563,6 @@ ICP!$ICP$ac_delim MRLIBINSTALL!$MRLIBINSTALL$ac_delim LIBFINISH!$LIBFINISH$ac_delim MAKE_GRACKET!$MAKE_GRACKET$ac_delim -MAKE_PLOT!$MAKE_PLOT$ac_delim MAKE_COPYTREE!$MAKE_COPYTREE$ac_delim MAKE_FINISH!$MAKE_FINISH$ac_delim WXPRECOMP!$WXPRECOMP$ac_delim diff --git a/src/get-libs.rkt b/src/get-libs.rkt index 3d772166d8..491326c388 100644 --- a/src/get-libs.rkt +++ b/src/get-libs.rkt @@ -84,8 +84,6 @@ ["libpangocairo-1.0-0.dll" 94625] ["libpangowin32-1.0-0.dll" 102210] ["libpangoft2-1.0-0.dll" 679322] - ["libplplot.dll" 245760] - ["libfit.dll" 73728] ,@(if (getenv "PLT_WIN_GTK") '(["libatk-1.0-0.dll" 153763] ["libgtk-win32-2.0-0.dll" 4740156] @@ -111,9 +109,7 @@ ["libgthread-2.0-0.dll" 126615] ["libpangocairo-1.0-0.dll" 185168] ["libpangowin32-1.0-0.dll" 192656] - ["libpangoft2-1.0-0.dll" 1188615] - ["libplplot.dll" 248832] - ["libfit.dll" 69120]]])) + ["libpangoft2-1.0-0.dll" 1188615]]])) (define-values [package dest-dir] (command-line #:args [package [dest-dir (current-directory)]] diff --git a/src/plot/Makefile.in b/src/plot/Makefile.in deleted file mode 100644 index a0ee45deb6..0000000000 --- a/src/plot/Makefile.in +++ /dev/null @@ -1,67 +0,0 @@ - -srcdir = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -libdir = @libdir@ -libpltdir = @libpltdir@ -collectsdir = @collectsdir@ -builddir = @builddir@ - -ICP=@ICP@ - -CC = @CC@ - -# See ../Makefile about RUN_RACKET_, which -# typically redirects to RUN_THIS_RACKET_: -RUN_THIS_RACKET_CGC = ../racket/racket@CGC@ - -WITH_ENV = env CC="@PLAIN_CC@" CFLAGS="@CFLAGS@ @COMPFLAGS@ @PREFLAGS@" LDFLAGS="@LDFLAGS@" - -PLPLOT_SRCS = $(srcdir)/plplot/dc_drv.c \ - $(srcdir)/plplot/plcont.c \ - $(srcdir)/plplot/plfill.c \ - $(srcdir)/plplot/plmap.c \ - $(srcdir)/plplot/plshade.c \ - $(srcdir)/plplot/plwind.c \ - $(srcdir)/plplot/pdfutils.c \ - $(srcdir)/plplot/plcore.c \ - $(srcdir)/plplot/plgridd.c \ - $(srcdir)/plplot/plmeta.c \ - $(srcdir)/plplot/plstripc.c \ - $(srcdir)/plplot/plargs.c \ - $(srcdir)/plplot/plctrl.c \ - $(srcdir)/plplot/plhist.c \ - $(srcdir)/plplot/plot3d.c \ - $(srcdir)/plplot/plsym.c \ - $(srcdir)/plplot/plbox.c \ - $(srcdir)/plplot/plcvt.c \ - $(srcdir)/plplot/plimage.c \ - $(srcdir)/plplot/plpage.c \ - $(srcdir)/plplot/pltick.c \ - $(srcdir)/plplot/plbuf.c \ - $(srcdir)/plplot/pldtik.c \ - $(srcdir)/plplot/plline.c \ - $(srcdir)/plplot/plsdef.c \ - $(srcdir)/plplot/plvpor.c - -FIT_SRCS = $(srcdir)/fit/fit.c $(srcdir)/fit/matrix.c - -XCOLLECTS = -X ../racket/gc2/xform-collects - -plot-lib: libplplot@SO_SUFFIX@ libfit@SO_SUFFIX@ - -3m: - $(MAKE) plot-lib -cgc: - $(MAKE) plot-lib - -libplplot@SO_SUFFIX@: - $(WITH_ENV) @RUN_RACKET_CGC@ -c $(srcdir)/build.rkt "libplplot" $(PLPLOT_SRCS) - -libfit@SO_SUFFIX@: - $(WITH_ENV) @RUN_RACKET_CGC@ -c $(srcdir)/build.rkt "libfit" $(FIT_SRCS) - -install: - cd ..; $(ICP) plot/libplplot@SO_SUFFIX@ "$(DESTDIR)$(libpltdir)/libplplot@SO_SUFFIX@" - cd ..; $(ICP) plot/libfit@SO_SUFFIX@ "$(DESTDIR)$(libpltdir)/libfit@SO_SUFFIX@" diff --git a/src/plot/build.bat b/src/plot/build.bat deleted file mode 100644 index a60b3ffa73..0000000000 --- a/src/plot/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -..\..\racket build.rkt libplplot plplot/dc_drv.c plplot/plcont.c plplot/plfill.c plplot/plmap.c plplot/plshade.c plplot/plwind.c plplot/pdfutils.c plplot/plcore.c plplot/plgridd.c plplot/plmeta.c plplot/plstripc.c plplot/plargs.c plplot/plctrl.c plplot/plhist.c plplot/plot3d.c plplot/plsym.c plplot/plbox.c plplot/plcvt.c plplot/plimage.c plplot/plpage.c plplot/pltick.c plplot/plbuf.c plplot/pldtik.c plplot/plline.c plplot/plsdef.c plplot/plvpor.c -..\..\racket build.rkt libfit fit/fit.c fit/matrix.c diff --git a/src/plot/build.rkt b/src/plot/build.rkt deleted file mode 100644 index 8bd0b99bb4..0000000000 --- a/src/plot/build.rkt +++ /dev/null @@ -1,32 +0,0 @@ -(module build racket/base - (require racket/path - racket/file - dynext/file - dynext/link - dynext/compile) - - (define-values (libname c-files) - (let ([l (vector->list (current-command-line-arguments))]) - (values (car l) - (cdr l)))) - - (define sys-subpath (system-library-subpath #f)) - - (define so-name (append-extension-suffix libname)) - (parameterize (;; we compile a simple .so, not an extension - [current-standard-link-libraries '()]) - (when (or (not (file-exists? so-name)) - (let ([so-time (file-or-directory-modify-seconds so-name)]) - (for/or ([f c-files]) - ((file-or-directory-modify-seconds f) . > . so-time)))) - (let ([o-files - (for/list ([c-file c-files]) - (let ([o-file (append-object-suffix (path-replace-suffix (file-name-from-path c-file) #""))]) - ;; first #f means not quiet (here and in link-extension) - (compile-extension #f c-file o-file null) - o-file))]) - (let* ([flags (if (string=? "i386-cygwin" (path->string sys-subpath)) - ;; DLL needs every dependence explicit: - '("-lc" "-lm" "-lcygwin" "-lkernel32") - null)]) - (link-extension #f (append o-files flags) so-name)))))) diff --git a/src/plot/dllexport.h b/src/plot/dllexport.h deleted file mode 100644 index b0f4023d2b..0000000000 --- a/src/plot/dllexport.h +++ /dev/null @@ -1,6 +0,0 @@ - -#if (defined(__WIN32__) || defined(WIN32) || defined(_WIN32)) -# define MZ_DLLEXPORT __declspec(dllexport) -#else -# define MZ_DLLEXPORT -#endif diff --git a/src/plot/fit/fit.c b/src/plot/fit/fit.c deleted file mode 100644 index b6f819190d..0000000000 --- a/src/plot/fit/fit.c +++ /dev/null @@ -1,752 +0,0 @@ -/* NOTICE: Change of Copyright Status - * - * The author of this module, Carsten Grammes, has expressed in - * personal email that he has no more interest in this code, and - * doesn't claim any copyright. He has agreed to put this module - * into the public domain. - * - * Lars Hecking 15-02-1999 - */ - -/* - * Nonlinear least squares fit according to the - * Marquardt-Levenberg-algorithm - * - * added as Patch to Gnuplot (v3.2 and higher) - * by Carsten Grammes - * Experimental Physics, University of Saarbruecken, Germany - * - * Internet address: cagr@rz.uni-sb.de - * - * Copyright of this module: 1993, 1998 Carsten Grammes - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose with or without fee is hereby granted, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. - * - * This software is provided "as is" without express or implied warranty. - * - * 930726: Recoding of the Unix-like raw console I/O routines by: - * Michele Marziani (marziani@ferrara.infn.it) - * drd: start unitialised variables at 1 rather than NEARLY_ZERO - * (fit is more likely to converge if started from 1 than 1e-30 ?) - * - * HBB (Broeker@physik.rwth-aachen.de) : fit didn't calculate the errors - * in the 'physically correct' (:-) way, if a third data column containing - * the errors (or 'uncertainties') of the input data was given. I think - * I've fixed that, but I'm not sure I really understood the M-L-algo well - * enough to get it right. I deduced my change from the final steps of the - * equivalent algorithm for the linear case, which is much easier to - * understand. (I also made some minor, mostly cosmetic changes) - * - * HBB (again): added error checking for negative covar[i][i] values and - * for too many parameters being specified. - * - * drd: allow 3d fitting. Data value is now called fit_z internally, - * ie a 2d fit is z vs x, and a 3d fit is z vs x and y. - * - * Lars Hecking : review update command, for VMS in particular, where - * it is not necessary to rename the old file. - * - * HBB, 971023: lifted fixed limit on number of datapoints, and number - * of parameters. - */ - - -#define FIT_MAIN - -#define NULL 0 - -//#include - - - -#include "matrix.h" -#include "fit.h" -#include -#include -#include - -/* #define STANDARD stderr */ - - -enum marq_res { - OK, ERROR, BETTER, WORSE -}; -typedef enum marq_res marq_res_t; - -#ifdef INFINITY -# undef INFINITY -#endif - -#define INFINITY 1e30 -#define NEARLY_ZERO 1e-30 - - -/* Relative change for derivatives */ -#define DELTA 0.001 - -#define MAX_DATA 2048 -#define MAX_PARAMS 32 -#define MAX_LAMBDA 1e20 -#define MIN_LAMBDA 1e-20 -#define LAMBDA_UP_FACTOR 10 -#define LAMBDA_DOWN_FACTOR 10 - -#define TBOOLEAN int - -# define PLUSMINUS "+/-" - - - -/* HBB 971023: new, allow for dynamic adjustment of these: */ -static UNUSED int max_data; -static UNUSED int max_params; - -static double epsilon = 1e-5; /* convergence limit */ -static int maxiter = 0; /* HBB 970304: maxiter patch */ - -static UNUSED char *FIXED = "# FIXED"; -static UNUSED char *GNUFITLOG = "FIT_LOG"; -static UNUSED char *FITLIMIT = "FIT_LIMIT"; -static UNUSED char *FITSTARTLAMBDA = "FIT_START_LAMBDA"; -static UNUSED char *FITLAMBDAFACTOR = "FIT_LAMBDA_FACTOR"; -static UNUSED char *FITMAXITER = "FIT_MAXITER"; /* HBB 970304: maxiter patch */ -static UNUSED char *FITSCRIPT = "FIT_SCRIPT"; -static UNUSED char *DEFAULT_CMD = "replot"; /* if no fitscript spec. */ - - -static int num_data, num_params; -static UNUSED int columns; -static double *fit_x; -static double *fit_y; -static double *fit_z ; -static double *err_data; -static double *a; - - -/* static fixstr * par_name; */ - -static double startup_lambda = 0; -static double lambda_down_factor = LAMBDA_DOWN_FACTOR; -static double lambda_up_factor = LAMBDA_UP_FACTOR; - - -static void * current_fun; - - -/***************************************************************** - internal vars to store results of fit -*****************************************************************/ - -double rms = 0; -double varience = 0; -double *asym_error; -double *asym_error_percent; - -MZ_DLLEXPORT -double get_rms() -{return rms;} - -MZ_DLLEXPORT -double get_varience() -{return varience;} - -MZ_DLLEXPORT -double * get_asym_error() -{return asym_error;} - -MZ_DLLEXPORT -double * get_asym_error_percent() -{return asym_error_percent;} - - -/***************************************************************** - internal Prototypes -*****************************************************************/ - -/*static void printmatrix __PROTO((double **C, int m, int n)); */ -static UNUSED void print_matrix_and_vectors (double **C, double *d, double *r, int m, int n); -static marq_res_t marquardt (double a[], double **alpha, double *chisq, - double *lambda); -static TBOOLEAN analyze (double a[], double **alpha, double beta[], - double *chisq); -static void calculate (double *zfunc, double **dzda, double a[]); -static void call_scheme (double *par, double *data); - -static TBOOLEAN regress (double a[]); -//static void show_fit (int i, double chisq, double last_chisq, double *a, -// double lambda, FILE * device); - - -/***************************************************************** - New utility routine: print a matrix (for debugging the alg.) -*****************************************************************/ -static UNUSED void printmatrix(C, m, n) -double **C; -int m, n; -{ - int i, j; - - for (i = 0; i < m; i++) { - for (j = 0; j < n - 1; j++); - /* Dblf2("%.8g |", C[i][j]); */ - /* Dblf2("%.8g\n", C[i][j]); */ - } - /* Dblf("\n"); */ -} - -/************************************************************************** - Yet another debugging aid: print matrix, with diff. and residue vector -**************************************************************************/ -static UNUSED void print_matrix_and_vectors(C, d, r, m, n) -double **C; -double *d, *r; -int m, n; -{ - int i, j; - - for (i = 0; i < m; i++) { - for (j = 0; j < n; j++); - /* Dblf2("%8g ", C[i][j]); */ - /* Dblf3("| %8g | %8g\n", d[i], r[i]); */ - } - /* Dblf("\n"); */ -} - - -/***************************************************************** - Marquardt's nonlinear least squares fit -*****************************************************************/ -static marq_res_t marquardt(a, C, chisq, lambda) -double a[]; -double **C; -double *chisq; -double *lambda; -{ - int i, j; - static double *da = 0, /* delta-step of the parameter */ - *temp_a = 0, /* temptative new params set */ - *d = 0, *tmp_d = 0, **tmp_C = 0, *residues = 0; - double tmp_chisq; - - /* Initialization when lambda == -1 */ - - if (*lambda == -1) { /* Get first chi-square check */ - TBOOLEAN analyze_ret; - - temp_a = vec(num_params); - d = vec(num_data + num_params); - tmp_d = vec(num_data + num_params); - da = vec(num_params); - residues = vec(num_data + num_params); - tmp_C = matr(num_data + num_params, num_params); - - analyze_ret = analyze(a, C, d, chisq); - - /* Calculate a useful startup value for lambda, as given by Schwarz */ - /* FIXME: this is doesn't turn out to be much better, really... */ - if (startup_lambda != 0) - *lambda = startup_lambda; - else { - *lambda = 0; - for (i = 0; i < num_data; i++) - for (j = 0; j < num_params; j++) - *lambda += C[i][j] * C[i][j]; - *lambda = sqrt(*lambda / num_data / num_params); - } - - /* Fill in the lower square part of C (the diagonal is filled in on - each iteration, see below) */ - for (i = 0; i < num_params; i++) - for (j = 0; j < i; j++) - C[num_data + i][j] = 0, C[num_data + j][i] = 0; - /* printmatrix(C, num_data+num_params, num_params); */ - return analyze_ret ? OK : ERROR; - } - /* once converged, free dynamic allocated vars */ - - if (*lambda == -2) { - return OK; - } - /* Givens calculates in-place, so make working copies of C and d */ - - for (j = 0; j < num_data + num_params; j++) - memcpy(tmp_C[j], C[j], num_params * sizeof(double)); - memcpy(tmp_d, d, num_data * sizeof(double)); - - /* fill in additional parts of tmp_C, tmp_d */ - - for (i = 0; i < num_params; i++) { - /* fill in low diag. of tmp_C ... */ - tmp_C[num_data + i][i] = *lambda; - /* ... and low part of tmp_d */ - tmp_d[num_data + i] = 0; - } - /* printmatrix(tmp_C, num_data+num_params, num_params); */ - - /* FIXME: residues[] isn't used at all. Why? Should it be used? */ - - Givens(tmp_C, tmp_d, da, residues, num_params + num_data, num_params, 1); - /*print_matrix_and_vectors (tmp_C, tmp_d, residues, - num_params+num_data, num_params); */ - - /* check if trial did ameliorate sum of squares */ - - for (j = 0; j < num_params; j++) - temp_a[j] = a[j] + da[j]; - - if (!analyze(temp_a, tmp_C, tmp_d, &tmp_chisq)) { - /* FIXME: will never be reached: always returns TRUE */ - return ERROR; - } - - if (tmp_chisq < *chisq) { /* Success, accept new solution */ - if (*lambda > MIN_LAMBDA) { - /* (void) putc('/', stderr); */ - *lambda /= lambda_down_factor; - } - *chisq = tmp_chisq; - for (j = 0; j < num_data; j++) { - memcpy(C[j], tmp_C[j], num_params * sizeof(double)); - d[j] = tmp_d[j]; - } - for (j = 0; j < num_params; j++) - a[j] = temp_a[j]; - return BETTER; - } else { /* failure, increase lambda and return */ - /* (void) putc('*', stderr); */ - *lambda *= lambda_up_factor; - return WORSE; - } -} - - -/* FIXME: in the new code, this function doesn't really do enough to be - * useful. Maybe it ought to be deleted, i.e. integrated with - * calculate() ? - */ -/***************************************************************** - compute chi-square and numeric derivations -*****************************************************************/ -static TBOOLEAN analyze(a, C, d, chisq) -double a[]; -double **C; -double d[]; -double *chisq; -{ -/* - * used by marquardt to evaluate the linearized fitting matrix C - * and vector d, fills in only the top part of C and d - * I don't use a temporary array zfunc[] any more. Just use - * d[] instead. - */ - int i, j; - - *chisq = 0; - calculate(d, C, a); - - for (i = 0; i < num_data; i++) { - /* note: order reversed, as used by Schwarz */ - d[i] = (d[i] - fit_z[i]) / err_data[i]; - *chisq += d[i] * d[i]; - for (j = 0; j < num_params; j++) - C[i][j] /= err_data[i]; - } - /* FIXME: why return a value that is always TRUE ? */ - return 1; -} - - -/* To use the more exact, but slower two-side formula, activate the - following line: */ - -#define TWO_SIDE_DIFFERENTIATION - -/***************************************************************** - compute function values and partial derivatives of chi-square -*****************************************************************/ -static void calculate(zfunc, dzda, a) -double *zfunc; -double **dzda; -double a[]; -{ - int k, p; - double tmp_a; - double *tmp_high, *tmp_pars; -#ifdef TWO_SIDE_DIFFERENTIATION - double *tmp_low; -#endif - - tmp_high = vec(num_data); /* numeric derivations */ -#ifdef TWO_SIDE_DIFFERENTIATION - tmp_low = vec(num_data); -#endif - tmp_pars = vec(num_params); - - /* first function values */ - - call_scheme(a, zfunc); - - /* then derivatives */ - - for (p = 0; p < num_params; p++) - tmp_pars[p] = a[p]; - for (p = 0; p < num_params; p++) { - tmp_a = fabs(a[p]) < NEARLY_ZERO ? NEARLY_ZERO : a[p]; - tmp_pars[p] = tmp_a * (1 + DELTA); - call_scheme(tmp_pars, tmp_high); -#ifdef TWO_SIDE_DIFFERENTIATION - tmp_pars[p] = tmp_a * (1 - DELTA); - call_scheme(tmp_pars, tmp_low); -#endif - for (k = 0; k < num_data; k++) -#ifdef TWO_SIDE_DIFFERENTIATION - dzda[k][p] = (tmp_high[k] - tmp_low[k]) / (2 * tmp_a * DELTA); -#else - dzda[k][p] = (tmp_high[k] - zfunc[k]) / (tmp_a * DELTA); -#endif - tmp_pars[p] = a[p]; - } - -} - - -/***************************************************************** - evaluate the scheme function -*****************************************************************/ -static void call_scheme(par, data) -double *par; -double *data; -{ - int rators = 2 + num_params; - double * rands = - (double *) malloc(rators * sizeof(double)); - - int i; - - /* set up the constant params */ - for(i = 0 ; i< num_params; i++) { - rands[i+2] = par[i]; - } - - /* now calculate the function at the existing points */ - for (i = 0; i < num_data; i++) { - rands[0] = fit_x[i]; - rands[1] = fit_y[i]; - - data[i] = ((double (*) (int, double *) )current_fun) // ouch! - (rators, rands); - } - - free(rands); - -} - -/* /\***************************************************************** */ -/* evaluate the scheme function */ -/* *****************************************************************\/ */ -/* static void call_scheme(par, data) */ -/* double *par; */ -/* double *data; */ -/* { */ -/* int rators = 2 + num_params; */ -/* Scheme_Object ** rands = */ -/* scheme_malloc(rators * sizeof(Scheme_Object)); */ - -/* int i; */ - -/* /\* set up the constant params *\/ */ -/* for(i = 0 ; i< num_params; i++) { */ -/* rands[i+2] = scheme_make_double(par[i]); */ -/* } */ - -/* /\* now calculate the function at the existing points *\/ */ -/* for (i = 0; i < num_data; i++) { */ -/* rands[0] = scheme_make_double(fit_x[i]); */ -/* rands[1] = scheme_make_double(fit_y[i]); */ - -/* data[i] = scheme_real_to_double(scheme_apply(current_fun, rators, rands)); */ -/* } */ -/* } */ - -/***************************************************************** - Frame routine for the marquardt-fit -*****************************************************************/ -static TBOOLEAN regress(a) - double a[]; -{ - double **covar, *dpar, **C, chisq, last_chisq, lambda; - int iter, i, j; - marq_res_t res; - - chisq = last_chisq = INFINITY; - C = matr(num_data + num_params, num_params); - lambda = -1; /* use sign as flag */ - iter = 0; /* iteration counter */ - - /* Initialize internal variables and 1st chi-square check */ - - if ((res = marquardt(a, C, &chisq, &lambda)) == ERROR) - return 0; /* an error occurded */ - - res = BETTER; - - /* show_fit(iter, chisq, chisq, a, lambda, STANDARD); */ - - /* MAIN FIT LOOP: do the regression iteration */ - - do { - if (res == BETTER) { - iter++; - last_chisq = chisq; - } - if ((res = marquardt(a, C, &chisq, &lambda)) == BETTER) - {}; - /* show_fit(iter, chisq, last_chisq, a, lambda, STANDARD); */ - } while ((res != ERROR) - && (lambda < MAX_LAMBDA) - && ((maxiter == 0) || (iter <= maxiter)) - && (res == WORSE - || ((chisq > NEARLY_ZERO) - ? ((last_chisq - chisq) / chisq) - : (last_chisq - chisq)) > epsilon - ) - ); - - /* fit done */ - - /* save all the info that was otherwise printed out */ - - rms = sqrt(chisq / (num_data - num_params)); - varience = chisq / (num_data - num_params); - asym_error = malloc (num_params * sizeof (double)); - asym_error_percent = malloc (num_params * sizeof (double)) ; - - /* don't know what the following code does... */ - - /* compute covar[][] directly from C */ - Givens(C, 0, 0, 0, num_data, num_params, 0); - covar = C + num_data; - Invert_RtR(C, covar, num_params); - - dpar = vec(num_params); - for (i = 0; i < num_params; i++) { - /* FIXME: can this still happen ? */ - if (covar[i][i] <= 0.0) /* HBB: prevent floating point exception later on */ - return 0; /* Eex("Calculation error: non-positive diagonal element in covar. matrix"); */ - dpar[i] = sqrt(covar[i][i]); - } - - /* transform covariances into correlations */ - for (i = 0; i < num_params; i++) { - /* only lower triangle needs to be handled */ - for (j = 0; j <= i; j++) - covar[i][j] /= dpar[i] * dpar[j]; - } - - /* scale parameter errors based on chisq */ - chisq = sqrt(chisq / (num_data - num_params)); - for (i = 0; i < num_params; i++) - dpar[i] *= chisq; - - for(i = 0; i< num_params; i++) - { - double temp = - (fabs(a[i]) < NEARLY_ZERO) ? 0.0 : fabs(100.0 * dpar[i] / a[i]); - asym_error[i] = dpar[i]; - asym_error_percent[i] = temp; - } - - return 1; - - - /******** CRAP LEFT OVER FROM GNUPLOT ***********/ - - /* HBB 970304: the maxiter patch: */ - /* - if ((maxiter > 0) && (iter > maxiter)) { - Dblf2("\nMaximum iteration count (%d) reached. Fit stopped.\n", maxiter); - } else { - Dblf2("\nAfter %d iterations the fit converged.\n", iter); - } - - Dblf2("final sum of squares of residuals : %g\n", chisq); - if (chisq > NEARLY_ZERO) { - Dblf2("rel. change during last iteration : %g\n\n", (chisq - last_chisq) / chisq); - } else { - Dblf2("abs. change during last iteration : %g\n\n", (chisq - last_chisq)); - } - - if (res == ERROR) - // Eex("FIT: error occurred during fit"); - */ - /* compute errors in the parameters */ - - /* if (num_data == num_params) { */ -/* int i; */ - -/* Dblf("\nExactly as many data points as there are parameters.\n"); */ -/* Dblf("In this degenerate case, all errors are zero by definition.\n\n"); */ -/* Dblf("Final set of parameters \n"); */ -/* Dblf("======================= \n\n"); */ -/* for (i = 0; i < num_params; i++) */ -/* Dblf3("%-15.15s = %-15g\n", par_name[i], a[i]); */ -/* } else if (chisq < NEARLY_ZERO) { */ -/* int i; */ - -/* Dblf("\nHmmmm.... Sum of squared residuals is zero. Can't compute errors.\n\n"); */ -/* Dblf("Final set of parameters \n"); */ -/* Dblf("======================= \n\n"); */ -/* for (i = 0; i < num_params; i++) */ -/* Dblf3("%-15.15s = %-15g\n", par_name[i], a[i]); */ -/* } else { */ -/* Dblf2("degrees of freedom (ndf) : %d\n", num_data - num_params); */ -/* Dblf2("rms of residuals (stdfit) = sqrt(WSSR/ndf) : %g\n", sqrt(chisq / (num_data - num_params))); */ -/* Dblf2("variance of residuals (reduced chisquare) = WSSR/ndf : %g\n\n", chisq / (num_data - num_params)); */ - -/* /\* get covariance-, Korrelations- and Kurvature-Matrix *\/ */ -/* /\* and errors in the parameters *\/ */ - -/* /\* compute covar[][] directly from C *\/ */ -/* Givens(C, 0, 0, 0, num_data, num_params, 0); */ -/* /\*printmatrix(C, num_params, num_params); *\/ */ - -/* /\* Use lower square of C for covar *\/ */ -/* covar = C + num_data; */ -/* Invert_RtR(C, covar, num_params); */ -/* /\*printmatrix(covar, num_params, num_params); *\/ */ - -/* /\* calculate unscaled parameter errors in dpar[]: *\/ */ -/* dpar = vec(num_params); */ -/* for (i = 0; i < num_params; i++) { */ -/* /\* FIXME: can this still happen ? *\/ */ -/* if (covar[i][i] <= 0.0) /\* HBB: prevent floating point exception later on *\/ */ -/* Eex("Calculation error: non-positive diagonal element in covar. matrix"); */ -/* dpar[i] = sqrt(covar[i][i]); */ -/* } */ - -/* /\* transform covariances into correlations *\/ */ -/* for (i = 0; i < num_params; i++) { */ -/* /\* only lower triangle needs to be handled *\/ */ -/* for (j = 0; j <= i; j++) */ -/* covar[i][j] /= dpar[i] * dpar[j]; */ -/* } */ - -/* /\* scale parameter errors based on chisq *\/ */ -/* chisq = sqrt(chisq / (num_data - num_params)); */ -/* for (i = 0; i < num_params; i++) */ -/* dpar[i] *= chisq; */ - -/* Dblf("Final set of parameters Asymptotic Standard Error\n"); */ -/* Dblf("======================= ==========================\n\n"); */ - -/* for (i = 0; i < num_params; i++) { */ -/* double temp = */ -/* (fabs(a[i]) < NEARLY_ZERO) ? 0.0 : fabs(100.0 * dpar[i] / a[i]); */ -/* Dblf6("%-15.15s = %-15g %-3.3s %-12.4g (%.4g%%)\n", */ -/* par_name[i], a[i], PLUSMINUS, dpar[i], temp); */ -/* } */ - -/* Dblf("\n\ncorrelation matrix of the fit parameters:\n\n"); */ -/* Dblf(" "); */ - -/* for (j = 0; j < num_params; j++) */ -/* Dblf2("%-6.6s ", par_name[j]); */ - -/* Dblf("\n"); */ -/* for (i = 0; i < num_params; i++) { */ -/* Dblf2("%-15.15s", par_name[i]); */ -/* for (j = 0; j <= i; j++) { */ -/* /\* Only print lower triangle of symmetric matrix *\/ */ -/* Dblf2("%6.3f ", covar[i][j]); */ -/* } */ -/* Dblf("\n"); */ -/* } */ - -/* free(dpar); */ -/* } */ - - return 1; -} - - -/***************************************************************** - display actual state of the fit -*****************************************************************/ -/* static void show_fit(i, chisq, last_chisq, a, lambda, device) */ -/* int i; */ -/* double chisq; */ -/* double last_chisq; */ -/* double *a; */ -/* double lambda; */ -/* FILE *device; */ -//{ - /* - int k; - - fprintf(device, "\n\n\ -Iteration %d\n\ -WSSR : %-15g delta(WSSR)/WSSR : %g\n\ -delta(WSSR) : %-15g limit for stopping : %g\n\ -lambda : %g\n\n%s parameter values\n\n", - i, chisq, chisq > NEARLY_ZERO ? (chisq - last_chisq) / chisq : 0.0, - chisq - last_chisq, epsilon, lambda, - (i > 0 ? "resultant" : "initial set of free")); - for (k = 0; k < num_params; k++) - fprintf(device, "%-15.15s = %g\n", par_name[k], a[k]); - */ -//} - - - - - - -/***************************************************************** - Interface to scheme -*****************************************************************/ -MZ_DLLEXPORT -double * do_fit(void * function, - int n_values, - double * x_values, - double * y_values, - double * z_values, - double * errors, - int n_parameters, - double * parameters) { - - /* reset lambda and other parameters if desired */ - int i; - current_fun = function; - - num_data = n_values; - fit_x = x_values; - fit_y = y_values; - fit_z = z_values; /* value is stored in z */ - err_data = errors; - - a = parameters; - num_params = n_parameters; - - /* redim_vec(&a, num_params); */ - /* par_name = (fixstr *) gp_realloc(par_name, (num_params + 1) * sizeof(fixstr), "fit param"); */ - - /* avoid parameters being equal to zero */ - for (i = 0; i < num_params; i++) { - if (a[i] == 0) { - a[i] = NEARLY_ZERO; - } - } - - if(regress(a)) { - gc_cleanup(); - return a; - } - else { /* something went wrong */ - gc_cleanup(); - return NULL; - } -} diff --git a/src/plot/fit/fit.h b/src/plot/fit/fit.h deleted file mode 100644 index 83fa7a9f33..0000000000 --- a/src/plot/fit/fit.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id: fit.h,v 1.5 2005/03/15 23:19:40 eli Exp $ */ - -/* GNUPLOT - fit.h */ - -/* NOTICE: Change of Copyright Status - * - * The author of this module, Carsten Grammes, has expressed in - * personal email that he has no more interest in this code, and - * doesn't claim any copyright. He has agreed to put this module - * into the public domain. - * - * Lars Hecking 15-02-1999 - */ - -/* - * Header file: public functions in fit.c - * - * - * Copyright of this module: Carsten Grammes, 1993 - * Experimental Physics, University of Saarbruecken, Germany - * - * Internet address: cagr@rz.uni-sb.de - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose with or without fee is hereby granted, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. - * - * This software is provided "as is" without express or implied warranty. - */ - -#include "../dllexport.h" - -#ifdef __GNUC__ -# define UNUSED __attribute__((unused)) -#else -# define UNUSED -#endif - -MZ_DLLEXPORT -double * do_fit(void * function, - int n_values, - double * x_values, - double * y_values, - double * z_values, - double * errors, - int n_parameters, - double * parameters); - - -MZ_DLLEXPORT -double get_rms(); - -MZ_DLLEXPORT -double get_varience(); - -MZ_DLLEXPORT -double * get_asym_error(); - -MZ_DLLEXPORT -double * get_asym_error_percent(); diff --git a/src/plot/fit/matrix.c b/src/plot/fit/matrix.c deleted file mode 100644 index 76015775db..0000000000 --- a/src/plot/fit/matrix.c +++ /dev/null @@ -1,315 +0,0 @@ -/* NOTICE: Change of Copyright Status - * - * The author of this module, Carsten Grammes, has expressed in - * personal email that he has no more interest in this code, and - * doesn't claim any copyright. He has agreed to put this module - * into the public domain. - * - * Lars Hecking 15-02-1999 - */ - -/* - * Matrix algebra, part of - * - * Nonlinear least squares fit according to the - * Marquardt-Levenberg-algorithm - * - * added as Patch to Gnuplot (v3.2 and higher) - * by Carsten Grammes - * Experimental Physics, University of Saarbruecken, Germany - * - * Internet address: cagr@rz.uni-sb.de - * - * Copyright of this module: Carsten Grammes, 1993 - * - * Permission to use, copy, and distribute this software and its - * documentation for any purpose with or without fee is hereby granted, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. - * - * This software is provided "as is" without express or implied warranty. - */ - -#define NULL 0 -#define null 0 - -#include "fit.h" -#include "matrix.h" -#include -#include - -// create a simple gc malloc... -typedef struct Node { - struct Node * next; - void * ptr; -} Node; - -Node * head = null; - -void * my_gc_malloc(int size) { - void * ptr = malloc(size); - Node * n = (Node *)malloc(sizeof (Node)); - n->ptr = ptr; - n->next = head; - head = n; - return ptr; -} - -void gc_cleanup(){ - while(head) { - Node * current = head; - head = current->next; - free(current->ptr); - free(current); - } -} - - - -/*****************************************************************/ - -#define Swap(a,b) {double temp = (a); (a) = (b); (b) = temp;} -#define WINZIG 1e-30 - - -/***************************************************************** - internal prototypes -*****************************************************************/ - -static int fsign (double x); - -/***************************************************************** - first straightforward vector and matrix allocation functions -*****************************************************************/ -MZ_DLLEXPORT -double *vec (n) -int n; -{ - /* allocates a double vector with n elements */ - double *dp; - if( n < 1 ) - return (double *) NULL; - dp = (double *) my_gc_malloc (n * sizeof(double)); - return dp; -} - - -MZ_DLLEXPORT -double **matr (rows, cols) -int rows; -int cols; -{ - /* allocates a double matrix */ - - register int i; - register double **m; - - if ( rows < 1 || cols < 1 ) - return NULL; - m = (double **) my_gc_malloc (rows * sizeof(double *)); - m[0] = (double *) my_gc_malloc (rows * cols * sizeof(double)); - for ( i = 1; i0 ? 1 : (x < 0) ? -1 : 0) ; -} - -/***************************************************************** - - Solve least squares Problem C*x+d = r, |r| = min!, by Given rotations - (QR-decomposition). Direct implementation of the algorithm - presented in H.R.Schwarz: Numerische Mathematik, 'equation' - number (7.33) - - If 'd == NULL', d is not accesed: the routine just computes the QR - decomposition of C and exits. - - If 'want_r == 0', r is not rotated back (\hat{r} is returned - instead). - -*****************************************************************/ - -MZ_DLLEXPORT -void Givens (C, d, x, r, N, n, want_r) -double **C; -double *d; -double *x; -double *r; -int N; -int n; -int want_r; -{ - int i, j, k; - double w, gamma, sigma, rho, temp; - double epsilon = 1e-5; /* FIXME (?)*/ - -/* - * First, construct QR decomposition of C, by 'rotating away' - * all elements of C below the diagonal. The rotations are - * stored in place as Givens coefficients rho. - * Vector d is also rotated in this same turn, if it exists - */ - for (j = 0; j= 0; i--) { /* solve R*x+d = 0, by backsubstitution */ - double s = d[i]; - r[i] = 0; /* ... and also set r[i] = 0 for i= 0; j--) - for (i = N-1; i >= 0; i--) { - if ((rho = C[i][j]) == 1) { /* reconstruct gamma, sigma from stored rho */ - gamma = 0; - sigma = 1; - } else if (fabs(rho)<1) { - sigma = rho; - gamma = sqrt(1-sigma*sigma); - } else { - gamma = 1/fabs(rho); - sigma = fsign(rho)*sqrt(1-gamma*gamma); - } - temp = gamma*r[j] + sigma*r[i]; /* rotate back indices (i,j) */ - r[i] = -sigma*r[j] + gamma*r[i]; - r[j] = temp; - } -} - - -/* Given a triangular Matrix R, compute (R^T * R)^(-1), by forward - * then back substitution - * - * R, I are n x n Matrices, I is for the result. Both must already be - * allocated. - * - * Will only calculate the lower triangle of I, as it is symmetric - */ - -MZ_DLLEXPORT -void Invert_RtR ( R, I, n) -double **R; -double **I; -int n; -{ - int i, j, k; - - /* fill in the I matrix, and check R for regularity : */ - - for (i = 0; i= k; i--) { /* don't compute upper triangle of A */ - double s = I[i][k]; - for (j = i+1; j. -*/ - -#include "plDevs.h" -#include "plplotP.h" -#include "drivers.h" - -/* Device info */ -char* plD_DEVICE_INFO_dc = "dc:dc<%>:0:dc:50:dc"; - -void plD_init_dc (PLStream *); -void plD_line_dc (PLStream *, short, short, short, short); -void plD_polyline_dc (PLStream *, short *, short *, PLINT); -void plD_eop_dc (PLStream *); -void plD_eop_jpeg (PLStream *); -void plD_bop_dc (PLStream *); -void plD_tidy_dc (PLStream *); -void plD_state_dc (PLStream *, PLINT); -void plD_esc_dc (PLStream *, PLINT, void *); - -typedef struct { - void *p; - void (*drawLine)(void *p, short x1a, short y1a, short x2a, short y2a); - void (*drawLines)(void *p, short *xa, short *ya, PLINT npts); - void (*fillPoly)(void *p, short *xa, short *ya, PLINT npts); - void (*setWidth)(void *p, int w); - void (*setColor)(void *p, short i); - void (*setColorRGB)(void *p, short r, short g, short b); - void (*startPage)(void *p); - void (*endPage)(void *p); - void (*endDoc)(void *p); -} dc_Dev; - -void plD_dispatch_init_dc( PLDispatchTable *pdt ) -{ - pdt->pl_MenuStr = "drawing context"; - pdt->pl_DevName = "dc<%>"; - pdt->pl_type = plDevType_FileOriented; - pdt->pl_seq = 50; - pdt->pl_init = (plD_init_fp) plD_init_dc; - pdt->pl_line = (plD_line_fp) plD_line_dc; - pdt->pl_polyline = (plD_polyline_fp) plD_polyline_dc; - pdt->pl_eop = (plD_eop_fp) plD_eop_dc; - pdt->pl_bop = (plD_bop_fp) plD_bop_dc; - pdt->pl_tidy = (plD_tidy_fp) plD_tidy_dc; - pdt->pl_state = (plD_state_fp) plD_state_dc; - pdt->pl_esc = (plD_esc_fp) plD_esc_dc; -} - -/*--------------------------------------------------------------------------*\ - * plD_init_dc_Dev() - * -\*--------------------------------------------------------------------------*/ - -static void -plD_init_dc_Dev(PLStream *pls) -{ - /* Allocate and initialize device-specific data */ - dc_Dev *dev; - - if (pls->dev != NULL) - free((void *) pls->dev); - - pls->dev = calloc(1, (size_t) sizeof(dc_Dev)); - if (pls->dev == NULL) - plexit("plD_init_dc_Dev: Out of memory."); - - dev = (dc_Dev *) pls->dev; -} - -/*----------------------------------------------------------------------*\ - * plD_init_dc() - * - * Initialize device. -\*----------------------------------------------------------------------*/ - -void plD_init_dc(PLStream *pls) -{ - dc_Dev *dev; - - pls->termin = 0; /* Not an interactive device */ - pls->icol0 = 1; - pls->bytecnt = 0; - pls->page = 0; - pls->dev_fill0 = 1; /* Can do solid fills */ - - if (!pls->colorset) - pls->color = 1; /* Is a color device */ - -/* Initialize family file info */ - plFamInit(pls); - -/* Allocate and initialize device-specific data */ - plD_init_dc_Dev(pls); - dev=(dc_Dev *)pls->dev; - - if (pls->xlength <= 0 || pls->ylength <=0) - { -/* use default width, height of 800x600 if not specifed by -geometry option - * or plspage */ - plspage(0., 0., 800, 600, 0, 0); - } - - pls->graphx = GRAPHICS_MODE; - - if (pls->xdpi<=0) - { -/* This corresponds to a typical monitor resolution of 4 pixels/mm. */ - plspage(4.*25.4, 4.*25.4, 0, 0, 0, 0); - } - else - { - pls->ydpi=pls->xdpi; /* Set X and Y dpi's to the same value */ - } -/* Convert DPI to pixels/mm */ - plP_setpxl(1*pls->xdpi/25.4,1*pls->ydpi/25.4); - - plP_setphy(0, 1*(pls->xlength - 1), 0, 1*(pls->ylength - 1)); -} - -/*----------------------------------------------------------------------*\ - * plD_line_dc() - * - * Draw a line in the current color from (x1,y1) to (x2,y2). -\*----------------------------------------------------------------------*/ - -void -plD_line_dc(PLStream *pls, short x1a, short y1a, short x2a, short y2a) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - if (dev->drawLine) - dev->drawLine(dev->p, x1a, y1a, x2a, y2a); -} - -/*----------------------------------------------------------------------*\ - * plD_polyline_dc() - * - * Draw a polyline in the current color. -\*----------------------------------------------------------------------*/ - -void -plD_polyline_dc(PLStream *pls, short *xa, short *ya, PLINT npts) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - if (dev->drawLines) - dev->drawLines(dev->p, xa, ya, npts); -} - - -/*----------------------------------------------------------------------*\ - * fill_polygon() - * - * Fill polygon described in points pls->dev_x[] and pls->dev_y[]. -\*----------------------------------------------------------------------*/ - -static void -fill_polygon(PLStream *pls) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - if (dev->fillPoly) - dev->fillPoly(dev->p, pls->dev_x, pls->dev_y, pls->dev_npts); -} - - -/*----------------------------------------------------------------------*\ - * plD_state_dc() - * - * Handle change in PLStream state (color, pen width, fill attribute, etc). -\*----------------------------------------------------------------------*/ - -void -plD_state_dc(PLStream *pls, PLINT op) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - switch (op) { - - case PLSTATE_WIDTH: - if (dev->setWidth) - dev->setWidth(dev->p, pls->width); - break; - - case PLSTATE_COLOR0: - - if (pls->icol0 == PL_RGB_COLOR) { - if (dev->setColorRGB) - dev->setColorRGB(dev->p, pls->curcolor.r, pls->curcolor.g, pls->curcolor.b); - } else { - if (dev->setColor) - dev->setColor(dev->p, pls->icol0); - } - break; - - case PLSTATE_COLOR1: - if (dev->setColorRGB) - dev->setColorRGB(dev->p, pls->curcolor.r, pls->curcolor.g, pls->curcolor.b); - break; - } -} - - -/*----------------------------------------------------------------------*\ - * plD_esc_dc() - * - * Escape function. -\*----------------------------------------------------------------------*/ - -void plD_esc_dc(PLStream *pls, PLINT op, void *ptr) -{ - switch (op) { - - case PLESC_FILL: /* fill */ - fill_polygon(pls); - break; - - } -} - -/*----------------------------------------------------------------------*\ - * plD_bop_dc() - * - * Set up for the next page. - * Advance to next family file if necessary (file output). -\*----------------------------------------------------------------------*/ - -void plD_bop_dc(PLStream *pls) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - if (dev->startPage) - dev->startPage(dev->p); -} - -/*----------------------------------------------------------------------*\ - * plD_tidy_dc() - * - * Close graphics file or otherwise clean up. -\*----------------------------------------------------------------------*/ - -void plD_tidy_dc(PLStream *pls) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - if (dev->endDoc) - dev->endDoc(dev->p); - -} - -/*----------------------------------------------------------------------*\ - * plD_eop_dc() - * - * End of page. -\*----------------------------------------------------------------------*/ - -void plD_eop_dc(PLStream *pls) -{ - dc_Dev *dev=(dc_Dev *)pls->dev; - - if (dev->endPage) - dev->endPage(dev->p); -} diff --git a/src/plot/plplot/disptab.h b/src/plot/plplot/disptab.h deleted file mode 100644 index 6e98329ad0..0000000000 --- a/src/plot/plplot/disptab.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $Id: disptab.h,v 1.1 2004/03/01 20:54:46 cozmic Exp $ - - Defines the data structure which holds the driver functions. -*/ - -#ifndef __DISPATCH_H__ -#define __DISPATCH_H__ - -#include "plConfig.h" - -struct PLStream_struct; - -enum { - plDevType_FileOriented = 0, - plDevType_Interactive = 1, - plDevType_Null = -1 -}; - -/*--------------------------------------------------------------------------*\ - * Define structure containing pointers to device dependent functions. - * - * pl_MenuStr Pointer to string that is printed in device menu. - * - * pl_DevName A short device "name" for device selection by name. - * - * pl_type 0 for file-oriented device, 1 for interactive - * (the null driver uses -1 here) - * - * pl_seq The sequence number for ordering the presentation list of the - * available drivers. This is an ordering only, not an absolute - * position in the list. - * - * pl_init Initialize device. This routine may also prompt the user - * for certain device parameters or open a graphics file - * (see note). Called only once to set things up. Certain - * options such as familying and resolution (dots/mm) should - * be set up before calling this routine (note: some drivers - * ignore these). - * - * pl_line Draws a line between two points. - * - * pl_polyline Draws a polyline (no broken segments). - * - * pl_eop Finishes out current page (see note). - * - * pl_bop Set up for plotting on a new page. May also open a new - * a new graphics file (see note). - * - * pl_tidy Tidy up. May close graphics file (see note). - * - * pl_state Handle change in PLStream state - * (color, pen width, fill attribute, etc). - * - * pl_esc Escape function for driver-specific commands. - * - * - * Notes: - * - * Most devices allow multi-page plots to be stored in a single graphics - * file, in which case the graphics file should be opened in the pl_init() - * routine, closed in pl_tidy(), and page advances done by calling pl_eop - * and pl_bop() in sequence. If multi-page plots need to be stored in - * different files then pl_bop() should open the file and pl_eop() should - * close it. Do NOT open files in both pl_init() and pl_bop() or close - * files in both pl_eop() and pl_tidy(). -\*--------------------------------------------------------------------------*/ - -typedef void (*plD_init_fp) (struct PLStream_struct *); -typedef void (*plD_line_fp) (struct PLStream_struct *, short, short, short, short); -typedef void (*plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT); -typedef void (*plD_eop_fp) (struct PLStream_struct *); -typedef void (*plD_bop_fp) (struct PLStream_struct *); -typedef void (*plD_tidy_fp) (struct PLStream_struct *); -typedef void (*plD_state_fp) (struct PLStream_struct *, PLINT); -typedef void (*plD_esc_fp) (struct PLStream_struct *, PLINT, void *); - -typedef struct { - char *pl_MenuStr; - char *pl_DevName; - int pl_type; - int pl_seq; - plD_init_fp pl_init; - plD_line_fp pl_line; - plD_polyline_fp pl_polyline; - plD_eop_fp pl_eop; - plD_bop_fp pl_bop; - plD_tidy_fp pl_tidy; - plD_state_fp pl_state; - plD_esc_fp pl_esc; -} PLDispatchTable; - -#endif /* __DISPATCH_H__ */ diff --git a/src/plot/plplot/drivers.h b/src/plot/plplot/drivers.h deleted file mode 100644 index 30fc09190b..0000000000 --- a/src/plot/plplot/drivers.h +++ /dev/null @@ -1,81 +0,0 @@ -/* $Id: drivers.h,v 1.1 2004/03/01 20:54:46 cozmic Exp $ - - Contains all prototypes for driver functions. -*/ - -#ifndef __DRIVERS_H__ -#define __DRIVERS_H__ - -#include "pdf.h" -#include "plstrm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void plD_dispatch_init_mac8 ( PLDispatchTable *pdt ); -void plD_dispatch_init_mac1 ( PLDispatchTable *pdt ); -void plD_dispatch_init_nx ( PLDispatchTable *pdt ); -void plD_dispatch_init_os2 ( PLDispatchTable *pdt ); -void plD_dispatch_init_xw ( PLDispatchTable *pdt ); -void plD_dispatch_init_gnome ( PLDispatchTable *pdt ); -void plD_dispatch_init_tk ( PLDispatchTable *pdt ); -void plD_dispatch_init_vga ( PLDispatchTable *pdt ); -void plD_dispatch_init_mgr ( PLDispatchTable *pdt ); -void plD_dispatch_init_win3 ( PLDispatchTable *pdt ); -void plD_dispatch_init_vga ( PLDispatchTable *pdt ); -void plD_dispatch_init_vga ( PLDispatchTable *pdt ); -void plD_dispatch_init_vga ( PLDispatchTable *pdt ); -void plD_dispatch_init_tiff ( PLDispatchTable *pdt ); -void plD_dispatch_init_jpg ( PLDispatchTable *pdt ); -void plD_dispatch_init_jpeg ( PLDispatchTable *pdt ); -void plD_dispatch_init_bmp ( PLDispatchTable *pdt ); -void plD_dispatch_init_vga ( PLDispatchTable *pdt ); -void plD_dispatch_init_xterm ( PLDispatchTable *pdt ); -void plD_dispatch_init_tekt ( PLDispatchTable *pdt ); -void plD_dispatch_init_tek4107t ( PLDispatchTable *pdt ); -void plD_dispatch_init_mskermit ( PLDispatchTable *pdt ); -void plD_dispatch_init_versaterm( PLDispatchTable *pdt ); -void plD_dispatch_init_vlt ( PLDispatchTable *pdt ); -void plD_dispatch_init_conex ( PLDispatchTable *pdt ); -void plD_dispatch_init_dg ( PLDispatchTable *pdt ); -void plD_dispatch_init_plm ( PLDispatchTable *pdt ); -void plD_dispatch_init_tekf ( PLDispatchTable *pdt ); -void plD_dispatch_init_tek4107f ( PLDispatchTable *pdt ); -void plD_dispatch_init_psm ( PLDispatchTable *pdt ); -void plD_dispatch_init_psc ( PLDispatchTable *pdt ); -void plD_dispatch_init_xfig ( PLDispatchTable *pdt ); -void plD_dispatch_init_ljiip ( PLDispatchTable *pdt ); -void plD_dispatch_init_ljii ( PLDispatchTable *pdt ); -void plD_dispatch_init_hp7470 ( PLDispatchTable *pdt ); -void plD_dispatch_init_hp7580 ( PLDispatchTable *pdt ); -void plD_dispatch_init_hpgl ( PLDispatchTable *pdt ); -void plD_dispatch_init_imp ( PLDispatchTable *pdt ); -void plD_dispatch_init_pbm ( PLDispatchTable *pdt ); -void plD_dispatch_init_png ( PLDispatchTable *pdt ); -void plD_dispatch_init_cgm ( PLDispatchTable *pdt ); -void plD_dispatch_init_null ( PLDispatchTable *pdt ); -void plD_dispatch_init_tkwin ( PLDispatchTable *pdt ); -void plD_dispatch_init_pstex ( PLDispatchTable *pdt ); -void plD_dispatch_init_ntk ( PLDispatchTable *pdt ); -void plD_dispatch_init_mem ( PLDispatchTable *pdt ); -void plD_dispatch_init_dc ( PLDispatchTable *pdt ); - -/* Prototypes for plot buffer calls. */ - -void plbuf_init (PLStream *); -void plbuf_line (PLStream *, short, short, short, short); -void plbuf_polyline (PLStream *, short *, short *, PLINT); -void plbuf_eop (PLStream *); -void plbuf_bop (PLStream *); -void plbuf_tidy (PLStream *); -void plbuf_state (PLStream *, PLINT); -void plbuf_esc (PLStream *, PLINT, void *); - -void plRemakePlot (PLStream *); - -#ifdef __cplusplus -} -#endif - -#endif /* __DRIVERS_H__ */ diff --git a/src/plot/plplot/metadefs.h b/src/plot/plplot/metadefs.h deleted file mode 100644 index 0045c40c94..0000000000 --- a/src/plot/plplot/metadefs.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $Id: metadefs.h,v 1.1 2004/03/01 20:54:50 cozmic Exp $ - - Geoffrey Furnish - 5 May 1991 - - This file contains definitions of constants and structures which - are needed by the PLplot metafile writer and renderer. -*/ - -/* -* PLMETA_HEADER holds the magic string at head of metafile. -* PLMETA_VERSION holds the version number (year & letter). -* -* Note: All strings written into the file header are limited to a maximum -* of 80 characters. -*/ - -#define PLMETA_HEADER "PLPLOT" -#define PLMETA_VERSION "1993c" - -/* These are used by the TK driver client/server code */ - -#define PLSERV_HEADER "PLPLOT" -#define PLSERV_VERSION "1993b" - -/* Symbolic constants for old metafile versions (prior to 1992a). */ -/* Now these are stored in the metafile header. */ - -#define PLMETA_X_OLD 10000 -#define PLMETA_Y_OLD 10000 - -/* Virtual dots/mm for our virtual display space. */ - -#define PIXEL_RES_X_OLD 42 -#define PIXEL_RES_Y_OLD 56 - -/* Macros to make it easier to abort on nonzero return code */ -/* Can't call plexit on a write failure since that would be circular */ - -#define plm_wr(code) \ - if (code) { fprintf(stderr, "Unable to write to MetaFile\n"); exit(1); } - -#define plm_rd(code) \ - if (code) plexit( "Unable to read from MetaFile" ) - -/* - Metafile commands. - - *** NOTICE !!! *** - If you change ANY of the following, you will wreck backward - backward compatibility with old metafiles. You may add, but do - NOT delete !!! -*/ - -#define INITIALIZE 1 -#define CLOSE 2 -#define SWITCH_TO_TEXT 3 /* Obsolete, replaced by ESCAPE */ -#define SWITCH_TO_GRAPH 4 /* Obsolete, replaced by ESCAPE */ -#define EOP 5 -#define BOP 6 -#define NEW_COLOR 7 /* Obsolete, replaced by CHANGE_STATE */ -#define NEW_WIDTH 8 /* Obsolete, replaced by CHANGE_STATE */ -#define LINE 9 -#define LINETO 10 -#define ESCAPE 11 -#define ADVANCE 12 /* Obsolete, BOP/EOP used instead */ -#define POLYLINE 13 -#define NEW_COLOR0 NEW_COLOR -#define NEW_COLOR1 14 -#define CHANGE_STATE 15 -#define BOP0 16 /* First BOP in a file */ -#define END_OF_FIELD 255 diff --git a/src/plot/plplot/nan.h b/src/plot/plplot/nan.h deleted file mode 100644 index 8699d60f9c..0000000000 --- a/src/plot/plplot/nan.h +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** - * - * File: nan.h - * - * Created: 18/10/2001 - * - * Author: Pavel Sakov - * CSIRO Marine Research - * - * Purpose: NaN definition - * - * Description: Should cover 64 bit machines or other machines with GCC - * - * Revisions: None - * - *****************************************************************************/ - -#if !defined(_NAN_H) -#define _NAN_H - -#if defined(__GNUC__) -static const double NaN = 0.0 / 0.0; -#elif defined(BIG_ENDIAN) -static const long long lNaN = 0x7fffffffffffffff; - -#define NaN (*(double*)&lNaN) -#else -static const long lNaN = 0xfff8000000000000; - -#define NaN (*(double*)&lNaN) -#endif - -#endif diff --git a/src/plot/plplot/pdf.h b/src/plot/plplot/pdf.h deleted file mode 100644 index 646348d175..0000000000 --- a/src/plot/plplot/pdf.h +++ /dev/null @@ -1,107 +0,0 @@ -/* $Id: pdf.h,v 1.1 2004/03/01 20:54:50 cozmic Exp $ - - Copyright (C) 1992 by Maurice J. LeBrun - - Macros and prototypes for the PDF package. - - This software may be freely copied, modified and redistributed without - fee provided that this copyright notice is preserved intact on all - copies and modified copies. - - There is no warranty or other guarantee of fitness of this software. - It is provided solely "as is". The author(s) disclaim(s) all - responsibility and liability with respect to this software's usage or - its effect upon hardware or computer systems. -*/ - -#ifndef __PDF_H__ -#define __PDF_H__ - -/* Some unsigned types */ - -#ifndef U_CHAR -#define U_CHAR unsigned char -#endif - -#ifndef U_SHORT -#define U_SHORT unsigned short -#endif - -#ifndef U_INT -#define U_INT unsigned int -#endif - -#ifndef U_LONG -#define U_LONG unsigned long -#endif - -#ifdef PLPLOT_USE_TCL_CHANNELS -#include -#endif - -/* PDFstrm definition */ -/* The low level PDF i/o routines use the transfer method appropriate for */ -/* the first non-null type below */ - -typedef struct { - FILE *file; /* Filesystem */ - unsigned char *buffer; /* Memory buffer */ -#ifdef PLPLOT_USE_TCL_CHANNELS - Tcl_Channel tclChan; /* Tcl channel */ -#endif - long bp, bufmax; /* Buffer pointer and max size */ -} PDFstrm; - -/* Info for the i/o device. Only used by Tcl/TK/dp drivers for now */ - -typedef struct { - int fd; /* I/O device file descriptor */ - FILE *file; /* File handle */ - char *fileName; /* Fifo or socket name (if needed) */ - char *fileHandle; /* Handle for use from interpreter */ - int type; /* Communication channel type */ - char *typeName; /* As above, but in string form */ -} PLiodev; - -/* Error numbers */ - -#define PDF_ERROR 1 /* Unknown error */ -#define PDF_FNOPEN 2 /* File not open */ -#define PDF_FAOPEN 3 /* File already open */ -#define PDF_BADUN 4 /* Bad unit number */ -#define PDF_BADNBITS 5 /* Invalid # of bits */ -#define PDF_RDERR 6 /* Read error */ -#define PDF_WRERR 7 /* Write error */ -#define PDF_NOTPDF 8 /* Not a valid PDF file */ - -/* Prototypes */ -/* Use a wrapper for the prototypes for use from K&R C */ - -void pdf_set PLARGS((char *option, int value)); -PDFstrm *pdf_fopen PLARGS((char *fileName, char *mode)); -PDFstrm *pdf_bopen PLARGS((U_CHAR *buffer, long bufmax)); -PDFstrm *pdf_finit PLARGS((FILE *file)); -PDFstrm *plLibOpenPdfstrm PLARGS((char *fn)); -int pdf_close PLARGS((PDFstrm *pdfs)); - -int pdf_putc PLARGS((int c, PDFstrm *pdfs)); -int pdf_getc PLARGS((PDFstrm *pdfs)); -int pdf_ungetc PLARGS((int c, PDFstrm *pdfs)); -int pdf_rdx PLARGS((U_CHAR *x, long nitems, PDFstrm *pdfs)); - -int pdf_rd_header PLARGS((PDFstrm *pdfs, char *header)); -int pdf_wr_header PLARGS((PDFstrm *pdfs, char *header)); -int pdf_wr_string PLARGS((PDFstrm *pdfs, const char *string)); -int pdf_rd_string PLARGS((PDFstrm *pdfs, char *string, int nmax)); -int pdf_wr_1byte PLARGS((PDFstrm *pdfs, U_CHAR s)); -int pdf_rd_1byte PLARGS((PDFstrm *pdfs, U_CHAR *ps)); -int pdf_wr_2bytes PLARGS((PDFstrm *pdfs, U_SHORT s)); -int pdf_rd_2bytes PLARGS((PDFstrm *pdfs, U_SHORT *ps)); -int pdf_wr_2nbytes PLARGS((PDFstrm *pdfs, U_SHORT *s, PLINT n)); -int pdf_rd_2nbytes PLARGS((PDFstrm *pdfs, U_SHORT *s, PLINT n)); -int pdf_wr_4bytes PLARGS((PDFstrm *pdfs, U_LONG s)); -int pdf_rd_4bytes PLARGS((PDFstrm *pdfs, U_LONG *ps)); -int pdf_wr_ieeef PLARGS((PDFstrm *pdfs, float f)); -int pdf_rd_ieeef PLARGS((PDFstrm *pdfs, float *pf)); - -#endif /* __PDF_H__ */ diff --git a/src/plot/plplot/pdfutils.c b/src/plot/plplot/pdfutils.c deleted file mode 100644 index b9a91a73e1..0000000000 --- a/src/plot/plplot/pdfutils.c +++ /dev/null @@ -1,917 +0,0 @@ -/* $Id: pdfutils.c,v 1.1 2004/03/01 20:54:50 cozmic Exp $ - - pdf_utils.c - - Copyright (C) 1992, 1993, 1994, 1995 - Maurice LeBrun mjl@dino.ph.utexas.edu - Institute for Fusion Studies University of Texas at Austin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - These functions do the low-level reading/writing of portable data files. - Data can be written to/read from either a file handle or memory buffer. -*/ - -#define NEED_PLDEBUG -#include "plplotP.h" - -static void print_ieeef (void *, void *); -static int pdf_wrx (const U_CHAR *x, long nitems, PDFstrm *pdfs); - -static int debug = 0; - -/*--------------------------------------------------------------------------*\ - * void pdf_set (string, value) - * - * Set an option. Pretty sparse right now but you never know. -\*--------------------------------------------------------------------------*/ - -void -pdf_set(char *option, int value) -{ - if ( ! strcmp(option, "debug")) - debug = value; -} - -/*--------------------------------------------------------------------------*\ - * pdf_fopen() - * - * Initializes a PDFstrm for a file oriented device. - * Used exactly like fopen(). -\*--------------------------------------------------------------------------*/ - -PDFstrm * -pdf_fopen(char *filename, char *mode) -{ - PDFstrm *pdfs; - - dbug_enter("pdf_fopen"); - - pdfs = (PDFstrm *) malloc(sizeof(PDFstrm)); - - if (pdfs != NULL) { - pdfs->buffer = NULL; - pdfs->file = NULL; -#ifdef PLPLOT_USE_TCL_CHANNELS - pdfs->tclChan = NULL; - if (1) { - char new_mode[3]; - int binary = 0; - char *m, *p; - - /* Copy over the mode, removing 'b' if needed */ - for (m = mode, p = new_mode; *m != 0; m++) { - if (*m == 'b') { - binary = 1; - } else { - *p = *m; - p++; - } - } - *p = 0; - - pdfs->tclChan = Tcl_OpenFileChannel(NULL, filename, new_mode, 0); - if (pdfs->tclChan == NULL) { - pdf_close(pdfs); - pdfs = NULL; - } else { - if (binary) { - Tcl_SetChannelOption(NULL, pdfs->tclChan, "-translation", - "binary"); - } - } - } -#else - pdfs->file = fopen(filename, mode); - if (pdfs->file == NULL) { - pdf_close(pdfs); - pdfs = NULL; - } -#endif - } - - return pdfs; -} - -/*--------------------------------------------------------------------------*\ - * pdf_bopen() - * - * Initializes a PDFstrm for reading/writing to a memory buffer. - * If buffer is NULL, a standard buffer is allocated. -\*--------------------------------------------------------------------------*/ - -PDFstrm * -pdf_bopen(U_CHAR *buffer, long bufmax) -{ - PDFstrm *pdfs; - - dbug_enter("pdf_bopen"); - - pdfs = (PDFstrm *) malloc(sizeof(PDFstrm)); - - if (pdfs != NULL) { - pdfs->file = NULL; -#ifdef PLPLOT_USE_TCL_CHANNELS - pdfs->tclChan = NULL; -#endif - pdfs->bp = 0; - - if (buffer == NULL) { - if (bufmax > 0) - pdfs->bufmax = bufmax; - else - pdfs->bufmax = 2048; - - pdfs->buffer = (U_CHAR *) malloc(pdfs->bufmax); - if (pdfs->buffer == NULL) { - pdf_close(pdfs); - pdfs = NULL; - } - } - else { - pdfs->bufmax = bufmax; - pdfs->buffer = buffer; - } - } - - return pdfs; -} - -/*--------------------------------------------------------------------------*\ - * pdf_finit() - * - * Initializes a PDFstrm for a file oriented device. - * Like pdf_fopen() but an existing file handle is specified. -\*--------------------------------------------------------------------------*/ - -PDFstrm * -pdf_finit(FILE *file) -{ - PDFstrm *pdfs; - - dbug_enter("pdf_finit"); - - pdfs = (PDFstrm *) malloc(sizeof(PDFstrm)); - - if (pdfs != NULL) { - pdfs->buffer = NULL; - pdfs->file = file; -#ifdef PLPLOT_USE_TCL_CHANNELS - pdfs->tclChan = NULL; -#endif - pdfs->bp = 0; - } - - return pdfs; -} - -/*--------------------------------------------------------------------------*\ - * pdf_close() - * - * Closes a PDFstrm. - * Used exactly like fclose(). -\*--------------------------------------------------------------------------*/ - -int -pdf_close(PDFstrm *pdfs) -{ - dbug_enter("pdf_close"); - - if (pdfs != NULL) { - if (pdfs->file != NULL) { - fclose(pdfs->file); -#ifdef PLPLOT_USE_TCL_CHANNELS - } else if (pdfs->tclChan != NULL) { - Tcl_Close(NULL, pdfs->tclChan); -#endif - } else if (pdfs->buffer != NULL) { - free ((void *) pdfs->buffer); - } - free((void *) pdfs); - } - return 0; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_putc() - * - * Writes a single character. -\*--------------------------------------------------------------------------*/ - -int -pdf_putc(int c, PDFstrm *pdfs) -{ - int result = EOF; - - if (pdfs->file != NULL) { - result = putc(c, pdfs->file); - pdfs->bp++; -#ifdef PLPLOT_USE_TCL_CHANNELS - } else if (pdfs->tclChan != NULL) { - result = Tcl_WriteChars(pdfs->tclChan, &c, 1); - pdfs->bp++; -#endif - } else if (pdfs->buffer != NULL) { - if (pdfs->bp >= pdfs->bufmax) { - pldebug("pdf_putc", - "Increasing buffer to %d bytes\n", pdfs->bufmax); - pdfs->bufmax += 512; - pdfs->buffer = (U_CHAR *) - realloc((void *) pdfs->buffer, pdfs->bufmax); - } - pdfs->buffer[pdfs->bp++] = c; - result = c; - } - else - plexit("pdf_putc: Illegal operation"); - - return result; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_getc() - * - * Reads a single character. -\*--------------------------------------------------------------------------*/ - -int -pdf_getc(PDFstrm *pdfs) -{ - int result = EOF; - - if (pdfs->file != NULL) { - result = getc(pdfs->file); - pdfs->bp++; -#ifdef PLPLOT_USE_TCL_CHANNELS - } else if (pdfs->tclChan != NULL) { - result = Tcl_Read(pdfs->tclChan, &result, 1); - pdfs->bp++; -#endif - } else if (pdfs->buffer != NULL) { - if (pdfs->bp < pdfs->bufmax) - result = pdfs->buffer[pdfs->bp++]; - } - else - plexit("pdf_getc: Illegal operation"); - - return result; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_ungetc() - * - * Push back the last command read. -\*--------------------------------------------------------------------------*/ - -int -pdf_ungetc(int c, PDFstrm *pdfs) -{ - int result = EOF; - - if (pdfs->file != NULL) { - result = ungetc(c, pdfs->file); - if (pdfs->bp > 0) - pdfs->bp--; -#ifdef PLPLOT_USE_TCL_CHANNELS - } else if (pdfs->tclChan != NULL) { - result = Tcl_Ungets(pdfs->tclChan, &c, 1, 0); - if (pdfs->bp > 0) - pdfs->bp--; -#endif - } else if (pdfs->buffer != NULL) { - if (pdfs->bp > 0) { - pdfs->buffer[--pdfs->bp] = c; - result = c; - } - } - else - plexit("pdf_ungetc: Illegal operation"); - - return result; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_wrx() - * - * Writes a record. -\*--------------------------------------------------------------------------*/ - -static int -pdf_wrx(const U_CHAR *x, long nitems, PDFstrm *pdfs) -{ - int i, result = 0; - - if (pdfs->file != NULL) { - result = fwrite(x, 1, nitems, pdfs->file); - pdfs->bp += nitems; -#ifdef PLPLOT_USE_TCL_CHANNELS - } else if (pdfs->tclChan != NULL) { - result = Tcl_Write(pdfs->tclChan, x, nitems); - pdfs->bp += nitems; -#endif - } else if (pdfs->buffer != NULL) { - for (i = 0; i < nitems; i++) { - if (pdfs->bp >= pdfs->bufmax) { - pldebug("pdf_wrx", - "Increasing buffer to %d bytes\n", pdfs->bufmax); - pdfs->bufmax += 512; - pdfs->buffer = (U_CHAR *) - realloc((void *) (pdfs->buffer), pdfs->bufmax); - } - pdfs->buffer[pdfs->bp++] = x[i]; - } - result = i; - } - - return result; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_rdx() - * - * Reads a record. -\*--------------------------------------------------------------------------*/ - -int -pdf_rdx(U_CHAR *x, long nitems, PDFstrm *pdfs) -{ - int i, result = 0; - - if (pdfs->file != NULL) { - result = fread(x, 1, nitems, pdfs->file); - pdfs->bp += nitems; -#ifdef PLPLOT_USE_TCL_CHANNELS - } else if (pdfs->tclChan != NULL) { - result = Tcl_ReadRaw(pdfs->tclChan, x, nitems); - pdfs->bp += nitems; -#endif - } else if (pdfs->buffer != NULL) { - for (i = 0; i < nitems; i++) { - if (pdfs->bp > pdfs->bufmax) - break; - x[i] = pdfs->buffer[pdfs->bp++]; - } - result = i; - } - - return result; -} - -/*--------------------------------------------------------------------------*\ - * pdf_wr_header() - * - * Writes a header string. Input string must be NULL-terminated. The - * written string is terminated by a new-line, not a NULL. This is done - * so you can type e.g. "% strings | head" and get sensible output. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_header(PDFstrm *pdfs, char *header) -{ - int i; - - dbug_enter("pdf_wr_header"); - - for (i = 0; i < 79; i++) { - if (header[i] == '\0') - break; - if (pdf_putc(header[i], pdfs) == EOF) - return PDF_WRERR; - } - if (pdf_putc('\n', pdfs) == EOF) - return PDF_WRERR; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_rd_header - * - * Reads a newline-terminated header string from PDFstrm *pdfs, and - * converts to a usual NULL-terminated string. 80 chars maximum assumed. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_header(PDFstrm *pdfs, char *header) -{ - int i, c; - - dbug_enter("pdf_rd_header"); - - for (i = 0; i < 79; i++) { - if ((c = pdf_getc(pdfs)) == EOF) - return PDF_RDERR; - - header[i] = c; - if (header[i] == '\n') - break; - } - header[i] = '\0'; /* NULL terminate */ - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_wr_string() - * - * Writes a null-terminated string. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_string(PDFstrm *pdfs, const char *string) -{ - int i; - - dbug_enter("pdf_wr_string"); - - for (i = 0; i <= strlen(string); i++) { - if (pdf_putc(string[i], pdfs) == EOF) - return PDF_WRERR; - } - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_rd_string - * - * Reads a null-terminated string from PDFstrm *pdfs. - * A max of nmax chars are read. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_string(PDFstrm *pdfs, char *string, int nmax) -{ - int i, c; - - dbug_enter("pdf_rd_string"); - - for (i = 0; i < nmax; i++) { - if ((c = pdf_getc(pdfs)) == EOF) - return PDF_RDERR; - - string[i] = c; - if (c == '\0') - break; - } - string[i] = '\0'; /* handle boundary case */ - return 0; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_wr_1byte() - * - * Writes a U_CHAR as a single byte. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_1byte(PDFstrm *pdfs, U_CHAR s) -{ - U_CHAR x[1]; - - x[0] = s; - if (pdf_wrx(x, 1, pdfs) != 1) - return PDF_WRERR; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_rd_1byte() - * - * Reads a single byte, storing into a U_CHAR. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_1byte(PDFstrm *pdfs, U_CHAR *ps) -{ - U_CHAR x[1]; - - if ( ! pdf_rdx(x, 1, pdfs)) - return PDF_RDERR; - - *ps = ((U_CHAR) x[0]); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_wr_2bytes() - * - * Writes a U_SHORT as two single bytes, low end first. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_2bytes(PDFstrm *pdfs, U_SHORT s) -{ - U_CHAR x[2]; - - x[0] = (U_CHAR) ((U_LONG) (s & (U_LONG) 0x00FF)); - x[1] = (U_CHAR) ((U_LONG) (s & (U_LONG) 0xFF00) >> 8); - - if (pdf_wrx(x, 2, pdfs) != 2) - return PDF_WRERR; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_rd_2bytes() - * - * Reads a U_SHORT from two single bytes, low end first. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_2bytes(PDFstrm *pdfs, U_SHORT *ps) -{ - U_CHAR x[2]; - - if ( ! pdf_rdx(x, 2, pdfs)) - return PDF_RDERR; - - *ps = 0; - *ps |= (U_LONG) x[0]; - *ps |= (U_LONG) x[1] << 8; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_wr_2nbytes() - * - * Writes n U_SHORT's as 2n single bytes, low end first. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_2nbytes(PDFstrm *pdfs, U_SHORT *s, PLINT n) -{ - PLINT i; - U_CHAR x[2]; - - for (i = 0; i < n; i++) { - x[0] = (U_CHAR) ((U_LONG) (s[i] & (U_LONG) 0x00FF)); - x[1] = (U_CHAR) ((U_LONG) (s[i] & (U_LONG) 0xFF00) >> 8); - - if (pdf_wrx(x, 2, pdfs) != 2) - return PDF_WRERR; - } - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_rd_2nbytes() - * - * Reads n U_SHORT's from 2n single bytes, low end first. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_2nbytes(PDFstrm *pdfs, U_SHORT *s, PLINT n) -{ - PLINT i; - U_CHAR x[2]; - - for (i = 0; i < n; i++) { - if ( ! pdf_rdx(x, 2, pdfs)) - return PDF_RDERR; - - s[i] = 0; - s[i] |= (U_SHORT) x[0]; - s[i] |= (U_SHORT) x[1] << 8; - } - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_wr_4bytes() - * - * Writes an unsigned long as four single bytes, low end first. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_4bytes(PDFstrm *pdfs, U_LONG s) -{ - U_CHAR x[4]; - - x[0] = (U_CHAR) ((s & (U_LONG) 0x000000FF)); - x[1] = (U_CHAR) ((s & (U_LONG) 0x0000FF00) >> 8); - x[2] = (U_CHAR) ((s & (U_LONG) 0x00FF0000) >> 16); - x[3] = (U_CHAR) ((s & (U_LONG) 0xFF000000) >> 24); - - if (pdf_wrx(x, 4, pdfs) != 4) - return PDF_WRERR; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * pdf_rd_4bytes() - * - * Reads an unsigned long from 4 single bytes, low end first. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_4bytes(PDFstrm *pdfs, U_LONG *ps) -{ - U_CHAR x[4]; - - if ( ! pdf_rdx(x, 4, pdfs)) - return PDF_RDERR; - - *ps = 0; - *ps |= (U_LONG) x[0]; - *ps |= (U_LONG) x[1] << 8; - *ps |= (U_LONG) x[2] << 16; - *ps |= (U_LONG) x[3] << 24; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * Here is the IEEE floating point specification in both 32 bit and 64 bit - * precisions, from page 9 of "IEEE Standard for Binary Floating-Point - * Arithmetic", copyright 1985, IEEE Std 754-1985: - * - * - * Single Format - * - * msb means most significant bit - * lsb means least significant bit - * - * 1 8 23 - * _____________________________________________________________________ - * | | | | - * | s | e | f | - * |___|________________|______________________________________________| - * msb lsb msb lsb - * - * - * - * Double Format - * - * msb means most significant bit - * lsb means least significant bit - * - * 1 11 52 - * _____________________________________________________________________ - * | | | | - * | s | e | f | - * |___|________________|______________________________________________| - * msb lsb msb lsb - * - * - * (Thanks to: Andy Mai (mai@ncar.ucar.edu)) - * - * - * According to "inmos: Transputer instruction set" the IEEE standard - * specifies the floating format as: - * - * s exp frac - * - * Where: s = sign bit (1 bit) - * exp = exponent (8 bits for 32 bit float / 11 bits for 64 bit float) - * frac = fraction (23 bits for 32 bit float / 52 bits for 64 bit float) - * - * value of (s exp frac) = (-1)^s * 1.frac * 2^(exp-bias) ; if exp not 0 - * (-1)^s * 0.frac * 2^(1-bias) ; if exp = 0 - * - * where bias = 127 for 32 bit float - * bias = 1023 for 64 bit float - * - * (Thanks to: Tom Bjorkholm(TBJORKHOLM@abo.fi)) - * -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * int pdf_wr_ieeef() - * - * Writes a float in IEEE single precision (32 bit) format. -\*--------------------------------------------------------------------------*/ - -int -pdf_wr_ieeef(PDFstrm *pdfs, float f) -{ - double fdbl, fmant, f_new; - float fsgl, f_tmp; - int istat, exp, e_new, e_off, bias = 127; - U_LONG value, s_ieee, e_ieee, f_ieee; - - if (f == 0.0) { - value = 0; - return (pdf_wr_4bytes(pdfs, value)); - } - fsgl = fdbl = f; - fmant = frexp(fdbl, &exp); - - if (fmant < 0) - s_ieee = 1; - else - s_ieee = 0; - - fmant = fabs(fmant); - f_new = 2 * fmant; - e_new = exp - 1; - - if (e_new < 1 - bias) { - e_off = e_new - (1 - bias); - e_ieee = 0; - f_tmp = f_new * pow((double) 2.0, (double) e_off); - } - else { - e_ieee = e_new + bias; - f_tmp = f_new - 1; - } - f_ieee = f_tmp * 8388608; /* multiply by 2^23 */ - - if (e_ieee > 255) { - if (debug) - fprintf(stderr, "pdf_wr_ieeef: Warning -- overflow\n"); - e_ieee = 255; - } - - s_ieee = s_ieee << 31; - e_ieee = e_ieee << 23; - - value = s_ieee | e_ieee | f_ieee; - - if ((istat = pdf_wr_4bytes(pdfs, value))) - return (istat); - - if (debug) { - fprintf(stderr, "Float value (written): %g\n", fsgl); - print_ieeef(&fsgl, &value); - } - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * int pdf_rd_ieeef() - * - * Reads a float from a IEEE single precision (32 bit) format. -\*--------------------------------------------------------------------------*/ - -int -pdf_rd_ieeef(PDFstrm *pdfs, float *pf) -{ - double f_new, f_tmp; - float fsgl; - int istat, exp, bias = 127; - U_LONG value, s_ieee, e_ieee, f_ieee; - - if ((istat = pdf_rd_4bytes(pdfs, &value))) - return (istat); - - s_ieee = (value & (U_LONG) 0x80000000) >> 31; - e_ieee = (value & (U_LONG) 0x7F800000) >> 23; - f_ieee = (value & (U_LONG) 0x007FFFFF); - - f_tmp = (double) f_ieee / 8388608.0; /* divide by 2^23 */ - - if (e_ieee == 0) { - exp = 1 - bias; - f_new = f_tmp; - } - else { - exp = (int) e_ieee - bias; - f_new = 1.0 + f_tmp; - } - - fsgl = f_new * pow(2.0, (double) exp); - if (s_ieee == 1) - fsgl = -fsgl; - - *pf = fsgl; - - if (debug) { - fprintf(stderr, "Float value (read): %g\n", fsgl); - print_ieeef(&fsgl, &value); - } - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * print_ieeef() - * - * Prints binary representation for numbers pointed to by arguments. - * The first argument is the original float, the second is the - * IEEE representation. They should be the same on any machine that - * uses IEEE floats. -\*--------------------------------------------------------------------------*/ - -static void -print_ieeef(void *vx, void *vy) -{ - int i; - U_LONG f, *x = (U_LONG *) vx, *y = (U_LONG *) vy; - char bitrep[33]; - - bitrep[32] = '\0'; - - f = *x; - for (i = 0; i < 32; i++) { - if (f & 1) - bitrep[32 - i - 1] = '1'; - else - bitrep[32 - i - 1] = '0'; - f = f >> 1; - } - fprintf(stderr, "Binary representation: "); - fprintf(stderr, "%s\n", bitrep); - - f = *y; - for (i = 0; i < 32; i++) { - if (f & 1) - bitrep[32 - i - 1] = '1'; - else - bitrep[32 - i - 1] = '0'; - f = f >> 1; - } - fprintf(stderr, "Converted representation: "); - fprintf(stderr, "%s\n\n", bitrep); - - return; -} - -/*--------------------------------------------------------------------------*\ - * plAlloc2dGrid() - * - * Allocates a block of memory for use as a 2-d grid of PLFLT's. - * Resulting array can be indexed as f[i][j] anywhere. This is to be used - * instead of PLFLT f[nx][ny], which is less useful. Note that this type - * of allocation is required by the PLplot functions which take a 2-d - * grids of PLFLT's as an argument, such as plcont() and plot3d(). - * Example usage: - * - * PLFLT **z; - * - * Alloc2dGrid(&z, XPTS, YPTS); -\*--------------------------------------------------------------------------*/ - -void -plAlloc2dGrid(PLFLT ***f, PLINT nx, PLINT ny) -{ - PLINT i; - - if ((*f = (PLFLT **) calloc(nx, sizeof(PLFLT *)))==NULL) - plexit("Memory allocation error in \"plAlloc2dGrid\""); - - for (i = 0; i < nx; i++) { - if (((*f)[i] = (PLFLT *) calloc(ny ,sizeof(PLFLT)))==NULL) - plexit("Memory allocation error in \"plAlloc2dGrid\""); - } - -} - -/*--------------------------------------------------------------------------*\ - * Free2dGrid() - * - * Frees a block of memory allocated with Alloc2dGrid(). -\*--------------------------------------------------------------------------*/ - -void -plFree2dGrid(PLFLT **f, PLINT nx, PLINT ny) -{ - PLINT i; - - for (i = 0; i < nx; i++) - free((void *) f[i]); - - free((void *) f); -} - -/*--------------------------------------------------------------------------*\ - * MinMax2dGrid() - * - * Finds the maximum and minimum of a 2d matrix allocated with plAllc2dGrid(). -\*--------------------------------------------------------------------------*/ - -void -plMinMax2dGrid(PLFLT **f, PLINT nx, PLINT ny, PLFLT *fmax, PLFLT *fmin) -{ - int i, j; - PLFLT m, M; - - M = m = f[0][0]; - - for (i = 0; i < nx; i++) { - for (j = 0; j < ny; j++) { - if (f[i][j] > M) M = f[i][j]; - if (f[i][j] < m) m = f[i][j]; - } - } - *fmax = M; - *fmin = m; -} diff --git a/src/plot/plplot/plConfig.h b/src/plot/plplot/plConfig.h deleted file mode 100644 index fc2fcbaeee..0000000000 --- a/src/plot/plplot/plConfig.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __PLCONFIG_H__ -#define __PLCONFIG_H__ -#define LIB_DIR "..\\..\\..\\lib" -#define BIN_DIR "..\\..\\..\\bin" -#define DATA_DIR "..\\..\\..\\lib" -#define DRV_DIR "..\\..\\..\\lib" -#define VERSION "5.2.1" -#define PL_DOUBLE -#endif diff --git a/src/plot/plplot/plDevs.h b/src/plot/plplot/plDevs.h deleted file mode 100644 index 8abfacd988..0000000000 --- a/src/plot/plplot/plDevs.h +++ /dev/null @@ -1,2 +0,0 @@ -#define PLD_null - diff --git a/src/plot/plplot/plargs.c b/src/plot/plplot/plargs.c deleted file mode 100644 index 1594549feb..0000000000 --- a/src/plot/plplot/plargs.c +++ /dev/null @@ -1,2213 +0,0 @@ -/* $Id: plargs.c,v 1.1 2004/03/01 20:54:50 cozmic Exp $ - - Copyright 1993, 1994, 1995 - Maurice LeBrun mjl@dino.ph.utexas.edu - Institute for Fusion Studies University of Texas at Austin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Some parts of this code were derived from "xterm.c" and "ParseCmd.c" of - the X-windows Version 11 distribution. The copyright notice is - reproduced here: - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, -and the Massachusetts Institute of Technology, Cambridge, Massachusetts. - - All Rights Reserved - - The full permission notice is given in the PLplot documentation. - -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - This file contains routines to extract & process command flags. The - command flags recognized by PLplot are stored in the "ploption_table" - structure, along with strings giving the syntax, long help message, and - option handler. - - The command line parser -- plParseOpts() -- removes all recognized flags - (decreasing argc accordingly), so that invalid input may be readily - detected. It can also be used to process user command line flags. The - user can merge an option table of type PLOptionTable into the internal - option table info structure using plMergeOpts(). Or, the user can - specify that ONLY the external table(s) be parsed by calling - plClearOpts() before plMergeOpts(). - - The default action taken by plParseOpts() is as follows: - - Returns with an error if an unrecognized option or badly formed - option-value pair are encountered. - - Returns immediately (return code 0) when the first non-option - command line argument is found. - - Returns with the return code of the option handler, if one - was called. - - Deletes command line arguments from argv list as they are found, - and decrements argc accordingly. - - Does not show "invisible" options in usage or help messages. - - Assumes the program name is contained in argv[0]. - - These behaviors may be controlled through the "mode" argument, which can - have the following bits set: - - PL_PARSE_FULL -- Full parsing of command line and all error messages - enabled, including program exit when an error occurs. Anything on the - command line that isn't recognized as a valid option or option argument - is flagged as an error. - - PL_PARSE_QUIET -- Turns off all output except in the case of - errors. - - PL_PARSE_NODELETE -- Turns off deletion of processed arguments. - - PL_PARSE_SHOWALL -- Show invisible options - - PL_PARSE_NOPROGRAM -- Specified if argv[0] is NOT a pointer to the - program name. - - PL_PARSE_NODASH -- Set if leading dash is NOT required. - - PL_PARSE_SKIP -- Set to quietly skip over any unrecognized args. - - Note: if you want to have both your option and a PLplot option of the - same name processed (e.g. the -v option in plrender), do the following: - 1. Tag your option with PL_OPT_NODELETE - 2. Give it an option handler that uses a return code of 1. - 3. Merge your option table in. - By merging your table, your option will be processed before the PLplot - one. The PL_OPT_NODELETE ensures that the option string is not deleted - from the argv list, and the return code of 1 ensures that the parser - continues looking for it. - - See plrender.c for examples of actual usage. */ - -#include "plplotP.h" -#include - -/* Support functions */ - -static int ParseOpt (int *, char ***, int *, char ***, PLOptionTable *); -static int ProcessOpt (char *, PLOptionTable *, int *, char ***, int *); -static int GetOptarg (char **, int *, char ***, int *); -static void Help (void); -static void Syntax (void); - -/* Option handlers */ - -static int opt_h (char *, char *, void *); -static int opt_v (char *, char *, void *); -static int opt_verbose (char *, char *, void *); -static int opt_debug (char *, char *, void *); -static int opt_hack (char *, char *, void *); -static int opt_dev (char *, char *, void *); -static int opt_o (char *, char *, void *); -static int opt_geo (char *, char *, void *); -static int opt_a (char *, char *, void *); -static int opt_jx (char *, char *, void *); -static int opt_jy (char *, char *, void *); -static int opt_mar (char *, char *, void *); -static int opt_ori (char *, char *, void *); -static int opt_freeaspect (char *, char *, void *); -static int opt_portrait (char *, char *, void *); -static int opt_width (char *, char *, void *); -static int opt_bg (char *, char *, void *); -static int opt_ncol0 (char *, char *, void *); -static int opt_ncol1 (char *, char *, void *); -static int opt_fam (char *, char *, void *); -static int opt_fsiz (char *, char *, void *); -static int opt_fbeg (char *, char *, void *); -static int opt_finc (char *, char *, void *); -static int opt_fflen (char *, char *, void *); -static int opt_bufmax (char *, char *, void *); -static int opt_nopixmap (char *, char *, void *); -static int opt_db (char *, char *, void *); -static int opt_np (char *, char *, void *); -static int opt_px (char *, char *, void *); -static int opt_py (char *, char *, void *); -static int opt_wplt (char *, char *, void *); -static int opt_drvopt (char *, char *, void *); - -static int opt_plserver (char *, char *, void *); -static int opt_plwindow (char *, char *, void *); -static int opt_tcl_cmd (char *, char *, void *); -static int opt_auto_path (char *, char *, void *); -static int opt_bufmax (char *, char *, void *); -static int opt_server_name (char *, char *, void *); -static int opt_server_host (char *, char *, void *); -static int opt_server_port (char *, char *, void *); -static int opt_user (char *, char *, void *); -static int opt_tk_file (char *, char *, void *); -static int opt_dpi (char *, char *, void *); -static int opt_dev_compression (char *, char *, void *); - -/* Global variables */ - -static char *program = NULL; -static char *usage = NULL; - -static int mode_full; -static int mode_quiet; -static int mode_nodelete; -static int mode_showall; -static int mode_noprogram; -static int mode_nodash; -static int mode_skip; - -/* Temporary buffer used for parsing */ - -#define OPTMAX 1024 -static char opttmp[OPTMAX]; - -/*--------------------------------------------------------------------------*\ - * PLPLOT options data structure definition. - * - * The table is defined as follows - * - * typedef struct { - * char *opt; - * int (*handler) (char *, char *, void *); - * void *client_data; - * void *var; - * long mode; - * char *syntax; - * char *desc; - * } PLOptionTable; - * - * where each entry has the following meaning: - * - * opt option string - * handler pointer to function for processing the option and - * (optionally) its argument - * client_data pointer to data that gets passed to (*handler) - * var address of variable to set based on "mode" - * mode governs handling of option (see below) - * syntax short syntax description - * desc long syntax description - * - * The syntax and or desc strings can be NULL if the option is never to be - * described. Usually this is only used for obsolete arguments; those we - * just wish to hide from normal use are better made invisible (which are - * made visible by either specifying -showall first or PL_PARSE_SHOWALL). - * - * The mode bits are: - * - * PL_OPT_ARG Option has an argment - * PL_OPT_NODELETE Don't delete after processing - * PL_OPT_INVISIBLE Make invisible (usually for debugging) - * PL_OPT_DISABLED Ignore this option - * - * The following mode bits cause the option to be processed as specified: - * - * PL_OPT_FUNC Call function handler (opt, optarg) - * PL_OPT_BOOL Set *var=1 - * PL_OPT_INT Set *var=atoi(optarg) - * PL_OPT_FLOAT Set *var=atof(optarg) - * PL_OPT_STRING Set *var=optarg - * - * where opt points to the option string and optarg points to the - * argument string. - * -\*--------------------------------------------------------------------------*/ - -static PLOptionTable ploption_table[] = { -{ - "showall", /* Turns on invisible options */ - NULL, - NULL, - &mode_showall, - PL_OPT_BOOL | PL_OPT_INVISIBLE, - "-showall", - "Turns on invisible options" }, -{ - "h", /* Help */ - opt_h, - NULL, - NULL, - PL_OPT_FUNC, - "-h", - "Print out this message" }, -{ - "v", /* Version */ - opt_v, - NULL, - NULL, - PL_OPT_FUNC, - "-v", - "Print out the PLplot library version number" }, -{ - "verbose", /* Be more verbose than usual */ - opt_verbose, - NULL, - NULL, - PL_OPT_FUNC, - "-verbose", - "Be more verbose than usual" }, -{ - "debug", /* Print debugging info */ - opt_debug, - NULL, - NULL, - PL_OPT_FUNC, - "-debug", - "Print debugging info (implies -verbose)" }, -{ - "hack", /* Enable driver-specific hack(s) */ - opt_hack, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_INVISIBLE, - "-hack", - "Enable driver-specific hack(s)" }, -{ - "dev", /* Output device */ - opt_dev, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-dev name", - "Output device name" }, -{ - "o", /* Output filename */ - opt_o, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-o name", - "Output filename" }, -{ - "display", /* X server */ - opt_o, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-display name", - "X server to contact" }, -{ - "px", /* Plots per page in x */ - opt_px, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-px number", - "Plots per page in x" }, -{ - "py", /* Plots per page in y */ - opt_py, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-py number", - "Plots per page in y" }, -{ - "geometry", /* Geometry */ - opt_geo, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-geometry geom", - "Window size, in pixels (e.g. -geometry 400x300)" }, -{ - "geo", /* Geometry (alias) */ - opt_geo, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-geo geom", - "Window size, in pixels (e.g. -geo 400x300)" }, -{ - "wplt", /* Plot window */ - opt_wplt, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-wplt xl,yl,xr,yr", - "Relative coordinates [0-1] of window into plot" }, -{ - "mar", /* Margin */ - opt_mar, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-mar margin", - "Margin space in relative coordinates (0 to 0.5, def 0)" }, -{ - "a", /* Aspect ratio */ - opt_a, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-a aspect", - "Page aspect ratio (def: same as output device)"}, -{ - "jx", /* Justification in x */ - opt_jx, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-jx justx", - "Page justification in x (-0.5 to 0.5, def 0)"}, -{ - "jy", /* Justification in y */ - opt_jy, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-jy justy", - "Page justification in y (-0.5 to 0.5, def 0)"}, -{ - "ori", /* Orientation */ - opt_ori, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-ori orient", - "Plot orientation (0,1,2,3=landscape,portrait,seascape,upside-down)" }, -{ - "freeaspect", /* floating aspect ratio */ - opt_freeaspect, - NULL, - NULL, - PL_OPT_FUNC, - "-freeaspect", - "Allow aspect ratio to adjust to orientation swaps" }, -{ - "portrait", /* floating aspect ratio */ - opt_portrait, - NULL, - NULL, - PL_OPT_FUNC, - "-portrait", - "Sets portrait mode (both orientation and aspect ratio)" }, -{ - "width", /* Pen width */ - opt_width, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-width width", - "Sets pen width (0 <= width)" }, -{ - "bg", /* Background color */ - opt_bg, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-bg color", - "Background color (0=black, FFFFFF=white)" }, -{ - "ncol0", /* Allocated colors in cmap 0 */ - opt_ncol0, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-ncol0 n", - "Number of colors to allocate in cmap 0 (upper bound)" }, -{ - "ncol1", /* Allocated colors in cmap 1 */ - opt_ncol1, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-ncol1 n", - "Number of colors to allocate in cmap 1 (upper bound)" }, -{ - "fam", /* Familying on switch */ - opt_fam, - NULL, - NULL, - PL_OPT_FUNC, - "-fam", - "Create a family of output files" }, -{ - "fsiz", /* Family file size */ - opt_fsiz, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-fsiz size[kKmMgG]", - "Output family file size (e.g. -fsiz 0.5G, def MB)" }, -{ - "fbeg", /* Family starting member */ - opt_fbeg, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-fbeg number", - "First family member number on output" }, -{ - "finc", /* Family member increment */ - opt_finc, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-finc number", - "Increment between family members" }, -{ - "fflen", /* Family member min field width */ - opt_fflen, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-fflen length", - "Family member number minimum field width" }, -{ - "nopixmap", /* Do not use pixmaps */ - opt_nopixmap, - NULL, - NULL, - PL_OPT_FUNC, - "-nopixmap", - "Don't use pixmaps in X-based drivers" }, -{ - "db", /* Double buffering on switch */ - opt_db, - NULL, - NULL, - PL_OPT_FUNC, - "-db", - "Double buffer X window output" }, -{ - "np", /* Page pause off switch */ - opt_np, - NULL, - NULL, - PL_OPT_FUNC, - "-np", - "No pause between pages" }, -{ - "bufmax", /* # bytes sent before flushing output */ - opt_bufmax, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-bufmax", - "bytes sent before flushing output" }, -{ - "server_name", /* Main window name of server */ - opt_server_name, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-server_name name", - "Main window name of PLplot server (tk driver)" }, -{ - "server_host", /* Host to run server on */ - opt_server_host, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-server_host name", - "Host to run PLplot server on (dp driver)" }, -{ - "server_port", /* Port to talk to server on */ - opt_server_port, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-server_port name", - "Port to talk to PLplot server on (dp driver)" }, -{ - "user", /* user name on remote node */ - opt_user, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-user name", - "User name on remote node (dp driver)" }, -{ - "plserver", /* PLplot server name */ - opt_plserver, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-plserver name", - "Invoked name of PLplot server (tk or dp driver)" }, -{ - "plwindow", /* PLplot container window name */ - opt_plwindow, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-plwindow name", - "Name of PLplot container window (tk or dp driver)" }, -{ - "tcl_cmd", /* TCL initialization command */ - opt_tcl_cmd, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-tcl_cmd command", - "TCL command string run at startup (note: disabled)" }, -{ - "auto_path", /* Additional directory(s) to autoload */ - opt_auto_path, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-auto_path dir", - "Additional directory(s) to autoload (tk or dp driver)" }, -{ - "tk_file", /* -file option for plserver */ - opt_tk_file, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG | PL_OPT_INVISIBLE, - "-tk_file file", - "file for plserver (tk or dp driver)" }, -{ - "dpi", /* Dots per inch */ - opt_dpi, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-dpi dpi", - "Resolution, in dots per inch (e.g. -dpi 360x360)" }, -{ - "compression", /* compression */ - opt_dev_compression, - NULL, - NULL, - PL_OPT_FUNC | PL_OPT_ARG, - "-compression num", - "Sets compression level in supporting devices" }, -{ - "drvopt", /* Driver specific options */ - opt_drvopt, - NULL, - NULL, - PL_OPT_ARG | PL_OPT_FUNC, - "-drvopt option[=value][,option[=value]]*", - "Driver specific options" }, -{ - NULL, /* option */ - NULL, /* handler */ - NULL, /* client data */ - NULL, /* address of variable to set */ - 0, /* mode flag */ - NULL, /* short syntax */ - NULL } /* long syntax */ -}; - -static char *plplot_notes[] = { -"All parameters must be white-space delimited. Some options are driver", -"dependent. Please see the PLplot reference document for more detail.", -NULL}; - -/*--------------------------------------------------------------------------*\ - * Array of option tables and associated info. - * - * The user may merge up to PL_MAX_OPT_TABLES custom option tables (of type - * PLOptionTable) with the internal one. The resulting treatment is simple, - * powerful, and robust. The tables are parsed in the order of last added - * first, to the internal table last. If multiple options of the same name - * occur, only the first parsed is "seen", thus, the user can easily - * override any PLplot internal option merely by providing the same option. - * This same precedence is followed when printing help and usage messages, - * with each set of options given separately. See example usage in - * plrender.c. -\*--------------------------------------------------------------------------*/ - -typedef struct { - PLOptionTable *options; - char *name; - char **notes; -} PLOptionInfo; - -PLOptionInfo ploption_info_default = { - ploption_table, - "PLplot options", - plplot_notes -}; - -#define PL_MAX_OPT_TABLES 10 -PLOptionInfo ploption_info[PL_MAX_OPT_TABLES] = { - { - ploption_table, - "PLplot options", - plplot_notes - } -}; - -/* The structure that hold the driver specific command line options */ - -typedef struct DrvOptCmd { - char *option; - char *value; - struct DrvOptCmd *next; -} DrvOptCmd; - -/* the variable where opt_drvopt() stores the driver specific command line options */ -static DrvOptCmd drv_opt; - -static int tables = 1; - -/*--------------------------------------------------------------------------*\ - * plSetOpt() - * - * Process input strings, treating them as an option and argument pair. - * Returns 1 on an error. -\*--------------------------------------------------------------------------*/ - -int -c_plsetopt(char *opt, char *optarg) -{ - return(plSetOpt(opt, optarg)); -} - -int -plSetOpt(char *opt, char *optarg) -{ - int mode = 0, argc = 2, status; - char *argv[3]; - - argv[0] = opt; - argv[1] = optarg; - argv[2] = NULL; - mode = - PL_PARSE_QUIET | - PL_PARSE_NODELETE | - PL_PARSE_NOPROGRAM | - PL_PARSE_NODASH; - - status = plParseOpts(&argc, argv, mode); - if (status) { - fprintf( stderr, "plSetOpt: Unrecognized option %s\n", opt); - } - return status; -} - -/*--------------------------------------------------------------------------*\ - * plMergeOpts() - * - * Merge user option table info structure with internal one. -\*--------------------------------------------------------------------------*/ - -int -plMergeOpts(PLOptionTable *options, char *name, char **notes) -{ - PLOptionTable *tab; - - pllib_init(); - -/* Check to make sure option table has been terminated correctly */ - - for (tab = options; tab->opt; tab++) - ; - -/* We've reached the last table entry. All the subentries must be NULL or 0 */ - - if ((tab->handler != NULL) || - (tab->client_data != NULL) || - (tab->var != NULL) || - (tab->mode != 0) || - (tab->syntax != NULL) || - (tab->desc != NULL)) { - - plabort("plMergeOpts: input table improperly terminated"); - return 1; - } - -/* No room for more tables */ - - if (tables++ >= PL_MAX_OPT_TABLES) { - plabort("plMergeOpts: max tables limit exceeded, table not merged"); - return 1; - } - - ploption_info[tables-1].options = options; - ploption_info[tables-1].name = name; - ploption_info[tables-1].notes = notes; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * plClearOpts() - * - * Clear internal option table info structure. -\*--------------------------------------------------------------------------*/ - -void -plClearOpts(void) -{ - tables = 0; -} - -/*--------------------------------------------------------------------------*\ - * plResetOpts() - * - * Reset internal option table info structure. -\*--------------------------------------------------------------------------*/ - -void -plResetOpts(void) -{ - ploption_info[0] = ploption_info_default; - tables = 1; -} - -/*--------------------------------------------------------------------------*\ - * plParseOpts() - * - * Process options list using current ploptions_info structure. - * An error in parsing the argument list causes a program exit if - * mode_full is set, otherwise the function returns with an error. -\*--------------------------------------------------------------------------*/ - -int -plParseOpts(int *p_argc, char **argv, PLINT mode) -{ - char **argsave, **argend; - int i, myargc, status = 0; - - pllib_init(); - -/* Initialize */ - - mode_full = mode & PL_PARSE_FULL; - mode_quiet = mode & PL_PARSE_QUIET; - mode_nodelete = mode & PL_PARSE_NODELETE; - mode_showall = mode & PL_PARSE_SHOWALL; - mode_noprogram = mode & PL_PARSE_NOPROGRAM; - mode_nodash = mode & PL_PARSE_NODASH; - mode_skip = mode & PL_PARSE_SKIP; - - /* Initialize the driver specific option linked structure */ - drv_opt.option = drv_opt.value = NULL; - drv_opt.next = NULL; - - myargc = (*p_argc); - argend = argv + myargc; - -/* If program name is first argument, save and advance */ - - if ( ! mode_noprogram) { - plsc->program = program = argv[0]; - --myargc; ++argv; - } - if (myargc == 0) - return 0; - -/* Process the command line */ - - argsave = argv; - for (; myargc > 0; --myargc, ++argv) { - - /* Allow for "holes" in argv list */ - - if (*argv == NULL || *argv[0] == '\0') - continue; - - /* Loop over all options tables, starting with the last */ - - for (i = tables-1; i >= 0; i--) { - - /* Check option table for option */ - - status = ParseOpt(&myargc, &argv, p_argc, &argsave, - ploption_info[i].options); - - if ( ! status) break; - } - - /* Handle error return as specified by the mode flag */ - - if (status == -1) { - - /* No match. Keep going if mode_skip is set, otherwise abort if - fully parsing, else return without error. */ - - if (mode_skip) { - if ( ! mode_nodelete) - *argsave++ = *argv; - continue; - } - if ( ! mode_quiet && mode_full) { - fprintf(stderr, "\nBad command line option \"%s\"\n", argv[0]); - plOptUsage(); - } - if (mode_full) exit(1); - - status = 0; - break; - - } else if (status == 1) { - - /* Illegal or badly formed */ - - if ( ! mode_quiet) { - fprintf(stderr, "\nBad command line option \"%s\"\n", argv[0]); - plOptUsage(); - } - if (mode_full) exit(1); - - break; - - } else if (status == 2) { - - /* Informational option encountered (-h or -v) */ - - exit(0); - } - } - -/* Compress and NULL-terminate argv */ - - if ( ! mode_nodelete) { - for (i = 0; i < myargc; i++) - *argsave++ = *argv++; - - if (argsave < argend) - *argsave = NULL; - } - - return status; -} - -/*--------------------------------------------------------------------------*\ - * ParseOpt() - * - * Parses & determines appropriate action for input flag. -\*--------------------------------------------------------------------------*/ - -static int -ParseOpt(int *p_myargc, char ***p_argv, int *p_argc, char ***p_argsave, - PLOptionTable *option_table) -{ - PLOptionTable *tab; - char *opt; - -/* Only handle actual flags and their arguments */ - - if ( mode_nodash || (*p_argv)[0][0] == '-') { - - opt = (*p_argv)[0]; - if (*opt == '-') - opt++; - - for (tab = option_table; tab->opt; tab++) { - - /* Skip if option not enabled */ - - if (tab->mode & PL_OPT_DISABLED) - continue; - - /* Try to match it */ - - if (*opt == *tab->opt && ! strcmp(opt, tab->opt)) { - - /* Option matched, so remove from argv list if applicable. */ - - if ( ! mode_nodelete) { - if (tab->mode & PL_OPT_NODELETE) - (*(*p_argsave)++) = (**p_argv); - else - --(*p_argc); - } - - /* Process option (and argument if applicable) */ - - return (ProcessOpt(opt, tab, p_myargc, p_argv, p_argc)); - } - } - } - - return -1; -} - -/*--------------------------------------------------------------------------*\ - * ProcessOpt() - * - * Process option (and argument if applicable). -\*--------------------------------------------------------------------------*/ - -static int -ProcessOpt(char *opt, PLOptionTable *tab, int *p_myargc, char ***p_argv, - int *p_argc) -{ - int need_arg, res; - char *optarg = NULL; - -/* Get option argument if necessary */ - - need_arg = PL_OPT_ARG | PL_OPT_INT | PL_OPT_FLOAT | PL_OPT_STRING; - - if (tab->mode & need_arg) { - if (GetOptarg(&optarg, p_myargc, p_argv, p_argc)) - return 1; - } - -/* Process argument */ - - switch (tab->mode & 0xFF00) { - - case PL_OPT_FUNC: - - /* Call function handler to do the job */ - - if (tab->handler == NULL) { - fprintf(stderr, - "ProcessOpt: no handler specified for option %s\n", - tab->opt); - return 1; - } - - if (mode_nodelete && optarg) { - - /* Make a copy, since handler may mung optarg with strtok() */ - char *copy = - (char *) malloc((size_t)(1+strlen(optarg))*sizeof(char)); - if (copy == NULL) { - plabort("ProcessOpt: out of memory"); - return 1; - } - strcpy(copy, optarg); - res = ((*tab->handler) (opt, copy, tab->client_data)); - free((void *) copy); - return res; - } - else { - return ((*tab->handler) (opt, optarg, tab->client_data)); - } - - case PL_OPT_BOOL: - - /* Set *var as a boolean */ - - if (tab->var == NULL) { - fprintf(stderr, - "ProcessOpt: no variable specified for option %s\n", - tab->opt); - return 1; - } - *(int *)tab->var = 1; - break; - - case PL_OPT_INT: - - /* Set *var as an int */ - - if (tab->var == NULL) { - fprintf(stderr, - "ProcessOpt: no variable specified for option %s\n", - tab->opt); - return 1; - } - *(int *)tab->var = atoi(optarg); - break; - - case PL_OPT_FLOAT: - - /* Set *var as a float */ - - if (tab->var == NULL) { - fprintf(stderr, - "ProcessOpt: no variable specified for option %s\n", - tab->opt); - return 1; - } - *(PLFLT *)tab->var = atof(optarg); - break; - - case PL_OPT_STRING: - - /* Set var (can be NULL initially) to point to optarg string */ - - *(char **)tab->var = (char *)optarg; - break; - - default: - - /* Somebody messed up.. */ - - fprintf(stderr, - "ProcessOpt: invalid processing mode for option %s\n", - tab->opt); - return 1; - } - return 0; -} - -/*--------------------------------------------------------------------------*\ - * GetOptarg() - * - * Retrieves an option argument. - * If an error occurs here it is a true syntax error. -\*--------------------------------------------------------------------------*/ - -static int -GetOptarg(char **poptarg, int *p_myargc, char ***p_argv, int *p_argc) -{ - int result = 0; - - --(*p_myargc); - - if ((*p_myargc) <= 0) /* oops, no more arguments */ - result = 1; - - if ( ! result) { - (*p_argv)++; - if ((*p_argv)[0][0] == '-' && isalpha((*p_argv)[0][1])) { - - (*p_argv)--; /* oops, next arg is a flag */ - result = 1; - } - } - - if ( ! result) { /* yeah, the user got it right */ - (*p_argc)--; - *poptarg = (*p_argv)[0]; - } - else { - if ( ! mode_quiet) { - fprintf(stderr, "Argument missing for %s option.\n", (*p_argv)[0]); - plOptUsage(); - } - } - return result; -} - -/*--------------------------------------------------------------------------*\ - * plSetUsage() - * - * Set the strings used in usage and syntax messages. -\*--------------------------------------------------------------------------*/ - -void -plSetUsage(char *program_string, char *usage_string) -{ - if (program_string != NULL) - program = program_string; - - if (usage_string != NULL) - usage = usage_string; -} - -/*--------------------------------------------------------------------------*\ - * plOptUsage() - * - * Print usage & syntax message. -\*--------------------------------------------------------------------------*/ - -void -plOptUsage(void) -{ - if (usage == NULL) - fprintf(stderr, "\nUsage:\n %s [options]\n", program); - else - fputs(usage, stderr); - - Syntax(); - - fprintf(stderr, "\n\nType %s -h for a full description.\n\n", - program); -} - -/*--------------------------------------------------------------------------*\ - * Syntax() - * - * Print short syntax message. -\*--------------------------------------------------------------------------*/ - -static void -Syntax(void) -{ - PLOptionTable *tab; - int i, col, len; - -/* Loop over all options tables */ - - for (i = tables-1; i >= 0; i--) { - - /* Introducer */ - - if (ploption_info[i].name) - fprintf(stderr, "\n%s:", ploption_info[i].name); - else - fputs("\nUser options:", stderr); - - /* Print syntax for each option */ - - col = 80; - for (tab = ploption_info[i].options; tab->opt; tab++) { - if (tab->mode & PL_OPT_DISABLED) - continue; - - if ( ! mode_showall && (tab->mode & PL_OPT_INVISIBLE)) - continue; - - if (tab->syntax == NULL) - continue; - - len = 3 + strlen(tab->syntax); /* space [ string ] */ - if (col + len > 79) { - fprintf(stderr, "\n "); /* 3 spaces */ - col = 3; - } - fprintf(stderr, " [%s]", tab->syntax); - col += len; - } - fprintf(stderr, "\n"); - } -} - -/*--------------------------------------------------------------------------*\ - * Help() - * - * Print long help message. -\*--------------------------------------------------------------------------*/ - -static void -Help(void) -{ - PLOptionTable *tab; - char **note; - int i; - FILE *outfile = stderr; - -#ifdef HAVE_POPEN - FILE *pager = NULL; - if (getenv("PAGER") != NULL) - pager = (FILE *) popen("$PAGER", "w"); - if (pager == NULL) - pager = (FILE *) popen("more", "w"); - if (pager != NULL) - outfile = pager; -#endif - -/* Usage line */ - - if (usage == NULL) - fprintf(outfile, "\nUsage:\n %s [options]\n", program); - else - fputs(usage, outfile); - -/* Loop over all options tables */ - - for (i = tables-1; i >= 0; i--) { - - /* Introducer */ - - if (ploption_info[i].name) - fprintf(outfile, "\n%s:\n", ploption_info[i].name); - else - fputs("\nUser options:\n", outfile); - - /* Print description for each option */ - - for (tab = ploption_info[i].options; tab->opt; tab++) { - if (tab->mode & PL_OPT_DISABLED) - continue; - - if ( ! mode_showall && (tab->mode & PL_OPT_INVISIBLE)) - continue; - - if (tab->desc == NULL) - continue; - - if (tab->mode & PL_OPT_INVISIBLE) - fprintf(outfile, " * %-20s %s\n", tab->syntax, tab->desc); - else - fprintf(outfile, " %-20s %s\n", tab->syntax, tab->desc); - } - - /* Usage notes */ - - if (ploption_info[i].notes) { - putc('\n', outfile); - for (note = ploption_info[i].notes; *note; note++) { - fputs(*note, outfile); - putc('\n', outfile); - } - } - } - -#ifdef HAVE_POPEN - if (pager != NULL) - pclose(pager); -#endif -} - -/*--------------------------------------------------------------------------*\ - * plParseDrvOpts - * - * Parse driver specific options -\*--------------------------------------------------------------------------*/ - -int -plParseDrvOpts(DrvOpt *acc_opt) { - DrvOptCmd *drvp; - DrvOpt *t; - int fl; - char msg[80]; - - if (!drv_opt.option) - return 1; - - drvp = &drv_opt; - do { - t = acc_opt; fl = 0; - while (t->opt) { - if (strcmp(drvp->option, t->opt) == 0) { - fl = 1; - switch (t->type) { - - case DRV_STR: - *(char **)(t->var_ptr) = (drvp->value); -#ifdef DEBUG - fprintf(stderr,"plParseDrvOpts: %s %s\n", t->opt, *(char**)t->var_ptr); -#endif - break; - - case DRV_INT: - if (sscanf(drvp->value, "%d", (int *)t->var_ptr) != 1) { - sprintf(msg,"Incorrect argument to '%s' option", drvp->option); - plexit(msg); - } -#ifdef DEBUG - fprintf(stderr,"plParseDrvOpts: %s %d\n", t->opt, *(int *) t->var_ptr); -#endif - break; - - case DRV_FLT: - if (sscanf(drvp->value, "%f", (float *)t->var_ptr) != 1) { - sprintf(msg,"Incorrect argument to '%s' option", drvp->option); - plexit(msg); - } -#ifdef DEBUG - fprintf(stderr,"plParseDrvOpts: %s %f\n", t->opt, *(float *) t->var_ptr); -#endif - break; - } - } - t++; - } - - if (!fl) { - sprintf(msg, "Option '%s' not recognized.\n\nRecognized options for this driver are:\n", drvp->option); - plwarn(msg); - plHelpDrvOpts(acc_opt); - plexit(""); - } - } - while((drvp = drvp->next)) - ; - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * plHelpDrvOpts - * - * Give driver specific help -\*--------------------------------------------------------------------------*/ - -void -plHelpDrvOpts(DrvOpt *acc_opt) { - DrvOpt *t; - - t = acc_opt; - while(t->opt) { - fprintf(stderr, "%s:\t%s\n", t->opt, t->hlp_msg); - t++; - } -} - -/*--------------------------------------------------------------------------*\ - * Option handlers -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * opt_h() - * - * Performs appropriate action for option "h": - * Issues help message -\*--------------------------------------------------------------------------*/ - -static int -opt_h(char *opt, char *optarg, void *client_data) -{ - if ( ! mode_quiet) - Help(); - - return 2; -} - -/*--------------------------------------------------------------------------*\ - * opt_v() - * - * Performs appropriate action for option "v": - * Issues version message -\*--------------------------------------------------------------------------*/ - -static int -opt_v(char *opt, char *optarg, void *client_data) -{ - if ( ! mode_quiet) - fprintf(stderr, "PLplot library version: %s\n", VERSION); - - return 2; -} - -/*--------------------------------------------------------------------------*\ - * opt_verbose() - * - * Performs appropriate action for option "verbose": - * Turn on verbosity flag -\*--------------------------------------------------------------------------*/ - -static int -opt_verbose(char *opt, char *optarg, void *client_data) -{ - plsc->verbose = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_debug() - * - * Performs appropriate action for option "debug": - * Turn on debugging flag -\*--------------------------------------------------------------------------*/ - -static int -opt_debug(char *opt, char *optarg, void *client_data) -{ - plsc->debug = 1; - plsc->verbose = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_hack() - * - * Performs appropriate action for option "hack": - * Enables driver-specific hack(s) -\*--------------------------------------------------------------------------*/ - -static int -opt_hack(char *opt, char *optarg, void *client_data) -{ - plsc->hack = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_dev() - * - * Performs appropriate action for option "dev": - * Sets output device keyword -\*--------------------------------------------------------------------------*/ - -static int -opt_dev(char *opt, char *optarg, void *client_data) -{ - plsdev(optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_o() - * - * Performs appropriate action for option "o": - * Sets output file name -\*--------------------------------------------------------------------------*/ - -static int -opt_o(char *opt, char *optarg, void *client_data) -{ - plsfnam(optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_mar() - * - * Performs appropriate action for option "mar": - * Sets relative margin width -\*--------------------------------------------------------------------------*/ - -static int -opt_mar(char *opt, char *optarg, void *client_data) -{ - plsdidev(atof(optarg), PL_NOTSET, PL_NOTSET, PL_NOTSET); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_a() - * - * Performs appropriate action for option "a": - * Sets plot aspect ratio on page -\*--------------------------------------------------------------------------*/ - -static int -opt_a(char *opt, char *optarg, void *client_data) -{ - plsdidev(PL_NOTSET, atof(optarg), PL_NOTSET, PL_NOTSET); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_jx() - * - * Performs appropriate action for option "jx": - * Sets relative justification in x -\*--------------------------------------------------------------------------*/ - -static int -opt_jx(char *opt, char *optarg, void *client_data) -{ - plsdidev(PL_NOTSET, PL_NOTSET, atof(optarg), PL_NOTSET); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_jy() - * - * Performs appropriate action for option "jy": - * Sets relative justification in y -\*--------------------------------------------------------------------------*/ - -static int -opt_jy(char *opt, char *optarg, void *client_data) -{ - plsdidev(PL_NOTSET, PL_NOTSET, PL_NOTSET, atof(optarg)); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_ori() - * - * Performs appropriate action for option "ori": - * Sets orientation -\*--------------------------------------------------------------------------*/ - -static int -opt_ori(char *opt, char *optarg, void *client_data) -{ - plsdiori(atof(optarg)); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_freeaspect() - * - * Performs appropriate action for option "freeaspect": - * Allow aspect ratio to adjust to orientation swaps. -\*--------------------------------------------------------------------------*/ - -static int -opt_freeaspect(char *opt, char *optarg, void *client_data) -{ - plsc->freeaspect = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_portrait() - * - * Performs appropriate action for option "portrait": - * Set portrait mode. If plsc->portrait = 1, then the orientation for certain - * drivers is changed by 90 deg to portrait orientation from the default - * landscape orientation used by PLplot while the aspect ratio allowed to - * adjust using freeaspect. - * N.B. the driver list where this flag is honored is currently limited - * to ljii, ljiip, psc, ps, and pstex. A 90 deg rotation is just not - * appropriate for certain other drivers. These drivers where portrait - * mode is ignored include display drivers (e.g., xwin, tk), drivers - * which are subequently going to be transformed to another form - * (e.g., meta or pbm), or drivers which are normally used for web - * publishing (e.g., png, jpeg). That said, the case is not entirely clear - * for all drivers so the list of drivers where portrait mode is honored - * may increase in the future. To add to the list simply copy the small - * bit of code from ps.c that has to do with pls->portrait to the - * appropriate driver file. -\*--------------------------------------------------------------------------*/ - -static int -opt_portrait(char *opt, char *optarg, void *client_data) -{ - plsc->portrait = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_width() - * - * Performs appropriate action for option "width": - * Sets pen width -\*--------------------------------------------------------------------------*/ - -static int -opt_width(char *opt, char *optarg, void *client_data) -{ - int width; - - width = atoi(optarg); - if (width < 0) { - fprintf(stderr, "?invalid width\n"); - return 1; - } - else { - plwid(width); - plsc->widthlock = 1; - } - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_bg() - * - * Performs appropriate action for option "bg": - * Sets background color -\*--------------------------------------------------------------------------*/ - -static int -opt_bg(char *opt, char *optarg, void *client_data) -{ - char *rgb; - long bgcolor, r, g, b; - -/* Always in hex! Strip off leading "#" (TK-ism) if present. */ - - if (*optarg == '#') - rgb = optarg + 1; - else - rgb = optarg; - -/* Get number in hex */ - - bgcolor = strtol(rgb, NULL, 16); - -/* Must be either a 3 or 6 digit hex number */ -/* If 3 digits, each is "doubled" (i.e. ABC becomes AABBCC). */ - - switch (strlen(rgb)) { - case 3: - r = (bgcolor & 0xF00) >> 8; - g = (bgcolor & 0x0F0) >> 4; - b = (bgcolor & 0x00F); - - r = r | (r << 4); - g = g | (g << 4); /* doubling */ - b = b | (b << 4); - break; - - case 6: - r = (bgcolor & 0xFF0000) >> 16; - g = (bgcolor & 0x00FF00) >> 8; - b = (bgcolor & 0x0000FF); - break; - - default: - fprintf(stderr, "Unrecognized background color value %s\n", rgb); - return 1; - } - - plscolbg(r, g, b); - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_ncol0() - * - * Performs appropriate action for option "ncol0": - * Sets number of colors to allocate in cmap 0 (upper bound). -\*--------------------------------------------------------------------------*/ - -static int -opt_ncol0(char *opt, char *optarg, void *client_data) -{ - plsc->ncol0 = atoi(optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_ncol1() - * - * Performs appropriate action for option "ncol1": - * Sets number of colors to allocate in cmap 1 (upper bound). -\*--------------------------------------------------------------------------*/ - -static int -opt_ncol1(char *opt, char *optarg, void *client_data) -{ - plsc->ncol1 = atoi(optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_wplt() - * - * Performs appropriate action for option "wplt": - * Sets (zoom) window into plot (e.g. "0,0,0.5,0.5") -\*--------------------------------------------------------------------------*/ - -static int -opt_wplt(char *opt, char *optarg, void *client_data) -{ - char *field; - PLFLT xl, yl, xr, yr; - - strncpy(opttmp, optarg, OPTMAX-1); - - if ((field = strtok(opttmp, ",")) == NULL) - return 1; - - xl = atof(field); - - if ((field = strtok(NULL, ",")) == NULL) - return 1; - - yl = atof(field); - - if ((field = strtok(NULL, ",")) == NULL) - return 1; - - xr = atof(field); - - if ((field = strtok(NULL, ",")) == NULL) - return 1; - - yr = atof(field); - - plsdiplt(xl, yl, xr, yr); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_drvopt() - * - * Get driver specific options in the form [,option[=value]]* - * If "value" is not specified, it defaults to "1". -\*--------------------------------------------------------------------------*/ - -static int -opt_drvopt(char *opt, char *optarg, void *client_data) -{ - char t, *tt, *option, *value; - int fl = 0; - DrvOptCmd *drvp; - - option = (char *) malloc((size_t)(1+strlen(optarg))*sizeof(char)); - if (option == NULL) - plexit("opt_drvopt: Out of memory!?"); - - value = (char *) malloc((size_t)(1+1)*sizeof(char)); - if (value == NULL) - plexit("opt_drvopt: Out of memory!?"); - - drvp = &drv_opt; - *option = *value = '\0'; - tt = option; - while((t = *optarg++)) { - switch (t) { - case ',': - if (fl) - fl = 0; - else { - value[0] = '1'; - value[1] = '\0'; - } - - *tt = '\0'; tt = option; - drvp->option = plstrdup(option); /* it should not be release, because of familying */ - drvp->value = plstrdup(value); /* don't release */ - drvp->next = (DrvOptCmd *) malloc(sizeof(DrvOptCmd)); /* don't release */ - if (drvp->next == NULL) - plexit("opt_drvopt: Out of memory!?\n"); - - drvp = drvp->next; - break; - - case '=': - fl = 1; - *tt = '\0'; tt = value; - break; - - default: - *tt++ = t; - } - } - - *tt = '\0'; - if (!fl) { - value[0] = '1'; - value[1] = '\0'; - } - - drvp->option = plstrdup(option); /* don't release */ - drvp->value = plstrdup(value); /* don't release */ - drvp->next = NULL; - -#ifdef DEBUG - fprintf(stderr, "\nopt_drvopt: -drvopt parsed options:\n"); - drvp = &drv_opt; - do - fprintf(stderr, "%s %s\n", drvp->option, drvp->value); - while(drvp = drvp->next); - fprintf(stderr, "\n"); -#endif - - free(option); free(value); - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_fam() - * - * Performs appropriate action for option "fam": - * Enables family output files -\*--------------------------------------------------------------------------*/ - -static int -opt_fam(char *opt, char *optarg, void *client_data) -{ - plsfam(1, -1, -1); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_fsiz() - * - * Performs appropriate action for option "fsiz": - * Sets size of a family member file (may be somewhat larger since eof must - * occur at a page break). Also turns on familying. Example usage: - * - * -fsiz 5M (5 MB) - * -fsiz 300K (300 KB) - * -fsiz .3M (same) - * -fsiz .5G (half a GB) - * - * Note case of the trailing suffix doesn't matter. - * If no suffix, defaults to MB. -\*--------------------------------------------------------------------------*/ - -static int -opt_fsiz(char *opt, char *optarg, void *client_data) -{ - PLINT bytemax; - int len = strlen(optarg); - char lastchar = optarg[len-1]; - PLFLT multiplier = 1.0e6; - char *spec = (char*)malloc(len+1); - -/* Interpret optional suffix */ - - switch (lastchar) { - case 'k': - case 'K': - multiplier = 1.0e3; len--; - break; - case 'm': - case 'M': - multiplier = 1.0e6; len--; - break; - case 'g': - case 'G': - multiplier = 1.0e9; len--; - break; - } - strncpy(spec, optarg, len); - spec[len] = '\0'; - - bytemax = multiplier * atof(spec); - if (bytemax == 0) { - fprintf(stderr, "?invalid bytemax\n"); - return 1; - } - plsfam(1, -1, bytemax); - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_fbeg() - * - * Performs appropriate action for option "fbeg": - * Starts with the specified family member number. -\*--------------------------------------------------------------------------*/ - -static int -opt_fbeg(char *opt, char *optarg, void *client_data) -{ - plsc->member = atoi(optarg); - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_finc() - * - * Performs appropriate action for option "finc": - * Specify increment between family members. -\*--------------------------------------------------------------------------*/ - -static int -opt_finc(char *opt, char *optarg, void *client_data) -{ - plsc->finc = atoi(optarg); - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_fflen() - * - * Performs appropriate action for option "fflen": - * Specify minimum field length for family member number. -\*--------------------------------------------------------------------------*/ - -static int -opt_fflen(char *opt, char *optarg, void *client_data) -{ - plsc->fflen = atoi(optarg); - - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_np() - * - * Performs appropriate action for option "np": - * Disables pause between pages -\*--------------------------------------------------------------------------*/ - -static int -opt_np(char *opt, char *optarg, void *client_data) -{ - plspause(0); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_nopixmap() - * - * Performs appropriate action for option "nopixmap": - * Disables use of pixmaps in X drivers -\*--------------------------------------------------------------------------*/ - -static int -opt_nopixmap(char *opt, char *optarg, void *client_data) -{ - plsc->nopixmap = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_db() - * - * Performs appropriate action for option "db": - * Double buffer X output (update only done on eop or Expose) -\*--------------------------------------------------------------------------*/ - -static int -opt_db(char *opt, char *optarg, void *client_data) -{ - plsc->db = 1; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_bufmax() - * - * Performs appropriate action for option "bufmax": - * Sets size of data buffer for tk driver -\*--------------------------------------------------------------------------*/ - -static int -opt_bufmax(char *opt, char *optarg, void *client_data) -{ - plsc->bufmax = atoi(optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_server_name() - * - * Performs appropriate action for option "server_name": - * Sets main window name of server (Tcl/TK/DP driver only) -\*--------------------------------------------------------------------------*/ - -static int -opt_server_name(char *opt, char *optarg, void *client_data) -{ - plsc->server_name = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_server_host() - * - * Performs appropriate action for option "server_host": - * Sets host to run server on (Tcl/TK/DP driver only) -\*--------------------------------------------------------------------------*/ - -static int -opt_server_host(char *opt, char *optarg, void *client_data) -{ - plsc->server_host = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_server_port() - * - * Performs appropriate action for option "server_port": - * Sets port to talk to server on (Tcl/TK/DP driver only) -\*--------------------------------------------------------------------------*/ - -static int -opt_server_port(char *opt, char *optarg, void *client_data) -{ - plsc->server_port = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_user() - * - * Performs appropriate action for option "user": - * Sets user name on remote node (for remsh), dp driver only -\*--------------------------------------------------------------------------*/ - -static int -opt_user(char *opt, char *optarg, void *client_data) -{ - plsc->user = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_plserver() - * - * Performs appropriate action for option "plserver": - * Sets name to use when invoking server (Tcl/TK/DP driver only) -\*--------------------------------------------------------------------------*/ - -static int -opt_plserver(char *opt, char *optarg, void *client_data) -{ - plsc->plserver = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_plwindow() - * - * Performs appropriate action for option "plwindow": - * Sets PLplot window name -\*--------------------------------------------------------------------------*/ - -static int -opt_plwindow(char *opt, char *optarg, void *client_data) -{ - plsc->plwindow = (char *) malloc((size_t)(1+strlen(optarg))*sizeof(char)); - strcpy (plsc->plwindow, optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_tcl_cmd() - * - * Performs appropriate action for option "tcl_cmd": - * Sets TCL command(s) to eval on startup -\*--------------------------------------------------------------------------*/ - -static int -opt_tcl_cmd(char *opt, char *optarg, void *client_data) -{ - plsc->tcl_cmd = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_auto_path() - * - * Performs appropriate action for option "auto_path": - * Sets additional directories to autoload -\*--------------------------------------------------------------------------*/ - -static int -opt_auto_path(char *opt, char *optarg, void *client_data) -{ - plsc->auto_path = optarg; - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_px() - * - * Performs appropriate action for option "px": - * Set packing in x -\*--------------------------------------------------------------------------*/ - -static int -opt_px(char *opt, char *optarg, void *client_data) -{ - plssub(atoi(optarg), -1); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_py() - * - * Performs appropriate action for option "py": - * Set packing in y -\*--------------------------------------------------------------------------*/ - -static int -opt_py(char *opt, char *optarg, void *client_data) -{ - plssub(-1, atoi(optarg)); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_geo() - * - * Performs appropriate action for option "geo": - * Set geometry for output window - * e.g., "-geometry 400x400+100+0" - * or with offsets alone "-geometry +Xoff+Yoff" - * e.g., "-geometry +100+0" -\*--------------------------------------------------------------------------*/ - -static int -opt_geo(char *opt, char *optarg, void *client_data) -{ - char *field; - PLFLT xdpi = 0., ydpi = 0.; - PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0; - -/* The TK driver uses the geometry string directly */ - - plsc->geometry = (char *) malloc((size_t)(1+strlen(optarg))*sizeof(char)); - strcpy (plsc->geometry, optarg); - -/* Set up plplot dimensions */ - - strncpy(opttmp, optarg, OPTMAX-1); - if (strchr (opttmp, 'x')) { - - /* -geometry WxH or -geometry WxH+Xoff+Yoff */ - - field = strtok (opttmp, "x"); - xwid = atoi (field); - if (xwid == 0) - fprintf (stderr, "?invalid xwid\n"); - - if ((field = strtok (NULL, "+")) == NULL) - return 1; - - ywid = atoi (field); - if (ywid == 0) - fprintf (stderr, "?invalid ywid\n"); - - field = strtok (NULL, "+"); - } - else { - - /* -geometry +Xoff or -geometry +Xoff+Yoff only */ - - field = strtok (opttmp, "+"); - } - - if (field != NULL) { - xoff = atoi (field); - if ((field = strtok (NULL, "+")) != NULL) - yoff = atoi (field); - } - - plspage (xdpi, ydpi, xwid, ywid, xoff, yoff); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_tk_file() - * - * File name for plserver tk_file option -\*--------------------------------------------------------------------------*/ - -static int -opt_tk_file(char *opt, char *optarg, void *client_data) -{ - plsc->tk_file = (char *) malloc((size_t)(1+strlen(optarg))*sizeof(char)); - strcpy (plsc->tk_file, optarg); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_dpi() - * - * Performs appropriate action for option "dpi": - * Set dpi resolution for output device - * e.g., "-dpi 600x300", will set X dpi to 600 and Y dpi to 300 - * or - * e.g., "-dpi 1200" - * Will set both X and Y dpi to 1200 dpi -\*--------------------------------------------------------------------------*/ - -static int -opt_dpi(char *opt, char *optarg, void *client_data) -{ - char *field; - PLFLT xdpi = 0., ydpi = 0.; - PLINT xwid = 0, ywid = 0, xoff = 0, yoff = 0; - - strncpy(opttmp, optarg, OPTMAX-1); - if (strchr (opttmp, 'x')) { - field = strtok (opttmp, "x"); - xdpi = atof (field); - if (xdpi == 0) - fprintf (stderr, "?invalid xdpi\n"); - - if ((field = strtok (NULL, " ")) == NULL) - return 1; - - ydpi = atof (field); - if (ydpi == 0) - fprintf (stderr, "?invalid ydpi\n"); - - } else { - xdpi = atof (opttmp); - ydpi=xdpi; - if (xdpi==0) return 1; - } - - plspage (xdpi, ydpi, xwid, ywid, xoff, yoff); - return 0; -} - -/*--------------------------------------------------------------------------*\ - * opt_dev_compression() - * - * Sets device compression -\*--------------------------------------------------------------------------*/ - -static int -opt_dev_compression(char *opt, char *optarg, void *client_data) -{ - PLINT comp = 0; - - comp = atoi(optarg); - if (comp == 0) { - fprintf(stderr, "?invalid compression\n"); - return 1; - } - plscompression (comp); - - return 0; -} diff --git a/src/plot/plplot/plbox.c b/src/plot/plplot/plbox.c deleted file mode 100644 index b55bc8fa70..0000000000 --- a/src/plot/plplot/plbox.c +++ /dev/null @@ -1,1352 +0,0 @@ -/* $Id: plbox.c,v 1.2 2005/03/17 21:39:21 eli Exp $ - - Routines for drawing axes & box around the current viewport. -*/ - -#include "plplotP.h" - -static PLFLT xlog[8] = -{ - 0.301030, 0.477121, 0.602060, 0.698970, - 0.778151, 0.845098, 0.903090, 0.954243 -}; - -/* Static function prototypes */ - -static void -plxybx(const char *opt, const char *label, PLFLT wx1, PLFLT wy1, - PLFLT wx2, PLFLT wy2, PLFLT vmin, PLFLT vmax, - PLFLT tick, PLINT nsub, PLINT nolast, PLINT *digits); - -static void -plzbx(const char *opt, const char *label, PLINT right, PLFLT dx, PLFLT dy, - PLFLT wx, PLFLT wy1, PLFLT wy2, PLFLT vmin, PLFLT vmax, - PLFLT tick, PLINT nsub, PLINT *digits); - -static void -plxytx(PLFLT wx1, PLFLT wy1, PLFLT wx2, PLFLT wy2, - PLFLT disp, PLFLT pos, PLFLT just, const char *text); - -static void -plztx(const char *opt, PLFLT dx, PLFLT dy, PLFLT wx, PLFLT wy1, - PLFLT wy2, PLFLT disp, PLFLT pos, PLFLT just, const char *text); - -static void -plform(PLFLT value, PLINT scale, PLINT prec, char *result, PLINT ll, PLINT lf); - -static void -grid_box(const char *xopt, PLFLT xtick1, PLINT nxsub1, - const char *yopt, PLFLT ytick1, PLINT nysub1); - -static void -label_box(const char *xopt, PLFLT xtick1, const char *yopt, PLFLT ytick1); - -/*--------------------------------------------------------------------------*\ - * void plbox() - * - * This draws a box around the current viewport, complete with axes, ticks, - * numeric labels, and grids, according to input specification. Just a - * front-end to plaxes(), which allows arbitrary placement of coordinate - * axes when plotted (here the origin is at 0,0). See the documentation for - * plaxes() for more info. -\*--------------------------------------------------------------------------*/ - -void -c_plbox(const char *xopt, PLFLT xtick, PLINT nxsub, - const char *yopt, PLFLT ytick, PLINT nysub) -{ - c_plaxes(0.0, 0.0, xopt, xtick, nxsub, yopt, ytick, nysub); -} - -/*--------------------------------------------------------------------------*\ - * void plaxes() - * - * This draws a box around the current viewport, complete with axes, - * ticks, numeric labels, and grids, according to input specification. - * - * x0 and y0 specify the origin of the axes. - * - * xopt and yopt are character strings which define the box as follows: - * - * a: Draw axis (X is horizontal line Y=0, Y is vertical line X=0) - * b: Draw bottom (X) or left (Y) edge of frame - * c: Draw top (X) or right (Y) edge of frame - * f: Always use fixed point numeric labels - * g: Draws a grid at the major tick interval - * h: Draws a grid at the minor tick interval - * i: Inverts tick marks - * l: Logarithmic axes, major ticks at decades, minor ticks at units - * n: Write numeric label at conventional location - * m: Write numeric label at unconventional location - * t: Draw major tick marks - * s: Draw minor tick marks - * v: (for Y only) Label vertically - * - * xtick, ytick are the major tick intervals required, zero for - * automatic selection - * - * nxsub, nysub are the number of subtick intervals in a major tick - * interval -\*--------------------------------------------------------------------------*/ - -void -c_plaxes(PLFLT x0, PLFLT y0, - const char *xopt, PLFLT xtick, PLINT nxsub, - const char *yopt, PLFLT ytick, PLINT nysub) -{ - PLINT lax, lbx, lcx, lgx, lix, llx, lsx, ltx; - PLINT lay, lby, lcy, lgy, liy, lly, lsy, lty; - PLINT xmajor, xminor, ymajor, yminor; - PLINT i, i1x, i2x, i3x, i4x, i1y, i2y, i3y, i4y; - PLINT nxsub1, nysub1; - PLINT lxmin, lxmax, lymin, lymax; - PLINT pxmin, pxmax, pymin, pymax; - PLINT vppxmi, vppxma, vppymi, vppyma; - PLFLT xtick1, ytick1, vpwxmi, vpwxma, vpwymi, vpwyma; - PLFLT vpwxmin, vpwxmax, vpwymin, vpwymax; - PLFLT xp0, yp0, tn, tp, temp; - - if (plsc->level < 3) { - plabort("plbox: Please set up window first"); - return; - } - -/* Open the clip limits to the subpage limits */ - - plP_gclp(&lxmin, &lxmax, &lymin, &lymax); - plP_gphy(&pxmin, &pxmax, &pymin, &pymax); - plP_sclp(pxmin, pxmax, pymin, pymax); - - vppxmi = plsc->vppxmi; - vppxma = plsc->vppxma; - vppymi = plsc->vppymi; - vppyma = plsc->vppyma; - -/* Convert world coordinates to physical */ - - xp0 = plP_wcpcx(x0); - yp0 = plP_wcpcy(y0); - -/* Set plot options from input */ - - lax = plP_stsearch(xopt, 'a'); - lbx = plP_stsearch(xopt, 'b'); - lcx = plP_stsearch(xopt, 'c'); - lgx = plP_stsearch(xopt, 'g'); - lix = plP_stsearch(xopt, 'i'); - llx = plP_stsearch(xopt, 'l'); - lsx = plP_stsearch(xopt, 's'); - ltx = plP_stsearch(xopt, 't'); - - lay = plP_stsearch(yopt, 'a'); - lby = plP_stsearch(yopt, 'b'); - lcy = plP_stsearch(yopt, 'c'); - lgy = plP_stsearch(yopt, 'g'); - liy = plP_stsearch(yopt, 'i'); - lly = plP_stsearch(yopt, 'l'); - lsy = plP_stsearch(yopt, 's'); - lty = plP_stsearch(yopt, 't'); - -/* Tick and subtick sizes in device coords */ - - xmajor = MAX(ROUND(plsc->majht * plsc->ypmm), 1); - ymajor = MAX(ROUND(plsc->majht * plsc->xpmm), 1); - xminor = MAX(ROUND(plsc->minht * plsc->ypmm), 1); - yminor = MAX(ROUND(plsc->minht * plsc->xpmm), 1); - - nxsub1 = nxsub; - nysub1 = nysub; - xtick1 = llx ? 1.0 : xtick; - ytick1 = lly ? 1.0 : ytick; - - plgvpw(&vpwxmin, &vpwxmax, &vpwymin, &vpwymax); -/* n.b. large change; vpwxmi always numerically less than vpwxma, and - * similarly for vpwymi */ - vpwxmi = (vpwxmax > vpwxmin) ? vpwxmin : vpwxmax; - vpwxma = (vpwxmax > vpwxmin) ? vpwxmax : vpwxmin; - vpwymi = (vpwymax > vpwymin) ? vpwymin : vpwymax; - vpwyma = (vpwymax > vpwymin) ? vpwymax : vpwymin; - - lax = lax && vpwymi < y0 && y0 < vpwyma ; - lay = lay && vpwxmi < x0 && x0 < vpwxma ; - -/* Calculate tick spacing */ - - if (ltx || lgx) - pldtik(vpwxmi, vpwxma, &xtick1, &nxsub1); - - if (lty || lgy) - pldtik(vpwymi, vpwyma, &ytick1, &nysub1); -/* n.b. large change; xtick1, nxsub1, ytick1, nysub1 always positive. */ - -/* Set up tick variables */ - - if (lix) { - i1x = xminor; - i2x = 0; - i3x = xmajor; - i4x = 0; - } - else { - i1x = 0; - i2x = xminor; - i3x = 0; - i4x = xmajor; - } - - if (liy) { - i1y = yminor; - i2y = 0; - i3y = ymajor; - i4y = 0; - } - else { - i1y = 0; - i2y = yminor; - i3y = 0; - i4y = ymajor; - } - -/* Draw the bottom edge of the box */ - - if (lbx) { - plP_movphy(vppxmi, vppymi); - if (ltx) { - tp = xtick1 * floor(vpwxmi / xtick1); - for (;;) { - tn = tp + xtick1; - if (lsx) { - if (llx) { - for (i = 0; i <= 7; i++) { - temp = tp + xlog[i]; - if (BETW(temp, vpwxmi, vpwxma)) - plxtik(plP_wcpcx(temp), vppymi, i1x, i2x); - } - } - else { - for (i = 1; i <= nxsub1 - 1; i++) { - temp = tp + i * xtick1 / nxsub1; - if (BETW(temp, vpwxmi, vpwxma)) - plxtik(plP_wcpcx(temp), vppymi, i1x, i2x); - } - } - } - if (!BETW(tn, vpwxmi, vpwxma)) - break; - plxtik(plP_wcpcx(tn), vppymi, i3x, i4x); - tp = tn; - } - } - plP_draphy(vppxma, vppymi); - } - -/* Draw right-hand edge of box */ - - if (lcy) { - plP_movphy(vppxma, vppymi); - if (lty) { - tp = ytick1 * floor(vpwymi / ytick1); - for (;;) { - tn = tp + ytick1; - if (lsy) { - if (lly) { - for (i = 0; i <= 7; i++) { - temp = tp + xlog[i]; - if (BETW(temp, vpwymi, vpwyma)) - plytik(vppxma, plP_wcpcy(temp), i2y, i1y); - } - } - else { - for (i = 1; i <= nysub1 - 1; i++) { - temp = tp + i * ytick1 / nysub1; - if (BETW(temp, vpwymi, vpwyma)) - plytik(vppxma, plP_wcpcy(temp), i2y, i1y); - } - } - } - if (!BETW(tn, vpwymi, vpwyma)) - break; - plytik(vppxma, plP_wcpcy(tn), i4y, i3y); - tp = tn; - } - } - plP_draphy(vppxma, vppyma); - } - -/* Draw the top edge of the box */ - - if (lcx) { - plP_movphy(vppxma, vppyma); - if (ltx) { - tp = xtick1 * (floor(vpwxma / xtick1) + 1); - for (;;) { - tn = tp - xtick1; - if (lsx) { - if (llx) { - for (i = 7; i >= 0; i--) { - temp = tn + xlog[i]; - if (BETW(temp, vpwxmi, vpwxma)) - plxtik(plP_wcpcx(temp), vppyma, i2x, i1x); - } - } - else { - for (i = nxsub1 - 1; i >= 1; i--) { - temp = tn + i * xtick1 / nxsub1; - if (BETW(temp, vpwxmi, vpwxma)) - plxtik(plP_wcpcx(temp), vppyma, i2x, i1x); - } - } - } - if (!BETW(tn, vpwxmi, vpwxma)) - break; - plxtik(plP_wcpcx(tn), vppyma, i4x, i3x); - tp = tn; - } - } - plP_draphy(vppxmi, vppyma); - } - -/* Draw left-hand edge of box */ - - if (lby) { - plP_movphy(vppxmi, vppyma); - if (lty) { - tp = ytick1 * (floor(vpwyma / ytick1) + 1); - for (;;) { - tn = tp - ytick1; - if (lsy) { - if (lly) { - for (i = 7; i >= 0; i--) { - temp = tn + xlog[i]; - if (BETW(temp, vpwymi, vpwyma)) - plytik(vppxmi, plP_wcpcy(temp), i1y, i2y); - } - } - else { - for (i = nysub1 - 1; i >= 1; i--) { - temp = tn + i * ytick1 / nysub1; - if (BETW(temp, vpwymi, vpwyma)) - plytik(vppxmi, plP_wcpcy(temp), i1y, i2y); - } - } - } - if (!BETW(tn, vpwymi, vpwyma)) - break; - plytik(vppxmi, plP_wcpcy(tn), i3y, i4y); - tp = tn; - } - } - plP_draphy(vppxmi, vppymi); - } - -/* Draw the horizontal axis */ - - if (lax) { - plP_movphy(vppxmi, yp0); - if (ltx) { - tp = xtick1 * floor(vpwxmi / xtick1); - for (;;) { - tn = tp + xtick1; - if (lsx) { - if (llx) { - for (i = 0; i <= 7; i++) { - temp = tp + xlog[i]; - if (BETW(temp, vpwxmi, vpwxma)) - plxtik(plP_wcpcx(temp), yp0, xminor, xminor); - } - } - else { - for (i = 1; i <= nxsub1 - 1; i++) { - temp = tp + i * xtick1 / nxsub1; - if (BETW(temp, vpwxmi, vpwxma)) - plxtik(plP_wcpcx(temp), yp0, xminor, xminor); - } - } - } - if (!BETW(tn, vpwxmi, vpwxma)) - break; - plxtik(plP_wcpcx(tn), yp0, xmajor, xmajor); - tp = tn; - } - } - plP_draphy(vppxma, yp0); - } - -/* Draw the vertical axis */ - - if (lay) { - plP_movphy(xp0, vppymi); - if (lty) { - tp = ytick1 * floor(vpwymi / ytick1); - for (;;) { - tn = tp + ytick1; - if (lsy) { - if (lly) { - for (i = 0; i <= 7; i++) { - temp = tp + xlog[i]; - if (BETW(temp, vpwymi, vpwyma)) - plytik(xp0, plP_wcpcy(temp), yminor, yminor); - } - } - else { - for (i = 1; i <= nysub1 - 1; i++) { - temp = tp + i * ytick1 / nysub1; - if (BETW(temp, vpwymi, vpwyma)) - plytik(xp0, plP_wcpcy(temp), yminor, yminor); - } - } - } - if (!BETW(tn, vpwymi, vpwyma)) - break; - plytik(xp0, plP_wcpcy(tn), ymajor, ymajor); - tp = tn; - } - } - plP_draphy(xp0, vppyma); - } - -/* Draw grids */ - - grid_box(xopt, xtick1, nxsub1, yopt, ytick1, nysub1); - -/* Write labels */ - - label_box(xopt, xtick1, yopt, ytick1); - -/* Restore the clip limits to viewport edge */ - - plP_sclp(lxmin, lxmax, lymin, lymax); -} - -/*--------------------------------------------------------------------------*\ - * void plbox3() - * - * This is the 3-d analogue of plbox(). -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plbox3(const char *xopt, const char *xlabel, PLFLT xtick, PLINT nsubx, - const char *yopt, const char *ylabel, PLFLT ytick, PLINT nsuby, - const char *zopt, const char *zlabel, PLFLT ztick, PLINT nsubz) -{ - PLFLT dx, dy, tx, ty, ux, uy; - PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale; - PLFLT cxx, cxy, cyx, cyy, cyz; - PLINT ln; - PLINT *zbflg, *zbcol; - PLFLT *zbtck; - PLINT xdigmax, xdigits; - PLINT ydigmax, ydigits; - PLINT zdigmax, zdigits; - - if (plsc->level < 3) { - plabort("plbox3: Please set up window first"); - return; - } - - plP_gw3wc(&cxx, &cxy, &cyx, &cyy, &cyz); - plP_gdom(&xmin, &xmax, &ymin, &ymax); - plP_grange(&zscale, &zmin, &zmax); - - plgxax(&xdigmax, &xdigits); - plgyax(&ydigmax, &ydigits); - plgzax(&zdigmax, &zdigits); - - xdigits = xdigmax; - ydigits = ydigmax; - zdigits = zdigmax; - -/* We have to wait until after the plot is drawn to draw back */ -/* grid so store this stuff. */ - - plP_gzback(&zbflg, &zbcol, &zbtck); - *zbflg = plP_stsearch(zopt, 'd'); - if (*zbflg) { - *zbtck = ztick; /* save tick spacing */ - *zbcol = plsc->icol0; /* and color */ - } - - if (cxx >= 0.0 && cxy <= 0.0) { - ln = plP_stsearch(xopt, 'n'); - tx = plP_w3wcx(xmin, ymin, zmin); - ty = plP_w3wcy(xmin, ymin, zmin); - ux = plP_w3wcx(xmax, ymin, zmin); - uy = plP_w3wcy(xmax, ymin, zmin); - plxybx(xopt, xlabel, tx, ty, ux, uy, - xmin, xmax, xtick, nsubx, 0, &xdigits); - - dx = ux - tx; - dy = uy - ty; - plzbx(zopt, zlabel, 1, dx, dy, ux, uy, - plP_w3wcy(xmax, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits); - - tx = plP_w3wcx(xmin, ymax, zmin); - ty = plP_w3wcy(xmin, ymax, zmin); - ux = plP_w3wcx(xmin, ymin, zmin); - uy = plP_w3wcy(xmin, ymin, zmin); - plxybx(yopt, ylabel, tx, ty, ux, uy, - ymax, ymin, ytick, nsuby, ln, &ydigits); - - dx = ux - tx; - dy = uy - ty; -/* restore zdigits to initial value for second call */ - zdigits = zdigmax; - plzbx(zopt, zlabel, 0, dx, dy, tx, ty, - plP_w3wcy(xmin, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits); - } - else if (cxx <= 0.0 && cxy <= 0.0) { - ln = plP_stsearch(yopt, 'n'); - tx = plP_w3wcx(xmin, ymax, zmin); - ty = plP_w3wcy(xmin, ymax, zmin); - ux = plP_w3wcx(xmin, ymin, zmin); - uy = plP_w3wcy(xmin, ymin, zmin); - plxybx(yopt, ylabel, tx, ty, ux, uy, - ymax, ymin, ytick, nsuby, 0, &ydigits); - - dx = ux - tx; - dy = uy - ty; - plzbx(zopt, zlabel, 1, dx, dy, ux, uy, - plP_w3wcy(xmin, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits); - - tx = plP_w3wcx(xmax, ymax, zmin); - ty = plP_w3wcy(xmax, ymax, zmin); - ux = plP_w3wcx(xmin, ymax, zmin); - uy = plP_w3wcy(xmin, ymax, zmin); - plxybx(xopt, xlabel, tx, ty, ux, uy, - xmax, xmin, xtick, nsubx, ln, &xdigits); - - dx = ux - tx; - dy = uy - ty; -/* restore zdigits to initial value for second call */ - zdigits = zdigmax; - plzbx(zopt, zlabel, 0, dx, dy, tx, ty, - plP_w3wcy(xmax, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits); - } - else if (cxx <= 0.0 && cxy >= 0.0) { - ln = plP_stsearch(xopt, 'n'); - tx = plP_w3wcx(xmax, ymax, zmin); - ty = plP_w3wcy(xmax, ymax, zmin); - ux = plP_w3wcx(xmin, ymax, zmin); - uy = plP_w3wcy(xmin, ymax, zmin); - plxybx(xopt, xlabel, tx, ty, ux, uy, - xmax, xmin, xtick, nsubx, 0, &xdigits); - - dx = ux - tx; - dy = uy - ty; - plzbx(zopt, zlabel, 1, dx, dy, ux, uy, - plP_w3wcy(xmin, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits); - - tx = plP_w3wcx(xmax, ymin, zmin); - ty = plP_w3wcy(xmax, ymin, zmin); - ux = plP_w3wcx(xmax, ymax, zmin); - uy = plP_w3wcy(xmax, ymax, zmin); - plxybx(yopt, ylabel, tx, ty, ux, uy, - ymin, ymax, ytick, nsuby, ln, &ydigits); - - dx = ux - tx; - dy = uy - ty; -/* restore zdigits to initial value for second call */ - zdigits = zdigmax; - plzbx(zopt, zlabel, 0, dx, dy, tx, ty, - plP_w3wcy(xmax, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits); - } - else if (cxx >= 0.0 && cxy >= 0.0) { - ln = plP_stsearch(yopt, 'n'); - tx = plP_w3wcx(xmax, ymin, zmin); - ty = plP_w3wcy(xmax, ymin, zmin); - ux = plP_w3wcx(xmax, ymax, zmin); - uy = plP_w3wcy(xmax, ymax, zmin); - plxybx(yopt, ylabel, tx, ty, ux, uy, - ymin, ymax, ytick, nsuby, 0, &ydigits); - - dx = ux - tx; - dy = uy - ty; - plzbx(zopt, zlabel, 1, dx, dy, ux, uy, - plP_w3wcy(xmax, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits); - - tx = plP_w3wcx(xmin, ymin, zmin); - ty = plP_w3wcy(xmin, ymin, zmin); - ux = plP_w3wcx(xmax, ymin, zmin); - uy = plP_w3wcy(xmax, ymin, zmin); - plxybx(xopt, xlabel, tx, ty, ux, uy, - xmin, xmax, xtick, nsubx, ln, &xdigits); - - dx = ux - tx; - dy = uy - ty; -/* restore zdigits to initial value for second call */ - zdigits = zdigmax; - plzbx(zopt, zlabel, 0, dx, dy, tx, ty, - plP_w3wcy(xmin, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits); - } - plsxax(xdigmax, xdigits); - plsyax(ydigmax, ydigits); - plszax(zdigmax, zdigits); -} - -/*--------------------------------------------------------------------------*\ - * Support routines for 3d box draw. -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * void plxybx() - * - * This draws a sloping line from (wx1,wy1) to (wx2,wy2) which represents an - * axis of a 3-d graph with data values from "vmin" to "vmax". Depending on - * "opt", vertical ticks and/or subticks are placed on the line at major tick - * interval "tick" with "nsub" subticks between major ticks. If "tick" and/or - * "nsub" is zero, automatic tick positions are computed - * - * b: Draw box boundary - * f: Always use fixed point numeric labels - * i: Inverts tick marks (i.e. drawn downwards) - * l: Logarithmic axes, major ticks at decades, minor ticks at units - * n: Write numeric label - * t: Draw major tick marks - * s: Draw minor tick marks - * u: Write label on line -\*--------------------------------------------------------------------------*/ - -static void -plxybx(const char *opt, const char *label, PLFLT wx1, PLFLT wy1, - PLFLT wx2, PLFLT wy2, PLFLT vmin_in, PLFLT vmax_in, - PLFLT tick, PLINT nsub, PLINT nolast, PLINT *digits) -{ - static char string[40]; - PLINT lb, lf, li, ll, ln, ls, lt, lu; - PLINT major, minor, mode, prec, scale; - PLINT i, i1, i2, i3, i4; - PLINT nsub1; - PLFLT pos, tn, tp, temp, height, tick1, vmin, vmax; -/* Note that 'tspace' is the minimim distance away (in fractional number - * of ticks) from the boundary that an X or Y numerical label can be drawn. */ - PLFLT dwx, dwy, lambda, tcrit, tspace = 0.1; - - vmin = (vmax_in > vmin_in) ? vmin_in : vmax_in; - vmax = (vmax_in > vmin_in) ? vmax_in : vmin_in; - - dwx = wx2 - wx1; - dwy = wy2 - wy1; - -/* Tick and subtick sizes in device coords */ - - major = MAX(ROUND(plsc->majht * plsc->ypmm), 1); - minor = MAX(ROUND(plsc->minht * plsc->ypmm), 1); - - tick1 = tick; - nsub1 = nsub; - - lb = plP_stsearch(opt, 'b'); - lf = plP_stsearch(opt, 'f'); - li = plP_stsearch(opt, 'i'); - ll = plP_stsearch(opt, 'l'); - ln = plP_stsearch(opt, 'n'); - ls = plP_stsearch(opt, 's'); - lt = plP_stsearch(opt, 't'); - lu = plP_stsearch(opt, 'u'); - - if (lu) - plxytx(wx1, wy1, wx2, wy2, 3.2, 0.5, 0.5, label); - if (!lb) - return; - - if (ll) - tick1 = (vmax > vmin) ? 1.0 : -1.0 ; - if (lt) - pldtik(vmin, vmax, &tick1, &nsub1); - - if (li) { - i1 = minor; - i2 = 0; - i3 = major; - i4 = 0; - } - else { - i1 = 0; - i2 = minor; - i3 = 0; - i4 = major; - } - -/* Draw the line */ - - plP_movwor(wx1, wy1); - if (lt) { - tp = tick1 * floor(vmin / tick1); - for (;;) { - tn = tp + tick1; - if (ls) { - if (ll) { - for (i = 0; i <= 7; i++) { - temp = tp + xlog[i]; - if (BETW(temp, vmin, vmax)) { - lambda = (vmax_in > vmin_in)? - (temp - vmin) / (vmax - vmin): - (vmax - temp) / (vmax - vmin); - plxtik(plP_wcpcx((PLFLT) (wx1 + lambda * dwx)), - plP_wcpcy((PLFLT) (wy1 + lambda * dwy)), - i1, i2); - } - } - } - else { - for (i = 1; i <= nsub1 - 1; i++) { - temp = tp + i * (tn - tp) / nsub1; - if (BETW(temp, vmin, vmax)) { - lambda = (vmax_in > vmin_in)? - (temp - vmin) / (vmax - vmin): - (vmax - temp) / (vmax - vmin); - plxtik(plP_wcpcx((PLFLT) (wx1 + lambda * dwx)), - plP_wcpcy((PLFLT) (wy1 + lambda * dwy)), - i1, i2); - } - } - } - } - temp = tn; - if (!BETW(temp, vmin, vmax)) - break; - - lambda = (vmax_in > vmin_in)? - (temp - vmin) / (vmax - vmin): - (vmax - temp) / (vmax - vmin); - plxtik(plP_wcpcx((PLFLT) (wx1 + lambda * dwx)), - plP_wcpcy((PLFLT) (wy1 + lambda * dwy)), i3, i4); - tp = tn; - } - } - - plP_drawor(wx2, wy2); - -/* Label the line */ - - if (ln && lt) { - pldprec(vmin, vmax, tick1, lf, &mode, &prec, *digits, &scale); - pos = 1.0; - height = 3.2; - tcrit = tspace*tick1; - tp = tick1 * (1. + floor(vmin / tick1)); - for (tn = tp; BETW(tn, vmin, vmax); tn += tick1) { - if(BETW(tn, vmin+tcrit, vmax-tcrit)) { - plform(tn, scale, prec, string, ll, lf); - pos = (vmax_in > vmin_in)? - (tn - vmin) / (vmax - vmin): - (vmax - tn) / (vmax - vmin); - plxytx(wx1, wy1, wx2, wy2, 1.5, pos, 0.5, string); - } - } - *digits = 2; - if (!ll && mode) { - sprintf(string, "(x10#u%d#d)", (int) scale); - plxytx(wx1, wy1, wx2, wy2, height, 1.0, 0.5, string); - } - } -} - -/*--------------------------------------------------------------------------*\ - * void plxytx() - * - * Prints out text along a sloping axis joining world coordinates - * (wx1,wy1) to (wx2,wy2). Parameters are as for plmtext. -\*--------------------------------------------------------------------------*/ - -static void -plxytx(PLFLT wx1, PLFLT wy1, PLFLT wx2, PLFLT wy2, - PLFLT disp, PLFLT pos, PLFLT just, const char *text) -{ - PLINT x, y, refx, refy; - PLFLT shift, cc, ss, wx, wy; - PLFLT xdv, ydv, xmm, ymm, refxmm, refymm, xform[4], diag; - PLFLT dispx, dispy; - PLFLT chrdef, chrht; - - cc = plsc->wmxscl * (wx2 - wx1); - ss = plsc->wmyscl * (wy2 - wy1); - diag = sqrt(cc * cc + ss * ss); - cc /= diag; - ss /= diag; - wx = wx1 + pos * (wx2 - wx1); - wy = wy1 + pos * (wy2 - wy1); - - xform[0] = cc; - xform[1] = 0.0; - xform[2] = ss; - xform[3] = 1.0; - - xdv = plP_wcdcx(wx); - ydv = plP_wcdcy(wy); - - dispx = 0.; - dispy = -disp; - - plgchr(&chrdef, &chrht); - shift = (just == 0.0) ? 0.0 : plstrl(text) * just; - - xmm = plP_dcmmx(xdv) + dispx * chrht; - ymm = plP_dcmmy(ydv) + dispy * chrht; - refxmm = xmm - shift * xform[0]; - refymm = ymm - shift * xform[2]; - - x = plP_mmpcx(xmm); - y = plP_mmpcy(ymm); - refx = plP_mmpcx(refxmm); - refy = plP_mmpcy(refymm); - - plP_text(0, just, xform, x, y, refx, refy, text); -} - -/*--------------------------------------------------------------------------*\ - * void plzbx() - * - * This draws a vertical line from (wx,wy1) to (wx,wy2) which represents the - * vertical axis of a 3-d graph with data values from "vmin" to "vmax". - * Depending on "opt", ticks and/or subticks are placed on the line at major - * tick interval "tick" with "nsub" subticks between major ticks. If "tick" - * and/or "nsub" is zero, automatic tick positions are computed - * - * b: Draws left-hand axis - * c: Draws right-hand axis - * f: Always use fixed point numeric labels - * i: Inverts tick marks (i.e. drawn to the left) - * l: Logarithmic axes, major ticks at decades, minor ticks at units - * m: Write numeric label on right axis - * n: Write numeric label on left axis - * s: Draw minor tick marks - * t: Draw major tick marks - * u: Writes left-hand label - * v: Writes right-hand label -\*--------------------------------------------------------------------------*/ - -static void -plzbx(const char *opt, const char *label, PLINT right, PLFLT dx, PLFLT dy, - PLFLT wx, PLFLT wy1, PLFLT wy2, PLFLT vmin_in, PLFLT vmax_in, - PLFLT tick, PLINT nsub, PLINT *digits) -{ - static char string[40]; - PLINT lb, lc, lf, li, ll, lm, ln, ls, lt, lu, lv; - PLINT i, mode, prec, scale; - PLINT nsub1, lstring; - PLFLT pos, tn, tp, temp, height, tick1; - PLFLT dwy, lambda, diag, major, minor, xmajor, xminor; - PLFLT ymajor, yminor, dxm, dym, vmin, vmax; - - vmin = (vmax_in > vmin_in) ? vmin_in : vmax_in; - vmax = (vmax_in > vmin_in) ? vmax_in : vmin_in; - - dwy = wy2 - wy1; - -/* Tick and subtick sizes in device coords */ - - major = plsc->majht; - minor = plsc->minht; - - tick1 = tick; - nsub1 = nsub; - - lb = plP_stsearch(opt, 'b'); - lc = plP_stsearch(opt, 'c'); - lf = plP_stsearch(opt, 'f'); - li = plP_stsearch(opt, 'i'); - ll = plP_stsearch(opt, 'l'); - lm = plP_stsearch(opt, 'm'); - ln = plP_stsearch(opt, 'n'); - ls = plP_stsearch(opt, 's'); - lt = plP_stsearch(opt, 't'); - lu = plP_stsearch(opt, 'u'); - lv = plP_stsearch(opt, 'v'); - - if (lu && !right) - plztx("h", dx, dy, wx, wy1, wy2, 5.0, 0.5, 0.5, label); - - if (lv && right) - plztx("h", dx, dy, wx, wy1, wy2, -5.0, 0.5, 0.5, label); - - if (right && !lc) - return; - - if (!right && !lb) - return; - - if (ll) - tick1 = 1.0; - - if (lt) - pldtik(vmin, vmax, &tick1, &nsub1); - - if ((li && !right) || (!li && right)) { - minor = -minor; - major = -major; - } - - dxm = dx * plsc->wmxscl; - dym = dy * plsc->wmyscl; - diag = sqrt(dxm * dxm + dym * dym); - - xminor = minor * dxm / diag; - xmajor = major * dxm / diag; - yminor = minor * dym / diag; - ymajor = major * dym / diag; - -/* Draw the line */ - - plP_movwor(wx, wy1); - if (lt) { - tp = tick1 * floor(vmin / tick1); - for (;;) { - tn = tp + tick1; - if (ls) { - if (ll) { - for (i = 0; i <= 7; i++) { - temp = tp + xlog[i]; - if (BETW(temp, vmin, vmax)) { - lambda = (vmax_in > vmin_in)? - (temp - vmin) / (vmax - vmin): - (vmax - temp) / (vmax - vmin); - plstik(plP_wcmmx(wx), - plP_wcmmy((PLFLT) (wy1 + lambda * dwy)), - xminor, yminor); - } - } - } - else { - for (i = 1; i <= nsub1 - 1; i++) { - temp = tp + i * tick1 / nsub1; - if (BETW(temp, vmin, vmax)) { - lambda = (vmax_in > vmin_in)? - (temp - vmin) / (vmax - vmin): - (vmax - temp) / (vmax - vmin); - plstik(plP_wcmmx(wx), - plP_wcmmy((PLFLT) (wy1 + lambda * dwy)), - xminor, yminor); - } - } - } - } - temp = tn; - if (!BETW(temp, vmin, vmax)) - break; - lambda = (vmax_in > vmin_in)? - (temp - vmin) / (vmax - vmin): - (vmax - temp) / (vmax - vmin); - plstik(plP_wcmmx(wx), plP_wcmmy((PLFLT) (wy1 + lambda * dwy)), - xmajor, ymajor); - tp = tn; - } - } - - plP_drawor(wx, wy2); - -/* Label the line */ - - if ((ln || lm) && lt) { - pldprec(vmin, vmax, tick1, lf, &mode, &prec, *digits, &scale); - *digits = 0; - tp = tick1 * floor(vmin / tick1); - for (tn = tp + tick1; BETW(tn, vmin, vmax); tn += tick1) { - plform(tn, scale, prec, string, ll, lf); - pos = (vmax_in > vmin_in)? - (tn - vmin) / (vmax - vmin): - (vmax - tn) / (vmax - vmin); - if (ln && !right) - plztx("v", dx, dy, wx, wy1, wy2, 0.5, pos, 1.0, string); - - if (lm && right) - plztx("v", dx, dy, wx, wy1, wy2, -0.5, pos, 0.0, string); - - lstring = strlen(string); - *digits = MAX(*digits, lstring); - } - if (!ll && mode) { - sprintf(string, "(x10#u%d#d)", (int) scale); - pos = 1.15; - height = 0.5; - if (ln && !right) { - plztx("v", dx, dy, wx, wy1, wy2, height, pos, 0.5, string); - } - if (lm && right) { - plztx("v", dx, dy, wx, wy1, wy2, - (PLFLT) -height, pos, 0.5, string); - } - } - } -} - -/*--------------------------------------------------------------------------*\ - * void plztx() - * - * Prints out text along a vertical axis for a 3d plot joining - * world coordinates (wx,wy1) to (wx,wy2). -\*--------------------------------------------------------------------------*/ - -static void -plztx(const char *opt, PLFLT dx, PLFLT dy, PLFLT wx, PLFLT wy1, - PLFLT wy2, PLFLT disp, PLFLT pos, PLFLT just, const char *text) -{ - PLINT refx = 0, refy = 0, x = 0, y = 0, vert = 0; - PLFLT shift, cc, ss, wy; - PLFLT xdv, ydv, xmm, ymm, refxmm, refymm, xform[4], diag; - PLFLT dispx, dispy; - PLFLT chrdef, chrht; - - cc = plsc->wmxscl * dx; - ss = plsc->wmyscl * dy; - diag = sqrt(cc * cc + ss * ss); - cc /= diag; - ss /= diag; - wy = wy1 + pos * (wy2 - wy1); - - if (plP_stsearch(opt, 'v')) - vert = 0; - else if (plP_stsearch(opt, 'h')) - vert = 1; - - if (vert) { - xform[0] = 0.0; - xform[1] = -cc; - xform[2] = 1.0; - xform[3] = -ss; - } else { - xform[0] = cc; - xform[1] = 0.0; - xform[2] = ss; - xform[3] = 1.0; - } - - xdv = plP_wcdcx(wx); - ydv = plP_wcdcy(wy); - - dispx = -disp * cc; - dispy = -disp * ss; - - plgchr(&chrdef, &chrht); - shift = (just == 0.0) ? 0.0 : plstrl(text) * just; - - xmm = plP_dcmmx(xdv) + dispx * chrht; - ymm = plP_dcmmy(ydv) + dispy * chrht; - refxmm = xmm - shift * xform[0]; - refymm = ymm - shift * xform[2]; - - x = plP_mmpcx(xmm); - y = plP_mmpcy(ymm); - refx = plP_mmpcx(refxmm); - refy = plP_mmpcy(refymm); - - plP_text(0, just, xform, x, y, refx, refy, text); -} - -/*--------------------------------------------------------------------------*\ - * void grid_box() - * - * Draws grids at tick locations (major and/or minor). - * - * Note that 'tspace' is the minimim distance away (in fractional number - * of ticks or subticks) from the boundary a grid line can be drawn. If - * you are too close, it looks bad. -\*--------------------------------------------------------------------------*/ - -static void -grid_box(const char *xopt, PLFLT xtick1, PLINT nxsub1, - const char *yopt, PLFLT ytick1, PLINT nysub1) -{ - PLINT lgx, lhx, llx; - PLINT lgy, lhy, lly; - PLFLT vpwxmi, vpwxma, vpwymi, vpwyma; - PLFLT vpwxmin, vpwxmax, vpwymin, vpwymax; - PLFLT tn, temp, tcrit, tspace = 0.1; - PLINT i; - -/* Set plot options from input */ - - lgx = plP_stsearch(xopt, 'g'); - lhx = plP_stsearch(xopt, 'h'); - llx = plP_stsearch(xopt, 'l'); - - lgy = plP_stsearch(yopt, 'g'); - lhy = plP_stsearch(yopt, 'h'); - lly = plP_stsearch(yopt, 'l'); - - plgvpw(&vpwxmin, &vpwxmax, &vpwymin, &vpwymax); -/* n.b. large change; vpwxmi always numerically less than vpwxma, and - * similarly for vpwymi */ - vpwxmi = (vpwxmax > vpwxmin) ? vpwxmin : vpwxmax; - vpwxma = (vpwxmax > vpwxmin) ? vpwxmax : vpwxmin; - vpwymi = (vpwymax > vpwymin) ? vpwymin : vpwymax; - vpwyma = (vpwymax > vpwymin) ? vpwymax : vpwymin; - -/* Draw grid in x direction. */ - - if (lgx) { - for (tn = xtick1 * floor(vpwxmi/xtick1); - tn <= vpwxma; tn += xtick1) { - if (lhx) { - if (llx) { - PLFLT otemp = tn; - for (i = 0; i <= 7; i++) { - temp = tn + xlog[i]; - tcrit = (temp - otemp)*tspace; - otemp = temp; - if (BETW(temp, vpwxmi+tcrit, vpwxma-tcrit)) - pljoin(temp, vpwymi, temp, vpwyma); - } - } - else { - for (i = 1; i <= nxsub1 - 1; i++) { - temp = tn + i * xtick1 / nxsub1; - tcrit = xtick1 / nxsub1 * tspace; - if (BETW(temp, vpwxmi+tcrit, vpwxma-tcrit)) - pljoin(temp, vpwymi, temp, vpwyma); - } - } - } - tcrit = xtick1*tspace; - if (BETW(tn, vpwxmi+tcrit, vpwxma-tcrit)) - pljoin(tn, vpwymi, tn, vpwyma); - } - } - -/* Draw grid in y direction */ - - if (lgy) { - tn = ytick1 * floor(vpwymi / ytick1 + tspace); - for (tn = ytick1 * floor(vpwymi/ytick1); - tn <= vpwyma; tn += ytick1) { - if (lhy) { - if (lly) { - PLFLT otemp = tn; - for (i = 0; i <= 7; i++) { - temp = tn + xlog[i]; - tcrit = (temp - otemp)*tspace; - otemp = temp; - if (BETW(temp, vpwymi+tcrit, vpwyma-tcrit)) - pljoin(vpwxmi, temp, vpwxma, temp); - } - } - else { - for (i = 1; i <= nysub1 - 1; i++) { - temp = tn + i * ytick1 / nysub1; - tcrit = ytick1 / nysub1 * tspace; - if (BETW(temp, vpwymi+tcrit, vpwyma-tcrit)) - pljoin(vpwxmi, temp, vpwxma, temp); - } - } - } - tcrit = ytick1*tspace; - if (BETW(tn, vpwymi+tcrit, vpwyma-tcrit)) - pljoin(vpwxmi, tn, vpwxma, tn); - } - } -} - -/*--------------------------------------------------------------------------*\ - * void label_box() - * - * Writes numeric labels on side(s) of box. -\*--------------------------------------------------------------------------*/ - -static void -label_box(const char *xopt, PLFLT xtick1, const char *yopt, PLFLT ytick1) -{ - static char string[40]; - PLINT lfx, lix, llx, lmx, lnx, ltx; - PLINT lfy, liy, lly, lmy, lny, lty, lvy; - PLFLT vpwxmi, vpwxma, vpwymi, vpwyma; - PLFLT vpwxmin, vpwxmax, vpwymin, vpwymax; - PLFLT pos, tn, tp, offset, height; - -/* Set plot options from input */ - - lfx = plP_stsearch(xopt, 'f'); - lix = plP_stsearch(xopt, 'i'); - llx = plP_stsearch(xopt, 'l'); - lmx = plP_stsearch(xopt, 'm'); - lnx = plP_stsearch(xopt, 'n'); - ltx = plP_stsearch(xopt, 't'); - - lfy = plP_stsearch(yopt, 'f'); - liy = plP_stsearch(yopt, 'i'); - lly = plP_stsearch(yopt, 'l'); - lmy = plP_stsearch(yopt, 'm'); - lny = plP_stsearch(yopt, 'n'); - lty = plP_stsearch(yopt, 't'); - lvy = plP_stsearch(yopt, 'v'); - - plgvpw(&vpwxmin, &vpwxmax, &vpwymin, &vpwymax); -/* n.b. large change; vpwxmi always numerically less than vpwxma, and - * similarly for vpwymi */ - vpwxmi = (vpwxmax > vpwxmin) ? vpwxmin : vpwxmax; - vpwxma = (vpwxmax > vpwxmin) ? vpwxmax : vpwxmin; - vpwymi = (vpwymax > vpwymin) ? vpwymin : vpwymax; - vpwyma = (vpwymax > vpwymin) ? vpwymax : vpwymin; - -/* Write horizontal label(s) */ - - if ((lmx || lnx) && ltx) { - PLINT xmode, xprec, xdigmax, xdigits, xscale; - - plgxax(&xdigmax, &xdigits); - pldprec(vpwxmi, vpwxma, xtick1, lfx, &xmode, &xprec, xdigmax, &xscale); - - tp = xtick1 * (1. + floor(vpwxmi / xtick1)); - for (tn = tp; BETW(tn, vpwxmi, vpwxma); tn += xtick1) { - plform(tn, xscale, xprec, string, llx, lfx); - height = lix ? 1.75 : 1.5; - pos = (vpwxmax > vpwxmin)? - (tn - vpwxmi) / (vpwxma - vpwxmi): - (vpwxma - tn) / (vpwxma - vpwxmi); - if (lnx) - plmtex("b", height, pos, 0.5, string); - if (lmx) - plmtex("t", height, pos, 0.5, string); - } - xdigits = 2; - plsxax(xdigmax, xdigits); - - /* Write separate exponential label if mode = 1. */ - - if (!llx && xmode) { - pos = 1.0; - height = 3.2; - sprintf(string, "(x10#u%d#d)", (int) xscale); - if (lnx) - plmtex("b", height, pos, 0.5, string); - if (lmx) - plmtex("t", height, pos, 0.5, string); - } - } - -/* Write vertical label(s) */ - - if ((lmy || lny) && lty) { - PLINT ymode, yprec, ydigmax, ydigits, yscale; - - plgyax(&ydigmax, &ydigits); - pldprec(vpwymi, vpwyma, ytick1, lfy, &ymode, &yprec, ydigmax, &yscale); - - ydigits = 0; - tp = ytick1 * (1. + floor(vpwymi / ytick1)); - for (tn = tp; BETW(tn, vpwymi, vpwyma); tn += ytick1) { - plform(tn, yscale, yprec, string, lly, lfy); - pos = (vpwymax > vpwymin)? - (tn - vpwymi) / (vpwyma - vpwymi): - (vpwyma - tn) / (vpwyma - vpwymi); - if (lny) { - if (lvy) { - height = liy ? 1.0 : 0.5; - plmtex("lv", height, pos, 1.0, string); - } else { - height = liy ? 1.75 : 1.5; - plmtex("l", height, pos, 0.5, string); - } - } - if (lmy) { - if (lvy) { - height = liy ? 1.0 : 0.5; - plmtex("rv", height, pos, 0.0, string); - } else { - height = liy ? 1.75 : 1.5; - plmtex("r", height, pos, 0.5, string); - } - } - ydigits = MAX(ydigits, strlen(string)); - } - if (!lvy) - ydigits = 2; - - plsyax(ydigmax, ydigits); - - /* Write separate exponential label if mode = 1. */ - - if (!lly && ymode) { - sprintf(string, "(x10#u%d#d)", (int) yscale); - offset = 0.02; - height = 2.0; - if (lny) { - pos = 0.0 - offset; - plmtex("t", height, pos, 1.0, string); - } - if (lmy) { - pos = 1.0 + offset; - plmtex("t", height, pos, 0.0, string); - } - } - } -} - -/*--------------------------------------------------------------------------*\ - * void plform() - * - * Formats a PLFLT value in one of the following formats. - * - * If ll (logarithmic), then: - * - * - If lf (fixed), then used fixed point notation, i.e. .1, 1, 10, etc, - * with unnecessary trailing .'s or 0's removed. - * - * - If !lf (default), then use exponential notation, i.e. 10^-1, etc. - * - * If !ll (linear), then: - * - * - If scale == 0, use fixed point format with "prec" places after the - * decimal point. - * - * - If scale == 1, use scientific notation with one place before the - * decimal point and "prec" places after. In this case, the value - * must be divided by 10^scale. -\*--------------------------------------------------------------------------*/ - -static void -plform(PLFLT value, PLINT scale, PLINT prec, char *string, PLINT ll, PLINT lf) -{ - if (ll) { - - /* Logarithmic */ - - if (lf) { - - /* Fixed point, i.e. .1, 1, 10, etc */ - - int exponent = ROUND(value); - - value = pow(10.0, exponent); - if (exponent < 0) { - char form[10]; - sprintf(form, "%%.%df", ABS(exponent)); - sprintf(string, form, value); - } - else { - sprintf(string, "%d", (int) value); - } - } - else { - - /* Exponential, i.e. 10^-1, 10^0, 10^1, etc */ - - sprintf(string, "10#u%d", (int) ROUND(value)); - } - } - else { - - /* Linear */ - - PLINT setpre, precis; - char form[10], temp[30]; - double scale2; - - plP_gprec(&setpre, &precis); - - if (setpre) - prec = precis; - - if (scale) - value /= pow(10.,(double)scale); - - /* This is necessary to prevent labels like "-0.0" on some systems */ - - scale2 = pow(10., prec); - value = floor((value * scale2) + .5) / scale2; - - sprintf(form, "%%.%df", (int) prec); - sprintf(temp, form, value); - strcpy(string, temp); - } -} diff --git a/src/plot/plplot/plbuf.c b/src/plot/plplot/plbuf.c deleted file mode 100644 index ffe50adebd..0000000000 --- a/src/plot/plplot/plbuf.c +++ /dev/null @@ -1,724 +0,0 @@ -/* $Id: plbuf.c,v 1.1 2004/03/01 20:54:50 cozmic Exp $ - - Handle plot buffer. - - Copyright 1992 - Maurice LeBrun - - This software may be freely copied, modified and redistributed without - fee provided that this copyright notice is preserved intact on all - copies and modified copies. - - There is no warranty or other guarantee of fitness of this software. - It is provided solely "as is". The author(s) disclaim(s) all - responsibility and liability with respect to this software's usage or - its effect upon hardware or computer systems. -*/ - -#define NEED_PLDEBUG -#include "plplotP.h" -#include "drivers.h" -#include "metadefs.h" - -#include - -/* Function prototypes */ - -static int rd_command (PLStream *pls, U_CHAR *p_c); -static int wr_command (PLStream *pls, U_CHAR c); -static void plbuf_control (PLStream *pls, U_CHAR c); - -static void rdbuf_init (PLStream *pls); -static void rdbuf_line (PLStream *pls); -static void rdbuf_polyline (PLStream *pls); -static void rdbuf_eop (PLStream *pls); -static void rdbuf_bop (PLStream *pls); -static void rdbuf_state (PLStream *pls); -static void rdbuf_esc (PLStream *pls); - -static void plbuf_fill (PLStream *pls); -static void rdbuf_fill (PLStream *pls); -static void plbuf_swin (PLStream *pls, PLWindow *plwin); -static void rdbuf_swin (PLStream *pls); - -/*--------------------------------------------------------------------------*\ - * plbuf_init() - * - * Initialize device. - * Actually just disables writes if plot buffer is already open (occurs - * when one stream is cloned, as in printing). -\*--------------------------------------------------------------------------*/ - -void -plbuf_init(PLStream *pls) -{ - dbug_enter("plbuf_init"); - - pls->plbuf_read = FALSE; - if (pls->plbufFile != NULL) - pls->plbuf_write = FALSE; -} - -/*--------------------------------------------------------------------------*\ - * plbuf_line() - * - * Draw a line in the current color from (x1,y1) to (x2,y2). -\*--------------------------------------------------------------------------*/ - -void -plbuf_line(PLStream *pls, short x1a, short y1a, short x2a, short y2a) -{ - short xpl[2], ypl[2]; - - dbug_enter("plbuf_line"); - - wr_command(pls, (U_CHAR) LINE); - - xpl[0] = x1a; - xpl[1] = x2a; - ypl[0] = y1a; - ypl[1] = y2a; - - fwrite(xpl, sizeof(short), 2, pls->plbufFile); - fwrite(ypl, sizeof(short), 2, pls->plbufFile); -} - -/*--------------------------------------------------------------------------*\ - * plbuf_polyline() - * - * Draw a polyline in the current color. -\*--------------------------------------------------------------------------*/ - -void -plbuf_polyline(PLStream *pls, short *xa, short *ya, PLINT npts) -{ - dbug_enter("plbuf_polyline"); - - wr_command(pls, (U_CHAR) POLYLINE); - fwrite(&npts, sizeof(PLINT), 1, pls->plbufFile); - - fwrite(xa, sizeof(short), npts, pls->plbufFile); - fwrite(ya, sizeof(short), npts, pls->plbufFile); -} - -/*--------------------------------------------------------------------------*\ - * plbuf_eop() - * - * End of page. -\*--------------------------------------------------------------------------*/ - -void -plbuf_eop(PLStream *pls) -{ - dbug_enter("plbuf_eop"); -} - -/*--------------------------------------------------------------------------*\ - * plbuf_bop() - * - * Set up for the next page. - * To avoid problems redisplaying partially filled pages, on each BOP the - * old file is thrown away and a new one is obtained. This way we can just - * read up to EOF to get everything on the current page. - * - * Also write state information to ensure the next page is correct. -\*--------------------------------------------------------------------------*/ - -void -plbuf_bop(PLStream *pls) -{ - dbug_enter("plbuf_bop"); - - plbuf_tidy(pls); - - pls->plbufFile = tmpfile(); - if (pls->plbufFile == NULL) - plexit("plbuf_init: Error opening plot data storage file."); - - wr_command(pls, (U_CHAR) BOP); - plbuf_state(pls, PLSTATE_COLOR0); - plbuf_state(pls, PLSTATE_WIDTH); -} - -/*--------------------------------------------------------------------------*\ - * plbuf_tidy() - * - * Close graphics file -\*--------------------------------------------------------------------------*/ - -void -plbuf_tidy(PLStream *pls) -{ - dbug_enter("plbuf_tidy"); - - if (pls->plbufFile == NULL) - return; - - fclose(pls->plbufFile); - pls->plbufFile = NULL; -} - -/*--------------------------------------------------------------------------*\ - * plbuf_state() - * - * Handle change in PLStream state (color, pen width, fill attribute, etc). -\*--------------------------------------------------------------------------*/ - -void -plbuf_state(PLStream *pls, PLINT op) -{ - dbug_enter("plbuf_state"); - - wr_command(pls, (U_CHAR) CHANGE_STATE); - wr_command(pls, (U_CHAR) op); - - switch (op) { - - case PLSTATE_WIDTH: { - U_CHAR width = pls->width; - - fwrite(&width, sizeof(U_CHAR), 1, pls->plbufFile); - break; - } - - case PLSTATE_COLOR0: { - U_CHAR icol0 = pls->icol0; - U_CHAR r = pls->curcolor.r; - U_CHAR g = pls->curcolor.g; - U_CHAR b = pls->curcolor.b; - - fwrite(&icol0, sizeof(U_CHAR), 1, pls->plbufFile); - if (icol0 == PL_RGB_COLOR) { - fwrite(&r, sizeof(U_CHAR), 1, pls->plbufFile); - fwrite(&g, sizeof(U_CHAR), 1, pls->plbufFile); - fwrite(&b, sizeof(U_CHAR), 1, pls->plbufFile); - } - break; - } - - case PLSTATE_COLOR1: { - U_CHAR icol1 = pls->icol1; - - fwrite(&icol1, sizeof(U_CHAR), 1, pls->plbufFile); - break; - } - - case PLSTATE_FILL:{ - signed char patt = pls->patt; - - fwrite(&patt, sizeof(signed char), 1, pls->plbufFile); - break; - } - } -} - - -/*--------------------------------------------------------------------------*\ - * plbuf_image() - * - * write image described in points pls->dev_x[], pls->dev_y[], pls->dev_z[]. - * pls->nptsX, pls->nptsY. -\*--------------------------------------------------------------------------*/ - -static void -plbuf_image(PLStream *pls, IMG_DT *img_dt) -{ - PLINT npts = pls->dev_nptsX * pls->dev_nptsY; - - dbug_enter("plbuf_image"); - - fwrite(&pls->dev_nptsX, sizeof(PLINT), 1, pls->plbufFile); - fwrite(&pls->dev_nptsY, sizeof(PLINT), 1, pls->plbufFile); - - fwrite(&img_dt->xmin, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&img_dt->ymin, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&img_dt->dx, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&img_dt->dy, sizeof(PLFLT), 1, pls->plbufFile); - - fwrite(&pls->dev_zmin, sizeof(short), 1, pls->plbufFile); - fwrite(&pls->dev_zmax, sizeof(short), 1, pls->plbufFile); - - fwrite(pls->dev_ix, sizeof(short), npts, pls->plbufFile); - fwrite(pls->dev_iy, sizeof(short), npts, pls->plbufFile); - fwrite(pls->dev_z, sizeof(unsigned short), (pls->dev_nptsX-1)*(pls->dev_nptsY-1), pls->plbufFile); -} - -/*--------------------------------------------------------------------------*\ - * plbuf_esc() - * - * Escape function. Note that any data written must be in device - * independent form to maintain the transportability of the metafile. - * - * Functions: - * - * PLESC_FILL Fill polygon - * PLESC_SWIN Set plot window parameters - * PLESC_IMAGE Draw image -\*--------------------------------------------------------------------------*/ - -void -plbuf_esc(PLStream *pls, PLINT op, void *ptr) -{ - dbug_enter("plbuf_esc"); - - wr_command(pls, (U_CHAR) ESCAPE); - wr_command(pls, (U_CHAR) op); - - switch (op) { - case PLESC_FILL: - plbuf_fill(pls); - break; - case PLESC_SWIN: - plbuf_swin(pls, (PLWindow *) ptr); - break; - case PLESC_IMAGE: - plbuf_image(pls, (IMG_DT *) ptr); - break; - } -} - -/*--------------------------------------------------------------------------*\ - * plbuf_fill() - * - * Fill polygon described in points pls->dev_x[] and pls->dev_y[]. -\*--------------------------------------------------------------------------*/ - -static void -plbuf_fill(PLStream *pls) -{ - dbug_enter("plbuf_fill"); - - fwrite(&pls->dev_npts, sizeof(PLINT), 1, pls->plbufFile); - fwrite(pls->dev_x, sizeof(short), pls->dev_npts, pls->plbufFile); - fwrite(pls->dev_y, sizeof(short), pls->dev_npts, pls->plbufFile); -} - -/*--------------------------------------------------------------------------*\ - * plbuf_swin() - * - * Set up plot window parameters. -\*--------------------------------------------------------------------------*/ - -static void -plbuf_swin(PLStream *pls, PLWindow *plwin) -{ - fwrite(&plwin->dxmi, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&plwin->dxma, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&plwin->dymi, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&plwin->dyma, sizeof(PLFLT), 1, pls->plbufFile); - - fwrite(&plwin->wxmi, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&plwin->wxma, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&plwin->wymi, sizeof(PLFLT), 1, pls->plbufFile); - fwrite(&plwin->wyma, sizeof(PLFLT), 1, pls->plbufFile); -} - -/*--------------------------------------------------------------------------*\ - * Routines to read from & process the plot buffer. -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * rdbuf_init() - * - * Initialize device. -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_init(PLStream *pls) -{ - dbug_enter("rdbuf_init"); -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_line() - * - * Draw a line in the current color from (x1,y1) to (x2,y2). -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_line(PLStream *pls) -{ - short xpl[2], ypl[2]; - PLINT npts = 2; - - dbug_enter("rdbuf_line"); - - if (npts != fread(xpl, sizeof(short), npts, pls->plbufFile)) return; - if (npts != fread(ypl, sizeof(short), npts, pls->plbufFile)) return; - - plP_line(xpl, ypl); -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_polyline() - * - * Draw a polyline in the current color. -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_polyline(PLStream *pls) -{ - short xpl[PL_MAXPOLY], ypl[PL_MAXPOLY]; - PLINT npts; - - dbug_enter("rdbuf_polyline"); - - if (1 != fread(&npts, sizeof(PLINT), 1, pls->plbufFile)) return; - if (npts != fread(xpl, sizeof(short), npts, pls->plbufFile)) return; - if (npts != fread(ypl, sizeof(short), npts, pls->plbufFile)) return; - - plP_polyline(xpl, ypl, npts); -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_eop() - * - * End of page. -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_eop(PLStream *pls) -{ - dbug_enter("rdbuf_eop"); -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_bop() - * - * Set up for the next page. -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_bop(PLStream *pls) -{ - dbug_enter("rdbuf_bop"); - - pls->nplwin = 0; -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_state() - * - * Handle change in PLStream state (color, pen width, fill attribute, etc). -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_state(PLStream *pls) -{ - U_CHAR op; - - dbug_enter("rdbuf_state"); - - if (1 != fread(&op, sizeof(U_CHAR), 1, pls->plbufFile)) return; - - switch (op) { - - case PLSTATE_WIDTH:{ - U_CHAR width; - - if (1 != fread(&width, sizeof(U_CHAR), 1, pls->plbufFile)) return; - pls->width = width; - plP_state(PLSTATE_WIDTH); - - break; - } - - case PLSTATE_COLOR0:{ - U_CHAR icol0, r, g, b; - - if (1 != fread(&icol0, sizeof(U_CHAR), 1, pls->plbufFile)) return; - if (icol0 == PL_RGB_COLOR) { - if (1 != fread(&r, sizeof(U_CHAR), 1, pls->plbufFile)) return; - if (1 != fread(&g, sizeof(U_CHAR), 1, pls->plbufFile)) return; - if (1 != fread(&b, sizeof(U_CHAR), 1, pls->plbufFile)) return; - } - else { - if ((int) icol0 > 15) { - plwarn("rdbuf_state: Color map 0 entry hosed"); - icol0 = 1; - } - r = pls->cmap0[icol0].r; - g = pls->cmap0[icol0].g; - b = pls->cmap0[icol0].b; - } - pls->icol0 = icol0; - pls->curcolor.r = r; - pls->curcolor.g = g; - pls->curcolor.b = b; - - plP_state(PLSTATE_COLOR0); - break; - } - - case PLSTATE_COLOR1: { - U_CHAR icol1; - - if (1 != fread(&icol1, sizeof(U_CHAR), 1, pls->plbufFile)) return; - - pls->icol1 = icol1; - pls->curcolor.r = pls->cmap1[icol1].r; - pls->curcolor.g = pls->cmap1[icol1].g; - pls->curcolor.b = pls->cmap1[icol1].b; - - plP_state(PLSTATE_COLOR1); - break; - } - - case PLSTATE_FILL: { - signed char patt; - - if (1 != fread(&patt, sizeof(signed char), 1, pls->plbufFile)) return; - - pls->patt = patt; - plP_state(PLSTATE_FILL); - break; - } - } -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_esc() - * - * Escape function. - * Must fill data structure with whatever data that was written, - * then call escape function. - * - * Note: it is best to only call the escape function for op-codes that - * are known to be supported. - * - * Functions: - * - * PLESC_FILL Fill polygon - * PLESC_SWIN Set plot window parameters - * PLESC_IMAGE Draw image -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_image(PLStream *pls); - -static void -rdbuf_esc(PLStream *pls) -{ - U_CHAR op; - - dbug_enter("rdbuf_esc"); - - if (1 != fread(&op, sizeof(U_CHAR), 1, pls->plbufFile)) return; - - switch (op) { - case PLESC_FILL: - rdbuf_fill(pls); - break; - case PLESC_SWIN: - rdbuf_swin(pls); - break; - case PLESC_IMAGE: - rdbuf_image(pls); - break; - } -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_fill() - * - * Fill polygon described by input points. -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_fill(PLStream *pls) -{ - short xpl[PL_MAXPOLY], ypl[PL_MAXPOLY]; - PLINT npts; - - dbug_enter("rdbuf_fill"); - - if (1 != fread(&npts, sizeof(PLINT), 1, pls->plbufFile)) return; - if (npts != fread(xpl, sizeof(short), npts, pls->plbufFile)) return; - if (npts != fread(ypl, sizeof(short), npts, pls->plbufFile)) return; - - plP_fill(xpl, ypl, npts); -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_image() - * - * . -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_image(PLStream *pls) -{ - short *dev_ix, *dev_iy; - unsigned short *dev_z, dev_zmin, dev_zmax; - PLINT nptsX,nptsY, npts; - PLFLT xmin, ymin, dx, dy; - - dbug_enter("rdbuf_image"); - - if (1 != fread(&nptsX, sizeof(PLINT), 1, pls->plbufFile)) return; - if (1 != fread(&nptsY, sizeof(PLINT), 1, pls->plbufFile)) return; - npts = nptsX*nptsY; - - if (1 != fread(&xmin, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&ymin, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&dx, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&dy, sizeof(PLFLT), 1, pls->plbufFile)) return; - - if (1 != fread(&dev_zmin, sizeof(short), 1, pls->plbufFile)) return; - if (1 != fread(&dev_zmax, sizeof(short), 1, pls->plbufFile)) return; - - dev_ix=(short *)malloc(npts*sizeof(short)); - if (!dev_ix) return; - dev_iy=(short *)malloc(npts*sizeof(short)); - if (!dev_iy) goto end_y; - dev_z=(unsigned short *)malloc((nptsX-1)*(nptsY-1)*sizeof(unsigned short)); - if (!dev_z) goto end_z; - - if (npts != fread(dev_ix, sizeof(short), npts, pls->plbufFile)) goto end; - if (npts != fread(dev_iy, sizeof(short), npts, pls->plbufFile)) goto end; - if ((nptsX-1)*(nptsY-1) != fread(dev_z, sizeof(unsigned short), (nptsX-1)*(nptsY-1), pls->plbufFile)) goto end; - - plP_image(dev_ix, dev_iy, dev_z, nptsX, nptsY, xmin, ymin, dx, dy, dev_zmin, dev_zmax); - -end: - free(dev_z); -end_z: - free(dev_iy); -end_y: - free(dev_ix); -} - -/*--------------------------------------------------------------------------*\ - * rdbuf_swin() - * - * Set up plot window parameters. -\*--------------------------------------------------------------------------*/ - -static void -rdbuf_swin(PLStream *pls) -{ - PLWindow plwin; - - if (1 != fread(&plwin.dxmi, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&plwin.dxma, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&plwin.dymi, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&plwin.dyma, sizeof(PLFLT), 1, pls->plbufFile)) return; - - if (1 != fread(&plwin.wxmi, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&plwin.wxma, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&plwin.wymi, sizeof(PLFLT), 1, pls->plbufFile)) return; - if (1 != fread(&plwin.wyma, sizeof(PLFLT), 1, pls->plbufFile)) return; - - plP_swin(&plwin); -} - -/*--------------------------------------------------------------------------*\ - * plRemakePlot() - * - * Rebuilds plot from plot buffer, usually in response to a window - * resize or exposure event. -\*--------------------------------------------------------------------------*/ - -void -plRemakePlot(PLStream *pls) -{ - U_CHAR c; - int plbuf_status; - - dbug_enter("plRemakePlot"); - - if (pls->plbufFile == NULL) - return; - - rewind(pls->plbufFile); - - plbuf_status = pls->plbuf_write; - pls->plbuf_write = FALSE; - pls->plbuf_read = TRUE; - while (rd_command(pls, &c)) { - plbuf_control(pls, c); - } - - pls->plbuf_read = FALSE; - pls->plbuf_write = plbuf_status; -} - -/*--------------------------------------------------------------------------*\ - * plbuf_control() - * - * Processes commands read from the plot buffer. -\*--------------------------------------------------------------------------*/ - -static void -plbuf_control(PLStream *pls, U_CHAR c) -{ - static U_CHAR c_old = 0; - - dbug_enter("plbuf_control"); - - switch ((int) c) { - - case INITIALIZE: - rdbuf_init(pls); - break; - - case EOP: - rdbuf_eop(pls); - break; - - case BOP: - rdbuf_bop(pls); - break; - - case CHANGE_STATE: - rdbuf_state(pls); - break; - - case LINE: - rdbuf_line(pls); - break; - - case POLYLINE: - rdbuf_polyline(pls); - break; - - case ESCAPE: - rdbuf_esc(pls); - break; - - default: - pldebug("plbuf_control", "Unrecognized command %d, previous %d\n", c, c_old); - } - c_old = c; -} - -/*--------------------------------------------------------------------------*\ - * rd_command() - * - * Read & return the next command -\*--------------------------------------------------------------------------*/ - -static int -rd_command(PLStream *pls, U_CHAR *p_c) -{ - int count; - - count = fread(p_c, sizeof(U_CHAR), 1, pls->plbufFile); - return (count); -} - -/*--------------------------------------------------------------------------*\ - * wr_command() - * - * Write the next command -\*--------------------------------------------------------------------------*/ - -static int -wr_command(PLStream *pls, U_CHAR c) -{ - U_CHAR c1 = c; - int count; - - count = fwrite(&c1, sizeof(U_CHAR), 1, pls->plbufFile); - return (count); -} diff --git a/src/plot/plplot/plcdemos.h b/src/plot/plplot/plcdemos.h deleted file mode 100644 index 1891cd1756..0000000000 --- a/src/plot/plplot/plcdemos.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $Id: plcdemos.h,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - - Everything needed by the C demo programs. - Created to avoid junking up plplot.h with this stuff. -*/ - -#ifndef __PLCDEMOS_H__ -#define __PLCDEMOS_H__ - -#include "plConfig.h" -#include "plplot.h" -#include -#include -#include - -/* define PI if not defined by math.h */ - -#ifndef PI -#define PI 3.1415926535897932384 -#endif - -/* various utility macros */ - -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef ROUND -#define ROUND(a) (PLINT)((a)<0. ? ((a)-.5) : ((a)+.5)) -#endif - -#endif /* __PLCDEMOS_H__ */ diff --git a/src/plot/plplot/plcont.c b/src/plot/plplot/plcont.c deleted file mode 100644 index e05846c021..0000000000 --- a/src/plot/plplot/plcont.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* $Id: plcont.c,v 1.4 2005/03/17 21:39:21 eli Exp $ - - Contour plotter. -*/ - -#include - -#include "plplotP.h" - -#ifdef MSDOS -#pragma optimize("",off) -#endif - -/* Static function prototypes. */ - -static void -plcntr(PLFLT (*plf2eval) (PLINT, PLINT, PLPointer), - PLPointer plf2eval_data, - PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT flev, PLINT *iscan, - PLINT *ixstor, PLINT *iystor, PLINT nstor, - void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), - PLPointer pltr_data); - -static void -pldrawcn(PLFLT (*plf2eval) (PLINT, PLINT, PLPointer), - PLPointer plf2eval_data, - PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT flev, char *flabel, PLINT kcol, PLINT krow, - PLINT *p_kscan, PLINT *p_kstor, PLINT *iscan, - PLINT *ixstor, PLINT *iystor, PLINT nstor, - void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), - PLPointer pltr_data); - -static void -plccal(PLFLT (*plf2eval) (PLINT, PLINT, PLPointer), - PLPointer plf2eval_data, - PLFLT flev, PLINT ix, PLINT iy, - PLINT ixg, PLINT iyg, PLFLT *dist); - -static void -plr45 (PLINT *ix, PLINT *iy, PLINT isens); - -static void -plr135 (PLINT *ix, PLINT *iy, PLINT isens); - -static void -plfloatlabel(PLFLT value, char *string); - -static PLFLT -plP_pcwcx(PLINT x); - -static PLFLT -plP_pcwcy(PLINT y); - -static void -pl_drawcontlabel(PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex); - -/* Error flag for aborts */ - -static int error; - -/****************************************/ -/* */ -/* Defaults for contour label printing. */ -/* */ -/****************************************/ - -/* Font height for contour labels (normalized) */ -static PLFLT -contlabel_size = 0.3; - -/* Offset of label from contour line (if set to 0.0, labels are printed on the lines). */ -static PLFLT -contlabel_offset = 0.006; - -/* Spacing parameter for contour labels */ -static PLFLT -contlabel_space = 0.1; - -/* Activate labels, default off */ -static PLINT -contlabel_active = 0; - -/* If the contour label exceed 10^(limexp) or 10^(-limexp), the exponential format is used */ -static PLINT -limexp = 4; - -/* Number of significant digits */ -static PLINT -sigprec = 2; - -/******** contour lines storage ****************************/ - -static CONT_LEVEL *startlev = NULL; -static CONT_LEVEL *currlev; -static CONT_LINE *currline; - -static int cont3d = 0; - -static CONT_LINE * -alloc_line(CONT_LEVEL *node) -{ - CONT_LINE *line; - - line = (CONT_LINE *) malloc(sizeof(CONT_LINE)); - line->x = (PLFLT *) malloc(LINE_ITEMS*sizeof(PLFLT)); - line->y = (PLFLT *) malloc(LINE_ITEMS*sizeof(PLFLT)); - line->npts = 0; - line->next = NULL; - - return line; -} - -static CONT_LEVEL * -alloc_level(PLFLT level) -{ - CONT_LEVEL *node; - - node = (CONT_LEVEL *) malloc(sizeof(CONT_LEVEL)); - node->level = level; - node->next = NULL; - node->line = alloc_line(node); - - return node; -} - -static void -realloc_line(CONT_LINE *line) -{ - line->x = (PLFLT *) realloc(line->x, - (line->npts + LINE_ITEMS)*sizeof(PLFLT)); - line->y = (PLFLT *) realloc(line->y, - (line->npts + LINE_ITEMS)*sizeof(PLFLT)); -} - - -/* new contour level */ -static void -cont_new_store(PLFLT level) -{ - if (cont3d) { - if (startlev == NULL) { - startlev = alloc_level(level); - currlev = startlev; - } else { - currlev->next = alloc_level(level); - currlev = currlev->next; - } - currline = currlev->line; - } -} - -void -cont_clean_store(CONT_LEVEL *ct) -{ - CONT_LINE *tline, *cline; - CONT_LEVEL *tlev, *clevel; - - if (ct != NULL) { - clevel = ct; - - do { - cline = clevel->line; - do { -#ifdef CONT_PLOT_DEBUG /* for 2D plots. For 3D plots look at plot3.c:plotsh3di() */ - plP_movwor(cline->x[0],cline->y[0]); - for (j=1; jnpts; j++) - plP_drawor(cline->x[j], cline->y[j]); -#endif - tline = cline->next; - free(cline->x); - free(cline->y); - free(cline); - cline = tline; - } - while(cline != NULL); - tlev = clevel->next; - free(clevel); - clevel = tlev; - } - while(clevel != NULL); - startlev = NULL; - } -} - -static void -cont_xy_store(PLFLT xx, PLFLT yy) -{ - if (cont3d) { - PLINT pts = currline->npts; - - if (pts % LINE_ITEMS == 0) - realloc_line(currline); - - currline->x[pts] = xx; - currline->y[pts] = yy; - currline->npts++; - } else - plP_drawor(xx, yy); -} - -static void -cont_mv_store(PLFLT xx, PLFLT yy) -{ - if (cont3d) { - if (currline->npts != 0) { /* not an empty list, allocate new */ - currline->next = alloc_line(currlev); - currline = currline->next; - } - - /* and fill first element */ - currline->x[0] = xx; - currline->y[0] = yy; - currline->npts = 1; - } else - plP_movwor(xx, yy); -} - -/* small routine to set offset and spacing of contour labels, see desciption above */ -void c_pl_setcontlabelparam(PLFLT offset, PLFLT size, PLFLT spacing, PLINT active) -{ - contlabel_offset = offset; - contlabel_size = size; - contlabel_space = spacing; - contlabel_active = active; -} - -/* small routine to set the format of the contour labels, description of limexp and prec see above */ -void c_pl_setcontlabelformat(PLINT lexp, PLINT sigdig) -{ - limexp = lexp; - sigprec = sigdig; -} - -static void pl_drawcontlabel(PLFLT tpx, PLFLT tpy, char *flabel, PLFLT *distance, PLINT *lastindex) -{ - PLFLT currx_old, curry_old, delta_x, delta_y; - - delta_x = plP_pcdcx(plsc->currx)-plP_pcdcx(plP_wcpcx(tpx)); - delta_y = plP_pcdcy(plsc->curry)-plP_pcdcy(plP_wcpcy(tpy)); - - currx_old = plsc->currx; - curry_old = plsc->curry; - - *distance += sqrt(delta_x*delta_x + delta_y*delta_y); - - plP_drawor(tpx, tpy); - - if ((int )(fabs(*distance/contlabel_space)) > *lastindex) { - PLFLT scale, vec_x, vec_y, mx, my, dev_x, dev_y, off_x, off_y; - - vec_x = tpx-plP_pcwcx(currx_old); - vec_y = tpy-plP_pcwcy(curry_old); - - mx = (double )plsc->wpxscl/(double )plsc->phyxlen; - my = (double )plsc->wpyscl/(double )plsc->phyylen; - - dev_x = -my*vec_y/mx; - dev_y = mx*vec_x/my; - - scale = sqrt((mx*mx*dev_x*dev_x + my*my*dev_y*dev_y)/ - (contlabel_offset*contlabel_offset)); - - off_x = dev_x/scale; - off_y = dev_y/scale; - - plptex(tpx+off_x, tpy+off_y, vec_x, vec_y, 0.5, flabel); - plP_movwor(tpx, tpy); - (*lastindex)++; - - } else - plP_movwor(tpx, tpy); -} - - -/* Format contour labels. Arguments: - * value: floating point number to be formatted - * string: the formatted label, plptex must be called with it to actually - * print the label - */ - -static void plfloatlabel(PLFLT value, char *string) -{ - PLINT setpre, precis; - char form[32], tmpstring[32]; /* PLTSCHEME: used to be size 10, which lead to a buffer overrun */ - PLINT exponent = 0; - PLFLT mant, tmp; - - PLINT prec = sigprec; - - plP_gprec(&setpre, &precis); - - if (setpre) - prec = precis; - - if (value > 0.0) - tmp = log10(value); - else if (value < 0.0) - tmp = log10(-value); - else - tmp = 0; - - if (tmp >= 0.0) - exponent = (int )tmp; - else if (tmp < 0.0) { - tmp = -tmp; - if (floor(tmp) < tmp) - exponent = -(int )(floor(tmp) + 1.0); - else - exponent = -(int )(floor(tmp)); - } - - mant = value/pow(10.0, exponent); - - if (mant != 0.0) - mant = (int )(mant*pow(10.0, prec-1) + 0.5*mant/fabs(mant))/pow(10.0, prec-1); - - sprintf(form, "%%.%df", prec-1); - sprintf(string, form, mant); - /* sprintf(tmpstring, "#(229)10#u%d", exponent); */ - sprintf(tmpstring, "#(229)10#u%d", exponent); - strcat(string, tmpstring); - - if (abs(exponent) < limexp || value == 0.0) { - value = pow(10.0, exponent) * mant; - - if (exponent >= 0) - prec = prec - 1 - exponent; - else - prec = prec - 1 + abs(exponent); - - if (prec < 0) - prec = 0; - - sprintf(form, "%%.%df", (int) prec); - sprintf(string, form, value); - } -} - -/* physical coords (x) to world coords */ - -static PLFLT -plP_pcwcx(PLINT x) -{ - return ((x-plsc->wpxoff)/plsc->wpxscl); -} - -/* physical coords (y) to world coords */ - -static PLFLT -plP_pcwcy(PLINT y) -{ - return ((y-plsc->wpyoff)/plsc->wpyscl); -} - - - -/*--------------------------------------------------------------------------*\ - * plf2eval2() - * - * Does a lookup from a 2d function array. Array is of type (PLFLT **), - * and is column dominant (normal C ordering). -\*--------------------------------------------------------------------------*/ - -PLFLT -plf2eval2(PLINT ix, PLINT iy, PLPointer plf2eval_data) -{ - PLFLT value; - PLfGrid2 *grid = (PLfGrid2 *) plf2eval_data; - - value = grid->f[ix][iy]; - - return value; -} - -/*--------------------------------------------------------------------------*\ - * plf2eval() - * - * Does a lookup from a 2d function array. Array is of type (PLFLT *), and - * is column dominant (normal C ordering). You MUST fill the ny maximum - * array index entry in the PLfGrid struct. -\*--------------------------------------------------------------------------*/ - -PLFLT -plf2eval(PLINT ix, PLINT iy, PLPointer plf2eval_data) -{ - PLFLT value; - PLfGrid *grid = (PLfGrid *) plf2eval_data; - - value = grid->f[ix * grid->ny + iy]; - - return value; -} - -/*--------------------------------------------------------------------------*\ - * plf2evalr() - * - * Does a lookup from a 2d function array. Array is of type (PLFLT *), and - * is row dominant (Fortran ordering). You MUST fill the nx maximum array - * index entry in the PLfGrid struct. -\*--------------------------------------------------------------------------*/ - -PLFLT -plf2evalr(PLINT ix, PLINT iy, PLPointer plf2eval_data) -{ - PLFLT value; - PLfGrid *grid = (PLfGrid *) plf2eval_data; - - value = grid->f[ix + iy * grid->nx]; - - return value; -} - -/*--------------------------------------------------------------------------*\ - * - * cont_store: - * - * Draw contour lines in memory. - * cont_clean_store() must be called after use to release allocated memory. - * -\*--------------------------------------------------------------------------*/ - -void -cont_store(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT *clevel, PLINT nlevel, CONT_LEVEL **contour) -{ - PLcGrid grid1; - - cont3d = 1; - - grid1.nx = nx; grid1.ny = ny; grid1.xg = x; grid1.yg = y; - plcont(z, nx, ny, 1, nx, 1, ny, clevel, nlevel, - pltr1, (void *) & grid1 ); - - *contour = startlev; - cont3d = 0; -} - -/*--------------------------------------------------------------------------*\ - * void plcont() - * - * Draws a contour plot from data in f(nx,ny). Is just a front-end to - * plfcont, with a particular choice for f2eval and f2eval_data. -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plcont(PLFLT **f, PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT *clevel, PLINT nlevel, - void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), - PLPointer pltr_data) -{ - PLfGrid2 grid; - - grid.f = f; - plfcont(plf2eval2, (PLPointer) &grid, - nx, ny, kx, lx, ky, ly, clevel, nlevel, - pltr, pltr_data); -} - -/*--------------------------------------------------------------------------*\ - * void plfcont() - * - * Draws a contour plot using the function evaluator f2eval and data stored - * by way of the f2eval_data pointer. This allows arbitrary organizations - * of 2d array data to be used. - * - * The subrange of indices used for contouring is kx to lx in the x - * direction and from ky to ly in the y direction. The array of contour - * levels is clevel(nlevel), and "pltr" is the name of a function which - * transforms array indices into world coordinates. - * - * Note that the fortran-like minimum and maximum indices (kx, lx, ky, ly) - * are translated into more C-like ones. I've only kept them as they are - * for the plcontf() argument list because of backward compatibility. -\*--------------------------------------------------------------------------*/ - -void -plfcont(PLFLT (*f2eval) (PLINT, PLINT, PLPointer), - PLPointer f2eval_data, - PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT *clevel, PLINT nlevel, - void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), - PLPointer pltr_data) -{ - PLINT i, mx, my, nstor, *heapc; - - mx = lx - kx + 1; - my = ly - ky + 1; - - if (kx < 1 || kx >= lx) { - plabort("plfcont: indices must satisfy 1 <= kx <= lx <= nx"); - return; - } - if (ky < 1 || ky >= ly) { - plabort("plfcont: indices must satisfy 1 <= ky <= ly <= ny"); - return; - } - - nstor = mx * my; - heapc = (PLINT *) malloc((size_t) (2*mx + 10 * nstor) * sizeof(PLINT)); - if (heapc == NULL) { - plabort("plfcont: out of memory in heap allocation"); - return; - } - - for (i = 0; i < nlevel; i++) { - plcntr(f2eval, f2eval_data, - nx, ny, kx-1, lx-1, ky-1, ly-1, clevel[i], &heapc[0], - &heapc[nx], &heapc[nx + nstor], nstor, pltr, pltr_data); - - if (error) { - error = 0; - goto done; - } - } - - done: - free((void *) heapc); -} - -/*--------------------------------------------------------------------------*\ - * void plcntr() - * - * The contour for a given level is drawn here. Note iscan has nx - * elements. ixstor and iystor each have nstor elements. -\*--------------------------------------------------------------------------*/ - -static void -plcntr(PLFLT (*f2eval) (PLINT, PLINT, PLPointer), - PLPointer f2eval_data, - PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT flev, PLINT *iscan, - PLINT *ixstor, PLINT *iystor, PLINT nstor, - void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), - PLPointer pltr_data) -{ - PLINT kcol, krow, kstor, kscan, l, ixt, iyt, jstor, next; - - char flabel[30]; - - cont_new_store(flev); - - /* format contour label for plptex and define the font height of the labels */ - plfloatlabel(flev, flabel); - plschr(0.0, contlabel_size); - - /* Initialize memory pointers */ - - kstor = 0; - kscan = 0; - - for (krow = ky; krow <= ly; krow++) { - for (kcol = kx + 1; kcol <= lx; kcol++) { - - /* Follow and draw a contour */ - - pldrawcn(f2eval, f2eval_data, - nx, ny, kx, lx, ky, ly, flev, flabel, kcol, krow, - &kscan, &kstor, iscan, ixstor, iystor, nstor, - pltr, pltr_data); - - if (error) - return; - } - - /* Search of row complete */ - /* Set up memory of next row in iscan and edit ixstor and iystor */ - - if (krow < ny-1) { - jstor = 0; - kscan = 0; - next = krow + 1; - for (l = 1; l <= kstor; l++) { - ixt = ixstor[l - 1]; - iyt = iystor[l - 1]; - - /* Memory of next row into iscan */ - - if (iyt == next) { - kscan = kscan + 1; - iscan[kscan - 1] = ixt; - } - - /* Retain memory of rows to come, and forget rest */ - - else if (iyt > next) { - jstor = jstor + 1; - ixstor[jstor - 1] = ixt; - iystor[jstor - 1] = iyt; - } - } - kstor = jstor; - } - } - plschr(0.0, 1.0); -} - -/*--------------------------------------------------------------------------*\ - * void pldrawcn() - * - * Follow and draw a contour. -\*--------------------------------------------------------------------------*/ - -static void -pldrawcn(PLFLT (*f2eval) (PLINT, PLINT, PLPointer), - PLPointer f2eval_data, - PLINT nx, PLINT ny, PLINT kx, PLINT lx, - PLINT ky, PLINT ly, PLFLT flev, char *flabel, PLINT kcol, PLINT krow, - PLINT *p_kscan, PLINT *p_kstor, PLINT *iscan, - PLINT *ixstor, PLINT *iystor, PLINT nstor, - void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), - PLPointer pltr_data) -{ - PLINT iwbeg, ixbeg, iybeg, izbeg; - PLINT iboun, iw, ix, iy, iz, ifirst, istep, ixgo, iygo; - PLINT l, ixg, iyg, ia, ib; - - PLFLT dist, dx, dy, xnew, ynew, fxl, fxr; - PLFLT xlas = 0., ylas = 0., tpx, tpy, xt, yt; - PLFLT f1, f2, f3, f4, fcheck; - - PLINT lastindex = 0; - PLFLT distance = 0.0; - -/* Check if a contour has been crossed */ - - fxl = f2eval(kcol-1, krow, f2eval_data); - fxr = f2eval(kcol, krow, f2eval_data); - - if (fxl < flev && fxr >= flev) { - ixbeg = kcol - 1; - iwbeg = kcol; - } - else if (fxr < flev && fxl > flev) { - ixbeg = kcol; - iwbeg = kcol - 1; - } - else - return; - - iybeg = krow; - izbeg = krow; - -/* A contour has been crossed. */ -/* Check to see if it is a new one. */ - - for (l = 0; l < *p_kscan; l++) { - if (ixbeg == iscan[l]) - return; - } - - for (iboun = 1; iboun >= -1; iboun -= 2) { - - /* Set up starting point and initial search directions */ - - ix = ixbeg; - iy = iybeg; - iw = iwbeg; - iz = izbeg; - ifirst = 1; - istep = 0; - ixgo = iw - ix; - iygo = iz - iy; - - for (;;) { - plccal(f2eval, f2eval_data, - flev, ix, iy, ixgo, iygo, &dist); - - dx = dist * ixgo; - dy = dist * iygo; - xnew = ix + dx; - ynew = iy + dy; - - /* Has a step occured in search? */ - - if (istep != 0) { - if (ixgo * iygo == 0) { - - /* This was a diagonal step, so interpolate missed point. */ - /* Rotating 45 degrees to get it */ - - ixg = ixgo; - iyg = iygo; - plr45(&ixg, &iyg, iboun); - ia = iw - ixg; - ib = iz - iyg; - plccal(f2eval, f2eval_data, - flev, ia, ib, ixg, iyg, &dist); - - (*pltr) (xlas, ylas, &tpx, &tpy, pltr_data); - - if (contlabel_active) - pl_drawcontlabel(tpx, tpy, flabel, &distance, &lastindex); - else - cont_xy_store(tpx,tpy); /* plP_drawor(tpx, tpy); */ - - dx = dist * ixg; - dy = dist * iyg; - xlas = ia + dx; - ylas = ib + dy; - } - else { - if (dist > 0.5) { - xt = xlas; - xlas = xnew; - xnew = xt; - yt = ylas; - ylas = ynew; - ynew = yt; - } - } - } - if (ifirst != 1) { - (*pltr) (xlas, ylas, &tpx, &tpy, pltr_data); - if (contlabel_active) - pl_drawcontlabel(tpx, tpy, flabel, &distance, &lastindex); - else - cont_xy_store(tpx,tpy); /* plP_drawor(tpx, tpy); */ - } - else { - (*pltr) (xnew, ynew, &tpx, &tpy, pltr_data); - cont_mv_store(tpx,tpy); /* plP_movwor(tpx, tpy); */ - } - xlas = xnew; - ylas = ynew; - - /* Check if the contour is closed */ - - if (ifirst != 1 && - ix == ixbeg && iy == iybeg && iw == iwbeg && iz == izbeg) { - (*pltr) (xlas, ylas, &tpx, &tpy, pltr_data); - if (contlabel_active) - pl_drawcontlabel(tpx, tpy, flabel, &distance, &lastindex); - else - cont_xy_store(tpx,tpy); /* plP_drawor(tpx, tpy); */ - return; - } - ifirst = 0; - - /* Now the rotation */ - - istep = 0; - plr45(&ixgo, &iygo, iboun); - iw = ix + ixgo; - iz = iy + iygo; - - /* Check if out of bounds */ - - if (iw < kx || iw > lx || iz < ky || iz > ly) - break; - - /* Has contact been lost with the contour? */ - - if (ixgo * iygo == 0) - fcheck = f2eval(iw, iz, f2eval_data); - else { - f1 = f2eval(ix, iy, f2eval_data); - f2 = f2eval(iw, iz, f2eval_data); - f3 = f2eval(ix, iz, f2eval_data); - f4 = f2eval(iw, iy, f2eval_data); - - fcheck = MAX(f2, (f1 + f2 + f3 + f4) / 4.); - } - - if (fcheck < flev) { - - /* Yes, lost contact => step to new center */ - - istep = 1; - ix = iw; - iy = iz; - plr135(&ixgo, &iygo, iboun); - iw = ix + ixgo; - iz = iy + iygo; - - /* And do the contour memory */ - - if (iy == krow) { - *p_kscan = *p_kscan + 1; - iscan[*p_kscan - 1] = ix; - } - else if (iy > krow) { - *p_kstor = *p_kstor + 1; - if (*p_kstor > nstor) { - plabort("plfcont: heap exhausted"); - error = 1; - return; - } - ixstor[*p_kstor - 1] = ix; - iystor[*p_kstor - 1] = iy; - } - } - } - /* Reach here only if boundary encountered - Draw last bit */ - - (*pltr) (xnew, ynew, &tpx, &tpy, pltr_data); - /* distance = 0.0; */ - - cont_xy_store(tpx,tpy); /* plP_drawor(tpx, tpy); */ - } -} - -/*--------------------------------------------------------------------------*\ - * void plccal() - * - * Function to interpolate the position of a contour which is known to be - * next to ix,iy in the direction ixg,iyg. The unscaled distance along - * ixg,iyg is returned as dist. -\*--------------------------------------------------------------------------*/ - -static void -plccal(PLFLT (*f2eval) (PLINT, PLINT, PLPointer), - PLPointer f2eval_data, - PLFLT flev, PLINT ix, PLINT iy, - PLINT ixg, PLINT iyg, PLFLT *dist) -{ - PLINT ia, ib; - PLFLT dbot, dtop, fmid; - PLFLT fxy, fab, fay, fxb, flow; - - ia = ix + ixg; - ib = iy + iyg; - fxy = f2eval(ix, iy, f2eval_data); - fab = f2eval(ia, ib, f2eval_data); - fxb = f2eval(ix, ib, f2eval_data); - fay = f2eval(ia, iy, f2eval_data); - - if (ixg == 0 || iyg == 0) { - dtop = flev - fxy; - dbot = fab - fxy; - *dist = 0.0; - if (dbot != 0.0) - *dist = dtop / dbot; - } - else { - fmid = (fxy + fab + fxb + fay) / 4.0; - *dist = 0.5; - - if ((fxy - flev) * (fab - flev) <= 0.) { - - if (fmid >= flev) { - dtop = flev - fxy; - dbot = fmid - fxy; - if (dbot != 0.0) - *dist = 0.5 * dtop / dbot; - } - else { - dtop = flev - fab; - dbot = fmid - fab; - if (dbot != 0.0) - *dist = 1.0 - 0.5 * dtop / dbot; - } - } - else { - flow = (fxb + fay) / 2.0; - dtop = fab - flev; - dbot = fab + fxy - 2.0 * flow; - if (dbot != 0.0) - *dist = 1. - dtop / dbot; - } - } - if (*dist > 1.) - *dist = 1.; -} - -/*--------------------------------------------------------------------------*\ - * Rotators -\*--------------------------------------------------------------------------*/ - -static void -plr45 (PLINT *ix, PLINT *iy, PLINT isens) -{ - PLINT ixx, iyy; - - ixx = *ix - isens * (*iy); - iyy = *ix * isens + *iy; - *ix = ixx / MAX(1, ABS(ixx)); - *iy = iyy / MAX(1, ABS(iyy)); -} - -static void -plr135 (PLINT *ix, PLINT *iy, PLINT isens) -{ - *ix = -*ix; - *iy = -*iy; - plr45(ix, iy, isens); -} - -/*--------------------------------------------------------------------------*\ - * pltr0() - * - * Identity transformation. -\*--------------------------------------------------------------------------*/ - -void -pltr0(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data) -{ - *tx = x; - *ty = y; -} - -/*--------------------------------------------------------------------------*\ - * pltr1() - * - * Does linear interpolation from singly dimensioned coord arrays. - * - * Just abort for now if coordinates are out of bounds (don't think it's - * possible, but if so we could use linear extrapolation). -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -pltr1(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data) -{ - PLINT ul, ur, vl, vr; - PLFLT du, dv; - PLFLT xl, xr, yl, yr; - - PLcGrid *grid = (PLcGrid *) pltr_data; - PLFLT *xg = grid->xg; - PLFLT *yg = grid->yg; - PLINT nx = grid->nx; - PLINT ny = grid->ny; - - ul = (PLINT) x; - ur = ul + 1; - du = x - ul; - - vl = (PLINT) y; - vr = vl + 1; - dv = y - vl; - - if (x < 0 || x > nx - 1 || y < 0 || y > ny - 1) { - - /* fprintf(stderr, "nx : %d, ny : %d",nx,ny); */ - plexit("pltr1: Invalid coordinates"); - } - -/* Look up coordinates in row-dominant array. - * Have to handle right boundary specially -- if at the edge, we'd better - * not reference the out of bounds point. - */ - - xl = xg[ul]; - yl = yg[vl]; - - if (ur == nx) { - *tx = xl; - } - else { - xr = xg[ur]; - *tx = xl * (1 - du) + xr * du; - } - if (vr == ny) { - *ty = yl; - } - else { - yr = yg[vr]; - *ty = yl * (1 - dv) + yr * dv; - } -} - -/*--------------------------------------------------------------------------*\ - * pltr2() - * - * Does linear interpolation from doubly dimensioned coord arrays (column - * dominant, as per normal C 2d arrays). - * - * This routine includes lots of checks for out of bounds. This would occur - * occasionally due to some bugs in the contour plotter (now fixed). If an - * out of bounds coordinate is obtained, the boundary value is provided - * along with a warning. These checks should stay since no harm is done if - * if everything works correctly. -\*--------------------------------------------------------------------------*/ - -void -pltr2(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data) -{ - PLINT ul, ur, vl, vr; - PLFLT du, dv; - PLFLT xll, xlr, xrl, xrr; - PLFLT yll, ylr, yrl, yrr; - PLFLT xmin, xmax, ymin, ymax; - - PLcGrid2 *grid = (PLcGrid2 *) pltr_data; - PLFLT **xg = grid->xg; - PLFLT **yg = grid->yg; - PLINT nx = grid->nx; - PLINT ny = grid->ny; - - ul = (PLINT) x; - ur = ul + 1; - du = x - ul; - - vl = (PLINT) y; - vr = vl + 1; - dv = y - vl; - - xmin = 0; - xmax = nx - 1; - ymin = 0; - ymax = ny - 1; - - if (x < xmin || x > xmax || y < ymin || y > ymax) { - plwarn("pltr2: Invalid coordinates"); - if (x < xmin) { - - if (y < ymin) { - *tx = xg[0][0]; - *ty = yg[0][0]; - } - else if (y > ymax) { - *tx = xg[0][ny-1]; - *ty = yg[0][ny-1]; - } - else { - xll = xg[0][vl]; - yll = yg[0][vl]; - xlr = xg[0][vr]; - ylr = yg[0][vr]; - - *tx = xll * (1 - dv) + xlr * (dv); - *ty = yll * (1 - dv) + ylr * (dv); - } - } - else if (x > xmax) { - - if (y < ymin) { - *tx = xg[nx-1][0]; - *ty = yg[nx-1][0]; - } - else if (y > ymax) { - *tx = xg[nx-1][ny-1]; - *ty = yg[nx-1][ny-1]; - } - else { - xll = xg[nx-1][vl]; - yll = yg[nx-1][vl]; - xlr = xg[nx-1][vr]; - ylr = yg[nx-1][vr]; - - *tx = xll * (1 - dv) + xlr * (dv); - *ty = yll * (1 - dv) + ylr * (dv); - } - } - else { - if (y < ymin) { - xll = xg[ul][0]; - xrl = xg[ur][0]; - yll = yg[ul][0]; - yrl = yg[ur][0]; - - *tx = xll * (1 - du) + xrl * (du); - *ty = yll * (1 - du) + yrl * (du); - } - else if (y > ymax) { - xlr = xg[ul][ny-1]; - xrr = xg[ur][ny-1]; - ylr = yg[ul][ny-1]; - yrr = yg[ur][ny-1]; - - *tx = xlr * (1 - du) + xrr * (du); - *ty = ylr * (1 - du) + yrr * (du); - } - } - } - -/* Normal case. - * Look up coordinates in row-dominant array. - * Have to handle right boundary specially -- if at the edge, we'd - * better not reference the out of bounds point. - */ - - else { - - xll = xg[ul][vl]; - yll = yg[ul][vl]; - - /* ur is out of bounds */ - - if (ur == nx && vr < ny) { - - xlr = xg[ul][vr]; - ylr = yg[ul][vr]; - - *tx = xll * (1 - dv) + xlr * (dv); - *ty = yll * (1 - dv) + ylr * (dv); - } - - /* vr is out of bounds */ - - else if (ur < nx && vr == ny) { - - xrl = xg[ur][vl]; - yrl = yg[ur][vl]; - - *tx = xll * (1 - du) + xrl * (du); - *ty = yll * (1 - du) + yrl * (du); - } - - /* both ur and vr are out of bounds */ - - else if (ur == nx && vr == ny) { - - *tx = xll; - *ty = yll; - } - - /* everything in bounds */ - - else { - - xrl = xg[ur][vl]; - xlr = xg[ul][vr]; - xrr = xg[ur][vr]; - - yrl = yg[ur][vl]; - ylr = yg[ul][vr]; - yrr = yg[ur][vr]; - - *tx = xll * (1 - du) * (1 - dv) + xlr * (1 - du) * (dv) + - xrl * (du) * (1 - dv) + xrr * (du) * (dv); - - *ty = yll * (1 - du) * (1 - dv) + ylr * (1 - du) * (dv) + - yrl * (du) * (1 - dv) + yrr * (du) * (dv); - } - } -} - -/*--------------------------------------------------------------------------*\ - * pltr2p() - * - * Just like pltr2() but uses pointer arithmetic to get coordinates from 2d - * grid tables. This form of grid tables is compatible with those from - * PLplot 4.0. The grid data must be pointed to by a PLcGrid structure. -\*--------------------------------------------------------------------------*/ - -void -pltr2p(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, PLPointer pltr_data) -{ - PLINT ul, ur, vl, vr; - PLFLT du, dv; - PLFLT xll, xlr, xrl, xrr; - PLFLT yll, ylr, yrl, yrr; - PLFLT xmin, xmax, ymin, ymax; - - PLcGrid *grid = (PLcGrid *) pltr_data; - PLFLT *xg = grid->xg; - PLFLT *yg = grid->yg; - PLINT nx = grid->nx; - PLINT ny = grid->ny; - - ul = (PLINT) x; - ur = ul + 1; - du = x - ul; - - vl = (PLINT) y; - vr = vl + 1; - dv = y - vl; - - xmin = 0; - xmax = nx - 1; - ymin = 0; - ymax = ny - 1; - - if (x < xmin || x > xmax || y < ymin || y > ymax) { - plwarn("pltr2p: Invalid coordinates"); - if (x < xmin) { - - if (y < ymin) { - *tx = *xg; - *ty = *yg; - } - else if (y > ymax) { - *tx = *(xg + (ny - 1)); - *ty = *(yg + (ny - 1)); - } - else { - ul = 0; - xll = *(xg + ul * ny + vl); - yll = *(yg + ul * ny + vl); - xlr = *(xg + ul * ny + vr); - ylr = *(yg + ul * ny + vr); - - *tx = xll * (1 - dv) + xlr * (dv); - *ty = yll * (1 - dv) + ylr * (dv); - } - } - else if (x > xmax) { - - if (y < ymin) { - *tx = *(xg + (ny - 1) * nx); - *ty = *(yg + (ny - 1) * nx); - } - else if (y > ymax) { - *tx = *(xg + (ny - 1) + (nx - 1) * ny); - *ty = *(yg + (ny - 1) + (nx - 1) * ny); - } - else { - ul = nx - 1; - xll = *(xg + ul * ny + vl); - yll = *(yg + ul * ny + vl); - xlr = *(xg + ul * ny + vr); - ylr = *(yg + ul * ny + vr); - - *tx = xll * (1 - dv) + xlr * (dv); - *ty = yll * (1 - dv) + ylr * (dv); - } - } - else { - if (y < ymin) { - vl = 0; - xll = *(xg + ul * ny + vl); - xrl = *(xg + ur * ny + vl); - yll = *(yg + ul * ny + vl); - yrl = *(yg + ur * ny + vl); - - *tx = xll * (1 - du) + xrl * (du); - *ty = yll * (1 - du) + yrl * (du); - } - else if (y > ymax) { - vr = ny - 1; - xlr = *(xg + ul * ny + vr); - xrr = *(xg + ur * ny + vr); - ylr = *(yg + ul * ny + vr); - yrr = *(yg + ur * ny + vr); - - *tx = xlr * (1 - du) + xrr * (du); - *ty = ylr * (1 - du) + yrr * (du); - } - } - } - -/* Normal case. - * Look up coordinates in row-dominant array. - * Have to handle right boundary specially -- if at the edge, we'd better - * not reference the out of bounds point. - */ - - else { - - xll = *(xg + ul * ny + vl); - yll = *(yg + ul * ny + vl); - - /* ur is out of bounds */ - - if (ur == nx && vr < ny) { - - xlr = *(xg + ul * ny + vr); - ylr = *(yg + ul * ny + vr); - - *tx = xll * (1 - dv) + xlr * (dv); - *ty = yll * (1 - dv) + ylr * (dv); - } - - /* vr is out of bounds */ - - else if (ur < nx && vr == ny) { - - xrl = *(xg + ur * ny + vl); - yrl = *(yg + ur * ny + vl); - - *tx = xll * (1 - du) + xrl * (du); - *ty = yll * (1 - du) + yrl * (du); - } - - /* both ur and vr are out of bounds */ - - else if (ur == nx && vr == ny) { - - *tx = xll; - *ty = yll; - } - - /* everything in bounds */ - - else { - - xrl = *(xg + ur * ny + vl); - xlr = *(xg + ul * ny + vr); - xrr = *(xg + ur * ny + vr); - - yrl = *(yg + ur * ny + vl); - ylr = *(yg + ul * ny + vr); - yrr = *(yg + ur * ny + vr); - - *tx = xll * (1 - du) * (1 - dv) + xlr * (1 - du) * (dv) + - xrl * (du) * (1 - dv) + xrr * (du) * (dv); - - *ty = yll * (1 - du) * (1 - dv) + ylr * (1 - du) * (dv) + - yrl * (du) * (1 - dv) + yrr * (du) * (dv); - } - } -} diff --git a/src/plot/plplot/plcore.c b/src/plot/plplot/plcore.c deleted file mode 100644 index b42e9d7bed..0000000000 --- a/src/plot/plplot/plcore.c +++ /dev/null @@ -1,2833 +0,0 @@ -/* $Id: plcore.c,v 1.2 2005/03/17 21:39:21 eli Exp $ - - Central dispatch facility for PLplot. - Also contains the PLplot main data structures, external access - routines, and initialization calls. - - This stuff used to be in "dispatch.h", "dispatch.c", and "base.c". -*/ - -#define DEBUG - -#define NEED_PLDEBUG -#include "plcore.h" - -#ifdef ENABLE_DYNDRIVERS -#include -#endif - -/*--------------------------------------------------------------------------*\ - * Driver Interface - * - * These routines are the low-level interface to the driver -- all calls to - * driver functions must pass through here. For implementing driver- - * specific functions, the escape function is provided. The command stream - * gets duplicated to the plot buffer here. - * - * All functions that result in graphics actually being plotted (rather than - * just a change of state) are filtered as necessary before being passed on. - * The default settings do not require any filtering, i.e. PLplot physical - * coordinates are the same as the device physical coordinates (currently - * this can't be changed anyway), and a global view equal to the entire page - * is used. - * - * The reason one wants to put view-specific filtering here is that if - * enabled, the plot buffer should receive the unfiltered data stream. This - * allows a specific view to be used from an interactive device (e.g. TCL/TK - * driver) but be restored to the full view at any time merely by - * reprocessing the contents of the plot buffer. - * - * The metafile, on the other hand, *should* be affected by changes in the - * view, since this is a crucial editing capability. It is recommended that - * the initial metafile be created without a restricted global view, and - * modification of the view done on a per-plot basis as desired during - * subsequent processing. - * -\*--------------------------------------------------------------------------*/ - -enum {AT_BOP, DRAWING, AT_EOP}; - -/* Initialize device. */ -/* The plot buffer must be called last */ - -void -plP_init(void) -{ - plsc->page_status = AT_EOP; - - (*plsc->dispatch_table->pl_init) ((struct PLStream_struct *) plsc); - - if (plsc->plbuf_write) - plbuf_init(plsc); -} - -/* End of page */ -/* The plot buffer must be called first */ -/* Ignore instruction if there's nothing drawn */ - -void -plP_eop(void) -{ - int skip_driver_eop = 0; - - if (plsc->page_status != DRAWING) - return; - - plsc->page_status = AT_EOP; - - if (plsc->plbuf_write) - plbuf_eop(plsc); - -/* Call user eop handler if present. */ - - if (plsc->eop_handler != NULL) - (*plsc->eop_handler) (plsc->eop_data, &skip_driver_eop); - - if (!skip_driver_eop) - (*plsc->dispatch_table->pl_eop) ((struct PLStream_struct *) plsc); -} - -/* Set up new page. */ -/* The plot buffer must be called last */ -/* Ignore if the bop was already issued. */ -/* It's not actually necessary to be AT_EOP here, so don't check for it. */ - -void -plP_bop(void) -{ - int skip_driver_bop = 0; - - plP_subpInit(); - if (plsc->page_status == AT_BOP) - return; - - plsc->page_status = AT_BOP; - plsc->nplwin = 0; - -/* Call user bop handler if present. */ - - if (plsc->bop_handler != NULL) - (*plsc->bop_handler) (plsc->bop_data, &skip_driver_bop); - - if (!skip_driver_bop) - (*plsc->dispatch_table->pl_bop) ((struct PLStream_struct *) plsc); - - if (plsc->plbuf_write) - plbuf_bop(plsc); -} - -/* Tidy up device (flush buffers, close file, etc). */ - -void -plP_tidy(void) -{ - if (plsc->tidy) { - (*plsc->tidy) (plsc->tidy_data); - plsc->tidy = NULL; - plsc->tidy_data = NULL; - } - - (*plsc->dispatch_table->pl_tidy) ((struct PLStream_struct *) plsc); - - if (plsc->plbuf_write) - plbuf_tidy(plsc); - - plsc->OutFile = NULL; - free_mem(plsc->FileName); -} - -/* Change state. */ - -void -plP_state(PLINT op) -{ - (*plsc->dispatch_table->pl_state) ((struct PLStream_struct *) plsc, op); - - if (plsc->plbuf_write) - plbuf_state(plsc, op); -} - -/* Escape function, for driver-specific commands. */ - -void -plP_esc(PLINT op, void *ptr) -{ - (*plsc->dispatch_table->pl_esc) ((struct PLStream_struct *) plsc, op, ptr); - - if (plsc->plbuf_write) - plbuf_esc(plsc, op, ptr); -} - -/* Set up plot window parameters. */ -/* The plot buffer must be called first */ -/* Some drivers (metafile, Tk) need access to this data */ - -void -plP_swin(PLWindow *plwin) -{ - PLWindow *w; - PLINT clpxmi, clpxma, clpymi, clpyma; - -/* Provide plot buffer with unfiltered window data */ - - if (plsc->plbuf_write) - plbuf_esc(plsc, PLESC_SWIN, (void *) plwin); - - w = &plsc->plwin[plsc->nplwin++ % PL_MAXWINDOWS]; - - w->dxmi = plwin->dxmi; - w->dxma = plwin->dxma; - w->dymi = plwin->dymi; - w->dyma = plwin->dyma; - - if (plsc->difilt) { - xscl[0] = plP_dcpcx(w->dxmi); - xscl[1] = plP_dcpcx(w->dxma); - yscl[0] = plP_dcpcy(w->dymi); - yscl[1] = plP_dcpcy(w->dyma); - - difilt(xscl, yscl, 2, &clpxmi, &clpxma, &clpymi, &clpyma); - - w->dxmi = plP_pcdcx(xscl[0]); - w->dxma = plP_pcdcx(xscl[1]); - w->dymi = plP_pcdcy(yscl[0]); - w->dyma = plP_pcdcy(yscl[1]); - } - - w->wxmi = plwin->wxmi; - w->wxma = plwin->wxma; - w->wymi = plwin->wymi; - w->wyma = plwin->wyma; - -/* If the driver wants to process swin commands, call it now */ -/* It must use the filtered data, which it can get from *plsc */ - - if (plsc->dev_swin) { - (*plsc->dispatch_table->pl_esc) ( (struct PLStream_struct *) plsc, - PLESC_SWIN, NULL ); - } -} - -/*--------------------------------------------------------------------------*\ - * Drawing commands. -\*--------------------------------------------------------------------------*/ - -/* Draw line between two points */ -/* The plot buffer must be called first so it gets the unfiltered data */ - -void -plP_line(short *x, short *y) -{ - PLINT i, npts = 2, clpxmi, clpxma, clpymi, clpyma; - - plsc->page_status = DRAWING; - - if (plsc->plbuf_write) - plbuf_line(plsc, x[0], y[0], x[1], y[1]); - - if (plsc->difilt) { - for (i = 0; i < npts; i++) { - xscl[i] = x[i]; - yscl[i] = y[i]; - } - difilt(xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma); - plP_pllclp(xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma, grline); - } - else { - grline(x, y, npts); - } -} - -/* Draw polyline */ -/* The plot buffer must be called first */ - -void -plP_polyline(short *x, short *y, PLINT npts) -{ - PLINT i, clpxmi, clpxma, clpymi, clpyma; - - plsc->page_status = DRAWING; - - if (plsc->plbuf_write) - plbuf_polyline(plsc, x, y, npts); - - if (plsc->difilt) { - for (i = 0; i < npts; i++) { - xscl[i] = x[i]; - yscl[i] = y[i]; - } - difilt(xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma); - plP_pllclp(xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma, - grpolyline); - } - else { - grpolyline(x, y, npts); - } -} - -/* Fill polygon */ -/* The plot buffer must be called first */ -/* Here if the desired area fill capability isn't present, we mock up */ -/* something in software */ - -static int foo; - -void -plP_fill(short *x, short *y, PLINT npts) -{ - PLINT i, clpxmi, clpxma, clpymi, clpyma; - - plsc->page_status = DRAWING; - - if (plsc->plbuf_write) { - plsc->dev_npts = npts; - plsc->dev_x = x; - plsc->dev_y = y; - plbuf_esc(plsc, PLESC_FILL, NULL); - } - -/* Account for driver ability to do fills */ - - if (plsc->patt == 0 && ! plsc->dev_fill0) { - if ( ! foo) { - plwarn("Driver does not support hardware solid fills, switching to software fill.\n"); - foo = 1; - } - plsc->patt = 8; - plpsty(plsc->patt); - } - if (plsc->dev_fill1) { - plsc->patt = -ABS(plsc->patt); - } - -/* Perform fill. Here we MUST NOT allow the software fill to pass through the - driver interface filtering twice, else we get the infamous 2*rotation for - software fills on orientation swaps. -*/ - - if (plsc->patt > 0) - plfill_soft(x, y, npts); - - else { - if (plsc->difilt) { - for (i = 0; i < npts; i++) { - xscl[i] = x[i]; - yscl[i] = y[i]; - } - difilt(xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma); - plP_plfclp(xscl, yscl, npts, clpxmi, clpxma, clpymi, clpyma, - grfill); - } - else { - grfill(x, y, npts); - } - } -} - -/* Account for driver ability to draw text itself */ -/* -#define DEBUG_TEXT -*/ - -void -plP_text(PLINT base, PLFLT just, PLFLT *xform, PLINT x, PLINT y, - PLINT refx, PLINT refy, const char *string) -{ - if (plsc->dev_text) { - EscText args; - - args.base = base; - args.just = just; - args.xform = xform; - args.x = x; - args.y = y; - args.refx = refx; - args.refy = refy; - args.string = string; - - if (plsc->plbuf_write) - plbuf_esc(plsc, PLESC_HAS_TEXT, &args); - - plP_esc(PLESC_HAS_TEXT, &args); -#ifndef DEBUG_TEXT - } else { -#endif - plstr(base, xform, refx, refy, string); - } -} - -static void -grline(short *x, short *y, PLINT npts) -{ - (*plsc->dispatch_table->pl_line) ( (struct PLStream_struct *) plsc, - x[0], y[0], x[1], y[1] ); -} - -static void -grpolyline(short *x, short *y, PLINT npts) -{ - (*plsc->dispatch_table->pl_polyline) ( (struct PLStream_struct *) plsc, - x, y, npts ); -} - -static void -grfill(short *x, short *y, PLINT npts) -{ - plsc->dev_npts = npts; - plsc->dev_x = x; - plsc->dev_y = y; - - (*plsc->dispatch_table->pl_esc) ( (struct PLStream_struct *) plsc, - PLESC_FILL, NULL ); -} - -/*--------------------------------------------------------------------------*\ - * void difilt - * - * Driver interface filter -- passes all coordinates through a variety - * of filters. These include filters to change : - * - * - mapping of meta to physical coordinates - * - plot orientation - * - window into plot (zooms) - * - window into device (i.e set margins) - * - * The filters are applied in the order specified above. Because the - * orientation change comes first, subsequent window specifications affect - * the new coordinates (i.e. after a 90 degree flip, what was x is now y). - * This is the only way that makes sense from a graphical interface - * (e.g. TCL/TK driver). - * - * Where appropriate, the page clip limits are modified. -\*--------------------------------------------------------------------------*/ - -void -difilt(PLINT *xscl, PLINT *yscl, PLINT npts, - PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma) -{ - PLINT i, x, y; - -/* Map meta coordinates to physical coordinates */ - - if (plsc->difilt & PLDI_MAP) { - for (i = 0; i < npts; i++) { - xscl[i] = plsc->dimxax * xscl[i] + plsc->dimxb; - yscl[i] = plsc->dimyay * yscl[i] + plsc->dimyb; - } - } - -/* Change orientation */ - - if (plsc->difilt & PLDI_ORI) { - for (i = 0; i < npts; i++) { - x = plsc->dioxax * xscl[i] + plsc->dioxay * yscl[i] + plsc->dioxb; - y = plsc->dioyax * xscl[i] + plsc->dioyay * yscl[i] + plsc->dioyb; - xscl[i] = x; - yscl[i] = y; - } - } - -/* Change window into plot space */ - - if (plsc->difilt & PLDI_PLT) { - for (i = 0; i < npts; i++) { - xscl[i] = plsc->dipxax * xscl[i] + plsc->dipxb; - yscl[i] = plsc->dipyay * yscl[i] + plsc->dipyb; - } - } - -/* Change window into device space and set clip limits */ -/* (this is the only filter that modifies them) */ - - if (plsc->difilt & PLDI_DEV) { - for (i = 0; i < npts; i++) { - xscl[i] = plsc->didxax * xscl[i] + plsc->didxb; - yscl[i] = plsc->didyay * yscl[i] + plsc->didyb; - } - *clpxmi = plsc->diclpxmi; - *clpxma = plsc->diclpxma; - *clpymi = plsc->diclpymi; - *clpyma = plsc->diclpyma; - } - else { - *clpxmi = plsc->phyxmi; - *clpxma = plsc->phyxma; - *clpymi = plsc->phyymi; - *clpyma = plsc->phyyma; - } -} - -void -sdifilt(short *xscl, short *yscl, PLINT npts, - PLINT *clpxmi, PLINT *clpxma, PLINT *clpymi, PLINT *clpyma) -{ - int i; - short x, y; - -/* Map meta coordinates to physical coordinates */ - - if (plsc->difilt & PLDI_MAP) { - for (i = 0; i < npts; i++) { - xscl[i] = plsc->dimxax * xscl[i] + plsc->dimxb; - yscl[i] = plsc->dimyay * yscl[i] + plsc->dimyb; - } - } - -/* Change orientation */ - - if (plsc->difilt & PLDI_ORI) { - for (i = 0; i < npts; i++) { - x = plsc->dioxax * xscl[i] + plsc->dioxay * yscl[i] + plsc->dioxb; - y = plsc->dioyax * xscl[i] + plsc->dioyay * yscl[i] + plsc->dioyb; - xscl[i] = x; - yscl[i] = y; - } - } - -/* Change window into plot space */ - - if (plsc->difilt & PLDI_PLT) { - for (i = 0; i < npts; i++) { - xscl[i] = plsc->dipxax * xscl[i] + plsc->dipxb; - yscl[i] = plsc->dipyay * yscl[i] + plsc->dipyb; - } - } - -/* Change window into device space and set clip limits */ -/* (this is the only filter that modifies them) */ - - if (plsc->difilt & PLDI_DEV) { - for (i = 0; i < npts; i++) { - xscl[i] = plsc->didxax * xscl[i] + plsc->didxb; - yscl[i] = plsc->didyay * yscl[i] + plsc->didyb; - } - *clpxmi = plsc->diclpxmi; - *clpxma = plsc->diclpxma; - *clpymi = plsc->diclpymi; - *clpyma = plsc->diclpyma; - } - else { - *clpxmi = plsc->phyxmi; - *clpxma = plsc->phyxma; - *clpymi = plsc->phyymi; - *clpyma = plsc->phyyma; - } -} - -/*--------------------------------------------------------------------------*\ - * void pldi_ini - * - * Updates driver interface, making sure everything is in order. - * Even if filter is not being used, the defaults need to be set up. -\*--------------------------------------------------------------------------*/ - -static void -setdef_diplt() -{ - plsc->dipxmin = 0.0; - plsc->dipxmax = 1.0; - plsc->dipymin = 0.0; - plsc->dipymax = 1.0; -} - -static void -setdef_didev() -{ - plsc->mar = 0.0; - plsc->aspect = 0.0; - plsc->jx = 0.0; - plsc->jy = 0.0; -} - -static void -setdef_diori() -{ - plsc->diorot = 0.; -} - -static void -pldi_ini(void) -{ - if (plsc->level >= 1) { - if (plsc->difilt & PLDI_MAP) /* Coordinate mapping */ - calc_dimap(); - - if (plsc->difilt & PLDI_ORI) /* Orientation */ - calc_diori(); - else - setdef_diori(); - - if (plsc->difilt & PLDI_PLT) /* Plot window */ - calc_diplt(); - else - setdef_diplt(); - - if (plsc->difilt & PLDI_DEV) /* Device window */ - calc_didev(); - else - setdef_didev(); - } -} - -/*--------------------------------------------------------------------------*\ - * void pldid2pc - * - * Converts input values from relative device coordinates to relative plot - * coordinates. This function must be called when selecting a plot window - * from a display driver, since the coordinates chosen by the user are - * necessarily device-specific. -\*--------------------------------------------------------------------------*/ - -void -pldid2pc(PLFLT *xmin, PLFLT *ymin, PLFLT *xmax, PLFLT *ymax) -{ - PLFLT pxmin, pymin, pxmax, pymax; - PLFLT sxmin, symin, sxmax, symax; - PLFLT rxmin, rymin, rxmax, rymax; - - if (plsc->difilt & PLDI_DEV) { - - pldebug("pldid2pc", - "Relative device coordinates (in): %f, %f, %f, %f\n", - *xmin, *ymin, *xmax, *ymax); - - pxmin = plP_dcpcx(*xmin); - pymin = plP_dcpcy(*ymin); - pxmax = plP_dcpcx(*xmax); - pymax = plP_dcpcy(*ymax); - - sxmin = (pxmin - plsc->didxb) / plsc->didxax; - symin = (pymin - plsc->didyb) / plsc->didyay; - sxmax = (pxmax - plsc->didxb) / plsc->didxax; - symax = (pymax - plsc->didyb) / plsc->didyay; - - rxmin = plP_pcdcx(sxmin); - rymin = plP_pcdcy(symin); - rxmax = plP_pcdcx(sxmax); - rymax = plP_pcdcy(symax); - - *xmin = (rxmin < 0) ? 0 : rxmin; - *xmax = (rxmax > 1) ? 1 : rxmax; - *ymin = (rymin < 0) ? 0 : rymin; - *ymax = (rymax > 1) ? 1 : rymax; - - pldebug("pldid2pc", - "Relative plot coordinates (out): %f, %f, %f, %f\n", - rxmin, rymin, rxmax, rymax); - } -} - -/*--------------------------------------------------------------------------*\ - * void pldip2dc - * - * Converts input values from relative plot coordinates to relative - * device coordinates. -\*--------------------------------------------------------------------------*/ - -void -pldip2dc(PLFLT *xmin, PLFLT *ymin, PLFLT *xmax, PLFLT *ymax) -{ - PLFLT pxmin, pymin, pxmax, pymax; - PLFLT sxmin, symin, sxmax, symax; - PLFLT rxmin, rymin, rxmax, rymax; - - if (plsc->difilt & PLDI_DEV) { - - pldebug("pldip2pc", - "Relative plot coordinates (in): %f, %f, %f, %f\n", - *xmin, *ymin, *xmax, *ymax); - - pxmin = plP_dcpcx(*xmin); - pymin = plP_dcpcy(*ymin); - pxmax = plP_dcpcx(*xmax); - pymax = plP_dcpcy(*ymax); - - sxmin = pxmin * plsc->didxax + plsc->didxb; - symin = pymin * plsc->didyay + plsc->didyb; - sxmax = pxmax * plsc->didxax + plsc->didxb; - symax = pymax * plsc->didyay + plsc->didyb; - - rxmin = plP_pcdcx(sxmin); - rymin = plP_pcdcy(symin); - rxmax = plP_pcdcx(sxmax); - rymax = plP_pcdcy(symax); - - *xmin = (rxmin < 0) ? 0 : rxmin; - *xmax = (rxmax > 1) ? 1 : rxmax; - *ymin = (rymin < 0) ? 0 : rymin; - *ymax = (rymax > 1) ? 1 : rymax; - - pldebug("pldip2pc", - "Relative device coordinates (out): %f, %f, %f, %f\n", - rxmin, rymin, rxmax, rymax); - } -} - -/*--------------------------------------------------------------------------*\ - * void plsdiplt - * - * Set window into plot space -\*--------------------------------------------------------------------------*/ - -void -c_plsdiplt(PLFLT xmin, PLFLT ymin, PLFLT xmax, PLFLT ymax) -{ - plsc->dipxmin = (xmin < xmax) ? xmin : xmax; - plsc->dipxmax = (xmin < xmax) ? xmax : xmin; - plsc->dipymin = (ymin < ymax) ? ymin : ymax; - plsc->dipymax = (ymin < ymax) ? ymax : ymin; - - if (xmin == 0. && xmax == 1. && ymin == 0. && ymax == 1.) { - plsc->difilt &= ~PLDI_PLT; - return; - } - - plsc->difilt |= PLDI_PLT; - pldi_ini(); -} - -/*--------------------------------------------------------------------------*\ - * void plsdiplz - * - * Set window into plot space incrementally (zoom) -\*--------------------------------------------------------------------------*/ - -void -c_plsdiplz(PLFLT xmin, PLFLT ymin, PLFLT xmax, PLFLT ymax) -{ - if (plsc->difilt & PLDI_PLT) { - xmin = plsc->dipxmin + (plsc->dipxmax - plsc->dipxmin) * xmin; - ymin = plsc->dipymin + (plsc->dipymax - plsc->dipymin) * ymin; - xmax = plsc->dipxmin + (plsc->dipxmax - plsc->dipxmin) * xmax; - ymax = plsc->dipymin + (plsc->dipymax - plsc->dipymin) * ymax; - } - - plsdiplt(xmin, ymin, xmax, ymax); -} - -/*--------------------------------------------------------------------------*\ - * void calc_diplt - * - * Calculate transformation coefficients to set window into plot space. - * - * Note: if driver has requested to handle these commands itself, we must - * send the appropriate escape command. If the driver succeeds it will - * cancel the filter operation. The command is deferred until this point - * to ensure that the driver has been initialized. -\*--------------------------------------------------------------------------*/ - -static void -calc_diplt(void) -{ - PLINT pxmin, pxmax, pymin, pymax, pxlen, pylen; - - if (plsc->dev_di) { - (*plsc->dispatch_table->pl_esc) ( (struct PLStream_struct *) plsc, - PLESC_DI, NULL ); - } - - if ( ! (plsc->difilt & PLDI_PLT)) - return; - - pxmin = plP_dcpcx(plsc->dipxmin); - pxmax = plP_dcpcx(plsc->dipxmax); - pymin = plP_dcpcy(plsc->dipymin); - pymax = plP_dcpcy(plsc->dipymax); - - pxlen = pxmax - pxmin; - pylen = pymax - pymin; - pxlen = MAX(1, pxlen); - pylen = MAX(1, pylen); - - plsc->dipxax = plsc->phyxlen / (double) pxlen; - plsc->dipyay = plsc->phyylen / (double) pylen; - plsc->dipxb = plsc->phyxmi - plsc->dipxax * pxmin; - plsc->dipyb = plsc->phyymi - plsc->dipyay * pymin; -} - -/*--------------------------------------------------------------------------*\ - * void plgdiplt - * - * Retrieve current window into plot space -\*--------------------------------------------------------------------------*/ - -void -c_plgdiplt(PLFLT *p_xmin, PLFLT *p_ymin, PLFLT *p_xmax, PLFLT *p_ymax) -{ - *p_xmin = plsc->dipxmin; - *p_xmax = plsc->dipxmax; - *p_ymin = plsc->dipymin; - *p_ymax = plsc->dipymax; -} - -/*--------------------------------------------------------------------------*\ - * void plsdidev - * - * Set window into device space using margin, aspect ratio, and - * justification. If you want to just use the previous value for any of - * these, just pass in the magic value PL_NOTSET. - * - * It is unlikely that one should ever need to change the aspect ratio - * but it's in there for completeness. -\*--------------------------------------------------------------------------*/ - -void -c_plsdidev(PLFLT mar, PLFLT aspect, PLFLT jx, PLFLT jy) -{ - plsetvar(plsc->mar, mar); - plsetvar(plsc->aspect, aspect); - plsetvar(plsc->jx, jx); - plsetvar(plsc->jy, jy); - - if (mar == 0. && aspect == 0. && jx == 0. && jy == 0. && - ! (plsc->difilt & PLDI_ORI)) { - plsc->difilt &= ~PLDI_DEV; - return; - } - - plsc->difilt |= PLDI_DEV; - pldi_ini(); -} - -/*--------------------------------------------------------------------------*\ - * void calc_didev - * - * Calculate transformation coefficients to set window into device space. - * Calculates relative window bounds and calls plsdidxy to finish the job. -\*--------------------------------------------------------------------------*/ - -static void -calc_didev(void) -{ - PLFLT lx, ly, aspect, aspdev; - PLFLT xmin, xmax, xlen, ymin, ymax, ylen; - PLINT pxmin, pxmax, pymin, pymax, pxlen, pylen; - - if (plsc->dev_di) { - (*plsc->dispatch_table->pl_esc) ( (struct PLStream_struct *) plsc, - PLESC_DI, NULL ); - } - - if ( ! (plsc->difilt & PLDI_DEV)) - return; - -/* Calculate aspect ratio of physical device */ - - lx = plsc->phyxlen / plsc->xpmm; - ly = plsc->phyylen / plsc->ypmm; - aspdev = lx / ly; - - if (plsc->difilt & PLDI_ORI) - aspect = plsc->aspori; - else - aspect = plsc->aspect; - - if (aspect <= 0.) - aspect = plsc->aspdev; - -/* Failsafe */ - - plsc->mar = (plsc->mar > 0.5) ? 0.5 : plsc->mar; - plsc->mar = (plsc->mar < 0.0) ? 0.0 : plsc->mar; - plsc->jx = (plsc->jx > 0.5) ? 0.5 : plsc->jx; - plsc->jx = (plsc->jx < -0.5) ? -0.5 : plsc->jx; - plsc->jy = (plsc->jy > 0.5) ? 0.5 : plsc->jy; - plsc->jy = (plsc->jy < -0.5) ? -0.5 : plsc->jy; - -/* Relative device coordinates that neutralize aspect ratio difference */ - - xlen = (aspect < aspdev) ? (aspect / aspdev) : 1.0; - ylen = (aspect < aspdev) ? 1.0 : (aspdev / aspect); - - xlen *= (1.0 - 2.*plsc->mar); - ylen *= (1.0 - 2.*plsc->mar); - - xmin = (1. - xlen) * (0.5 + plsc->jx); - xmax = xmin + xlen; - - ymin = (1. - ylen) * (0.5 + plsc->jy); - ymax = ymin + ylen; - -/* Calculate transformation coefficients */ - - pxmin = plP_dcpcx(xmin); - pxmax = plP_dcpcx(xmax); - pymin = plP_dcpcy(ymin); - pymax = plP_dcpcy(ymax); - - pxlen = pxmax - pxmin; - pylen = pymax - pymin; - pxlen = MAX(1, pxlen); - pylen = MAX(1, pylen); - - plsc->didxax = pxlen / (double) plsc->phyxlen; - plsc->didyay = pylen / (double) plsc->phyylen; - plsc->didxb = pxmin - plsc->didxax * plsc->phyxmi; - plsc->didyb = pymin - plsc->didyay * plsc->phyymi; - -/* Set clip limits to conform to new page size */ - - plsc->diclpxmi = plsc->didxax * plsc->phyxmi + plsc->didxb; - plsc->diclpxma = plsc->didxax * plsc->phyxma + plsc->didxb; - plsc->diclpymi = plsc->didyay * plsc->phyymi + plsc->didyb; - plsc->diclpyma = plsc->didyay * plsc->phyyma + plsc->didyb; -} - -/*--------------------------------------------------------------------------*\ - * void plgdidev - * - * Retrieve current window into device space -\*--------------------------------------------------------------------------*/ - -void -c_plgdidev(PLFLT *p_mar, PLFLT *p_aspect, PLFLT *p_jx, PLFLT *p_jy) -{ - *p_mar = plsc->mar; - *p_aspect = plsc->aspect; - *p_jx = plsc->jx; - *p_jy = plsc->jy; -} - -/*--------------------------------------------------------------------------*\ - * void plsdiori - * - * Set plot orientation, specifying rotation in units of pi/2. -\*--------------------------------------------------------------------------*/ - -void -c_plsdiori(PLFLT rot) -{ - plsc->diorot = rot; - if (rot == 0.) { - plsc->difilt &= ~PLDI_ORI; - pldi_ini(); - return; - } - - plsc->difilt |= PLDI_ORI; - pldi_ini(); -} - -/*--------------------------------------------------------------------------*\ - * void calc_diori - * - * Calculate transformation coefficients to arbitrarily orient plot. - * Preserve aspect ratios so the output doesn't suck. -\*--------------------------------------------------------------------------*/ - -static void -calc_diori(void) -{ - PLFLT r11, r21, r12, r22, cost, sint; - PLFLT x0, y0, lx, ly, aspect; - - if (plsc->dev_di) { - (*plsc->dispatch_table->pl_esc) ( (struct PLStream_struct *) plsc, - PLESC_DI, NULL ); - } - - if ( ! (plsc->difilt & PLDI_ORI)) - return; - -/* Center point of rotation */ - - x0 = (plsc->phyxma + plsc->phyxmi) / 2.; - y0 = (plsc->phyyma + plsc->phyymi) / 2.; - -/* Rotation matrix */ - - r11 = cos(plsc->diorot * PI / 2.); - r21 = sin(plsc->diorot * PI / 2.); - r12 = -r21; - r22 = r11; - - cost = ABS(r11); - sint = ABS(r21); - -/* Flip aspect ratio as necessary. Grungy but I don't see a better way */ - - aspect = plsc->aspect; - if (aspect == 0.) - aspect = plsc->aspdev; - - if (plsc->freeaspect) - plsc->aspori = aspect; - else - plsc->aspori = (aspect * cost + sint) / (aspect * sint + cost); - - if ( ! (plsc->difilt & PLDI_DEV)) { - plsc->difilt |= PLDI_DEV; - setdef_didev(); - } - calc_didev(); - -/* Compute scale factors */ - - lx = plsc->phyxlen; - ly = plsc->phyylen; - -/* Transformation coefficients */ - - plsc->dioxax = r11; - plsc->dioxay = r21 * (lx / ly); - plsc->dioxb = (1. - r11) * x0 - r21 * y0 * (lx / ly); - - plsc->dioyax = r12 * (ly / lx); - plsc->dioyay = r22; - plsc->dioyb = (1. - r22) * y0 - r12 * x0 * (ly / lx); -} - -/*--------------------------------------------------------------------------*\ - * void plgdiori - * - * Get plot orientation -\*--------------------------------------------------------------------------*/ - -void -c_plgdiori(PLFLT *p_rot) -{ - *p_rot = plsc->diorot; -} - -/*--------------------------------------------------------------------------*\ - * void plsdimap - * - * Set up transformation from metafile coordinates. The size of the plot is - * scaled so as to preserve aspect ratio. This isn't intended to be a - * general-purpose facility just yet (not sure why the user would need it, - * for one). -\*--------------------------------------------------------------------------*/ - -void -c_plsdimap(PLINT dimxmin, PLINT dimxmax, PLINT dimymin, PLINT dimymax, - PLFLT dimxpmm, PLFLT dimypmm) -{ - plsetvar(plsc->dimxmin, dimxmin); - plsetvar(plsc->dimxmax, dimxmax); - plsetvar(plsc->dimymin, dimymin); - plsetvar(plsc->dimymax, dimymax); - plsetvar(plsc->dimxpmm, dimxpmm); - plsetvar(plsc->dimypmm, dimypmm); - - plsc->difilt |= PLDI_MAP; - pldi_ini(); -} - -/*--------------------------------------------------------------------------*\ - * void calc_dimap - * - * Set up transformation from metafile coordinates. The size of the plot is - * scaled so as to preserve aspect ratio. This isn't intended to be a - * general-purpose facility just yet (not sure why the user would need it, - * for one). -\*--------------------------------------------------------------------------*/ - -static void -calc_dimap() -{ - PLFLT lx, ly; - PLINT pxmin, pxmax, pymin, pymax; - PLFLT dimxlen, dimylen, pxlen, pylen; - - if ((plsc->dimxmin == plsc->phyxmi) && (plsc->dimxmax == plsc->phyxma) && - (plsc->dimymin == plsc->phyymi) && (plsc->dimymax == plsc->phyyma) && - (plsc->dimxpmm == plsc->xpmm) && (plsc->dimypmm == plsc->ypmm)) { - plsc->difilt &= ~PLDI_MAP; - return; - } - -/* Set default aspect ratio */ - - lx = (plsc->dimxmax - plsc->dimxmin + 1) / plsc->dimxpmm; - ly = (plsc->dimymax - plsc->dimymin + 1) / plsc->dimypmm; - - plsc->aspdev = lx / ly; - -/* Build transformation to correct physical coordinates */ - - dimxlen = plsc->dimxmax - plsc->dimxmin; - dimylen = plsc->dimymax - plsc->dimymin; - - pxmin = plsc->phyxmi; - pxmax = plsc->phyxma; - pymin = plsc->phyymi; - pymax = plsc->phyyma; - pxlen = pxmax - pxmin; - pylen = pymax - pymin; - - plsc->dimxax = pxlen / dimxlen; - plsc->dimyay = pylen / dimylen; - plsc->dimxb = pxmin - pxlen * plsc->dimxmin / dimxlen; - plsc->dimyb = pymin - pylen * plsc->dimymin / dimylen; -} - -/*--------------------------------------------------------------------------*\ - * void plflush() - * - * Flushes the output stream. Use sparingly, if at all. -\*--------------------------------------------------------------------------*/ - -void -c_plflush(void) -{ - if (plsc->dev_flush) { - (*plsc->dispatch_table->pl_esc) ( (struct PLStream_struct *) plsc, - PLESC_FLUSH, NULL ); - } - else { - if (plsc->OutFile != NULL) - fflush(plsc->OutFile); - } -} - -/*--------------------------------------------------------------------------*\ - * Startup routines. -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * void pllib_init() - * - * Initialize library. Called internally by every startup routine. - * Everything you want to always be initialized before plinit() is called - * you should put here. E.g. dispatch table setup, rcfile read, etc. -\*--------------------------------------------------------------------------*/ - -void -pllib_init() -{ - if (lib_initialized) return; - lib_initialized = 1; - -#ifdef ENABLE_DYNDRIVERS -/* Create libltdl resources */ - lt_dlinit(); -#endif - -/* Initialize the dispatch table with the info from the static drivers table - and the available dynamic drivers. */ - - plInitDispatchTable(); -} - -/*--------------------------------------------------------------------------*\ - * void plstar(nx, ny) - * - * Initialize PLplot, passing in the windows/page settings. -\*--------------------------------------------------------------------------*/ - -void -c_plstar(PLINT nx, PLINT ny) -{ - pllib_init(); - - if (plsc->level != 0) - plend1(); - - plssub(nx, ny); - - c_plinit(); -} - -/*--------------------------------------------------------------------------*\ - * void plstart(devname, nx, ny) - * - * Initialize PLplot, passing the device name and windows/page settings. -\*--------------------------------------------------------------------------*/ - -void -c_plstart(const char *devname, PLINT nx, PLINT ny) -{ - pllib_init(); - - if (plsc->level != 0) - plend1(); - - plssub(nx, ny); - plsdev(devname); - - c_plinit(); -} - -/*--------------------------------------------------------------------------*\ - * void plinit() - * - * Initializes PLplot, using preset or default options. -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void * -c_plinit(void) -{ - PLFLT lx, ly, xpmm_loc, ypmm_loc, aspect_old, aspect_new; - PLINT mk = 0, sp = 0, inc = 0, del = 2000; - - pllib_init(); - - if (plsc->level != 0) - plend1(); - -/* Set stream number */ - - plsc->ipls = ipls; - -/* Set up devices */ - - pllib_devinit(); - -/* Auxiliary stream setup */ - - plstrm_init(); - -/* Initialize device & first page */ - - plP_init(); - plP_bop(); - plsc->level = 1; - -/* Calculate factor such that the character aspect ratio is preserved - * when the overall aspect ratio is changed, i.e., if portrait mode is - * requested (only honored for subset of drivers) or if the aspect ratio - * is specified in any way, or if a 90 deg rotation occurs with - * -freeaspect. */ - -/* Case where plsc->aspect has a value.... (e.g., -a aspect on the - * command line or 2nd parameter of plsdidev specified) */ - if (plsc->aspect > 0.) { - lx = plsc->phyxlen / plsc->xpmm; - ly = plsc->phyylen / plsc->ypmm; - aspect_old = lx / ly; - aspect_new = plsc->aspect; - plsc->caspfactor = sqrt(aspect_old/aspect_new); - } -/* Case of 90 deg rotations with -freeaspect (this is also how portraite - * mode is implemented for the drivers that honor -portrait). */ - else if (plsc->freeaspect && ABS(cos(plsc->diorot * PI / 2.)) <= 1.e-5) { - lx = plsc->phyxlen / plsc->xpmm; - ly = plsc->phyylen / plsc->ypmm; - aspect_old = lx / ly; - aspect_new = ly / lx; - plsc->caspfactor = sqrt(aspect_old/aspect_new); - } - - else - plsc->caspfactor = 1.; - -/* Load fonts */ - - plsc->cfont = 1; - plfntld(initfont); - -/* Set up subpages */ - - plP_subpInit(); - -/* Set up number of allowed digits before switching to scientific notation */ -/* The user can always change this */ - - if (plsc->xdigmax == 0) - plsc->xdigmax = 4; - - if (plsc->ydigmax == 0) - plsc->ydigmax = 4; - - if (plsc->zdigmax == 0) - plsc->zdigmax = 3; - -/* Switch to graphics mode and set color */ - - plgra(); - plcol(1); - - plstyl(0, &mk, &sp); - plpat(1, &inc, &del); - -/* Set clip limits. */ - - plsc->clpxmi = plsc->phyxmi; - plsc->clpxma = plsc->phyxma; - plsc->clpymi = plsc->phyymi; - plsc->clpyma = plsc->phyyma; - -/* Page aspect ratio. */ - - lx = plsc->phyxlen / plsc->xpmm; - ly = plsc->phyylen / plsc->ypmm; - plsc->aspdev = lx / ly; - -/* Initialize driver interface */ - - pldi_ini(); - -/* Apply compensating factor to original xpmm and ypmm so that - * character aspect ratio is preserved when overall aspect ratio - * is changed. This must appear here in the code because previous - * code in this routine and in routines that it calls must use the original - * values of xpmm and ypmm before the compensating factor is applied. */ - - plP_gpixmm(&xpmm_loc, &ypmm_loc); - plP_setpxl(xpmm_loc*plsc->caspfactor, ypmm_loc/plsc->caspfactor); - - return plsc->dev; -} - -/*--------------------------------------------------------------------------*\ - * void plend() - * - * End a plotting session for all open streams. -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plend(void) -{ - PLINT i; - - for (i = PL_NSTREAMS-1; i >= 0; i--) { - if (pls[i] != NULL) { - plsstrm(i); - c_plend1(); - } - } - plfontrel(); -#ifdef ENABLE_DYNDRIVERS -/* Release the libltdl resources */ - lt_dlexit(); -#endif -} - -/*--------------------------------------------------------------------------*\ - * void plend1() - * - * End a plotting session for the current stream only. After the stream is - * ended the memory associated with the stream's PLStream data structure is - * freed (for stream > 0), and the stream counter is set to 0 (the default). -\*--------------------------------------------------------------------------*/ - -void -c_plend1(void) -{ - if (plsc->level > 0) { - plP_eop(); - plP_tidy(); - plsc->level = 0; - } - -/* Free all malloc'ed stream memory */ - - free_mem(plsc->cmap0); - free_mem(plsc->cmap1); - free_mem(plsc->plwindow); - free_mem(plsc->geometry); - free_mem(plsc->dev); - free_mem(plsc->BaseName); - -/* Free malloc'ed stream if not in initial stream, else clear it out */ - - if (ipls > 0) { - free_mem(plsc); - pls[ipls] = NULL; - plsstrm(0); - } - else { - memset((char *) pls[ipls], 0, sizeof(PLStream)); - } -} - -/*--------------------------------------------------------------------------*\ - * void plsstrm - * - * Set stream number. If the data structure for a new stream is - * unallocated, we allocate it here. -\*--------------------------------------------------------------------------*/ - -void -c_plsstrm(PLINT strm) -{ - if (strm < 0 || strm >= PL_NSTREAMS) { - fprintf(stderr, - "plsstrm: Illegal stream number %d, must be in [0, %d]\n", - (int) strm, PL_NSTREAMS); - } - else { - ipls = strm; - if (pls[ipls] == NULL) { - pls[ipls] = (PLStream *) malloc((size_t) sizeof(PLStream)); - if (pls[ipls] == NULL) - plexit("plsstrm: Out of memory."); - - memset((char *) pls[ipls], 0, sizeof(PLStream)); - } - plsc = pls[ipls]; - plsc->ipls = ipls; - } -} - -/*--------------------------------------------------------------------------*\ - * void plgstrm - * - * Get current stream number. -\*--------------------------------------------------------------------------*/ - -void -c_plgstrm(PLINT *p_strm) -{ - *p_strm = ipls; -} - -/*--------------------------------------------------------------------------*\ - * void plmkstrm - * - * Creates a new stream and makes it the default. Differs from using - * plsstrm(), in that a free stream number is found, and returned. - * - * Unfortunately, I /have/ to start at stream 1 and work upward, since - * stream 0 is preallocated. One of the BIG flaws in the PLplot API is - * that no initial, library-opening call is required. So stream 0 must be - * preallocated, and there is no simple way of determining whether it is - * already in use or not. -\*--------------------------------------------------------------------------*/ - -void -c_plmkstrm(PLINT *p_strm) -{ - int i; - - for (i = 1; i < PL_NSTREAMS; i++) { - if (pls[i] == NULL) - break; - } - - if (i == PL_NSTREAMS) { - fprintf(stderr, "plmkstrm: Cannot create new stream\n"); - *p_strm = -1; - } - else { - *p_strm = i; - plsstrm(i); - } - plstrm_init(); -} - -/*--------------------------------------------------------------------------*\ - * void plstrm_init - * - * Does required startup initialization of a stream. Should be called right - * after creating one (for allocating extra memory, etc). Users shouldn't - * need to call this directly. - * - * This function can be called multiple times for a given stream, in which - * case only the first call produces any effect. For streams >= 1, which - * are created dynamically, this is called by the routine that allocates - * the stream. Stream 0, which is preallocated, is much harder to deal with - * because any of a number of different calls may be the first call to the - * library. This is handled by just calling plstrm_init() from every - * function that might be called first. Sucks, but it should work. -\*--------------------------------------------------------------------------*/ - -void -plstrm_init(void) -{ - if ( ! plsc->initialized) { - plsc->initialized = 1; - - if (plsc->cmap0 == NULL) - plscmap0n(0); - - if (plsc->cmap1 == NULL) - plscmap1n(0); - } -} - -/*--------------------------------------------------------------------------*\ - * pl_cpcolor - * - * Utility to copy one PLColor to another. -\*--------------------------------------------------------------------------*/ - -void -pl_cpcolor(PLColor *to, PLColor *from) -{ - to->r = from->r; - to->g = from->g; - to->b = from->b; -} - -/*--------------------------------------------------------------------------*\ - * void plcpstrm - * - * Copies state parameters from the reference stream to the current stream. - * Tell driver interface to map device coordinates unless flags == 1. - * - * This function is used for making save files of selected plots (e.g. - * from the TK driver). After initializing, you can get a copy of the - * current plot to the specified device by switching to this stream and - * issuing a plcpstrm() and a plreplot(), with calls to plbop() and - * pleop() as appropriate. The plot buffer must have previously been - * enabled (done automatically by some display drivers, such as X). -\*--------------------------------------------------------------------------*/ - -void -c_plcpstrm(PLINT iplsr, PLINT flags) -{ - int i; - PLStream *plsr; - - plsr = pls[iplsr]; - if (plsr == NULL) { - fprintf(stderr, "plcpstrm: stream %d not in use\n", (int) iplsr); - return; - } - -/* May be debugging */ - - plsc->debug = plsr->debug; - -/* Plot buffer -- need to copy file pointer so that plreplot() works */ -/* This also prevents inadvertent writes into the plot buffer */ - - plsc->plbufFile = plsr->plbufFile; - -/* Driver interface */ -/* Transformation must be recalculated in current driver coordinates */ - - if (plsr->difilt & PLDI_PLT) - plsdiplt(plsr->dipxmin, plsr->dipymin, plsr->dipxmax, plsr->dipymax); - - if (plsr->difilt & PLDI_DEV) - plsdidev(plsr->mar, plsr->aspect, plsr->jx, plsr->jy); - - if (plsr->difilt & PLDI_ORI) - plsdiori(plsr->diorot); - -/* Map device coordinates */ - - if ( ! (flags & 0x01)) { - pldebug("plcpstrm", "mapping parameters: %d %d %d %d %f %f\n", - plsr->phyxmi, plsr->phyxma, plsr->phyymi, plsr->phyyma, - plsr->xpmm, plsr->ypmm); - plsdimap(plsr->phyxmi, plsr->phyxma, plsr->phyymi, plsr->phyyma, - plsr->xpmm, plsr->ypmm); - } - -/* current color */ - - pl_cpcolor(&plsc->curcolor, &plsr->curcolor); - -/* cmap 0 */ - - plsc->icol0 = plsr->icol0; - plsc->ncol0 = plsr->ncol0; - if (plsc->cmap0 != NULL) - free((void *) plsc->cmap0); - - plsc->cmap0 = (PLColor *) calloc(1, plsc->ncol0 * sizeof(PLColor)); - for (i = 0; i < plsc->ncol0; i++) - pl_cpcolor(&plsc->cmap0[i], &plsr->cmap0[i]); - -/* cmap 1 */ - - plsc->icol1 = plsr->icol1; - plsc->ncol1 = plsr->ncol1; - if (plsc->cmap1 != NULL) - free((void *) plsc->cmap1); - - plsc->cmap1 = (PLColor *) calloc(1, plsc->ncol1 * sizeof(PLColor)); - for (i = 0; i < plsc->ncol1; i++) - pl_cpcolor(&plsc->cmap1[i], &plsr->cmap1[i]); - -/* Initialize if it hasn't been done yet. */ - - if (plsc->level == 0) - plinit(); -} - -/*--------------------------------------------------------------------------*\ - * pllib_devinit() - * - * Does preliminary setup of device driver. - * - * This function (previously plGetDev) used to be what is now shown as - * plSelectDev below. However, the situation is a bit more complicated now in - * the dynloadable drivers era. We now have to: - * - * 1) Make sure the dispatch table is initialized to the union of static - * drivers and available dynamic drivers (done from pllib_init now). - * 2) Allow the user to select the desired device. - * 3) Initialize the dispatch table entries for the selected device, in the - * case that it is a dynloadable driver that has not yet been loaded. - * - * Also made non-static, in order to allow some device calls to be made prior - * to calling plinit(). E.g. plframe needs to tell the X driver to create its - * internal data structure during widget construction time (using the escape - * function), but doesn't call plinit() until the plframe is actually mapped. -\*--------------------------------------------------------------------------*/ - -void -pllib_devinit() -{ - if (plsc->dev_initialized) return; - plsc->dev_initialized = 1; - - plSelectDev(); - - plLoadDriver(); - -/* offset by one since table is zero-based, but input list is not */ - plsc->dispatch_table = dispatch_table[plsc->device - 1]; -} - -#ifdef ENABLE_DYNDRIVERS - -static char* -plGetDrvDir () -{ - char* drvdir; - -/* Get drivers directory in PLPLOT_DRV_DIR or DATA_DIR/DRV_DIR, - * on this order - */ - - pldebug("plGetDrvDir", "Trying to read env var PLPLOT_DRV_DIR\n"); - drvdir = getenv ("PLPLOT_DRV_DIR"); - - if (drvdir == NULL) { - pldebug("plGetDrvDir", - "Will use drivers dir: " DATA_DIR "/" DRV_DIR "\n"); - drvdir = DATA_DIR "/" DRV_DIR; - } - - return drvdir; -} - -#endif - - -/*--------------------------------------------------------------------------*\ - * void plInitDispatchTable() - * - * ... -\*--------------------------------------------------------------------------*/ - -static int plDispatchSequencer( const void *p1, const void *p2 ) -{ - const PLDispatchTable* t1 = *(PLDispatchTable **) p1; - const PLDispatchTable* t2 = *(PLDispatchTable **) p2; - -/* printf( "sorting: t1.name=%s t1.seq=%d t2.name=%s t2.seq=%d\n", */ -/* t1->pl_DevName, t1->pl_seq, t2->pl_DevName, t2->pl_seq ); */ - - return t1->pl_seq - t2->pl_seq; -} - -static void -plInitDispatchTable() -{ - int n; - -#ifdef ENABLE_DYNDRIVERS - char buf[300]; - char* drvdir; - char *devnam, *devdesc, *devtype, *driver, *tag, *seqstr; - int seq; - int i, j, driver_found, done=0; - FILE *fp_drvdb = NULL; - DIR* dp_drvdir = NULL; - struct dirent* entry; - lt_dlhandle dlhand; - -/* Open a temporary file in which all the plD_DEVICE_INFO_ strings - will be stored */ - fp_drvdb = tmpfile (); - -/* Open the drivers directory */ - drvdir = plGetDrvDir (); - dp_drvdir = opendir (drvdir); - if (dp_drvdir == NULL) - plabort ("plInitDispatchTable: Could not open drivers directory"); - -/* Loop over each entry in the drivers directory */ - - pldebug ("plInitDispatchTable", "Scanning dyndrivers dir\n"); - while ((entry = readdir (dp_drvdir)) != NULL) - { - char* name = entry->d_name; - int len = strlen (name) - 3; - - pldebug ("plInitDispatchTable", - "Consider file %s\n", name); - -/* Only consider entries that have the ".rc" suffix */ - if ((len > 0) && (strcmp (name + len, ".rc") == 0)) { - char path[300]; - char buf[300]; - FILE* fd; - -/* Open the driver's info file */ - sprintf (path, "%s/%s", drvdir, name); - fd = fopen (path, "r"); - if (fd == NULL) { - sprintf (buf, - "plInitDispatchTable: Could not open driver info file %s\n", - name); - plabort (buf); - } - -/* Each line in the .rc file corresponds to a specific device. - * Write it to the drivers db file and take care of leading newline - * character */ - - pldebug ("plInitDispatchTable", - "Opened driver info file %s\n", name); - while (fgets (buf, 300, fd) != NULL) - { - fprintf (fp_drvdb, "%s", buf); - if ( buf [strlen (buf) - 1] != '\n' ) - fprintf (fp_drvdb, "\n"); - npldynamicdevices++; - } - fclose (fd); - } - } - -/* Make sure that the temporary file containing the driversr database - * is ready to read and close the directory handle */ - fflush (fp_drvdb); - closedir (dp_drvdir); - -#endif - -/* Allocate space for the dispatch table. */ - dispatch_table = (PLDispatchTable **) - malloc( (nplstaticdevices + npldynamicdevices) * sizeof(PLDispatchTable *) ); - -/* Initialize the dispatch table entries for the static devices by calling - the dispatch table initialization function for each static device. This - is the same function that would be called at load time for dynamic - drivers. */ - - for( n=0; n < nplstaticdevices; n++ ) - { - dispatch_table[n] = (PLDispatchTable *)malloc( sizeof(PLDispatchTable) ); - - (*static_device_initializers[n])( dispatch_table[n] ); - } - npldrivers = nplstaticdevices; - -#ifdef ENABLE_DYNDRIVERS - -/* Allocate space for the device and driver specs. We may not use all of - * these driver descriptors, but we obviously won't need more drivers than - * devices... */ - loadable_device_list = malloc( npldynamicdevices * sizeof(PLLoadableDevice) ); - loadable_driver_list = malloc( npldynamicdevices * sizeof(PLLoadableDriver) ); - - rewind( fp_drvdb ); - - i = 0; - done = !(i < npldynamicdevices); - while( !done ) { - char *p = fgets( buf, 300, fp_drvdb ); - - if (p == 0) { - done = 1; - continue; - } - - devnam = strtok( buf, ":" ); - devdesc = strtok( 0, ":" ); - devtype = strtok( 0, ":" ); - driver = strtok( 0, ":" ); - seqstr = strtok( 0, ":" ); - tag = strtok( 0, "\n" ); - - seq = atoi(seqstr); - - n = npldrivers++; - - dispatch_table[n] = malloc( sizeof(PLDispatchTable) ); - - /* Fill in the dispatch table entries. */ - dispatch_table[n]->pl_MenuStr = plstrdup(devdesc); - dispatch_table[n]->pl_DevName = plstrdup(devnam); - dispatch_table[n]->pl_type = atoi(devtype); - dispatch_table[n]->pl_seq = seq; - dispatch_table[n]->pl_init = 0; - dispatch_table[n]->pl_line = 0; - dispatch_table[n]->pl_polyline = 0; - dispatch_table[n]->pl_eop = 0; - dispatch_table[n]->pl_bop = 0; - dispatch_table[n]->pl_tidy = 0; - dispatch_table[n]->pl_state = 0; - dispatch_table[n]->pl_esc = 0; - - /* Add a record to the loadable device list */ - loadable_device_list[i].devnam = plstrdup(devnam); - loadable_device_list[i].description = plstrdup(devdesc); - loadable_device_list[i].drvnam = plstrdup(driver); - loadable_device_list[i].tag = plstrdup(tag); - - /* Now see if this driver has been seen before. If not, add a driver - * entry for it. */ - driver_found = 0; - for( j=0; j < nloadabledrivers; j++ ) - if (strcmp( driver, loadable_driver_list[j].drvnam) == 0) - { - driver_found = 1; - break; - } - - if (!driver_found) - { - loadable_driver_list[nloadabledrivers].drvnam = plstrdup(driver); - loadable_driver_list[nloadabledrivers].dlhand = 0; - nloadabledrivers++; - } - - loadable_device_list[i].drvidx = j; - - /* Get ready for next loadable device spec */ - i++; - } - -/* RML: close fp_drvdb */ - fclose (fp_drvdb); - -#endif - -/* Finally, we need to sort the list into presentation order, based on the - sequence number in the dispatch ttable entries. */ - - qsort( dispatch_table, npldrivers, sizeof(PLDispatchTable*), - plDispatchSequencer ); -} - -/*--------------------------------------------------------------------------*\ - * void plSelectDev() - * - * If the user has not already specified the output device, or the - * one specified is either: (a) not available, (b) "?", or (c) NULL, the - * user is prompted for it. - * - * Prompting quits after 10 unsuccessful tries in case the user has - * run the program in the background with insufficient input. -\*--------------------------------------------------------------------------*/ - -static void -plSelectDev() -{ - int dev, i, count, length; - char response[80]; - -/* Device name already specified. See if it is valid. */ - - if (*(plsc->DevName) != '\0' && *(plsc->DevName) != '?') { - length = strlen(plsc->DevName); - for (i = 0; i < npldrivers; i++) { - if ((*plsc->DevName == *dispatch_table[i]->pl_DevName) && - (strncmp(plsc->DevName, - dispatch_table[i]->pl_DevName, length) == 0)) - break; - } - if (i < npldrivers) { - plsc->device = i + 1; - return; - } - else { - fprintf(stderr, "Requested device %s not available\n", - plsc->DevName); - } - } - - dev = 0; - count = 0; - - if (npldrivers == 1) - dev = 1; - -/* User hasn't specified it correctly yet, so we prompt */ - - while (dev < 1 || dev > npldrivers) { - fprintf(stdout, "\nPlotting Options:\n"); - for (i = 0; i < npldrivers; i++) { - fprintf(stdout, " <%2d> %-10s %s\n", i + 1, - dispatch_table[i]->pl_DevName, - dispatch_table[i]->pl_MenuStr); - } - if (ipls == 0) - fprintf(stdout, "\nEnter device number or keyword: "); - else - fprintf(stdout, "\nEnter device number or keyword (stream %d): ", - (int) ipls); - - if (! (fgets(response, sizeof(response), stdin))) { - return; - } - - /* First check to see if device keyword was entered. */ - /* Final "\n" in response messes things up, so ignore it. */ - - length = strlen(response); - if (*(response - 1 + length) == '\n') - length--; - - for (i = 0; i < npldrivers; i++) { - if ( ! strncmp(response, dispatch_table[i]->pl_DevName, - (unsigned int) length)) - break; - } - if (i < npldrivers) { - dev = i + 1; - } - else { - if ((dev = atoi(response)) < 1) { - fprintf(stdout, "\nInvalid device: %s", response); - dev = 0; - } - } - if (count++ > 10) - plexit("plSelectDev: Too many tries."); - } - plsc->device = dev; - strcpy(plsc->DevName, dispatch_table[dev - 1]->pl_DevName); -} - -/*--------------------------------------------------------------------------*\ - * void plLoadDriver() - * - * Make sure the selected driver is loaded. Static drivers are already - * loaded, but if the user selected a dynamically loadable driver, we may - * have to take care of that now. -\*--------------------------------------------------------------------------*/ - -static void -plLoadDriver(void) -{ -#ifdef ENABLE_DYNDRIVERS - int i, drvidx; - char sym[60]; - char *tag; - - int n=plsc->device - 1; - PLDispatchTable *dev = dispatch_table[n]; - PLLoadableDriver *driver = 0; - -/* If the dispatch table is already filled in, then either the device was - * linked in statically, or else perhaps it was already loaded. In either - * case, we have nothing left to do. */ - if (dev->pl_init) - return; - - pldebug("plLoadDriver", "Device not loaded!\n"); - -/* Now search through the list of loadable devices, looking for the record - * that corresponds to the requested device. */ - for( i=0; i < npldynamicdevices; i++ ) - if (strcmp( dev->pl_DevName, loadable_device_list[i].devnam ) == 0) - break; - -/* If we couldn't find such a record, then there is some sort of internal - * logic flaw since plSelectDev is supposed to only select a valid device. - */ - if (i == npldynamicdevices) { - fprintf( stderr, "No such device: %s.\n", dev->pl_DevName ); - plexit("plLoadDriver detected device logic screwup"); - } - -/* Note the device tag, and the driver index. Note that a given driver could - * supply multiple devices, each with a unique tag to distinguish the driver - * entry points for the differnet supported devices. */ - tag = loadable_device_list[i].tag; - drvidx = loadable_device_list[i].drvidx; - - pldebug("plLoadDriver", "tag=%s, drvidx=%d\n", tag, drvidx ); - - driver = &loadable_driver_list[drvidx]; - -/* Load the driver if it hasn't been loaded yet. */ - if (!driver->dlhand) - { - char drvspec[ 400 ]; - sprintf( drvspec, "%s/%s", plGetDrvDir (), driver->drvnam ); - - pldebug("plLoadDriver", "Trying to load %s on %s\n", - driver->drvnam, drvspec ); - - driver->dlhand = lt_dlopenext( drvspec); - } - -/* If it still isn't loaded, then we're doomed. */ - if (!driver->dlhand) - { - pldebug("plLoadDriver", "lt_dlopenext failed because of " - "the following reason:\n%s\n", lt_dlerror ()); - fprintf( stderr, "Unable to load driver: %s.\n", driver->drvnam ); - plexit("Unable to load driver"); - } - -/* Now we are ready to ask the driver's device dispatch init function to - initialize the entries in the dispatch table. */ - - sprintf( sym, "plD_dispatch_init_%s", tag ); - { - PLDispatchInit dispatch_init = (PLDispatchInit) lt_dlsym( driver->dlhand, sym ); - if (!dispatch_init) - { - fprintf( stderr, - "Unable to locate dispatch table initialization function for driver: %s.\n", - driver->drvnam ); - return; - } - - (*dispatch_init)( dev ); - } -#endif -} - -/*--------------------------------------------------------------------------*\ - * void plfontld() - * - * Load specified font set. -\*--------------------------------------------------------------------------*/ - -void -c_plfontld(PLINT ifont) -{ - if (ifont != 0) - ifont = 1; - - if (plsc->level > 0) - plfntld(ifont); - else - initfont = ifont; -} - -/*--------------------------------------------------------------------------*\ - * void plreplot() - * - * Replays contents of plot buffer to current device/file. -\*--------------------------------------------------------------------------*/ - -void -c_plreplot(void) -{ - if (plsc->plbufFile != NULL) { - plRemakePlot(plsc); - } - else { - plwarn("plreplot: plot buffer not available"); - } -} - -/*--------------------------------------------------------------------------*\ - * void plgFileDevs() - * - * Returns a list of file-oriented device names and their menu strings, - * for use in a graphical interface. The caller must allocate enough - * space for (*p_menustr) and (*p_devname) to hold a pointer for each - * device -- 20 or so is plenty. E.g. char *menustr[20]. The size of - * these arrays should be passed in *p_ndev, which, on exit, holds the - * number of devices actually present. -\*--------------------------------------------------------------------------*/ - -void -plgFileDevs(char ***p_menustr, char ***p_devname, int *p_ndev) -{ - plgdevlst(*p_menustr, *p_devname, p_ndev, 0); -} - -/*--------------------------------------------------------------------------*\ - * void plgDevs() - * - * Like plgFileDevs(), but returns names and menu strings for all devices. -\*--------------------------------------------------------------------------*/ - -void -plgDevs(char ***p_menustr, char ***p_devname, int *p_ndev) -{ - plgdevlst(*p_menustr, *p_devname, p_ndev, -1); -} - -static void -plgdevlst(char **p_menustr, char **p_devname, int *p_ndev, int type) -{ - int i, j; - - pllib_init(); - - for (i = j = 0; i < npldrivers; i++) { - if (type < 0 || dispatch_table[i]->pl_type == type) { - p_menustr[j] = dispatch_table[i]->pl_MenuStr; - p_devname[j] = dispatch_table[i]->pl_DevName; - if (++j + 1 >= *p_ndev) { - plwarn("plgdevlst: too many devices"); - break; - } - } - } - p_menustr[j] = NULL; - p_devname[j] = NULL; - *p_ndev = j; -} - -/*--------------------------------------------------------------------------*\ - * Various external access routines. -\*--------------------------------------------------------------------------*/ - -/* Get output device parameters. */ - -void -c_plgpage(PLFLT *p_xp, PLFLT *p_yp, - PLINT *p_xleng, PLINT *p_yleng, PLINT *p_xoff, PLINT *p_yoff) -{ - *p_xp = plsc->xdpi; - *p_yp = plsc->ydpi; - *p_xleng = plsc->xlength; - *p_yleng = plsc->ylength; - *p_xoff = plsc->xoffset; - *p_yoff = plsc->yoffset; -} - -/* Set output device parameters. Usually ignored by the driver. */ - -MZ_DLLEXPORT -void -c_plspage(PLFLT xp, PLFLT yp, PLINT xleng, PLINT yleng, PLINT xoff, PLINT yoff) -{ - if (xp) - plsc->xdpi = xp; - if (yp) - plsc->ydpi = yp; - - if (xleng) - plsc->xlength = xleng; - if (yleng) - plsc->ylength = yleng; - - if (xoff) - plsc->xoffset = xoff; - if (yoff) - plsc->yoffset = yoff; - - plsc->pageset = 1; -} - -/* Set the number of subwindows in x and y */ - -void -c_plssub(PLINT nx, PLINT ny) -{ - if (nx > 0) - plsc->nsubx = nx; - if (ny > 0) - plsc->nsuby = ny; - -/* Force a page advance */ - - if (plsc->level > 0) { - plP_subpInit(); -/*AWI plP_eop(); - plP_bop();*/ - } -} - -/* Set the device (keyword) name */ - -MZ_DLLEXPORT -void -c_plsdev(const char *devname) -{ - if (plsc->level > 0) { - plwarn("plsdev: Must be called before plinit."); - return; - } - if (devname != NULL) { - strncpy(plsc->DevName, devname, sizeof(plsc->DevName) - 1); - plsc->DevName[sizeof(plsc->DevName) - 1] = '\0'; - } -} - -/* Get the current device (keyword) name */ -/* Note: you MUST have allocated space for this (80 characters is safe) */ - -void -c_plgdev(char *p_dev) -{ - strcpy(p_dev, plsc->DevName); -} - -/* Set the memory area to be plotted (with the 'mem' driver) as the 'dev' - member of the stream structure. Also set the number - of pixels in the memory passed in in 'plotmem'. - Plotmem is a block of memory maxy by maxx by 3 bytes long, say: - 480 x 640 x 3 (Y, X, RGB) - - This memory will be freed by the user! -*/ - -void -c_plsmem(PLINT maxx, PLINT maxy, void *plotmem) -{ - plsc->dev = plotmem; - plP_setphy (0, maxx, 0, maxy); -} - -/* Get the current stream pointer */ - -void -plgpls(PLStream **p_pls) -{ - *p_pls = plsc; -} - -/* Get the (current) run level. - * Valid settings are: - * 0 uninitialized - * 1 initialized - * 2 viewport defined - * 3 world coords defined - */ - -void -c_plglevel(PLINT *p_level) -{ - *p_level = plsc->level; -} - -/* Set the function pointer for the keyboard event handler */ - -void -plsKeyEH(void (*KeyEH) (PLGraphicsIn *, void *, int *), - void *KeyEH_data) -{ - plsc->KeyEH = KeyEH; - plsc->KeyEH_data = KeyEH_data; -} - -/* Set the function pointer for the (mouse) button event handler */ - -void -plsButtonEH(void (*ButtonEH) (PLGraphicsIn *, void *, int *), - void *ButtonEH_data) -{ - plsc->ButtonEH = ButtonEH; - plsc->ButtonEH_data = ButtonEH_data; -} - -/* Sets an optional user bop handler. */ - -void -plsbopH(void (*handler) (void *, int *), void *handler_data) -{ - plsc->bop_handler = handler; - plsc->bop_data = handler_data; -} - -/* Sets an optional user eop handler. */ - -void -plseopH(void (*handler) (void *, int *), void *handler_data) -{ - plsc->eop_handler = handler; - plsc->eop_data = handler_data; -} - -/* Set the variables to be used for storing error info */ - -void -plsError(PLINT *errcode, char *errmsg) -{ - if (errcode != NULL) - plsc->errcode = errcode; - - if (errmsg != NULL) - plsc->errmsg = errmsg; -} - -/* Set orientation. Must be done before calling plinit. */ - -void -c_plsori(PLINT ori) -{ - plsdiori((PLFLT) ori); -} - -/* - * Set pen width. Can be done any time, but before calling plinit is best - * since otherwise it may be volatile (i.e. reset on next page advance). - * If width < 0 or is unchanged by the call, nothing is done. - */ - -MZ_DLLEXPORT -void -c_plwid(PLINT width) -{ - if (width != plsc->width && width >= 0) { - plsc->width = width; - - if (plsc->level > 0) { - if ( ! plsc->widthlock) - plP_state(PLSTATE_WIDTH); - } - } -} - -/* Set the output file pointer */ - -void -plgfile(FILE **p_file) -{ - *p_file = plsc->OutFile; -} - -/* Get the output file pointer */ - -void -plsfile(FILE *file) -{ - plsc->OutFile = file; -} - -/* Get the (current) output file name. Must be preallocated to >=80 bytes */ -/* Beyond that, I truncate it. You have been warned. */ - -void -c_plgfnam(char *fnam) -{ - if (fnam == NULL) { - plabort("filename string must be preallocated to >=80 bytes"); - return; - } - - *fnam = '\0'; - if (plsc->FileName != NULL) { - strncpy(fnam, plsc->FileName, 79); - fnam[79] = '\0'; - } -} - -/* Set the output file name. */ - -MZ_DLLEXPORT -void -c_plsfnam(const char *fnam) -{ - plP_sfnam(plsc, fnam); -} - -/* Set the pause (on end-of-page) status */ - -void -c_plspause(PLINT pause) -{ - plsc->nopause = ! pause; -} - -/* Set the floating point precision (in number of places) in numeric labels. */ - -void -c_plprec(PLINT setp, PLINT prec) -{ - plsc->setpre = setp; - plsc->precis = prec; -} - -/* Get the floating point precision (in number of places) in numeric labels. */ - -void -plP_gprec(PLINT *p_setp, PLINT *p_prec) -{ - *p_setp = plsc->setpre; - *p_prec = plsc->precis; -} - -/* - * Set the escape character for text strings. - * From C you can pass as a character, from Fortran it needs to be the decimal - * ASCII value. Only selected characters are allowed to prevent the user from - * shooting himself in the foot (a '\' isn't allowed since it conflicts with - * C's use of backslash as a character escape). - */ - -void -c_plsesc(char esc) -{ - switch (esc) { - case '!': /* ASCII 33 */ - case '#': /* ASCII 35 */ - case '$': /* ASCII 36 */ - case '%': /* ASCII 37 */ - case '&': /* ASCII 38 */ - case '*': /* ASCII 42 */ - case '@': /* ASCII 64 */ - case '^': /* ASCII 94 */ - case '~': /* ASCII 126 */ - plsc->esc = esc; - break; - - default: - plwarn("plsesc: Invalid escape character, ignoring."); - } -} - -/* Get the escape character for text strings. */ - -void -plgesc(char *p_esc) -{ - if (plsc->esc == '\0') - plsc->esc = '#'; - - *p_esc = plsc->esc; -} - -/* Get the current library version number */ -/* Note: you MUST have allocated space for this (80 characters is safe) */ - -void -c_plgver(char *p_ver) -{ - strcpy(p_ver, VERSION); -} - -/* Set inferior X window */ - -void -plsxwin(PLINT window_id) -{ - plsc->window_id = window_id; -} - -/*--------------------------------------------------------------------------*\ - * These set/get information for family files, and may be called prior - * to plinit to set up the necessary parameters. Arguments: - * - * fam familying flag (boolean) - * num member number - * bmax maximum member size -\*--------------------------------------------------------------------------*/ - -/* Get family file parameters */ - -void -c_plgfam(PLINT *p_fam, PLINT *p_num, PLINT *p_bmax) -{ - *p_fam = plsc->family; - *p_num = plsc->member; - *p_bmax = plsc->bytemax; -} - -/* Set family file parameters */ - -void -c_plsfam(PLINT fam, PLINT num, PLINT bmax) -{ - if (plsc->level > 0) - plwarn("plsfam: Must be called before plinit."); - - if (fam >= 0) - plsc->family = fam; - if (num >= 0) - plsc->member = num; - if (bmax >= 0) - plsc->bytemax = bmax; -} - -/* Advance to the next family file on the next new page */ - -void -c_plfamadv(void) -{ - plsc->famadv = 1; -} - -/*--------------------------------------------------------------------------*\ - * Interface routines for axis labling parameters. - * See pldtik.c for more info. -\*--------------------------------------------------------------------------*/ - -/* Get x axis labeling parameters */ - -void -c_plgxax(PLINT *p_digmax, PLINT *p_digits) -{ - *p_digmax = plsc->xdigmax; - *p_digits = plsc->xdigits; -} - -/* Set x axis labeling parameters */ - -void -c_plsxax(PLINT digmax, PLINT digits) -{ - plsc->xdigmax = digmax; - plsc->xdigits = digits; -} - -/* Get y axis labeling parameters */ - -void -c_plgyax(PLINT *p_digmax, PLINT *p_digits) -{ - *p_digmax = plsc->ydigmax; - *p_digits = plsc->ydigits; -} - -/* Set y axis labeling parameters */ - -void -c_plsyax(PLINT digmax, PLINT digits) -{ - plsc->ydigmax = digmax; - plsc->ydigits = digits; -} - -/* Get z axis labeling parameters */ - -void -c_plgzax(PLINT *p_digmax, PLINT *p_digits) -{ - *p_digmax = plsc->zdigmax; - *p_digits = plsc->zdigits; -} - -/* Set z axis labeling parameters */ - -void -c_plszax(PLINT digmax, PLINT digits) -{ - plsc->zdigmax = digmax; - plsc->zdigits = digits; -} - -/* Get character default height and current (scaled) height */ - -void -c_plgchr(PLFLT *p_def, PLFLT *p_ht) -{ - *p_def = plsc->chrdef; - *p_ht = plsc->chrht; -} - -/* Get viewport boundaries in normalized device coordinates */ - -void -c_plgvpd(PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax) -{ - *p_xmin = plsc->vpdxmi; - *p_xmax = plsc->vpdxma; - *p_ymin = plsc->vpdymi; - *p_ymax = plsc->vpdyma; -} - -/* Get viewport boundaries in world coordinates */ - -void -c_plgvpw(PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax) -{ - *p_xmin = plsc->vpwxmi; - *p_xmax = plsc->vpwxma; - *p_ymin = plsc->vpwymi; - *p_ymax = plsc->vpwyma; -} - -/*--------------------------------------------------------------------------*\ - * These should not be called by the user. -\*--------------------------------------------------------------------------*/ - -/* Get x-y domain in world coordinates for 3d plots */ - -void -plP_gdom(PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax) -{ - *p_xmin = plsc->domxmi; - *p_xmax = plsc->domxma; - *p_ymin = plsc->domymi; - *p_ymax = plsc->domyma; -} - -/* Get vertical (z) scale parameters for 3-d plot */ - -void -plP_grange(PLFLT *p_zscl, PLFLT *p_zmin, PLFLT *p_zmax) -{ - *p_zscl = plsc->zzscl; - *p_zmin = plsc->ranmi; - *p_zmax = plsc->ranma; -} - -/* Get parameters used in 3d plots */ - -void -plP_gw3wc(PLFLT *p_dxx, PLFLT *p_dxy, PLFLT *p_dyx, PLFLT *p_dyy, PLFLT *p_dyz) -{ - *p_dxx = plsc->cxx; - *p_dxy = plsc->cxy; - *p_dyx = plsc->cyx; - *p_dyy = plsc->cyy; - *p_dyz = plsc->cyz; -} - -/* Get clip boundaries in physical coordinates */ - -void -plP_gclp(PLINT *p_ixmin, PLINT *p_ixmax, PLINT *p_iymin, PLINT *p_iymax) -{ - *p_ixmin = plsc->clpxmi; - *p_ixmax = plsc->clpxma; - *p_iymin = plsc->clpymi; - *p_iymax = plsc->clpyma; -} - -/* Set clip boundaries in physical coordinates */ - -void -plP_sclp(PLINT ixmin, PLINT ixmax, PLINT iymin, PLINT iymax) -{ - plsc->clpxmi = ixmin; - plsc->clpxma = ixmax; - plsc->clpymi = iymin; - plsc->clpyma = iymax; -} - -/* Get physical device limits in physical coordinates */ - -void -plP_gphy(PLINT *p_ixmin, PLINT *p_ixmax, PLINT *p_iymin, PLINT *p_iymax) -{ - *p_ixmin = plsc->phyxmi; - *p_ixmax = plsc->phyxma; - *p_iymin = plsc->phyymi; - *p_iymax = plsc->phyyma; -} - -/* Get number of subpages on physical device and current subpage */ - -void -plP_gsub(PLINT *p_nx, PLINT *p_ny, PLINT *p_cs) -{ - *p_nx = plsc->nsubx; - *p_ny = plsc->nsuby; - *p_cs = plsc->cursub; -} - -/* Set number of subpages on physical device and current subpage */ - -void -plP_ssub(PLINT nx, PLINT ny, PLINT cs) -{ - plsc->nsubx = nx; - plsc->nsuby = ny; - plsc->cursub = cs; -} - -/* Get number of pixels to a millimeter */ - -void -plP_gpixmm(PLFLT *p_x, PLFLT *p_y) -{ - *p_x = plsc->xpmm; - *p_y = plsc->ypmm; -} - -/* All the drivers call this to set physical pixels/mm. */ - -void -plP_setpxl(PLFLT xpmm, PLFLT ypmm) -{ - plsc->xpmm = xpmm; - plsc->ypmm = ypmm; - plsc->umx = 1000.0 / plsc->xpmm; - plsc->umy = 1000.0 / plsc->ypmm; -} - -/* Sets up physical limits of plotting device. */ - -void -plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax) -{ - if (xmin > xmax || ymin > ymax) - plexit("plP_setphy: device minima must not exceed maxima"); - - plsc->phyxmi = xmin; - plsc->phyxma = xmax; - plsc->phyymi = ymin; - plsc->phyyma = ymax; - plsc->phyxlen = xmax - xmin; - plsc->phyylen = ymax - ymin; -} - -/*--------------------------------------------------------------------------*\ - * void c_plscompression() - * - * Set compression. - * Has to be done before plinit. -\*--------------------------------------------------------------------------*/ - -void -c_plscompression(PLINT compression) -{ - if (plsc->level <= 0) - { - plsc->dev_compression=compression; - } -} - -/*--------------------------------------------------------------------------*\ - * void c_plgcompression() - * - * Get compression -\*--------------------------------------------------------------------------*/ - -void -c_plgcompression(PLINT *compression) -{ - *compression = plsc->dev_compression; -} - - -/*--------------------------------------------------------------------------*\ - * void plP_getinitdriverlist() - * - * Check to see if a driver/stream has been initialised - * Returns a space separated list of matches streams/drivers - * If more than one stream uses the same device, then the device name - * will be returned for each stream. - * Caller must allocate enough memory for "names" to hold the answer. -\*--------------------------------------------------------------------------*/ - -void -plP_getinitdriverlist(char *names) -{ -int i; - -for (i=0;iDevName); - else - { - strcat(names," "); - strcat(names,pls[i]->DevName); - } - } - else - break; - } -} - - -/*--------------------------------------------------------------------------*\ - * PLINT plP_checkdriverinit() - * - * Checks from a list of given drivers which ones have been initialised - * and returns the number of devices matching the list, or -1 if in error. - * Effectively returns the number of streams matching the given stream. -\*--------------------------------------------------------------------------*/ - -PLINT plP_checkdriverinit( char *names) -{ -char *buff; -char *tok=NULL; -PLINT ret=0; /* set up return code to 0, the value if no devices match*/ - -buff=(char *)malloc((size_t) PL_NSTREAMS*8); /* Allocate enough memory for 8 - characters for each possible stream */ - -if (buff!=NULL) - { - memset(buff,0,PL_NSTREAMS*8); /* Make sure we clear it */ - plP_getinitdriverlist(buff); /* Get the list of initialised devices */ - - for (tok = strtok(buff, " ,"); /* Check each device against the "name" */ - tok; tok=strtok(0, " ,")) /* supplied to the subroutine */ - { - if (strstr(names,tok)!=NULL) /* Check to see if the device has been initialised */ - { - ret++; /* Bump the return code if it has */ - } - } - free(buff); /* Clear up that memory we allocated */ - } -else - ret=-1; /* Error flag */ - -return(ret); -} - - -/*--------------------------------------------------------------------------*\ - * plP_image - * - * Author: Alessandro Mirone, Nov 2001 - * - * - * -\*--------------------------------------------------------------------------*/ - -void -plP_image(short *x, short *y, unsigned short *z , PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, unsigned short zmin, unsigned short zmax) -{ - PLINT i, npts; - short *xscl, *yscl; - int plbuf_write; - - plsc->page_status = DRAWING; - - if (plsc->dev_fastimg == 0) { - plimageslow(x, y, z, nx-1, ny-1, - xmin, ymin, dx, dy, zmin, zmax); - return ; - } - - if (plsc->plbuf_write) { - IMG_DT img_dt; - - img_dt.xmin=xmin; - img_dt.ymin=ymin; - img_dt.dx=dx; - img_dt.dy=dy; - - plsc->dev_ix = x; - plsc->dev_iy = y; - plsc->dev_z = z; - plsc->dev_nptsX = nx; - plsc->dev_nptsY = ny; - plsc->dev_zmin = zmin; - plsc->dev_zmax = zmax; - - plbuf_esc(plsc, PLESC_IMAGE, &img_dt); - } - - /* avoid re-saving plot buffer while in plP_esc() */ - plbuf_write = plsc->plbuf_write; - plsc->plbuf_write = 0; - - npts = nx*ny; - if (plsc->difilt) { /* isn't this odd? when replaying the plot buffer, e.g., when resizing the window, difilt() is caled again! the plot buffer should already contain the transformed data--it would save a lot of time! (and allow for differently oriented plots when in multiplot mode) */ - PLINT clpxmi, clpxma, clpymi, clpyma; - - xscl = (short *) malloc(nx*ny*sizeof(short)); - yscl = (short *) malloc(nx*ny*sizeof(short)); - for (i = 0; i < npts; i++) { - xscl[i] = x[i]; - yscl[i] = y[i]; - } - sdifilt(xscl, yscl, npts, &clpxmi, &clpxma, &clpymi, &clpyma); - plsc->imclxmin = clpxmi; - plsc->imclymin = clpymi; - plsc->imclxmax = clpxma; - plsc->imclymax = clpyma; - grimage(xscl, yscl, z, nx, ny); - free(xscl); - free(yscl); - } else { - plsc->imclxmin = plsc->phyxmi; - plsc->imclymin = plsc->phyymi; - plsc->imclxmax = plsc->phyxma; - plsc->imclymax = plsc->phyyma; - grimage(x, y, z, nx, ny ); - } - plsc->plbuf_write = plbuf_write; -} diff --git a/src/plot/plplot/plcore.h b/src/plot/plplot/plcore.h deleted file mode 100644 index 00af09accf..0000000000 --- a/src/plot/plplot/plcore.h +++ /dev/null @@ -1,253 +0,0 @@ -/* $Id: plcore.h,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - - Contains declarations for core plplot data structures. This file - should be included only by plcore.c. -*/ - -#ifndef __PLCORE_H__ -#define __PLCORE_H__ - -#include "plplotP.h" -#include "drivers.h" -#include "plDevs.h" -#include "disptab.h" - -#ifdef ENABLE_DYNDRIVERS -#include -typedef lt_ptr (*PLDispatchInit)( PLDispatchTable *pdt ); -#else -typedef void (*PLDispatchInit)( PLDispatchTable *pdt ); -#endif - -/* Static function prototypes */ - -static void grline (short *, short *, PLINT); -static void grpolyline (short *, short *, PLINT); -static void grfill (short *, short *, PLINT); -static void plSelectDev (void); -static void pldi_ini (void); -static void calc_diplt (void); -static void calc_didev (void); -static void calc_diori (void); -static void calc_dimap (void); -static void plgdevlst (char **, char **, int *, int); - -static void plInitDispatchTable (void); - -static void plLoadDriver (void); - -/* Static variables */ - -static PLINT xscl[PL_MAXPOLY], yscl[PL_MAXPOLY]; - -static PLINT initfont = 1; /* initial font: extended by default */ - -static PLINT lib_initialized = 0; - -/*--------------------------------------------------------------------------*\ - * Allocate a PLStream data structure (defined in plstrm.h). - * - * This struct contains a copy of every variable that is stream dependent. - * Only the first [index=0] stream is statically allocated; the rest - * are dynamically allocated when you switch streams (yes, it is legal - * to only initialize the first element of the array of pointers). -\*--------------------------------------------------------------------------*/ - -static PLStream pls0; /* preallocated stream */ -static PLINT ipls; /* current stream number */ - -static PLStream *pls[PL_NSTREAMS] = {&pls0}; /* Array of stream pointers */ - -/* Current stream pointer. Global, for easier access to state info */ - -PLStream *plsc = &pls0; - -/* Only now can we include this */ - -#include "pldebug.h" - -/*--------------------------------------------------------------------------*\ - * Initialize dispatch table. - * - * Each device is selected by the appropriate define, passed in from the - * makefile. When installing plplot you may wish to exclude devices not - * present on your system in order to reduce screen clutter. - * - * If you hit a in response to the plinit() prompt, you get the FIRST - * one active below, so arrange them accordingly for your system (i.e. all - * the system-specific ones should go first, since they won't appear on - * most systems.) -\*--------------------------------------------------------------------------*/ - -static PLDispatchTable **dispatch_table = 0; -static int npldrivers = 0; - -static PLDispatchInit static_device_initializers[] = { -#ifdef PLD_mac - plD_dispatch_init_mac8, - plD_dispatch_init_mac1, -#endif -#ifdef PLD_next - plD_dispatch_init_nx, -#endif -#ifdef PLD_os2pm - plD_dispatch_init_os2, -#endif -#if defined(PLD_xwin) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_xw, -#endif -#if defined(PLD_gnome) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_gnome, -#endif -#if defined(PLD_tk) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_tk, -#endif -#if defined(PLD_linuxvga) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_vga, -#endif -#ifdef PLD_mgr - plD_dispatch_init_mgr, -#endif -#ifdef PLD_win3 - plD_dispatch_init_win3, -#endif -#if defined (_MSC_VER) && defined (VGA) /* graphics for msc */ - plD_dispatch_init_vga, -#endif -#ifdef PLD_bgi - plD_dispatch_init_vga, -#endif -#ifdef PLD_gnusvga - plD_dispatch_init_vga, -#endif -#ifdef PLD_tiff - plD_dispatch_init_tiff, -#endif -#if defined(PLD_jpg) - plD_dispatch_init_jpg, -#endif -#if defined(PLD_bmp) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_bmp, -#endif -#ifdef PLD_emxvga /* graphics for emx+gcc */ - plD_dispatch_init_vga, -#endif -#if defined(PLD_xterm) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_xterm, -#endif -#if defined(PLD_tek4010) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_tekt, -#endif -#if defined(PLD_tek4107) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_tek4107t, -#endif -#if defined(PLD_mskermit) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_mskermit, -#endif -#if defined(PLD_versaterm) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_versaterm, -#endif -#if defined(PLD_vlt) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_vlt, -#endif -#if defined(PLD_conex) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_conex, -#endif -#if defined(PLD_dg300) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_dg, -#endif -#if defined(PLD_plmeta) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_plm, -#endif -#if defined(PLD_tek4010f) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_tekf, -#endif -#if defined(PLD_tek4107f) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_tek4107f, -#endif -#if defined(PLD_ps) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_psm, - plD_dispatch_init_psc, -#endif -#if defined(PLD_xfig) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_xfig, -#endif -#if defined(PLD_ljiip) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_ljiip, -#endif -#if defined(PLD_ljii) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_ljii, -#endif -#if defined( PLD_hp7470) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_hp7470, -#endif -#if defined( PLD_hp7580) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_hp7580, -#endif -#if defined( PLD_lj_hpgl) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_hpgl, -#endif -#if defined( PLD_imp) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_imp, -#endif -#if defined( PLD_pbm) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_pbm, -#endif -#if defined(PLD_png) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_png, -#endif -#if defined(PLD_jpeg) && !defined(ENABLE_DYNDRIVERS) - //plD_dispatch_init_jpeg, -#endif -#if defined(PLD_pstex) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_pstex, -#endif -#if defined(PLD_ntk) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_ntk, -#endif -#if defined(PLD_cgm) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_cgm, -#endif -#if defined(PLD_mem) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_mem, -#endif -#if defined(PLD_null) && !defined(ENABLE_DYNDRIVERS) - //plD_dispatch_init_null, -#endif -#if defined(PLD_tkwin) && !defined(ENABLE_DYNDRIVERS) - plD_dispatch_init_tkwin, -#endif - plD_dispatch_init_dc, - NULL -}; - -static int nplstaticdevices = ( sizeof(static_device_initializers) / - sizeof(PLDispatchInit) ) - 1; -static int npldynamicdevices = 0; - -/*--------------------------------------------------------------------------*\ - * Stuff to support the loadable device drivers. -\*--------------------------------------------------------------------------*/ - -#ifdef ENABLE_DYNDRIVERS -typedef struct { - char *devnam; - char *description; - char *drvnam; - char *tag; - int drvidx; -} PLLoadableDevice; - -typedef struct { - char *drvnam; - lt_dlhandle dlhand; - -} PLLoadableDriver; - -static PLLoadableDevice *loadable_device_list; -static PLLoadableDriver *loadable_driver_list; -#endif - -static UNUSED int nloadabledrivers = 0; - -#endif /* __PLCORE_H__ */ diff --git a/src/plot/plplot/plctrl.c b/src/plot/plplot/plctrl.c deleted file mode 100644 index b5ed250667..0000000000 --- a/src/plot/plplot/plctrl.c +++ /dev/null @@ -1,1745 +0,0 @@ -/* $Id: plctrl.c,v 1.3 2005/03/18 20:32:41 eli Exp $ - - Misc. control routines, like begin, end, exit, change graphics/text - mode, change color. Includes some spillage from plcore.c. If you - don't know where it should go, put it here. -*/ - -#define DEBUG - -#define NEED_PLDEBUG -#include "plplotP.h" -#ifdef macintosh -#include "mac.h" -/* for plMacLibOpen prototype; used in plLibOpen */ -#endif - -#ifdef DJGPP /* dos386/djgpp */ -#ifdef __unix -#undef __unix -#endif -#endif - -#ifdef __unix -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#endif - -/* Static functions */ - -/* Used by any external init code to suggest a path */ -MZ_DLLEXPORT -char* plplotLibDir = 0; - -static void -color_set(PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, char *name ); - -static void -strcat_delim(char *dirspec); - -static int -(*exit_handler) (char *errormsg); - -static void -plcmap0_def(int imin, int imax); - -static void -plcmap1_def(void); - -static PLFLT -value(double n1, double n2, double hue); - -/* An additional hardwired location for lib files. */ -/* I have no plans to change these again, ever. */ - -#if defined(DJGPP) -#ifndef PLLIBDEV -#define PLLIBDEV "c:/plplot/lib" -#endif - -#elif defined(MSDOS) -#ifndef PLLIBDEV -#define PLLIBDEV "c:\\plplot\\lib" -#endif - -#else - -/* Anything else is assumed to be Unix */ - -#ifndef PLLIBDEV -#define PLLIBDEV "/usr/local/plplot/lib" -#endif - -#endif - -/*--------------------------------------------------------------------------*\ - * Routines that deal with colors & color maps. -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * plcol0() - * - * Set color, map 0. Argument is integer between 0 and plsc->ncol0. -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plcol0(PLINT icol0) -{ - if (plsc->level < 1) { - plabort("plcol0: Please call plinit first"); - return; - } - if (icol0 < 0 || icol0 >= plsc->ncol0) { - char buffer[256]; - sprintf(buffer, "plcol0: Invalid color map entry: %d", (int) icol0); - plabort(buffer); - return; - } - - plsc->icol0 = icol0; - plsc->curcolor.r = plsc->cmap0[icol0].r; - plsc->curcolor.g = plsc->cmap0[icol0].g; - plsc->curcolor.b = plsc->cmap0[icol0].b; - - plsc->curcmap = 0; - plP_state(PLSTATE_COLOR0); -} - -/*--------------------------------------------------------------------------*\ - * plcol1() - * - * Set color, map 1. Argument is a float between 0. and 1. -\*--------------------------------------------------------------------------*/ - -void -c_plcol1(PLFLT col1) -{ - PLINT icol1; - - if (plsc->level < 1) { - plabort("plcol1: Please call plinit first"); - return; - } - if (col1 < 0 || col1 > 1) { - char buffer[256]; - sprintf(buffer, "plcol1: Invalid color map position: %f", (PLFLT) col1); - plabort(buffer); - return; - } - - icol1 = col1 * plsc->ncol1; - icol1 = MIN(icol1, plsc->ncol1-1); - - plsc->icol1 = icol1; - plsc->curcolor.r = plsc->cmap1[plsc->icol1].r; - plsc->curcolor.g = plsc->cmap1[plsc->icol1].g; - plsc->curcolor.b = plsc->cmap1[plsc->icol1].b; - - plsc->curcmap = 1; - plP_state(PLSTATE_COLOR1); -} - -/*--------------------------------------------------------------------------*\ - * plscolbg() - * - * Set the background color (cmap0[0]) by 8 bit RGB value -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plscolbg(PLINT r, PLINT g, PLINT b) -{ - plscol0(0, r, g, b); -} - -/*--------------------------------------------------------------------------*\ - * plgcolbg() - * - * Returns the background color (cmap0[0]) by 8 bit RGB value -\*--------------------------------------------------------------------------*/ - -void -c_plgcolbg(PLINT *r, PLINT *g, PLINT *b) -{ - plgcol0(0, r, g, b); -} - -/*--------------------------------------------------------------------------*\ - * plscol0() - * - * Set a given color from color map 0 by 8 bit RGB value - * Does not result in any additional cells to be allocated. -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plscol0(PLINT icol0, PLINT r, PLINT g, PLINT b) -{ - if (plsc->cmap0 == NULL) - plscmap0n(0); - - if (icol0 < 0 || icol0 >= plsc->ncol0) { - char buffer[256]; - sprintf(buffer, "plscol0: Illegal color table value: %d", (int) icol0); - plabort(buffer); - return; - } - if ((r < 0 || r > 255) || (g < 0 || g > 255) || (b < 0 || b > 255)) { - char buffer[256]; - sprintf(buffer, "plscol0: Invalid RGB color: %d, %d, %d", - (int) r, (int) g, (int) b); - plabort(buffer); - return; - } - - plsc->cmap0[icol0].r = r; - plsc->cmap0[icol0].g = g; - plsc->cmap0[icol0].b = b; - - if (plsc->level > 0) - plP_state(PLSTATE_CMAP0); -} - -/*--------------------------------------------------------------------------*\ - * plgcol0() - * - * Returns 8 bit RGB values for given color from color map 0 - * Values are negative if an invalid color id is given -\*--------------------------------------------------------------------------*/ - -void -c_plgcol0(PLINT icol0, PLINT *r, PLINT *g, PLINT *b) -{ - if (plsc->cmap0 == NULL) - plscmap0n(0); - - *r = -1; - *g = -1; - *b = -1; - - if (icol0 < 0 || icol0 > plsc->ncol0) { - char buffer[256]; - sprintf(buffer, "plgcol0: Invalid color index: %d", (int) icol0); - plabort(buffer); - return; - } - - *r = plsc->cmap0[icol0].r; - *g = plsc->cmap0[icol0].g; - *b = plsc->cmap0[icol0].b; - - return; -} - -/*--------------------------------------------------------------------------*\ - * plscmap0() - * - * Set color map 0 colors by 8 bit RGB values. This sets the entire color - * map -- only as many colors as specified will be allocated. -\*--------------------------------------------------------------------------*/ - -void -c_plscmap0(PLINT *r, PLINT *g, PLINT *b, PLINT ncol0) -{ - int i; - - plscmap0n(ncol0); - - for (i = 0; i < plsc->ncol0; i++) { - if ((r[i] < 0 || r[i] > 255) || - (g[i] < 0 || g[i] > 255) || - (b[i] < 0 || b[i] > 255)) { - - char buffer[256]; - sprintf(buffer, "plscmap0: Invalid RGB color: %d, %d, %d", - (int) r[i], (int) g[i], (int) b[i]); - plabort(buffer); - return; - } - - plsc->cmap0[i].r = r[i]; - plsc->cmap0[i].g = g[i]; - plsc->cmap0[i].b = b[i]; - } - - if (plsc->level > 0) - plP_state(PLSTATE_CMAP0); -} - -/*--------------------------------------------------------------------------*\ - * plscmap1() - * - * Set color map 1 colors by 8 bit RGB values - * This also sets the number of colors. -\*--------------------------------------------------------------------------*/ - -void -c_plscmap1(PLINT *r, PLINT *g, PLINT *b, PLINT ncol1) -{ - int i; - - plscmap1n(ncol1); - - for (i = 0; i < plsc->ncol1; i++) { - if ((r[i] < 0 || r[i] > 255) || - (g[i] < 0 || g[i] > 255) || - (b[i] < 0 || b[i] > 255)) { - - char buffer[256]; - sprintf(buffer, "plscmap1: Invalid RGB color: %d, %d, %d", - (int) r[i], (int) g[i], (int) b[i]); - plabort(buffer); - return; - } - plsc->cmap1[i].r = r[i]; - plsc->cmap1[i].g = g[i]; - plsc->cmap1[i].b = b[i]; - } - - if (plsc->level > 0) - plP_state(PLSTATE_CMAP1); -} - -/*--------------------------------------------------------------------------*\ - * plscmap1l() - * - * Set color map 1 colors using a piece-wise linear relationship between - * position in the color map (from 0 to 1) and position in HLS or RGB color - * space. May be called at any time. - * - * The idea here is to specify a number of control points that specify the - * mapping between HLS (or RGB or CMY) and palette 1 value. Between these - * points, linear interpolation is used. By mapping position in the color - * map to function value, this gives a smooth variation of color with - * intensity. Any number of control points may be specified, located at - * arbitrary positions (intensities), although typically 2 - 4 are enough. - * Another way of stating this is that we are traversing a given number of - * lines through HLS (or RGB) space as we move through cmap 1 entries. The - * control points at the minimum and maximum intensity (0 and 1) must - * always be specified. By adding more control points you can get more - * variation. One good technique for plotting functions that vary about - * some expected average is to use an additional 2 control points in the - * center (intensity ~= 0.5) that are the same color as the background - * (typically white for paper output, black for crt), and same hue as the - * boundary control points. This allows the highs and lows to be very - * easily distinguished. - * - * Each control point must specify the position in cmap 1 as well as three - * coordinates in HLS or RGB space. The first point MUST correspond to - * position = 0, and the last to position = 1. - * - * The hue is interpolated around the "front" of the color wheel - * (red<->green<->blue<->red) unless the "rev" flag is set, in which case - * interpolation proceeds around the back (reverse) side. Specifying - * rev=NULL is equivalent to setting rev[]=0 for every control point. - * - * Bounds on RGB coordinates: - * R,G,B [0, 1] magnitude - * - * Bounds on HLS coordinates: - * hue [0, 360] degrees - * lightness [0, 1] magnitude - * saturation [0, 1] magnitude - * - * The inputs are: - * itype 0: HLS, 1: RGB - * npts number of control points - * pos[] position for each control point - * coord1[] first coordinate for each control point - * coord2[] second coordinate for each control point - * coord3[] third coordinate for each control point - * rev[] reverse flag for each control point -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plscmap1l(PLINT itype, PLINT npts, PLFLT *pos, - PLFLT *coord1, PLFLT *coord2, PLFLT *coord3, PLINT *rev) -{ - int n; - PLFLT h, l, s, r, g, b; - - if (npts < 2) { - plabort("plscmap1l: Must specify at least two control points"); - return; - } - - if ( (pos[0] != 0) || (pos[npts-1] != 1)) { - plabort("plscmap1l: First, last control points must lie on boundary"); - return; - } - - if ( npts > PL_MAX_CMAP1CP ) { - plabort("plscmap1l: exceeded maximum number of control points"); - return; - } - -/* Allocate if not done yet */ - - if (plsc->cmap1 == NULL) - plscmap1n(0); - -/* Save control points */ - - plsc->ncp1 = npts; - - for (n = 0; n < npts; n++) { - - if (itype == 0) { - h = coord1[n]; - l = coord2[n]; - s = coord3[n]; - } - else { - r = coord1[n]; - g = coord2[n]; - b = coord3[n]; - plRGB_HLS(r, g, b, &h, &l, &s); - } - - plsc->cmap1cp[n].h = h; - plsc->cmap1cp[n].l = l; - plsc->cmap1cp[n].s = s; - plsc->cmap1cp[n].p = pos[n]; - - if (rev == NULL) - plsc->cmap1cp[n].rev = 0; - else - plsc->cmap1cp[n].rev = rev[n]; - } - -/* Calculate and set color map */ - - plcmap1_calc(); -} - -/*--------------------------------------------------------------------------*\ - * plcmap1_calc() - * - * Bin up cmap 1 space and assign colors to make inverse mapping easy. - * Always do interpolation in HLS space. -\*--------------------------------------------------------------------------*/ - -void -plcmap1_calc(void) -{ - int i, n; - PLFLT delta, dp, dh, dl, ds; - PLFLT h, l, s, p, r, g, b; - -/* Loop over all control point pairs */ - - for (n = 0; n < plsc->ncp1-1; n++) { - - if ( plsc->cmap1cp[n].p == plsc->cmap1cp[n+1].p ) - continue; - - /* Differences in p, h, l, s between ctrl pts */ - - dp = plsc->cmap1cp[n+1].p - plsc->cmap1cp[n].p; - dh = plsc->cmap1cp[n+1].h - plsc->cmap1cp[n].h; - dl = plsc->cmap1cp[n+1].l - plsc->cmap1cp[n].l; - ds = plsc->cmap1cp[n+1].s - plsc->cmap1cp[n].s; - - /* Adjust dh if we are to go around "the back side" */ - - if (plsc->cmap1cp[n].rev) - dh = (dh > 0) ? dh-360 : dh+360; - - /* Loop over all color cells. Only interested in cells located (in */ - /* cmap1 space) between n_th and n+1_th control points */ - - for (i = 0; i < plsc->ncol1; i++) { - p = (double) i / (plsc->ncol1 - 1.0); - if ( (p < plsc->cmap1cp[n].p) || - (p > plsc->cmap1cp[n+1].p) ) - continue; - - /* Interpolate based on position of color cell in cmap1 space */ - - delta = (p - plsc->cmap1cp[n].p) / dp; - - /* Linearly interpolate to get color cell h, l, s values */ - - h = plsc->cmap1cp[n].h + dh * delta; - l = plsc->cmap1cp[n].l + dl * delta; - s = plsc->cmap1cp[n].s + ds * delta; - - while (h >= 360.) - h -= 360.; - - while (h < 0.) - h += 360.; - - plHLS_RGB(h, l, s, &r, &g, &b); - - plsc->cmap1[i].r = MAX(0, MIN(255, (int) (256. * r))); - plsc->cmap1[i].g = MAX(0, MIN(255, (int) (256. * g))); - plsc->cmap1[i].b = MAX(0, MIN(255, (int) (256. * b))); - } - } - - if (plsc->level > 0) - plP_state(PLSTATE_CMAP1); -} - -/*--------------------------------------------------------------------------*\ - * plscmap0n() - * - * Set number of colors in cmap 0, (re-)allocate cmap 0, and fill with - * default values for those colors not previously allocated (and less - * than index 15, after that you just get grey). - * - * The driver is not guaranteed to support all of these. -\*--------------------------------------------------------------------------*/ - -void -c_plscmap0n(PLINT ncol0) -{ - int ncol, size, imin, imax; - -/* No change */ - - if (ncol0 > 0 && plsc->ncol0 == ncol0) - return; - -/* Handle all possible startup conditions */ - - if (plsc->ncol0 <= 0 && ncol0 <= 0) - ncol = 16; - else if (ncol0 <= 0) - ncol = plsc->ncol0; - else - ncol = ncol0; - - imax = ncol-1; - size = ncol * sizeof(PLColor); - -/* Allocate the space */ - - if (plsc->cmap0 == NULL) { - plsc->cmap0 = (PLColor *) calloc(1, size); - imin = 0; - } - else { - plsc->cmap0 = (PLColor *) realloc(plsc->cmap0, size); - imin = plsc->ncol0; - } - -/* Fill in default entries */ - - plsc->ncol0 = ncol; - plcmap0_def(imin, imax); -} - -/*--------------------------------------------------------------------------*\ - * plscmap1n() - * - * Set number of colors in cmap 1, (re-)allocate cmap 1, and set default - * values if this is the first allocation. - * - * Note that the driver is allowed to disregard this number. - * In particular, most use fewer than we use internally. -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plscmap1n(PLINT ncol1) -{ - int ncol, size; - -/* No change */ - - if (ncol1 > 0 && plsc->ncol1 == ncol1) - return; - -/* Handle all possible startup conditions */ - - if (plsc->ncol1 <= 0 && ncol1 <= 0) - ncol = 128; - else if (ncol1 <= 0) - ncol = plsc->ncol1; - else - ncol = ncol1; - - size = ncol * sizeof(PLColor); - -/* Allocate the space */ - - if (plsc->ncol1 > 0) - plsc->cmap1 = (PLColor *) realloc(plsc->cmap1, size); - else - plsc->cmap1 = (PLColor *) calloc(ncol, sizeof(PLColor)); - -/* Fill in default entries */ - - plsc->ncol1 = ncol; - if (plsc->ncp1 == 0) - plcmap1_def(); - else - plcmap1_calc(); -} - -/*--------------------------------------------------------------------------*\ - * color_set() - * - * Initializes color table entry by RGB values. -\*--------------------------------------------------------------------------*/ - -static void -color_set(PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, char *name ) -{ - plsc->cmap0[i].r = r; - plsc->cmap0[i].g = g; - plsc->cmap0[i].b = b; - plsc->cmap0[i].name = name; -} - -/*--------------------------------------------------------------------------*\ - * plcmap0_def() - * - * Initializes specified color map 0 color entry to its default. - * - * Initial RGB values for color map 0 taken from X11R6 - * (XFree86-3.3.6) X-windows - * rgb.txt file, and may not accurately represent the described colors on - * all systems. -\*--------------------------------------------------------------------------*/ - -#define color_def(i, r, g, b, n) \ -if (i >= imin && i <= imax) color_set(i, r, g, b, n); - -static void -plcmap0_def(int imin, int imax) -{ - int i; - - color_def(0, 0, 0, 0, "black" ); /* black */ - color_def(1, 255, 0, 0, "red"); /* red */ - color_def(2, 255, 255, 0, "yellow" ); /* yellow */ - color_def(3, 0, 255, 0, "green" ); /* green */ - color_def(4, 127, 255, 212, "aquamarine" ); /* aquamarine */ - color_def(5, 255, 192, 203, "pink" ); /* pink */ - color_def(6, 245, 222, 179, "wheat" ); /* wheat */ - color_def(7, 190, 190, 190, "grey" ); /* grey */ - color_def(8, 165, 42, 42, "brown" ); /* brown */ - color_def(9, 0, 0, 255, "blue" ); /* blue */ - color_def(10, 138, 43, 226, "BlueViolet" ); /* Blue Violet */ - color_def(11, 0, 255, 255, "cyan" ); /* cyan */ - color_def(12, 64, 224, 208, "turquoise" ); /* turquoise */ - color_def(13, 255, 0, 255, "magenta" ); /* magenta */ - color_def(14, 250, 128, 114, "salmon" ); /* salmon */ - color_def(15, 255, 255, 255, "white" ); /* white */ - -/* Any others are just arbitrarily set */ - - for (i = 16; i <= imax; i++) - color_def(i, 255, 0, 0, "red"); /* red */ -} - -/*--------------------------------------------------------------------------*\ - * plcmap1_def() - * - * Initializes color map 1. - * - * The default initialization uses 6 control points in HLS space, the inner - * ones being very close to one of the vertices of the HLS double cone. The - * vertex used (black or white) is chosen to be the closer to the background - * color. The 6 points were chosen over the older 4 points in order to make - * weaker structures more easily visible, and give more control through the - * palette editor. If you don't like these settings.. change them! -\*--------------------------------------------------------------------------*/ - -static void -plcmap1_def(void) -{ - PLFLT i[6], h[6], l[6], s[6], midpt = 0., vertex = 0.; - -/* Positions of control points */ - - i[0] = 0; /* left boundary */ - i[1] = 0.44; /* a little left of center */ - i[2] = 0.50; /* at center */ - i[3] = 0.50; /* at center */ - i[4] = 0.56; /* a little right of center */ - i[5] = 1; /* right boundary */ - -/* For center control points, pick black or white, whichever is closer to bg */ -/* Be carefult to pick just short of top or bottom else hue info is lost */ - - if (plsc->cmap0 != NULL) - vertex = ((PLFLT) plsc->cmap0[0].r + - (PLFLT) plsc->cmap0[0].g + - (PLFLT) plsc->cmap0[0].b) / 3. / 255.; - - if (vertex < 0.5) { - vertex = 0.01; - midpt = 0.10; - } else { - vertex = 0.99; - midpt = 0.90; - } - -/* Set hue */ - - h[0] = 260; /* low: blue-violet */ - h[1] = 260; /* only change as we go over vertex */ - h[2] = 260; /* only change as we go over vertex */ - h[3] = 0; /* high: red */ - h[4] = 0; /* high: red */ - h[5] = 0; /* keep fixed */ - -/* Set lightness */ - - l[0] = 0.5; /* low */ - l[1] = midpt; /* midpoint value */ - l[2] = vertex; /* bg */ - l[3] = vertex; /* bg */ - l[4] = midpt; /* midpoint value */ - l[5] = 0.5; /* high */ - -/* Set saturation -- keep at maximum */ - - s[0] = 1; - s[1] = 1; - s[2] = 1; - s[3] = 1; - s[4] = 1; - s[5] = 1; - - c_plscmap1l(0, 6, i, h, l, s, NULL); -} - -/*--------------------------------------------------------------------------*\ - * plscolor() - * - * Used to globally turn color output on/off -\*--------------------------------------------------------------------------*/ - -void -c_plscolor(PLINT color) -{ - plsc->colorset = 1; - plsc->color = color; -} - -/*--------------------------------------------------------------------------*\ - * plrgb() - * - * Set line color by red, green, blue from 0. to 1. - * Do NOT use this. Only retained for backward compatibility -\*--------------------------------------------------------------------------*/ - -void -c_plrgb(PLFLT r, PLFLT g, PLFLT b) -{ - if (plsc->level < 1) { - plabort("plrgb: Please call plinit first"); - return; - } - - plsc->icol0 = PL_RGB_COLOR; - plsc->curcolor.r = MAX(0, MIN(255, (int) (256. * r))); - plsc->curcolor.g = MAX(0, MIN(255, (int) (256. * g))); - plsc->curcolor.b = MAX(0, MIN(255, (int) (256. * b))); - - plsc->curcmap = 0; - plP_state(PLSTATE_COLOR0); -} - -/*--------------------------------------------------------------------------*\ - * plrgb1() - * - * Set line color by 8 bit RGB values. - * Do NOT use this. Only retained for backward compatibility -\*--------------------------------------------------------------------------*/ - -void -c_plrgb1(PLINT r, PLINT g, PLINT b) -{ - if (plsc->level < 1) { - plabort("plrgb1: Please call plinit first"); - return; - } - if ((r < 0 || r > 255) || (g < 0 || g > 255) || (b < 0 || b > 255)) { - plabort("plrgb1: Invalid color"); - return; - } - - plsc->icol0 = PL_RGB_COLOR; - plsc->curcolor.r = r; - plsc->curcolor.g = g; - plsc->curcolor.b = b; - - plsc->curcmap = 0; - plP_state(PLSTATE_COLOR0); -} - -/*--------------------------------------------------------------------------*\ - * void plhls() - * - * Set current color by hue, lightness, and saturation. - * Convert hls color coordinates to rgb, then call plrgb. - * Do NOT use this. Only retained for backward compatibility -\*--------------------------------------------------------------------------*/ - -void -c_plhls(PLFLT h, PLFLT l, PLFLT s) -{ - PLFLT r, g, b; - - plHLS_RGB(h, l, s, &r, &g, &b); - plrgb(r, g, b); -} - -/*--------------------------------------------------------------------------*\ - * void value() - * - * Auxiliary function used by plHLS_RGB(). -\*--------------------------------------------------------------------------*/ - -static PLFLT -value(double n1, double n2, double hue) -{ - PLFLT val; - - while (hue >= 360.) - hue -= 360.; - while (hue < 0.) - hue += 360.; - - if (hue < 60.) - val = n1 + (n2 - n1) * hue / 60.; - else if (hue < 180.) - val = n2; - else if (hue < 240.) - val = n1 + (n2 - n1) * (240. - hue) / 60.; - else - val = n1; - - return (val); -} - -/*--------------------------------------------------------------------------*\ - * void plHLS_RGB() - * - * Convert HLS color to RGB color. - * Bounds on HLS (input): - * hue [0., 360.] degrees - * lightness [0., 1.] magnitude - * saturation [0., 1.] magnitude - * - * Hue is always mapped onto the interval [0., 360.] regardless of input. - * Bounds on RGB (output) is always [0., 1.]. Convert to RGB color values - * by multiplying by 2**nbits (nbits typically 8). -\*--------------------------------------------------------------------------*/ - -void -plHLS_RGB(PLFLT h, PLFLT l, PLFLT s, PLFLT *p_r, PLFLT *p_g, PLFLT *p_b) -{ - PLFLT m1, m2; - - if (l <= .5) - m2 = l * (s + 1.); - else - m2 = l + s - l * s; - - m1 = 2 * l - m2; - - *p_r = value(m1, m2, h + 120.); - *p_g = value(m1, m2, h); - *p_b = value(m1, m2, h - 120.); -} - -/*--------------------------------------------------------------------------*\ - * void plRGB_HLS() - * - * Convert RGB color to HLS color. - * Bounds on RGB (input) is always [0., 1.]. - * Bounds on HLS (output): - * hue [0., 360.] degrees - * lightness [0., 1.] magnitude - * saturation [0., 1.] magnitude -\*--------------------------------------------------------------------------*/ - -void -plRGB_HLS(PLFLT r, PLFLT g, PLFLT b, PLFLT *p_h, PLFLT *p_l, PLFLT *p_s) -{ - PLFLT h, l, s, d, rc, gc, bc, rgb_min, rgb_max; - - rgb_min = MIN( r, MIN( g, b )); - rgb_max = MAX( r, MAX( g, b )); - - l = (rgb_min+rgb_max) / 2.0; - - if (rgb_min == rgb_max) { - s = 0; - h = 0; - } - else { - d = rgb_max - rgb_min; - if (l < 0.5) - s = 0.5 * d / l; - else - s = 0.5* d / (1.-l); - - rc = (rgb_max-r) / d; - gc = (rgb_max-g) / d; - bc = (rgb_max-b) / d; - - if (r == rgb_max) - h = bc-gc; - else if (g == rgb_max) - h = rc-bc+2; - else - h = gc-rc-2; - - h = h*60; - if (h < 0) - h = h+360; - else if (h >= 360) - h = h-360; - } - *p_h = h; - *p_l = l; - *p_s = s; -} - -/*--------------------------------------------------------------------------*\ - * A grab-bag of various control routines. -\*--------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------*\ - * void plwarn() - * - * A handy way to issue warnings, if need be. -\*--------------------------------------------------------------------------*/ - -void -plwarn(char *errormsg) -{ - int was_gfx = 0; - - if (plsc->graphx == 1) { - was_gfx = 1; - pltext(); - } - - fprintf(stderr, "\n*** PLPLOT WARNING ***\n"); - if (*errormsg != '\0') - fprintf(stderr, "%s\n", errormsg); - - if (was_gfx == 1) - plgra(); -} - -/*--------------------------------------------------------------------------*\ - * void plabort() - * - * Much the same as plwarn(), but appends ", aborting operation" to the - * error message. Helps to keep source code uncluttered and provides a - * convention for error aborts. -\*--------------------------------------------------------------------------*/ - -void -plabort(char *errormsg) -{ - if (plsc->errcode != NULL) - *(plsc->errcode) = 1; - - if (plsc->errmsg != NULL) { - sprintf(plsc->errmsg, "\n*** PLPLOT ERROR ***\n"); - if (*errormsg != '\0') - sprintf(plsc->errmsg, "%s, aborting operation\n", errormsg); - - } else { - int was_gfx = 0; - - if (plsc->graphx == 1) { - was_gfx = 1; - pltext(); - } - - fprintf(stderr, "\n*** PLPLOT ERROR ***\n"); - if (*errormsg != '\0') - fprintf(stderr, "%s, aborting operation\n", errormsg); - - if (was_gfx == 1) - plgra(); - } -} - -/*--------------------------------------------------------------------------*\ - * void plexit() - * - * In case of an abort this routine is called. It just prints out an error - * message and tries to clean up as much as possible. It's best to turn - * off pause and then restore previous setting before returning. - * - * If cleanup needs to be done in the main program, the user should write - * his/her own exit handler and pass it in via plsexit(). This function - * should should either call plend() before exiting, or simply return. -\*--------------------------------------------------------------------------*/ - -void -plexit(char *errormsg) -{ - int status = 1; - - if (exit_handler != NULL) - status = (*exit_handler)(errormsg); - - plsc->nopause = 1; - if (*errormsg != '\0') { - fprintf(stderr, "\n*** PLPLOT ERROR ***\n"); - fprintf(stderr, "%s\n", errormsg); - } - plend(); - - fprintf(stderr, "Program aborted\n"); - exit(status); -} - -/*--------------------------------------------------------------------------*\ - * void plsexit() - * - * Sets an optional user exit handler. -\*--------------------------------------------------------------------------*/ - -void -plsexit(int (*handler) (char *)) -{ - exit_handler = handler; -} - -/*--------------------------------------------------------------------------*\ - * void plgra() - * - * Switches to graphics screen. - * - * Here and in pltext() it's a good idea to return silently if plinit() - * hasn't yet been called, since plwarn() calls pltext() and plgra(), and - * plwarn() may be called at any time. -\*--------------------------------------------------------------------------*/ - -void -c_plgra(void) -{ - if (plsc->level > 0) - plP_esc(PLESC_GRAPH, NULL); -} - -void -c_plxormod(PLINT mode, PLINT *status) /* xor mode */ -{ - static int ostate = 0; - - if (!plsc->dev_xor) { - *status = 0; - return; - } - - if (plsc->level > 0) { - plP_esc(PLESC_XORMOD, &mode); - if (mode) { - ostate = plsc->plbuf_write; - plsc->plbuf_write = 0; - } else - plsc->plbuf_write = ostate; - } - *status = 1; -} - -/*--------------------------------------------------------------------------*\ - * void pltext() - * - * Switches to text screen. -\*--------------------------------------------------------------------------*/ - -void -c_pltext(void) -{ - if (plsc->level > 0) - plP_esc(PLESC_TEXT, NULL); -} - -/*--------------------------------------------------------------------------*\ - * void pl_cmd() - * - * Front-end to driver escape function. - * In principle this can be used to pass just about anything directly - * to the driver. -\*--------------------------------------------------------------------------*/ - -void -pl_cmd(PLINT op, void *ptr) -{ - plP_esc(op, ptr); -} - -/*--------------------------------------------------------------------------*\ - * char *plFindCommand - * - * Looks for the specified executable file. Search path: - * PLPLOT_BIN_ENV = $(PLPLOT_BIN) - * current directory - * PLPLOT_HOME_ENV/bin = $(PLPLOT_HOME)/bin - * BIN_DIR - * - * The caller must free the returned pointer (points to malloc'ed memory) - * when finished with it. -\*--------------------------------------------------------------------------*/ - -char * -plFindCommand(char *fn) -{ - char *fs = NULL, *dn; - -/* PLPLOT_BIN_ENV = $(PLPLOT_BIN) */ - -#if defined(PLPLOT_BIN_ENV) - if ((dn = getenv(PLPLOT_BIN_ENV)) != NULL) { - plGetName(dn, "", fn, &fs); - if ( ! plFindName(fs)) - return fs; - fprintf(stderr, PLPLOT_BIN_ENV"=\"%s\"\n", dn); /* what IS set? */ - } -#endif /* PLPLOT_BIN_ENV */ - -/* Current directory */ - - plGetName(".", "", fn, &fs); - if ( ! plFindName(fs)) - return fs; - -/* PLPLOT_HOME_ENV/bin = $(PLPLOT_HOME)/bin */ - -#if defined(PLPLOT_HOME_ENV) - if ((dn = getenv(PLPLOT_HOME_ENV)) != NULL) { - plGetName(dn, "bin", fn, &fs); - if ( ! plFindName(fs)) - return fs; - fprintf(stderr, PLPLOT_HOME_ENV"=\"%s\"\n",dn); /* what IS set? */ - } -#endif /* PLPLOT_HOME_ENV */ - -/* BIN_DIR */ - -#if defined (BIN_DIR) - plGetName(BIN_DIR, "", fn, &fs); - if ( ! plFindName(fs)) - return fs; -#endif - -/* Crapped out */ - - free_mem(fs); - fprintf(stderr, "plFindCommand: cannot locate command: %s\n", fn); -#if defined (BIN_DIR) - fprintf(stderr, "bin dir=\"" BIN_DIR "\"\n" ); /* what WAS set? */ -#endif /* BIN_DIR */ - return NULL; -} - -/*--------------------------------------------------------------------------*\ - * FILE *plLibOpen(fn) - * - * Return file pointer to lib file. - * Locations checked: - * PLPLOT_LIB_ENV = $(PLPLOT_LIB) - * current directory - * PLPLOT_HOME_ENV/lib = $(PLPLOT_HOME)/lib - * DATA_DIR - * PLLIBDEV -\*--------------------------------------------------------------------------*/ - -FILE * -plLibOpen(char *fn) -{ - FILE *ret = NULL; - - PDFstrm *pdfs = plLibOpenPdfstrm(fn); - if (pdfs == NULL) { - return NULL; - } - if (pdfs->file != NULL) { - ret = pdfs->file; - pdfs->file = NULL; - } - pdf_close(pdfs); - return ret; -} - -PDFstrm * -plLibOpenPdfstrm(char *fn) -{ - PDFstrm *file; - char *fs = NULL, *dn = NULL; - -/**** search PLPLOT_LIB_ENV = $(PLPLOT_LIB) ****/ - -#if defined(PLPLOT_LIB_ENV) - if ((dn = getenv(PLPLOT_LIB_ENV)) != NULL) { - plGetName(dn, "", fn, &fs); - - if ((file = pdf_fopen(fs, "rb")) != NULL) - goto done; - - fprintf(stderr, PLPLOT_LIB_ENV"=\"%s\"\n", dn); /* what IS set? */ - } -#endif /* PLPLOT_LIB_ENV */ - -/**** search current directory ****/ - - if ((file = pdf_fopen(fn, "rb")) != NULL) - goto done; - -/**** search PLPLOT_HOME_ENV/lib = $(PLPLOT_HOME)/lib ****/ - -#if defined (PLPLOT_HOME_ENV) - if ((dn = getenv(PLPLOT_HOME_ENV)) != NULL) { - plGetName(dn, "lib", fn, &fs); - - if ((file = pdf_fopen(fs, "rb")) != NULL) - goto done; - fprintf(stderr, PLPLOT_HOME_ENV"=\"%s\"\n",dn); /* what IS set? */ - } -#endif /* PLPLOT_HOME_ENV/lib */ - -/**** search installed location ****/ - -#if defined (DATA_DIR) - plGetName(DATA_DIR, "", fn, &fs); - - if ((file = pdf_fopen(fs, "rb")) != NULL) - goto done; -#endif /* DATA_DIR */ - -/**** search hardwired location ****/ - -#ifdef PLLIBDEV - plGetName(PLLIBDEV, "", fn, &fs); - - if ((file = pdf_fopen(fs, "rb")) != NULL) - goto done; -#endif /* PLLIBDEV */ - -#ifdef macintosh - file = plMacLibOpen(fn); - if (file != NULL) - goto done; -#endif /* macintosh */ - - if (plplotLibDir != NULL) { - plGetName(plplotLibDir, "", fn, &fs); - if ((file = pdf_fopen(fs, "rb")) != NULL) - goto done; - - } - -/**** not found, give up ****/ - - return NULL; - - done: - free_mem(fs); - return (file); -} - -/*--------------------------------------------------------------------------*\ - * int plFindName - * - * Authors: Paul Dubois (LLNL), others? - * This function is in the public domain. - * - * Given a pathname, determine if it is a symbolic link. If so, continue - * searching to the ultimate terminus - there may be more than one link. - * Use the error value to determine when the terminus is reached, and to - * determine if the pathname really exists. Then stat it to determine - * whether it's executable. Return 0 for an executable, errno otherwise. - * Note that 'p' _must_ have at least one '/' character - it does by - * construction in this program. The contents of the array pointed to by - * 'p' are changed to the actual pathname if findname is successful. - * - * This function is only defined under Unix for now. -\*--------------------------------------------------------------------------*/ - -#ifdef do_not_do // changed, this is unnessisary in this build anyway -int -plFindName(char *p) -{ - int n; - char buf[1024], *cp; - extern int errno; - struct stat sbuf; - - pldebug("plFindName", "Trying to find %s\n", p); - while ((n = readlink(p, buf, 1024)) > 0) { - pldebug("plFindName", "Readlink read %d chars at: %s\n", n, p); - if (buf[0] == '/') { - /* Link is an absolute path */ - - strncpy(p, buf, n); - p[n] = '\0'; - pldebug("plFindName", "Link is absolute: %s\n", p); - } - else { - /* Link is relative to its directory; make it absolute */ - - cp = 1 + strrchr(p, '/'); - strncpy(cp, buf, n); - cp[n] = '\0'; - pldebug("plFindName", - "Link is relative: %s\n\tTotal path:%s\n", cp, p); - } - } - -/* This macro not defined on the NEC SX-3 */ - -#ifdef SX -#define S_ISREG(mode) (mode & S_IFREG) -#endif - -/* SGI machines return ENXIO instead of EINVAL Dubois 11/92 */ - - if (errno == EINVAL || errno == ENXIO) { - pldebug("plFindName", "%s may be the one...\n", p); - if ((stat(p, &sbuf) == 0) && S_ISREG(sbuf.st_mode)) { - pldebug("plFindName", "%s is a regular file\n", p); - return (access(p, X_OK)); - } - } - pldebug("plFindName", "%s found but is not executable\n", p); - return (errno ? errno : -1); -} - -#else -int -plFindName(char *p) -{ - return 1; -} -#endif - -/*--------------------------------------------------------------------------*\ - * void plGetName() - * - * Gets search name for file by concatenating the dir, subdir, and file - * name, allocating memory as needed. The appropriate delimiter is added - * after the dir specification as necessary. The caller is responsible - * for freeing the malloc'ed memory. -\*--------------------------------------------------------------------------*/ - -void -plGetName(char *dir, char *subdir, char *filename, char **filespec) -{ - int lfilespec; - -/* Malloc space for filespec */ - - free_mem(*filespec); - lfilespec = 10; - lfilespec = strlen(dir) + strlen(subdir) + strlen(filename) + 10; - *filespec = (char *) malloc(lfilespec); - - strcpy(*filespec, dir); - - if (*subdir != '\0') { - strcat_delim(*filespec); - strcat(*filespec, subdir); - } - if (*filename != '\0') { - strcat_delim(*filespec); - strcat(*filespec, filename); - } -} - -/*--------------------------------------------------------------------------*\ - * void strcat_delim() - * - * Append path name deliminator if necessary (does not add one if one's - * there already, or if dealing with a colon-terminated device name). -\*--------------------------------------------------------------------------*/ - -static void -strcat_delim(char *dirspec) -{ - int ldirspec = strlen(dirspec); -#if defined (MSDOS) - if (dirspec[ldirspec-1] != '\\') - strcat(dirspec, "\\"); -#elif defined (macintosh) - if (dirspec[ldirspec-1] != ':') - strcat(dirspec, ":"); -#else /* unix is the default */ - if (dirspec[ldirspec-1] != '/') - strcat(dirspec, "/"); -#endif -} - -/*--------------------------------------------------------------------------*\ - * plcol_interp() - * - * Initializes device cmap 1 entry by interpolation from pls->cmap1 - * entries. Returned PLColor is supposed to represent the i_th color - * out of a total of ncol colors in the current color scheme. -\*--------------------------------------------------------------------------*/ - -void -plcol_interp(PLStream *pls, PLColor *newcolor, int i, int ncol) -{ - PLFLT x, delta; - int il, ir; - - x = (double) (i * (pls->ncol1-1)) / (double) (ncol-1); - il = x; - ir = il + 1; - delta = x - il; - - if (ir > pls->ncol1 || il < 0) - fprintf(stderr, "Invalid color\n"); - - else if (ir == pls->ncol1 || (delta == 0.)) { - newcolor->r = pls->cmap1[il].r; - newcolor->g = pls->cmap1[il].g; - newcolor->b = pls->cmap1[il].b; - } - else { - newcolor->r = (1.-delta) * pls->cmap1[il].r + delta * pls->cmap1[ir].r; - newcolor->g = (1.-delta) * pls->cmap1[il].g + delta * pls->cmap1[ir].g; - newcolor->b = (1.-delta) * pls->cmap1[il].b + delta * pls->cmap1[ir].b; - } -} - -/*--------------------------------------------------------------------------*\ - * plOpenFile() - * - * Opens file for output, prompting if not set. - * Prints extra newline at end to make output look better in batch runs. - * A file name of "-" indicates output to stdout. -\*--------------------------------------------------------------------------*/ - -#define MAX_NUM_TRIES 10 -void -plOpenFile(PLStream *pls) -{ - int i = 0, count = 0; - size_t len; - char line[256]; - - while (pls->OutFile == NULL) { - -/* Setting pls->FileName = NULL forces creation of a new family member */ -/* You should also free the memory associated with it if you do this */ - - if (pls->family && pls->BaseName != NULL) - plP_getmember(pls); - -/* Prompt if filename still not known */ - - if (pls->FileName == NULL) { - do { - fprintf(stdout, "Enter graphics output file name: "); - if (!fgets(line, sizeof(line), stdin)) { - return; - } - len = strlen(line); - if (len) - len--; - line[len] = '\0'; /* strip new-line */ - count++; /* count zero entries */ - } while (!len && count < MAX_NUM_TRIES); - plP_sfnam(pls, line); - } - -/* If name is "-", send to stdout */ - - if ( ! strcmp(pls->FileName, "-")) { - pls->OutFile = stdout; - pls->output_type = 1; - break; - } - -/* Need this here again, for prompted family initialization */ - - if (pls->family && pls->BaseName != NULL) - plP_getmember(pls); - - if (i++ > 10) - plexit("Too many tries."); - - if ((pls->OutFile = fopen(pls->FileName, "wb+")) == NULL) - fprintf(stdout, "Can't open %s.\n", pls->FileName); - else - { -// fprintf(stderr, "Opened %s\n", pls->FileName); -// this is not needed - } - } -} - -/*--------------------------------------------------------------------------*\ - * plP_getmember() - * - * Sets up next file member name (in pls->FileName), but does not open it. -\*--------------------------------------------------------------------------*/ - -void -plP_getmember(PLStream *pls) -{ - char tmp[256]; - - if (pls->FileName == NULL) - pls->FileName = (char *) malloc(10 + strlen(pls->BaseName)); - - sprintf(tmp, "%s.%%0%1ii", pls->BaseName, (int) pls->fflen); - sprintf(pls->FileName, tmp, pls->member); -} - -/*--------------------------------------------------------------------------*\ - * plP_sfnam() - * - * Sets up file name & family stem name. - * Reserve some extra space (5 chars) to hold an optional member number. -\*--------------------------------------------------------------------------*/ - -void -plP_sfnam(PLStream *pls, const char *fnam) -{ - pls->OutFile = NULL; - - if (pls->FileName != NULL) - free((void *) pls->FileName); - - pls->FileName = (char *) malloc(10 + strlen(fnam)); - - strcpy(pls->FileName, fnam); - - if (pls->BaseName != NULL) - free((void *) pls->BaseName); - - pls->BaseName = (char *) malloc(10 + strlen(fnam)); - - strcpy(pls->BaseName, fnam); -} - -/*--------------------------------------------------------------------------*\ - * plFamInit() - * - * Initializes family file parameters. -\*--------------------------------------------------------------------------*/ - -void -plFamInit(PLStream *pls) -{ - if (pls->family) { - pls->bytecnt = 0; - if ( ! pls->member) - pls->member = 1; - if ( ! pls->finc) - pls->finc = 1; - if ( ! pls->fflen) - pls->fflen = 1; - if ( ! pls->bytemax) - pls->bytemax = PL_FILESIZE_KB * 1000; - } -} - -/*--------------------------------------------------------------------------*\ - * plGetFam() - * - * Starts new member file of family file set if necessary. - * - * Note each member file is a complete graphics file (can be printed - * individually), although 'plrender' will treat a family as a single - * logical file if given the family name instead of the member name. -\*--------------------------------------------------------------------------*/ - -void -plGetFam(PLStream *pls) -{ - PLFLT xpmm_loc, ypmm_loc; - if (pls->family) { - if (pls->bytecnt > pls->bytemax || pls->famadv) { - plP_tidy(); - pls->member += pls->finc; - pls->famadv = 0; - plP_init(); - /* Apply compensating factor to original xpmm and ypmm so that - * character aspect ratio is preserved when overall aspect ratio - * is changed. */ - plP_gpixmm(&xpmm_loc, &ypmm_loc); - plP_setpxl(xpmm_loc*plsc->caspfactor, ypmm_loc/plsc->caspfactor); - return; - } - } -} - -/*--------------------------------------------------------------------------*\ - * plRotPhy() - * - * Rotates physical coordinates if necessary for given orientation. - * Each time orient is incremented, the plot is rotated 90 deg clockwise. - * Note: this is now used only to rotate by 90 degrees for devices that - * expect portrait mode. -\*--------------------------------------------------------------------------*/ - -void -plRotPhy(PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax, - int *px, int *py) -{ - int x, y; - - x = *px; - y = *py; - - switch (orient%4) { - - case 1: - *px = xmin + (y - ymin); - *py = ymin + (xmax - x); - break; - - case 2: - *px = xmin + (xmax - x); - *py = ymin + (ymax - y); - break; - - case 3: - *px = xmin + (ymax - y); - *py = ymin + (x - xmin); - break; - - default: - break; /* do nothing */ - } -} - -/*--------------------------------------------------------------------------*\ - * plAllocDev() - * - * Allocates a standard PLDev structure for device-specific data, stores - * the address in pls->dev, and returns the address as well. -\*--------------------------------------------------------------------------*/ - -PLDev * -plAllocDev(PLStream *pls) -{ - if (pls->dev != NULL) - free((void *) pls->dev); - - pls->dev = calloc(1, (size_t) sizeof(PLDev)); - if (pls->dev == NULL) - plexit("plAllocDev: cannot allocate memory\n"); - - return (PLDev *) pls->dev; -} - -/*--------------------------------------------------------------------------*\ - * plGinInit() - * - * Just fills in the PLGraphicsIn with appropriate initial values. -\*--------------------------------------------------------------------------*/ - -void -plGinInit(PLGraphicsIn *gin) -{ - gin->type = 0; - gin->state = 0; - gin->keysym = 0; - gin->button = 0; - gin->string[0] = '\0'; - gin->pX = gin->pY = -1; - gin->dX = gin->dY = 0.; - gin->wX = gin->wY = 0.; -} - -/*--------------------------------------------------------------------------*\ - * plGetInt() - * - * Prompts human to input an integer in response to given message. -\*--------------------------------------------------------------------------*/ - -PLINT -plGetInt(char *s) -{ - int m; - int i = 0; - char line[256]; - - while (i++ < 10) { - fprintf(stdout, "%s", s); - if (! (fgets(line, sizeof(line), stdin))) { - return 0; - } -#ifdef MSDOS - m = atoi(line); - return (m); -#else - if (sscanf(line, "%d", &m) == 1) - return (m); - fprintf(stdout, "No value or value out of range; please try again\n"); -#endif - } - plexit("Too many tries."); - return (0); -} - -/*--------------------------------------------------------------------------*\ - * plGetFlt() - * - * Prompts human to input a float in response to given message. -\*--------------------------------------------------------------------------*/ - -PLFLT -plGetFlt(char *s) -{ - PLFLT m; - double m1; - int i = 0; - char line[256]; - - while (i++ < 10) { - fprintf(stdout, "%s", s); - if (! (fgets(line, sizeof(line), stdin))) { - return (0.); - } -#ifdef MSDOS - m = atof(line); - return (m); -#else - if (sscanf(line, "%lf", &m1) == 1) { - m = (PLFLT) m1; - return (m); - } - fprintf(stdout, "No value or value out of range; please try again\n"); -#endif - } - plexit("Too many tries."); - return (0.); -} - -/*--------------------------------------------------------------------------*\ - * plstrdup() - * - * A replacement for strdup(), which isn't portable. - * Caller responsible for freeing the allocated memory. -\*--------------------------------------------------------------------------*/ - -char * -plstrdup(const char *src) -{ - char *dest = (char *) malloc( (strlen(src) + 1) * sizeof(char) ); - if (dest != NULL) - strcpy(dest, src); - else - plabort("Out of memory"); - - return dest; -} - diff --git a/src/plot/plplot/plcvt.c b/src/plot/plplot/plcvt.c deleted file mode 100644 index 9b99c453fd..0000000000 --- a/src/plot/plplot/plcvt.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $Id: plcvt.c,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - - Coordinate transformation routines. -*/ - -#include "plplotP.h" - -/*--------------------------------------------------------------------------*\ - * Transformations returning physical coordinates. -\*--------------------------------------------------------------------------*/ - -/* device coords to physical coords (x) */ - -PLINT -plP_dcpcx(PLFLT x) -{ - return (ROUND(plsc->phyxmi + plsc->phyxlen * x)); -} - -/* device coords to physical coords (y) */ - -PLINT -plP_dcpcy(PLFLT y) -{ - return (ROUND(plsc->phyymi + plsc->phyylen * y)); -} - -/* millimeters from bottom left-hand corner to physical coords (x) */ - -PLINT -plP_mmpcx(PLFLT x) -{ - return (ROUND(plsc->phyxmi + plsc->xpmm * x)); -} - -/* millimeters from bottom left-hand corner to physical coords (y) */ - -PLINT -plP_mmpcy(PLFLT y) -{ - return (ROUND(plsc->phyymi + plsc->ypmm * y)); -} - -/* world coords to physical coords (x) */ - -PLINT -plP_wcpcx(PLFLT x) -{ - return (ROUND(plsc->wpxoff + plsc->wpxscl * x)); -} - -/* world coords to physical coords (y) */ - -PLINT -plP_wcpcy(PLFLT y) -{ - return (ROUND(plsc->wpyoff + plsc->wpyscl * y)); -} - -/*--------------------------------------------------------------------------*\ - * Transformations returning device coordinates. -\*--------------------------------------------------------------------------*/ - -/* physical coords to device coords (x) */ - -PLFLT -plP_pcdcx(PLINT x) -{ - return (PLFLT) ((x - plsc->phyxmi) / (double) plsc->phyxlen); -} - -/* physical coords to device coords (y) */ - -PLFLT -plP_pcdcy(PLINT y) -{ - return (PLFLT) ((y - plsc->phyymi) / (double) plsc->phyylen); -} - -/* millimeters from bottom left corner to device coords (x) */ - -PLFLT -plP_mmdcx(PLFLT x) -{ - return ((PLFLT) (x * plsc->xpmm / ABS(plsc->phyxma - plsc->phyxmi))); -} - -/* millimeters from bottom left corner to device coords (y) */ - -PLFLT -plP_mmdcy(PLFLT y) -{ - return ((PLFLT) (y * plsc->ypmm / ABS(plsc->phyyma - plsc->phyymi))); -} - -/* world coords into device coords (x) */ - -PLFLT -plP_wcdcx(PLFLT x) -{ - return ((PLFLT) (plsc->wdxoff + plsc->wdxscl * x)); -} - -/* world coords into device coords (y) */ - -PLFLT -plP_wcdcy(PLFLT y) -{ - return ((PLFLT) (plsc->wdyoff + plsc->wdyscl * y)); -} - -/* subpage coords to device coords (x) */ - -PLFLT -plP_scdcx(PLFLT x) -{ - return ((PLFLT) (plsc->spdxmi + (plsc->spdxma - plsc->spdxmi) * x)); -} - -/* subpage coords to device coords (y) */ - -PLFLT -plP_scdcy(PLFLT y) -{ - return ((PLFLT) (plsc->spdymi + (plsc->spdyma - plsc->spdymi) * y)); -} - -/*--------------------------------------------------------------------------*\ - * Transformations returning millimeters. -\*--------------------------------------------------------------------------*/ - -/* device coords to millimeters from bottom left-hand corner (x) */ - -PLFLT -plP_dcmmx(PLFLT x) -{ - return ((PLFLT) (x * ABS(plsc->phyxma - plsc->phyxmi) / plsc->xpmm)); -} - -/* device coords to millimeters from bottom left-hand corner (y) */ - -PLFLT -plP_dcmmy(PLFLT y) -{ - return ((PLFLT) (y * ABS(plsc->phyyma - plsc->phyymi) / plsc->ypmm)); -} - -/* world coords into millimeters (x) */ - -PLFLT -plP_wcmmx(PLFLT x) -{ - return ((PLFLT) (plsc->wmxoff + plsc->wmxscl * x)); -} - -/* world coords into millimeters (y) */ - -PLFLT -plP_wcmmy(PLFLT y) -{ - return ((PLFLT) (plsc->wmyoff + plsc->wmyscl * y)); -} - -/*--------------------------------------------------------------------------*\ - * Transformations returning subpage coordinates. -\*--------------------------------------------------------------------------*/ - -/* device coords to subpage coords (x) */ - -PLFLT -plP_dcscx(PLFLT x) -{ - return ((PLFLT) ((x - plsc->spdxmi) / (plsc->spdxma - plsc->spdxmi))); -} - -/* device coords to subpage coords (y) */ - -PLFLT -plP_dcscy(PLFLT y) -{ - return ((PLFLT) ((y - plsc->spdymi) / (plsc->spdyma - plsc->spdymi))); -} - -/*--------------------------------------------------------------------------*\ - * 3-d plot transformations. -\*--------------------------------------------------------------------------*/ - -/* 3-d coords to 2-d projection (x) */ - -PLFLT -plP_w3wcx(PLFLT x, PLFLT y, PLFLT z) -{ - return ((PLFLT) ((x - plsc->basecx) * plsc->cxx + - (y - plsc->basecy) * plsc->cxy)); -} - -/* 3-d coords to 2-d projection (y) */ - -PLFLT -plP_w3wcy(PLFLT x, PLFLT y, PLFLT z) -{ - return ((PLFLT) ((x - plsc->basecx) * plsc->cyx + - (y - plsc->basecy) * plsc->cyy + - (z - plsc->ranmi) * plsc->cyz)); -} diff --git a/src/plot/plplot/pldebug.h b/src/plot/plplot/pldebug.h deleted file mode 100644 index f95b29d727..0000000000 --- a/src/plot/plplot/pldebug.h +++ /dev/null @@ -1,97 +0,0 @@ -/* $Id: pldebug.h,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - - Copyright (C) 1995 by Maurice J. LeBrun - - Debugging support for PLplot. - - This software may be freely copied, modified and redistributed without - fee provided that this copyright notice is preserved intact on all - copies and modified copies. - - There is no warranty or other guarantee of fitness of this software. - It is provided solely "as is". The author(s) disclaim(s) all - responsibility and liability with respect to this software's usage or - its effect upon hardware or computer systems. -*/ - -#ifndef __PLDEBUG_H__ -#define __PLDEBUG_H__ - -#include - -/* For the truly desperate debugging task */ - -#ifdef DEBUG_ENTER -#define dbug_enter(a) \ -if (plsc->debug) \ - fprintf(stderr, " entered %s (%s, line %d)\n", a, __FILE__, __LINE__); - -#else -#define dbug_enter(a) -#endif - -/* If we're using a debugging malloc, include the header file here */ - -#ifdef DEBUGGING_MALLOC -#include -#endif - -/*--------------------------------------------------------------------------*\ - * pldebug() - * - * Included into every plplot source file to control debugging output. To - * enable printing of debugging output, you must #define DEBUG before - * including plplotP.h or specify -DDEBUG in the compile line, for each file - * that you want to have debug output enabled. When running the program you - * must in addition specify -debug. This allows debugging output to tailored - * to many different circumstances but otherwise be fairly unobtrusive. - * - * Note, any file that actually uses pldebug() must also define NEED_PLDEBUG - * before the plplotP.h include. This is to eliminate warnings caused by - * those files in which this is defined but never referenced. All this could - * be much nicer if CPP had the abilities of m4, sigh.. - * - * Syntax: - * pldebug(label, format [, arg1, arg2, ...] ); - * - * The label is typically the calling function name. -\*--------------------------------------------------------------------------*/ - -#ifdef __GNUC__ -# define UNUSED __attribute__((unused)) -#else -# define UNUSED -#endif - -#ifdef NEED_PLDEBUG -UNUSED static void -pldebug( const char *label, ... ) -{ -#ifdef DEBUG - va_list args; - char *fmt; - - if (plsc->debug) { - if (plsc->termin) - c_pltext(); - va_start(args, label); - - /* print out identifying tag */ - - fprintf(stderr, "%s: ", label); - - /* print out remainder of message */ - /* Need to get fmt BEFORE it's used in the vfprintf */ - - fmt = (char *) va_arg(args, char *); - vfprintf(stderr, fmt, args); - - va_end(args); - if (plsc->termin) - c_plgra(); - } -#endif /* DEBUG */ -} -#endif /* NEED_PLDEBUG */ - -#endif /* __PLDEBUG_H__ */ diff --git a/src/plot/plplot/pldtik.c b/src/plot/plplot/pldtik.c deleted file mode 100644 index ff64ab944c..0000000000 --- a/src/plot/plplot/pldtik.c +++ /dev/null @@ -1,209 +0,0 @@ -/* $Id: pldtik.c,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - - Determines tick spacing and mode (fixed or floating) of - numeric axis labels. -*/ - -#include "plplotP.h" - -/*----------------------------------------------------------------------*\ - * void pldtik() - * - * Determine tick spacing: works out a "nice" interval (if tick == 0) such - * that there are between 3 and 7.5 major tick intervals in the input - * range vmin to vmax. The recommended number of subticks is returned in - * "nsubt" unless the routine is entered with a non-zero value of "nsubt". - * n.b. big change: now returns only positive values of tick and nsubt -\*----------------------------------------------------------------------*/ - -void -pldtik(PLFLT vmin, PLFLT vmax, PLFLT *tick, PLINT *nsubt) -{ - PLFLT t1, t2, tick_reasonable; - PLINT np, ns; - -/* Magnitude of min/max difference to get tick spacing */ - - t1 = (PLFLT) log10(ABS(vmax - vmin)); - np = (PLINT) floor(t1); - t1 = t1 - np; - -/* Get tick spacing. */ - - if (t1 > 0.7781512503) { - t2 = 2.0; - ns = 4; - } - else if (t1 > 0.4771212549) { - t2 = 1.0; - ns = 5; - } - else if (t1 > 0.1760912591) { - t2 = 5.0; - ns = 5; - np = np - 1; - } - else { - t2 = 2.0; - ns = 4; - np = np - 1; - } - -/* Now compute reasonable tick spacing */ - - tick_reasonable = t2 * pow(10.0, (double) np); - if (*tick == 0) { - *tick = t2 * pow(10.0, (double) np); - } - else { - *tick = ABS(*tick); - if(*tick < 1.e-4*tick_reasonable) { - plexit("pldtik: magnitude of specified tick spacing is much too small"); - return; - } - } - if (*nsubt == 0) - *nsubt = ns; - - *nsubt = ABS(*nsubt); -} - -/*----------------------------------------------------------------------*\ - * void pldprec() - * - * Determine precision: the output variable "mode" is set to 0 if labels - * are to be written in floating-point format, or to 1 if they are to be - * written in scientific format. For mode = 1, the exponent will be - * placed at: - * - * top left for vertical axis on left - * top right for vertical axis on right - * bottom right for horizontal axis - * - * The digmax flag can be set by the user, and represents the maximum - * number of digits a label may occupy including sign and decimal point. - * digmin, calculated internally, is the maximum number of digits - * labels at vmin and vmax would occupy if floating point. - * If digmax<0, it is disregarded, - * and if digmax=0 the default value is used. For digmax>0, mode=1 is - * chosen if there is insufficient room for the label within the specified - * # of digits (digmin > digfix, where digfix is determined from digmax with - * fuzz factors). - * - * In the case of mode=0, the actual # of digits will become too large - * when the magnitude of the labels become too large. The mode=1 case - * offers the greatest precision for the smallest field length. - * - * The determination of maximum length for fixed point quantities is - * complicated by the fact that very long fixed point representations look - * much worse than the same sized floating point representation. Further, - * a fixed point number with a large negative exponent will actually gain - * in precision when written as floating point. Thus we use certain fuzz - * factors to get 'digfix' from 'digmax', however it will always be true - * that digfix<=digmax. - * - * Finally, if 'digmax' is set, 'prec' is reduced in size if necessary so - * that the labels fit the requested field length, where prec is the number of - * places after the decimal place. -\*----------------------------------------------------------------------*/ - -#define MIN_FLTDIG 3 /* disregarded if fractional part is 0 */ -#define MAX_FIXDIG_POS 6 -#define MAX_FIXDIG_NEG 4 -#define DIGMAX_DEF 5 - -void -pldprec(PLFLT vmin, PLFLT vmax, PLFLT tick, PLINT lf, - PLINT *mode, PLINT *prec, PLINT digmax, PLINT *scale) -{ - PLFLT chosen, notchosen, vmod, t0; - PLINT msd, notmsd, np, digmin, digfix; - - *mode = 0; - *scale = 0; - - if (digmax == 0) - digmax = DIGMAX_DEF; - -/* Choose vmin or vmax depending on magnitudes of vmin and vmax. */ - chosen = (ABS(vmax) >= ABS(vmin))? vmax: vmin; - notchosen = (ABS(vmax) >= ABS(vmin))? vmin: vmax; -/* Magnitute of chosen to get number of significant digits */ - - if(ABS(chosen) > 0.) { - vmod = ABS(chosen); - t0 = (PLFLT) log10(vmod); - msd = (PLINT) floor(t0); - } - else { -/* this branch occurs only when 0. --- 0. range put in */ - vmod = 1.; - t0 = (PLFLT) log10(vmod); - msd = (PLINT) floor(t0); - } - - if(ABS(notchosen) > 0.) - notmsd = (PLINT) floor( (PLFLT) log10(ABS(notchosen))); - else - notmsd = msd; -/* Autoselect the mode flag */ -/* 'digmin' is the minimum number of places taken up by the label */ - - if (msd >= 0) { -/* n.b. no decimal point in the minimal case */ - digmin = msd + 1; - digfix = MAX_FIXDIG_POS; - if (digmax > 0) - digfix = MIN(digmax, MAX_FIXDIG_POS); - } - else { -/* adjust digmin to account for leading 0 and decimal point */ - digmin = -msd + 2; - digfix = MAX_FIXDIG_NEG; - if (digmax > 0) - digfix = MIN(digmax, MAX_FIXDIG_NEG); - } -/* adjust digmin to account for sign on the chosen end of axis or sign on the - * nonchosen end of axis if notmsd = msd or (msd <= 0 and notmsd < 0) - * For the latter case the notchosen label starts with "-0." - * For checking for the latter case, the notmsd < 0 condition is redundant - * since notmsd <= msd always and the equal part is selected by the first - * condition. - */ - if(chosen < 0.||(notchosen < 0. && (notmsd == msd || msd <= 0))) - digmin = digmin + 1; - - if (digmin > digfix && !lf) { - *mode = 1; - *scale = msd; - } - -/* Establish precision. */ -/* It must be fine enough to resolve the tick spacing */ - - np = (PLINT) floor(log10(ABS(tick))); - - if (*mode != 0) - *prec = msd - np; - else - *prec = MAX(-np, 0); - -/* One last hack required: if exponent < 0, i.e. number has leading '0.', - * it's better to change to floating point form if the number of digits - * is insufficient to represent the tick spacing. -*/ - if (*mode == 0 && digmax > 0 && !lf) { - if (t0 < 0.0) { - if (digmax - 2 - *prec < 0) { - *mode = 1; - *scale = msd; - } - } - else - *prec = MAX(MIN(*prec, digmax - msd - 1), 0); - } - if (*mode != 0) { - *prec = msd - np; - *prec = MAX(MIN(*prec, MAX(digmax-1, MIN_FLTDIG)), 0); - } -} diff --git a/src/plot/plplot/plevent.h b/src/plot/plplot/plevent.h deleted file mode 100644 index 6dba6c0ced..0000000000 --- a/src/plot/plplot/plevent.h +++ /dev/null @@ -1,205 +0,0 @@ -/* $Id: plevent.h,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - - Input event (especially keyboard) definitions for use from plplot - event handlers. - - Key definitions are taken from the X11/keysymdef.h include file, with - some changes: - - only the control keys are retained - - the XK prefix has been changed to PLK - - control keys with ASCII equivalents use the ASCII code - - By using the ASCII equivalent (if it exists) for all control keys, it - is easier to handle keyboard input from any device which is ASCII based. - Devices which use some other kind of key encoding must translate the raw - keycodes to those used here. -*/ - -#ifndef __PLEVENT_H__ -#define __PLEVENT_H__ - -/* Key definitions */ - -/*********************************************************** -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, -and the Massachusetts Institute of Technology, Cambridge, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Digital or MIT not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* Miscellaneous control keys, those with ASCII equivalents */ - -#define PLK_BackSpace 0x08 /* back space, back char */ -#define PLK_Tab 0x09 -#define PLK_Linefeed 0x0A /* Linefeed, LF */ -#define PLK_Return 0x0D /* Return, enter */ -#define PLK_Escape 0x1B -#define PLK_Delete 0xFF /* Delete, rubout */ - -/* Those without ASCII equivalents */ - -#define PLK_Clear 0xFF0B -#define PLK_Pause 0xFF13 /* Pause, hold */ -#define PLK_Scroll_Lock 0xFF14 - -/* Cursor control & motion */ - -#define PLK_Home 0xFF50 -#define PLK_Left 0xFF51 /* Move left, left arrow */ -#define PLK_Up 0xFF52 /* Move up, up arrow */ -#define PLK_Right 0xFF53 /* Move right, right arrow */ -#define PLK_Down 0xFF54 /* Move down, down arrow */ -#define PLK_Prior 0xFF55 /* Prior, previous (Page Up) */ -#define PLK_Next 0xFF56 /* Next (Page Down) */ -#define PLK_End 0xFF57 /* EOL */ -#define PLK_Begin 0xFF58 /* BOL */ - -/* Misc Functions */ - -#define PLK_Select 0xFF60 /* Select, mark */ -#define PLK_Print 0xFF61 -#define PLK_Execute 0xFF62 /* Execute, run, do */ -#define PLK_Insert 0xFF63 /* Insert, insert here */ -#define PLK_Undo 0xFF65 /* Undo, oops */ -#define PLK_Redo 0xFF66 /* redo, again */ -#define PLK_Menu 0xFF67 -#define PLK_Find 0xFF68 /* Find, search */ -#define PLK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ -#define PLK_Help 0xFF6A /* Help, ? */ -#define PLK_Break 0xFF6B -#define PLK_Mode_switch 0xFF7E /* Character set switch */ -#define PLK_script_switch 0xFF7E /* Alias for mode_switch */ -#define PLK_Num_Lock 0xFF7F - -/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ - -#define PLK_KP_Space 0xFF80 /* space */ -#define PLK_KP_Tab 0xFF89 -#define PLK_KP_Enter 0xFF8D /* enter */ -#define PLK_KP_F1 0xFF91 /* PF1, KP_A, ... */ -#define PLK_KP_F2 0xFF92 -#define PLK_KP_F3 0xFF93 -#define PLK_KP_F4 0xFF94 -#define PLK_KP_Equal 0xFFBD /* equals */ -#define PLK_KP_Multiply 0xFFAA -#define PLK_KP_Add 0xFFAB -#define PLK_KP_Separator 0xFFAC /* separator, often comma */ -#define PLK_KP_Subtract 0xFFAD -#define PLK_KP_Decimal 0xFFAE -#define PLK_KP_Divide 0xFFAF - -#define PLK_KP_0 0xFFB0 -#define PLK_KP_1 0xFFB1 -#define PLK_KP_2 0xFFB2 -#define PLK_KP_3 0xFFB3 -#define PLK_KP_4 0xFFB4 -#define PLK_KP_5 0xFFB5 -#define PLK_KP_6 0xFFB6 -#define PLK_KP_7 0xFFB7 -#define PLK_KP_8 0xFFB8 -#define PLK_KP_9 0xFFB9 - -/* - * Auxilliary Functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufactures have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - -#define PLK_F1 0xFFBE -#define PLK_F2 0xFFBF -#define PLK_F3 0xFFC0 -#define PLK_F4 0xFFC1 -#define PLK_F5 0xFFC2 -#define PLK_F6 0xFFC3 -#define PLK_F7 0xFFC4 -#define PLK_F8 0xFFC5 -#define PLK_F9 0xFFC6 -#define PLK_F10 0xFFC7 -#define PLK_F11 0xFFC8 -#define PLK_L1 0xFFC8 -#define PLK_F12 0xFFC9 -#define PLK_L2 0xFFC9 -#define PLK_F13 0xFFCA -#define PLK_L3 0xFFCA -#define PLK_F14 0xFFCB -#define PLK_L4 0xFFCB -#define PLK_F15 0xFFCC -#define PLK_L5 0xFFCC -#define PLK_F16 0xFFCD -#define PLK_L6 0xFFCD -#define PLK_F17 0xFFCE -#define PLK_L7 0xFFCE -#define PLK_F18 0xFFCF -#define PLK_L8 0xFFCF -#define PLK_F19 0xFFD0 -#define PLK_L9 0xFFD0 -#define PLK_F20 0xFFD1 -#define PLK_L10 0xFFD1 -#define PLK_F21 0xFFD2 -#define PLK_R1 0xFFD2 -#define PLK_F22 0xFFD3 -#define PLK_R2 0xFFD3 -#define PLK_F23 0xFFD4 -#define PLK_R3 0xFFD4 -#define PLK_F24 0xFFD5 -#define PLK_R4 0xFFD5 -#define PLK_F25 0xFFD6 -#define PLK_R5 0xFFD6 -#define PLK_F26 0xFFD7 -#define PLK_R6 0xFFD7 -#define PLK_F27 0xFFD8 -#define PLK_R7 0xFFD8 -#define PLK_F28 0xFFD9 -#define PLK_R8 0xFFD9 -#define PLK_F29 0xFFDA -#define PLK_R9 0xFFDA -#define PLK_F30 0xFFDB -#define PLK_R10 0xFFDB -#define PLK_F31 0xFFDC -#define PLK_R11 0xFFDC -#define PLK_F32 0xFFDD -#define PLK_R12 0xFFDD -#define PLK_R13 0xFFDE -#define PLK_F33 0xFFDE -#define PLK_F34 0xFFDF -#define PLK_R14 0xFFDF -#define PLK_F35 0xFFE0 -#define PLK_R15 0xFFE0 - -/* Modifiers */ - -#define PLK_Shift_L 0xFFE1 /* Left shift */ -#define PLK_Shift_R 0xFFE2 /* Right shift */ -#define PLK_Control_L 0xFFE3 /* Left control */ -#define PLK_Control_R 0xFFE4 /* Right control */ -#define PLK_Caps_Lock 0xFFE5 /* Caps lock */ -#define PLK_Shift_Lock 0xFFE6 /* Shift lock */ - -#define PLK_Meta_L 0xFFE7 /* Left meta */ -#define PLK_Meta_R 0xFFE8 /* Right meta */ -#define PLK_Alt_L 0xFFE9 /* Left alt */ -#define PLK_Alt_R 0xFFEA /* Right alt */ -#define PLK_Super_L 0xFFEB /* Left super */ -#define PLK_Super_R 0xFFEC /* Right super */ -#define PLK_Hyper_L 0xFFED /* Left hyper */ -#define PLK_Hyper_R 0xFFEE /* Right hyper */ - -#endif /* __PLEVENT_H__ */ diff --git a/src/plot/plplot/plfill.c b/src/plot/plplot/plfill.c deleted file mode 100644 index 351d4959b2..0000000000 --- a/src/plot/plplot/plfill.c +++ /dev/null @@ -1,341 +0,0 @@ -/* $Id: plfill.c,v 1.2 2005/03/17 21:39:21 eli Exp $ - - Polygon pattern fill. -*/ - -#include "plplotP.h" - -#define DTOR 0.0174533 -#define BINC 50 - -struct point { - PLINT x, y; -}; -static PLINT bufferleng, buffersize, *buffer; - -/* Static function prototypes */ -/* INDENT OFF */ - -static int compar (const void *, const void *); -static void addcoord (PLINT, PLINT); -static void tran (PLINT *, PLINT *, PLFLT, PLFLT); -static void buildlist (PLINT, PLINT, PLINT, PLINT, PLINT, PLINT, PLINT); - -/* INDENT ON */ - -/*----------------------------------------------------------------------*\ - * void plfill() - * - * Pattern fills the polygon bounded by the input points. - * If hardware fill is used, a maximum of PL_MAXPOLY-1 vertices is allowed. - * The final point is explicitly added if it doesn't match up to the first, - * to prevent clipping problems. -\*----------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plfill(PLINT n, PLFLT *x, PLFLT *y) -{ - PLINT xpoly[PL_MAXPOLY], ypoly[PL_MAXPOLY]; - PLINT i; - - if (plsc->level < 3) { - plabort("plfill: Please set up window first"); - return; - } - if (n < 3) { - plabort("plfill: Not enough points in object"); - return; - } - if (n > PL_MAXPOLY-1) { - plwarn("plfill: too many points in polygon"); - n = PL_MAXPOLY; - } - for (i = 0; i < n; i++) { - xpoly[i] = plP_wcpcx(x[i]); - ypoly[i] = plP_wcpcy(y[i]); - } - - if (x[0] != x[n-1] || y[0] != y[n-1]) { - n++; - xpoly[n-1] = plP_wcpcx(x[0]); - ypoly[n-1] = plP_wcpcy(y[0]); - } - - plP_plfclp(xpoly, ypoly, n, plsc->clpxmi, plsc->clpxma, - plsc->clpymi, plsc->clpyma, plP_fill); -} - -/*----------------------------------------------------------------------*\ - * void plfill3() - * - * Pattern fills the polygon in 3d bounded by the input points. - * If hardware fill is used, a maximum of PL_MAXPOLY-1 vertices is allowed. - * The final point is explicitly added if it doesn't match up to the first, - * to prevent clipping problems. -\*----------------------------------------------------------------------*/ - -void -c_plfill3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z) -{ - PLFLT tx[PL_MAXPOLY], ty[PL_MAXPOLY], tz[PL_MAXPOLY]; - PLFLT *V[3]; - PLINT xpoly[PL_MAXPOLY], ypoly[PL_MAXPOLY]; - PLINT i; - PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale; - - if (plsc->level < 3) { - plabort("plfill3: Please set up window first"); - return; - } - if (n < 3) { - plabort("plfill3: Not enough points in object"); - return; - } - if (n > PL_MAXPOLY-1) { - plwarn("plfill3: too many points in polygon"); - n = PL_MAXPOLY; - } - - plP_gdom(&xmin, &xmax, &ymin, &ymax); - plP_grange(&zscale, &zmin, &zmax); - - /* copy the vertices so we can clip without corrupting the input */ - for( i=0; i < n; i++ ) { - tx[i] = x[i]; ty[i] = y[i]; tz[i] = z[i]; - } - if (tx[0] != tx[n-1] || ty[0] != ty[n-1] || tz[0] != tz[n-1]) { - tx[n] = tx[0]; ty[n] = ty[0]; tz[n] = tz[0]; - n++; - } - V[0] = tx; V[1] = ty; V[2] = tz; - n = plP_clip_poly(n, V, 0, 1, -xmin); - n = plP_clip_poly(n, V, 0, -1, xmax); - n = plP_clip_poly(n, V, 1, 1, -ymin); - n = plP_clip_poly(n, V, 1, -1, ymax); - n = plP_clip_poly(n, V, 2, 1, -zmin); - n = plP_clip_poly(n, V, 2, -1, zmax); - for( i=0; i < n; i++ ) { - xpoly[i] = plP_wcpcx(plP_w3wcx( tx[i], ty[i], tz[i] )); - ypoly[i] = plP_wcpcy(plP_w3wcy( tx[i], ty[i], tz[i] )); - } - -/* AWI: in the past we have used - * plP_fill(xpoly, ypoly, n); - * here, but our educated guess is this fill should be done via the clipping - * interface instead as below. - * No example tests this code so one of our users will end up inadvertently - * testing this for us. - * - * jc: I have checked, and both versions does give the same result, i.e., clipping - * to the window boundaries. The reason is that the above plP_clip_poly() does - * the clipping. To check this, is enough to diminish the x/y/z min/max arguments in - * plw3d() in x08c. But let's keep it, although 10% slower... - */ - plP_plfclp(xpoly, ypoly, n, plsc->clpxmi, plsc->clpxma, - plsc->clpymi, plsc->clpyma, plP_fill); -} - -/*----------------------------------------------------------------------*\ - * void plfill_soft() - * - * Pattern fills in software the polygon bounded by the input points. -\*----------------------------------------------------------------------*/ - -void -plfill_soft(short *x, short *y, PLINT n) -{ - PLINT i, j; - PLINT xp1, yp1, xp2, yp2, xp3, yp3; - PLINT k, dinc; - PLFLT ci, si; - double temp; - - buffersize = 2 * BINC; - buffer = (PLINT *) malloc((size_t) buffersize * sizeof(PLINT)); - if ( ! buffer) { - plabort("plfill: Out of memory"); - return; - } - -/* Loop over sets of lines in pattern */ - - for (k = 0; k < plsc->nps; k++) { - bufferleng = 0; - - temp = DTOR * plsc->inclin[k] * 0.1; - si = sin(temp) * plsc->ypmm; - ci = cos(temp) * plsc->xpmm; - - /* normalize: 1 = si*si + ci*ci */ - - temp = sqrt((double) (si*si + ci*ci)); - si /= temp; - ci /= temp; - - dinc = plsc->delta[k] * SSQR(plsc->ypmm * ABS(ci), - plsc->xpmm * ABS(si)) / 1000.; - - if (dinc < 0) dinc = -dinc; - if (dinc == 0) dinc = 1; - - xp1 = x[n-2]; - yp1 = y[n-2]; - tran(&xp1, &yp1, (PLFLT) ci, (PLFLT) si); - - xp2 = x[n-1]; - yp2 = y[n-1]; - tran(&xp2, &yp2, (PLFLT) ci, (PLFLT) si); - -/* Loop over points in polygon */ - - for (i = 0; i < n; i++) { - xp3 = x[i]; - yp3 = y[i]; - tran(&xp3, &yp3, (PLFLT) ci, (PLFLT) si); - buildlist(xp1, yp1, xp2, yp2, xp3, yp3, dinc); - xp1 = xp2; - yp1 = yp2; - xp2 = xp3; - yp2 = yp3; - } - -/* Sort list by y then x */ - - qsort((void *) buffer, (size_t) bufferleng / 2, - (size_t) sizeof(struct point), compar); - -/* OK, now do the hatching */ - - i = 0; - - while (i < bufferleng) { - xp1 = buffer[i]; - yp1 = buffer[i + 1]; - i += 2; - xp2 = xp1; - yp2 = yp1; - tran(&xp1, &yp1, (PLFLT) ci, (PLFLT) (-si)); - plP_movphy(xp1, yp1); - xp1 = buffer[i]; - yp1 = buffer[i + 1]; - i += 2; - if (yp2 != yp1) { - fprintf(stderr, "plfill: oh oh we are lost\n"); - for (j = 0; j < bufferleng; j+=2) { - fprintf(stderr, "plfill: %d %d\n", - (int) buffer[j], (int) buffer[j+1]); - } - continue; /* Uh oh we're lost */ - } - tran(&xp1, &yp1, (PLFLT) ci, (PLFLT) (-si)); - plP_draphy(xp1, yp1); - } - } - free((void *) buffer); -} - -/*----------------------------------------------------------------------*\ - * Utility functions -\*----------------------------------------------------------------------*/ - -static void -tran(PLINT *a, PLINT *b, PLFLT c, PLFLT d) -{ - PLINT ta, tb; - - ta = *a; - tb = *b; - - *a = floor((double) (ta * c + tb * d + 0.5)); - *b = floor((double) (tb * c - ta * d + 0.5)); -} - -static void -buildlist(PLINT xp1, PLINT yp1, PLINT xp2, PLINT yp2, PLINT xp3, PLINT yp3, - PLINT dinc) -{ - PLINT min_y, max_y; - PLINT dx, dy, cstep, nstep, ploty, plotx; - - dx = xp2 - xp1; - dy = yp2 - yp1; - - if (dy == 0) { - if (yp2 > yp3 && ((yp2 % dinc) == 0)) - addcoord(xp2, yp2); - return; - } - - if (dy > 0) { - cstep = 1; - min_y = yp1; - max_y = yp2; - } - else { - cstep = -1; - min_y = yp2; - max_y = yp1; - } - - nstep = (yp3 > yp2 ? 1 : -1); - if (yp3 == yp2) nstep = 0; - - /* Build coordinate list */ - - ploty = (min_y / dinc) * dinc; - if (ploty < min_y) ploty += dinc; - - for (; ploty <= max_y; ploty += dinc) { - if (ploty == yp1) continue; - if (ploty == yp2) { - if (cstep == -nstep) continue; - if (yp2 == yp3 && yp1 > yp2) continue; - } - plotx = xp1 + floor(((double) (ploty - yp1) * dx) / dy + 0.5); - addcoord(plotx, ploty); - } -} - -static void -addcoord(PLINT xp1, PLINT yp1) -{ - PLINT *temp; - - if (bufferleng + 2 > buffersize) { - buffersize += 2 * BINC; - temp = (PLINT *) realloc((void *) buffer, - (size_t) buffersize * sizeof(PLINT)); - if (!temp) { - free((void *) buffer); - plexit("plfill: Out of memory!"); - } - buffer = temp; - } - - buffer[bufferleng++] = xp1; - buffer[bufferleng++] = yp1; -} - -static int -compar(const void *pnum1, const void *pnum2) -{ - const struct point *pnt1, *pnt2; - - pnt1 = (const struct point *) pnum1; - pnt2 = (const struct point *) pnum2; - - if (pnt1->y < pnt2->y) - return -1; - else if (pnt1->y > pnt2->y) - return 1; - - /* Only reach here if y coords are equal, so sort by x */ - - if (pnt1->x < pnt2->x) - return -1; - else if (pnt1->x > pnt2->x) - return 1; - - return 0; -} diff --git a/src/plot/plplot/plfreetype.h b/src/plot/plplot/plfreetype.h deleted file mode 100644 index 15dfc8768b..0000000000 --- a/src/plot/plplot/plfreetype.h +++ /dev/null @@ -1,126 +0,0 @@ -/* $Id: plfreetype.h,v 1.1 2004/03/01 20:54:51 cozmic Exp $ - * - * Header file for Support routines for freetype font engine - * - * See plfreetype.c for more details - */ - -#ifndef __PLFREETY_H__ -#define __PLFREETY_H__ - -#ifdef HAVE_FREETYPE - -#include -#include FT_FREETYPE_H -#include FT_GLYPH_H -#include FT_OUTLINE_H - -#define FT_Data _FT_Data_ - -typedef void (*plD_pixel_fp) (PLStream *, PLINT, PLINT); - -/*--------------------------------------------------------------------------*\ - * Define the FT_Data data structure. - * - * These are the "globalish" variables used by Freetype - * They are kept here so they are moderately thread safe, and stream specific -\*--------------------------------------------------------------------------*/ - -typedef struct FT_Data { - short x; - short y; - - char *textbuf; /* temporary string buffer */ - - PLFLT scale; -/* - * If set to 1, scale won't do anything, but this is an "arbitrary" scale - * factor for the transformation between virtual and real coordinates. This - * is included to fix up the problem with the "hidden line removal bug" of - * the 3D plots, which is fixed by providing a super-scaled image. This - * should be a mirror, for example, of dev->scale in the PNG driver. If I - * was thinking 12 months ahead, I would have put that scale factor in - * "pls", not "dev", but at this late stage, we can just live with it - * now... - */ - - unsigned char greek; - - unsigned char invert_y; -/* - * Set "invert_y" to 1 if the y coordinates need to be inverted for - * plotting. Most bitmaps will need this. - */ - - short ymax; -/* - * ymax should be equal to, what it says - the maximum y coordinate of the - * bitmap. This is used in the process of calculating the inversion of the - * bitmap when invert_y is set to 1. If invert_y isn't set, this setting is - * ignored. - */ - - - plD_pixel_fp pixel; /* pointer to a function which draws a single pixel */ - - - int want_smooth_text; /* flag to request text smoothing (won't */ - /* necessarily get it though */ - int smooth_text; /* Flag to indicate type of anti-aliasing used, if freetype text is active */ - - - char font_name[5][1024]; -/* - * List of font names and paths corresponding to the "predefined" fonts of - * plplot. 1024 chars is presumably generous for each one's length, but at - * least we probably won't get in trouble this way. - */ - - - PLINT cfont; -/* - * This is a mirror of pls->cfont and is basically used for detecting when - * fonts have been changed . - */ - - - FT_Matrix matrix; /* used for rotating etc... the font. */ - FT_Vector pos; /* used for calculating offsets of text boxes/sizes */ - - -/* - * The next few variables hold the original size of CMAP0, the number of - * extra slots added for anti-aliasing, and the "width" of the table used - * for anti-aliasing. - */ - - PLINT ncol0_org; /* Original number of colours in CMAP0 */ - PLINT ncol0_xtra; /* number of extra colours defined in CMAP0 for anti-aliasing */ - PLINT ncol0_width; /* Number of greyscale levels for each of the original colours */ - PLINT last_icol0; /* Last colour in cmap0, which should be one of the originals */ - - -/* - * The rest of the variables should be considered very much PRIVATE, and - * more to the point, subject to change. - * - * Don't rely on them existing in future versions of plplot's freetype - * support. If/when the Freetype cache manager is added to plplot, most, if - * not all, of these variables will move elsewhere. - */ - - FT_Library library; /* pointer to freetype library */ - FT_Face face; /* pointer to a font face */ - FT_GlyphSlot slot; /* pointer to a glyph slot */ - FT_Glyph image; /* bitmap or outline image of font */ - - short colour; /* depreciated ?? must check code */ - - PLINT shade, col_idx; /* Used for antialiasing */ - -} FT_Data; - -#endif - - -#endif /* __PLFREETY_H__ */ diff --git a/src/plot/plplot/plgridd.c b/src/plot/plplot/plgridd.c deleted file mode 100644 index 70ad348bd4..0000000000 --- a/src/plot/plplot/plgridd.c +++ /dev/null @@ -1,843 +0,0 @@ - -#include "plplotP.h" - -#ifdef WITH_CSA -#include "csa.h" -#endif -#include "nan.h" /* this is handy */ - -#ifdef HAVE_QHULL -#include "../lib/nn/nn.h" -#include -#endif - -#if !defined(HAVE_ISNAN) && !defined(isnan) -#define isnan(x) ((x) != (x)) -#endif - -/* forward declarations */ -static void -grid_nnaidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg); - -static void -grid_nnli (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg, - PLFLT threshold); - -static void -grid_nnidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg, - int knn_order); - -#ifdef WITH_CSA -static void -grid_csa (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg); -#endif - -#ifdef HAVE_QHULL -static void -grid_nni (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg, - PLFLT wmin); - -static void -grid_dtli (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg); -#endif - -static void -dist1(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts, int knn_order); -static void -dist2(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts); - -#define KNN_MAX_ORDER 100 - -typedef struct pt{ - PLFLT dist; - int item; -}PT; - -static PT items[KNN_MAX_ORDER]; - -/*----------------------------------------------------------------------*\ - * - * plgriddata(): grids data from irregularly sampled data. - * - * Real world data is frequently irregularly sampled, but most 3D plots - * require regularly gridded data. This function does exactly this - * using several methods: - * Irregularly sampled data x[npts], y[npts], z[npts] is gridded into - * zg[nptsx, nptsy] according to methode 'type' and grid information - * xg[nptsx], yg[nptsy]. - * - * 'type' can be: - * - * GRID_CSA: Bivariate Cubic Spline approximation (1) - * GRID_NNIDW: Nearest Neighbors Inverse Distance Weighted - * GRID_NNLI: Nearest Neighbors Linear Interpolation - * GRID_NNAIDW: Nearest Neighbors Around Inverse Distance Weighted - * GRID_DTLI: Delaunay Triangulation Linear Interpolation (2) - * GRID_NNI: Natural Neighbors interpolation (2) - * - * (1): Copyright 2000-2002 CSIRO Marine Research, Pavel Sakov's csa library - * (2): Copyright 2002 CSIRO Marine Research, Pavel Sakov's nn library - * -\*----------------------------------------------------------------------*/ - -void -c_plgriddata(PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, - PLFLT **zg, int type, PLFLT data) -{ - int i, j; - - if(npts < 1 || nptsx < 1 || nptsy < 1) { - plabort("plgriddata: Bad array dimensions"); - return; - } - - /* Check that points in xg and in yg are strictly increasing */ - - for (i = 0; i < nptsx - 1; i++) { - if (xg[i] >= xg[i + 1]) { - plabort("plgriddata: xg array must be strictly increasing"); - return; - } - } - for (i = 0; i < nptsy - 1; i++) { - if (yg[i] >= yg[i + 1]) { - plabort("plgriddata: yg array must be strictly increasing"); - return; - } - } - - /* clear array to return */ - for(i=0; ix = (double) *xt++; - pt->y = (double) *yt++; - pt->z = (double) *zt++; - pt++; - } - - nptsg = nptsx * nptsy; - pgrid = (point *) malloc(nptsg * sizeof(point)); - - yt = yg; pt = pgrid; - for(j=0; jx = (double) *xt++; - pt->y = (double) *yt; - pt++; - } - yt++; - } - - a = csa_create(); - csa_addpoints(a, npts, pin); - csa_calculatespline(a); - csa_approximate_points(a, nptsg, pgrid); - - for(i=0; iz; - } - } - - csa_destroy(a); - free(pin); - free(pgrid); -} -#endif /* WITH_CSA */ - -/* Nearest Neighbors Inverse Distance Weighted, brute force approach. - * - * The z value at the grid position will be the weighted average - * of the z values of the KNN points found. The weigth is the - * inverse squared distance between the grid point and each - * neighbor. - */ - -static void -grid_nnidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg, - int knn_order) -{ - int i, j, k; - PLFLT wi, nt; - - if (knn_order > KNN_MAX_ORDER) { - plabort("plgriddata(): GRID_NNIDW: knn_order too big"); /* make sure it is smaller that KNN_MAX_ORDER */ - return; - } - - if (knn_order == 0) { - plwarn("plgriddata(): GRID_NNIDW: knn_order must be specified with 'data' arg. Using 15"); - knn_order = 15;; - } - - for (i=0; i md) - md = items[k].dist; -#endif - zg[i][j] = 0.; - nt = 0.; - - for (k=0; k 2. || threshold < 1.) { - plabort("plgriddata(): GRID_NNLI: 1. < threshold < 2."); - return; - } - - for (i=0; i d2) { - t = d1; d1 = d2; d2 = t; - } - - /* and d2 < d3 */ - if (d2 > d3) { - t = d2; d2 = d3; d3 = t; - } - - if ((d1+d2)/d3 < threshold) { /* thin triangle! */ - zg[i][j] = NaN; /* deal with it latter */ - } else { /* calculate the plane passing through the three points */ - - A = yy[0]*(zz[1]-zz[2]) + yy[1]*(zz[2]-zz[0]) + yy[2]*(zz[0]-zz[1]); - B = zz[0]*(xx[1]-xx[2]) + zz[1]*(xx[2]-xx[0]) + zz[2]*(xx[0]-xx[1]); - C = xx[0]*(yy[1]-yy[2]) + xx[1]*(yy[2]-yy[0]) + xx[2]*(yy[0]-yy[1]); - D = - A*xx[0] - B*yy[0] - C*zz[0]; - - /* and interpolate (or extrapolate...) */ - zg[i][j] = - xg[i]*A/C - yg[j]*B/C - D/C; - } - } - } - - /* now deal with NaNs resulting from thin triangles. The idea is - * to use the 4 KNN points and exclude one at a time, creating - * four triangles, evaluating their thickness and choosing the - * most thick as the final one from where the interpolating - * plane will be build. Now that I'm talking of interpolating, - * one should really check that the target point is interior to - * the candidate triangle... otherwise one is extrapolating - */ - - { - for (i=0; i0; ii--) { - for (jj=0; jj items[jj+1].dist) { - t = items[jj].dist; - items[jj].dist = items[jj+1].dist; - items[jj+1].dist = t; - } - } - } - */ - - max_thick = 0.; excl_item = -1; - for (excl=0; excl<4; excl++) { /* the excluded point */ - - cnt = 0; - for (ii=0; ii<4; ii++) { - if (ii != excl) { - xx[cnt] = x[items[ii].item]; - yy[cnt] = y[items[ii].item]; - cnt++; - } - } - - d1 = sqrt((xx[1]-xx[0])*(xx[1]-xx[0]) + (yy[1]-yy[0])*(yy[1]-yy[0])); - d2 = sqrt((xx[2]-xx[1])*(xx[2]-xx[1]) + (yy[2]-yy[1])*(yy[2]-yy[1])); - d3 = sqrt((xx[0]-xx[2])*(xx[0]-xx[2]) + (yy[0]-yy[2])*(yy[0]-yy[2])); - if (d1 == 0. || d2 == 0. || d3 == 0.) /* coincident points */ continue; - - /* make d1 < d2 */ - if (d1 > d2) { - t = d1; d1 = d2; d2 = t; - } - /* and d2 < d3 */ - if (d2 > d3) { - t = d2; d2 = d3; d3 = t; - } - - t = (d1+d2)/d3; - if ( t > max_thick) { - max_thick = t; - excl_item = excl; - } - } - - if (excl_item == -1) /* all points are coincident? */ - continue; - - /* one has the thicker triangle constructed from the 4 KNN */ - cnt = 0; - for (ii=0; ii<4; ii++) { - if (ii != excl_item) { - xx[cnt] = x[items[ii].item]; - yy[cnt] = y[items[ii].item]; - zz[cnt] = z[items[ii].item]; - cnt++; - } - } - - A = yy[0]*(zz[1]-zz[2]) + yy[1]*(zz[2]-zz[0]) + yy[2]*(zz[0]-zz[1]); - B = zz[0]*(xx[1]-xx[2]) + zz[1]*(xx[2]-xx[0]) + zz[2]*(xx[0]-xx[1]); - C = xx[0]*(yy[1]-yy[2]) + xx[1]*(yy[2]-yy[0]) + xx[2]*(yy[0]-yy[1]); - D = - A*xx[0] - B*yy[0] - C*zz[0]; - - /* and interpolate (or extrapolate...) */ - zg[i][j] = - xg[i]*A/C - yg[j]*B/C - D/C; - - } - } - } - } -} - -/* - * Nearest Neighbors "Around" Inverse Distance Weighted, brute force approach. - * - * This uses the 1-KNN in each quadrant around the grid point, then - * Inverse Distance Weighted is used as in GRID_NNIDW. - */ - -static void -grid_nnaidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg) -{ - PLFLT d, nt; - int i, j, k; - - for (i=0; ix = (double) *xt++; - pt->y = (double) *yt++; - pt->z = (double) *zt++; - pt++; - } - - nptsg = nptsx * nptsy; - pgrid = (point *) malloc(nptsg * sizeof(point)); - - yt = yg; pt = pgrid; - for(j=0; jx = (double) *xt++; - pt->y = (double) *yt; - pt++; - } - yt++; - } - - lpi_interpolate_points(npts, pin, nptsg, pgrid); - for(i=0; iz; - } - } - - free(pin); - free(pgrid); -} - -/* - * Natural Neighbors using Pavel Sakov's nn package - * - * Points exterior to the convex hull of the data points cannot - * be interpolated and are set to NaN. - */ - -static void -grid_nni (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg, - PLFLT wmin) -{ - PLFLT *xt, *yt, *zt; - point *pin, *pgrid, *pt; - int i, j, nptsg; - nn_algorithm = NON_SIBSONIAN; - - if (sizeof(realT) != sizeof(double)) { - plabort("plgridata: QHull was compiled for floats instead of doubles"); - return; - } - - if (wmin == 0.) {/* only accept weights greater than wmin */ - plwarn("plgriddata(): GRID_NNI: wmin must be specified with 'data' arg. Using -PLFLT_MAX"); - wmin = -PLFLT_MAX; - } - - pin = (point *) malloc(npts * sizeof(point)); - - xt = x; yt = y; zt = z; pt = pin; - for(i=0; ix = (double) *xt++; - pt->y = (double) *yt++; - pt->z = (double) *zt++; - pt++; - } - - nptsg = nptsx * nptsy; - pgrid = (point *) malloc(nptsg * sizeof(point)); - - yt = yg; pt = pgrid; - for(j=0; jx = (double) *xt++; - pt->y = (double) *yt; - pt++; - } - yt++; - } - - nnpi_interpolate_points(npts, pin, wmin, nptsg, pgrid); - for(i=0; iz; - } - } - - free(pin); - free(pgrid); -} -#endif /* HAVE_QHULL*/ - -/* - * this function just calculates the K Nearest Neighbors of grid point - * [gx, gy]. - */ - -static void -dist1(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts, int knn_order) -{ - - PLFLT d, max_dist; - int max_slot, i, j; - - max_dist = PLFLT_MAX; - max_slot = 0; - - for (i=0; i max_dist) { - max_dist = items[j].dist; - max_slot = j; - } - } - } - } - for (j=0; j2, 2->0, 3->1, 4->3, but that is not important, - * speed is. */ - - quad = 2*(x[i] > gx) + (y[i] < gy); - - /* try to use the octants around the grid point, as it will give smoother - * (and slower) results. - * Hint: use the quadrant info plus x[i]/y[i] to determine the octant */ - - if (d < items[quad].dist) { - items[quad].dist = d; - items[quad].item = i; - } - } - - for (i=0; i<4; i++) - if (items[i].item != -1) - items[i].dist = sqrt(items[i].dist); /* now calculate the distance */ -} - -#ifdef NONN /* another DTLI, based only on QHULL, not nn */ -static void -grid_adtli (PLFLT *x, PLFLT *y, PLFLT *z, int npts, - PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg) -{ - coordT *points; /* array of coordinates for each point */ - boolT ismalloc = False; /* True if qhull should free points */ - char flags[250]; /* option flags for qhull */ - facetT *facet; /* set by FORALLfacets */ - vertexT *vertex, **vertexp; - facetT *neighbor,**neighborp; - int curlong, totlong; /* memory remaining after qh_memfreeshort */ - FILE *outfile = NULL; - FILE *errfile = stderr; /* error messages from qhull code */ - - int exitcode; - int i, j, k, l; - int dim = 2; - PLFLT xt[3], yt[3], zt[3]; - PLFLT A, B, C, D; - coordT point[3]; - boolT isoutside; - realT bestdist; - int totpart=0; - int numfacets, numsimplicial, numridges; - int totneighbors, numcoplanars, numtricoplanars; - - plwarn("plgriddata: GRID_DTLI, If you have QHull knowledge, FIXME."); - - /* Could pass extra args to qhull through the 'data' argument of - plgriddata() */ - sprintf(flags, "qhull d Qbb Qt"); - points = (coordT *) malloc(npts * (dim+1) * sizeof(coordT)); - - for (i=0; iupperdelaunay) { - FOREACHvertex_(facet->vertices) - printf (" %d", qh_pointid (vertex->point)); /* vertices index */ - printf ("\n"); - } - } -#endif - -#if 0 /* print each triangle neighbors */ - printf("Neigbors\n"); - - qh_findgood_all (qh facet_list); - qh_countfacets (qh facet_list, NULL, !qh_ALL, &numfacets, &numsimplicial, - &totneighbors, &numridges, &numcoplanars, &numtricoplanars); - - FORALLfacets { - if (!facet->upperdelaunay) { - FOREACHneighbor_(facet) - printf (" %d", neighbor->visitid ? neighbor->visitid - 1: - neighbor->id); - printf ("\n"); - } - } -#endif - - /* Without the setjmp(), Qhull will exit() after reporting an error */ - exitcode = setjmp (qh errexit); - if (!exitcode) { - qh NOerrexit= False; - for(i=0; iupperdelaunay) - zg[i][j] = NaN; - else { - FOREACHvertex_(facet->vertices) { - k = qh_pointid(vertex->point); - xt[l] = x[k]; - yt[l] = y[k]; - zt[l] = z[k]; - l++; - } - - /* calculate the plane passing through the three points */ - - A = yt[0]*(zt[1]-zt[2]) + yt[1]*(zt[2]-zt[0]) + yt[2]*(zt[0]-zt[1]); - B = zt[0]*(xt[1]-xt[2]) + zt[1]*(xt[2]-xt[0]) + zt[2]*(xt[0]-xt[1]); - C = xt[0]*(yt[1]-yt[2]) + xt[1]*(yt[2]-yt[0]) + xt[2]*(yt[0]-yt[1]); - D = - A*xt[0] - B*yt[0] - C*zt[0]; - - /* and interpolate */ - zg[i][j] = - xg[i]*A/C - yg[j]*B/C - D/C; - - } - } - } - qh NOerrexit= True; - } - - free(points); - qh_freeqhull(!qh_ALL); /* free long memory */ - qh_memfreeshort (&curlong, &totlong); /* free short memory and memory allocator */ - if (curlong || totlong) - fprintf (errfile, - "qhull: did not free %d bytes of long memory (%d pieces)\n", - totlong, curlong); -} -#endif /* NONN */ diff --git a/src/plot/plplot/plhist.c b/src/plot/plplot/plhist.c deleted file mode 100644 index 7ff741de64..0000000000 --- a/src/plot/plplot/plhist.c +++ /dev/null @@ -1,180 +0,0 @@ -/* $Id: plhist.c,v 1.1 2004/03/01 20:54:52 cozmic Exp $ - - Histogram plotter. -*/ - -#include "plplotP.h" - -/*----------------------------------------------------------------------*\ - * void plhist() - * - * Draws a histogram of n values of a variable in array data[0..n-1] in - * the range datmin to datmax using nbin bins. If "flags"'s first bit is 1, the - * histogram is plotted in the current window. If not, the routine calls - * "plenv" to set up the graphics environment. - * - * If flags's second bit is set, then items which fall outside the bin - * range are ignored. - * - * If flags's third bit is set, the outside bars are the same size - * as the rest. The default old behaviour was for the first and last - * bars to expand visually to fill the entire available space. -\*----------------------------------------------------------------------*/ - -void -c_plhist(PLINT n, PLFLT *data, PLFLT datmin, PLFLT datmax, - PLINT nbin, PLINT flags) -{ - PLINT i, bin; - PLFLT *x, *y, dx, ymax; - - if (plsc->level < 1) { - plabort("plhist: Please call plinit first"); - return; - } - if (plsc->level < 3 && (flags & 1)) { - plabort("plhist: Please set up window first"); - return; - } - if (datmin >= datmax) { - plabort("plhist: Data range invalid"); - return; - } - if ( ! (x = (PLFLT *) malloc((size_t) nbin * sizeof(PLFLT)))) { - plabort("plhist: Out of memory"); - return; - } - if ( ! (y = (PLFLT *) malloc((size_t) nbin * sizeof(PLFLT)))) { - free((void *) x); - plabort("plhist: Out of memory"); - return; - } - - dx = (datmax - datmin) / nbin; - for (i = 0; i < nbin; i++) { - x[i] = datmin + i * dx; - y[i] = 0.0; - } - - for (i = 0; i < n; i++) { - bin = (data[i] - datmin) / dx; - if ((flags & 2) == 0) { - bin = bin > 0 ? bin : 0; - bin = bin < nbin ? bin : nbin - 1; - y[bin]++; - } else { - if(bin >= 0 && bin < nbin) { - y[bin]++; - } - } - } - - if (!(flags & 1)) { - ymax = 0.0; - for (i = 0; i < nbin; i++) - ymax = MAX(ymax, y[i]); - - plenv(datmin, datmax, (PLFLT) 0.0, (PLFLT) (1.1 * ymax), 0, 0); - } - /* We pass on the highest couple of bits to the 'plbin' routine */ - plbin(nbin, x, y, (flags & (4+8+16+32)) >> 2); - free((void *) x); - free((void *) y); -} - -/*----------------------------------------------------------------------*\ - * void plbin() - * - * Plot a histogram using the arrays x and y to represent data values - * and frequencies respectively. If flags first bit is false, x values - * denote the lower edge of the bin, and if it is true, they denote - * the center of the bin. If flags second bit is true, then we assume - * the edge bins are the same size as the rest (i.e. the edge bins - * needn't go as far as the variables vpwxmi, vpwxma below). -\*----------------------------------------------------------------------*/ - -void -c_plbin(PLINT nbin, PLFLT *x, PLFLT *y, PLINT flags) -{ - PLINT i; - PLFLT xmin, xmax, vpwxmi, vpwxma, vpwymi, vpwyma; - - if (plsc->level < 3) { - plabort("plbin: Please set up window first"); - return; - } - - /* Check x[i] are in ascending order */ - - for (i = 0; i < nbin - 1; i++) { - if (x[i] >= x[i + 1]) { - plabort("plbin: Elements of x array must be increasing"); - return; - } - } - - plgvpw(&vpwxmi, &vpwxma, &vpwymi, &vpwyma); - if (!(flags & 1)) { - for (i = 0; i < nbin - 1; i++) { - if (!(flags & 4) || (y[i] != vpwymi)) { - pljoin(x[i], vpwymi, x[i], y[i]); - pljoin(x[i], y[i], x[i + 1], y[i]); - pljoin(x[i + 1], y[i], x[i + 1], vpwymi); - } - } - if (flags & 2) { - if (!(flags & 4) || (y[i] != vpwymi)) { - int xm = x[i] + (x[i] - x[i-1]); - pljoin(x[i], vpwymi, x[i], y[i]); - pljoin(x[i], y[i], xm, y[i]); - pljoin(xm, y[i], xm, vpwymi); - } - } else { - if (x[i] < vpwxma) { - if (!(flags & 4) || (y[i] != vpwymi)) { - pljoin(x[i], vpwymi, x[i], y[i]); - pljoin(x[i], y[i], vpwxma, y[i]); - pljoin(vpwxma, y[i], vpwxma, vpwymi); - } - } - } - } else { - if (nbin < 2) - return; - if (flags & 2) { - xmin = MAX(vpwxmi, 0.5 * (3 * x[0] - x[1])); - } else { - xmin = vpwxmi; - } - /* Vince fixed bug May 1998 */ - xmax = MAX(0.5 * (x[0] + x[1]), vpwxmi); - if (xmin < xmax) { - pljoin(xmin, vpwymi, xmin, y[0]); - pljoin(xmin, y[0], xmax, y[0]); - pljoin(xmax, y[0], xmax, vpwymi); - } - for (i = 1; i < nbin - 1; i++) { - xmin = xmax; - xmax = MIN(0.5 * (x[i] + x[i + 1]), vpwxma); - if (!(flags & 4) || (y[i] != vpwymi)) { - pljoin(xmin, vpwymi, xmin, y[i]); - pljoin(xmin, y[i], xmax, y[i]); - pljoin(xmax, y[i], xmax, vpwymi); - } - } - xmin = xmax; - xmax = vpwxma; - if (flags & 2) { - xmax = MIN(vpwxma, 0.5 * (3 * x[i] - x[i-1])); - } else { - xmax = vpwxma; - } - if (xmin < xmax) { - if (!(flags & 4) || (y[i] != vpwymi)) { - pljoin(xmin, vpwymi, xmin, y[i]); - pljoin(xmin, y[i], xmax, y[i]); - pljoin(xmax, y[i], xmax, vpwymi); - } - } - } -} diff --git a/src/plot/plplot/plimage.c b/src/plot/plplot/plimage.c deleted file mode 100644 index b800578a91..0000000000 --- a/src/plot/plplot/plimage.c +++ /dev/null @@ -1,235 +0,0 @@ -/* plimage() - * - * Author: Alessandro Mirone, Nov 2001 - * Adapted: Joao Cardoso - */ - -#include "plplotP.h" - -/* Get better names, those are too criptic! - * - * ZEROW2B: zero writing to buffer ? - * ZEROW2D: zero writing to display ? - * ONEW2B: set writing to buffer ? - * ONEW2D: set writing to display ? - */ - -void -NoBufferNoPixmap() -{ - PLINT op = ZEROW2B; - - plsc->plbuf_write = 0; /* TODO: store previous state */ - plP_esc(PLESC_EXPOSE, NULL); - plP_esc(PLESC_IMAGEOPS, &op); -} - -void -RestoreWrite2BufferPixmap() -{ - PLINT op = ONEW2B; - - plsc->plbuf_write = 1; /* TODO: revert from previous state */ - plP_esc(PLESC_IMAGEOPS, &op); -} - -void -disabledisplay() -{ - PLINT op = ZEROW2D; - - plP_esc(PLESC_IMAGEOPS, &op); -} - -void -enabledisplay() -{ - PLINT op = ONEW2D; - - plP_esc(PLESC_IMAGEOPS, &op); - plP_esc(PLESC_EXPOSE, NULL); -} - - - -void -plimageslow(short *x, short *y, unsigned short *data, PLINT nx, PLINT ny, - PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, - unsigned short zmin, unsigned short zmax) -{ - PLINT ix, iy, i; - PLFLT xf[4], yf[4]; - short xs[5], ys[5]; - int corners[4]; - unsigned short col; - - for (ix = 0; ix < nx ; ix++) { - for (iy = 0; iy < ny ; iy++) { - - col = data[ix*ny+iy]; - /* only plot points within zmin/zmax range */ - if (col < zmin || col > zmax) - continue; - - plcol1(col/(float)USHRT_MAX); - - if (plsc->plbuf_read == 1) { - /* buffer read, is a replot to a slow device. */ - - corners[0] = ix*(ny+1)+iy; /* [ix][iy] */ - corners[1] = (ix+1)*(ny+1)+iy; /* [ix+1][iy] */ - corners[2] = (ix+1)*(ny+1)+iy+1; /* [ix+1][iy+1] */ - corners[3] = ix*(ny+1)+iy+1; /* [ix][iy+1] */ - - for (i = 0; i < 4; i++) { - xs[i] = x[corners[i]]; - ys[i] = y[corners[i]]; - } - xs[4] = xs[0]; ys[4] = ys[0]; - plP_fill(xs, ys, 5); - - } else { - - xf[0] = xf[1] = ix; - xf[2] = xf[3] = ix+1; - yf[0] = yf[3] = iy; - yf[1] = yf[2] = iy+1; - - for (i = 0; i < 4; i++) { - xf[i] = xmin + xf[i]*dx; - yf[i] = ymin + yf[i]*dy; - } - plfill(4, xf, yf); - } - } - } -} - -void -grimage(short *x, short *y, unsigned short *z, PLINT nx, PLINT ny) -{ - plsc->dev_ix = x; - plsc->dev_iy = y; - plsc->dev_z = z; - plsc->dev_nptsX = nx; - plsc->dev_nptsY = ny; - - plP_esc(PLESC_IMAGE, NULL); -} - -/*-------------------------------------------------------------------------*\ - * plimage - * (***** SUBJECT TO CHANGE ******) - * - * arguments are - * data: array containing image data - * nx: dimension of the array in the X axis. - * ny: dimension of the array in the Y axis - * The array data is indexed like data[ix][iy] - * - * xmin, xmax, ymin, ymax: - * data[0][0] corresponds to (xmin,ymin) - * data[nx-1][ny-1] to (xmax,ymax) - * - * zmin, zmax: - * only data within bounds zmin <= data <= zmax will be - * plotted. If zmin == zmax, all data will be ploted. - * - * Dxmin, Dxmax, Dymin, Dymax: - * plots only the window of points whose(x,y)'s fall - * inside the [Dxmin->Dxmax]X[Dymin->Dymax] window - * -\*-------------------------------------------------------------------------*/ - -void -plimage(PLFLT **idata, PLINT nx, PLINT ny, - PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, - PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax) -{ - PLINT nnx, nny, ix, iy, ixx, iyy, xm, ym; - PLFLT dx, dy; - unsigned short *Zf, szmin, szmax; - short *Xf, *Yf; - PLFLT lzmin, lzmax, tz; - - if (plsc->level < 3) { - plabort("plimage: window must be set up first"); - return; - } - - if (nx <= 0 || ny <= 0) { - plabort("plimage: nx and ny must be positive"); - return; - } - - if (Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax){ - plabort("plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xminor xmax or ymin or ymax."); - return; - } - - dx = (xmax - xmin) / (nx - 1); - dy = (ymax - ymin) / (ny - 1); - nnx = (Dxmax-Dxmin)/dx + 1; - nny = (Dymax-Dymin)/dy + 1; - - Zf = (unsigned short *) malloc(nny*nnx*sizeof(unsigned short)); - - xm = floor((Dxmin-xmin)/dx); ym = floor((Dymin-ymin)/dy); - lzmin = lzmax = idata[xm][ym]; - - for (ix=xm; ix tz) - lzmin = tz; - } - } - - ixx=-1; - for (ix=xm; ix lzmax) - zmax = lzmax; - } - - szmin = (zmin - lzmin)/(lzmax-lzmin)*USHRT_MAX; - szmax = (zmax - lzmin)/(lzmax-lzmin)*USHRT_MAX; - - xmin = Dxmin; xmax = Dxmax; - ymin = Dymin; ymax = Dymax; - - /* The X and Y arrays has size nnx*nny */ - nnx++; nny++; - - Xf = (short *) malloc(nny*nnx*sizeof(short)); - Yf = (short *) malloc(nny*nnx*sizeof(short)); - - /* adjust the step for the X/Y arrays */ - dx = dx*(nx-1)/nx; - dy = dy*(ny-1)/ny; - - for (ix = 0; ix < nnx; ix++) - for (iy = 0; iy < nny; iy++) { - Xf[ix*nny+iy] = plP_wcpcx(xmin + ix*dx); - Yf[ix*nny+iy] = plP_wcpcy(ymin + iy*dy); - } - - plP_image(Xf, Yf, Zf, nnx, nny, xmin, ymin, dx, dy, szmin, szmax); - - free(Xf); - free(Yf); - free(Zf); -} diff --git a/src/plot/plplot/plline.c b/src/plot/plplot/plline.c deleted file mode 100644 index 4c608c09ef..0000000000 --- a/src/plot/plplot/plline.c +++ /dev/null @@ -1,927 +0,0 @@ -/* $Id: plline.c,v 1.2 2005/03/17 21:39:21 eli Exp $ - - Routines dealing with line generation. -*/ - -#include "plplotP.h" - -#define INSIDE(ix,iy) (BETW(ix,xmin,xmax) && BETW(iy,ymin,ymax)) - -static PLINT xline[PL_MAXPOLY], yline[PL_MAXPOLY]; - -static PLINT lastx = PL_UNDEFINED, lasty = PL_UNDEFINED; - -/* Function prototypes */ - -/* Draws a polyline within the clip limits. */ - -static void -pllclp(PLINT *x, PLINT *y, PLINT npts); - -/* Get clipped endpoints */ - -static int -clipline(PLINT *p_x1, PLINT *p_y1, PLINT *p_x2, PLINT *p_y2, - PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax); - -/* General line-drawing routine. Takes line styles into account. */ - -static void -genlin(short *x, short *y, PLINT npts); - -/* Draws a dashed line to the specified point from the previous one. */ - -static void -grdashline(short *x, short *y); - -/*----------------------------------------------------------------------*\ - * void pljoin() - * - * Draws a line segment from (x1, y1) to (x2, y2). -\*----------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_pljoin(PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2) -{ - plP_movwor(x1, y1); - plP_drawor(x2, y2); -} - -/*----------------------------------------------------------------------*\ - * void plline() - * - * Draws line segments connecting a series of points. -\*----------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plline(PLINT n, PLFLT *x, PLFLT *y) -{ - if (plsc->level < 3) { - plabort("plline: Please set up window first"); - return; - } - plP_drawor_poly(x, y, n); -} - -/*----------------------------------------------------------------------*\ - * void plline3(n, x, y, z) - * - * Draws a line in 3 space. You must first set up the viewport, the - * 2d viewing window (in world coordinates), and the 3d normalized - * coordinate box. See x18c.c for more info. - * - * This version adds clipping against the 3d bounding box specified in plw3d - - MZ_DLLEXPORT\*----------------------------------------------------------------------*/ -void -c_plline3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z) -{ - int i; - PLFLT vmin[3], vmax[3], zscale; - - if (plsc->level < 3) { - plabort("plline3: Please set up window first"); - return; - } - - /* get the bounding box in 3d */ - plP_gdom(&vmin[0], &vmax[0], &vmin[1], &vmax[1]); - plP_grange(&zscale, &vmin[2], &vmax[2]); - - /* interate over the vertices */ - for( i=0; i < n-1; i++ ) { - PLFLT p0[3], p1[3]; - int axis; - - /* copy the end points of the segment to allow clipping */ - p0[0] = x[i]; p0[1] = y[i]; p0[2] = z[i]; - p1[0] = x[i+1]; p1[1] = y[i+1]; p1[2] = z[i+1]; - - /* check against each axis of the bounding box */ - for(axis = 0; axis < 3; axis++) { - if(p0[axis] < vmin[axis]) { /* first out */ - if(p1[axis] < vmin[axis]) { - break; /* both endpoints out so quit */ - } else { - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p0[axis] = vmin[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p0[k] = (1-t)*p0[k] + t*p1[k]; - } - } - } else if(p1[axis] < vmin[axis]) { /* second out */ - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p1[axis] = vmin[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p1[k] = (1-t)*p0[k] + t*p1[k]; - } - } - if(p0[axis] > vmax[axis]) { /* first out */ - if(p1[axis] > vmax[axis]) { - break; /* both out so quit */ - } else { - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p0[axis] = vmax[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p0[k] = (1-t)*p0[k] + t*p1[k]; - } - } - } else if(p1[axis] > vmax[axis]) { /* second out */ - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p1[axis] = vmax[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p1[k] = (1-t)*p0[k] + t*p1[k]; - } - } - } - /* if we made it to here without "break"ing out of the loop, the - remaining segment is visible */ - if( axis == 3 ) { /* not clipped away */ - PLFLT u0, v0, u1, v1; - u0 = plP_wcpcx(plP_w3wcx( p0[0], p0[1], p0[2] )); - v0 = plP_wcpcy(plP_w3wcy( p0[0], p0[1], p0[2] )); - u1 = plP_wcpcx(plP_w3wcx( p1[0], p1[1], p1[2] )); - v1 = plP_wcpcy(plP_w3wcy( p1[0], p1[1], p1[2] )); - plP_movphy(u0,v0); - plP_draphy(u1,v1); - } - } - return; -} -/*----------------------------------------------------------------------*\ - * void plpoly3( n, x, y, z, draw, ifcc ) - * - * Draws a polygon in 3 space. This differs from plline3() in that - * this attempts to determine if the polygon is viewable. If the back - * of polygon is facing the viewer, then it isn't drawn. If this - * isn't what you want, then use plline3 instead. - * - * n specifies the number of points. They are assumed to be in a - * plane, and the directionality of the plane is determined from the - * first three points. Additional points do not /have/ to lie on the - * plane defined by the first three, but if they do not, then the - * determiniation of visibility obviously can't be 100% accurate... - * So if you're 3 space polygons are too far from planar, consider - * breaking them into smaller polygons. "3 points define a plane" :-). - * - * For ifcc == 1, the directionality of the polygon is determined by assuming - * the points are laid out in counter-clockwise order. - * - * For ifcc == 0, the directionality of the polygon is determined by assuming - * the points are laid out in clockwise order. - * - * BUGS: If one of the first two segments is of zero length, or if - * they are colinear, the calculation of visibility has a 50/50 chance - * of being correct. Avoid such situations :-). See x18c for an - * example of this problem. (Search for "20.1"). -\*----------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plpoly3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z, PLINT *draw, PLINT ifcc) -{ - int i; - PLFLT vmin[3], vmax[3], zscale; - PLFLT u1, v1, u2, v2, u3, v3; - PLFLT c; - - if (plsc->level < 3) { - plabort("plpoly3: Please set up window first"); - return; - } - - if ( n < 3 ) { - plabort("plpoly3: Must specify at least 3 points"); - return; - } - -/* Now figure out which side this is. */ - - u1 = plP_wcpcx(plP_w3wcx( x[0], y[0], z[0] )); - v1 = plP_wcpcy(plP_w3wcy( x[0], y[0], z[0] )); - - u2 = plP_wcpcx(plP_w3wcx( x[1], y[1], z[1] )); - v2 = plP_wcpcy(plP_w3wcy( x[1], y[1], z[1] )); - - u3 = plP_wcpcx(plP_w3wcx( x[2], y[2], z[2] )); - v3 = plP_wcpcy(plP_w3wcy( x[2], y[2], z[2] )); - - c = (u1-u2)*(v3-v2)-(v1-v2)*(u3-u2); - - if ( c *(1 - 2*ifcc) < 0. ) - return; - - /* get the bounding box in 3d */ - plP_gdom(&vmin[0], &vmax[0], &vmin[1], &vmax[1]); - plP_grange(&zscale, &vmin[2], &vmax[2]); - - /* interate over the vertices */ - for( i=0; i < n-1; i++ ) { - PLFLT p0[3], p1[3]; - int axis; - - /* copy the end points of the segment to allow clipping */ - p0[0] = x[i]; p0[1] = y[i]; p0[2] = z[i]; - p1[0] = x[i+1]; p1[1] = y[i+1]; p1[2] = z[i+1]; - - /* check against each axis of the bounding box */ - for(axis = 0; axis < 3; axis++) { - if(p0[axis] < vmin[axis]) { /* first out */ - if(p1[axis] < vmin[axis]) { - break; /* both endpoints out so quit */ - } else { - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p0[axis] = vmin[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p0[k] = (1-t)*p0[k] + t*p1[k]; - } - } - } else if(p1[axis] < vmin[axis]) { /* second out */ - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p1[axis] = vmin[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p1[k] = (1-t)*p0[k] + t*p1[k]; - } - } - if(p0[axis] > vmax[axis]) { /* first out */ - if(p1[axis] > vmax[axis]) { - break; /* both out so quit */ - } else { - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p0[axis] = vmax[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p0[k] = (1-t)*p0[k] + t*p1[k]; - } - } - } else if(p1[axis] > vmax[axis]) { /* second out */ - int j; - /* interpolate to find intersection with box */ - PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]); - p1[axis] = vmax[axis]; - for(j = 1; j<3; j++) { - int k = (axis+j)%3; - p1[k] = (1-t)*p0[k] + t*p1[k]; - } - } - } - /* if we made it to here without "break"ing out of the loop, the - remaining segment is visible */ - if( axis == 3 && draw[i] ) { /* not clipped away */ - PLFLT u0, v0, u1, v1; - u0 = plP_wcpcx(plP_w3wcx( p0[0], p0[1], p0[2] )); - v0 = plP_wcpcy(plP_w3wcy( p0[0], p0[1], p0[2] )); - u1 = plP_wcpcx(plP_w3wcx( p1[0], p1[1], p1[2] )); - v1 = plP_wcpcy(plP_w3wcy( p1[0], p1[1], p1[2] )); - plP_movphy(u0,v0); - plP_draphy(u1,v1); - } - } - return; -} - -/*----------------------------------------------------------------------*\ - * void plstyl() - * - * Set up a new line style of "nms" elements, with mark and space - * lengths given by arrays "mark" and "space". -\*----------------------------------------------------------------------*/ - -void -c_plstyl(PLINT nms, PLINT *mark, PLINT *space) -{ - short int i; - - if (plsc->level < 1) { - plabort("plstyl: Please call plinit first"); - return; - } - if ((nms < 0) || (nms > 10)) { - plabort("plstyl: Broken lines cannot have <0 or >10 elements"); - return; - } - for (i = 0; i < nms; i++) { - if ((mark[i] < 0) || (space[i] < 0)) { - plabort("plstyl: Mark and space lengths must be > 0"); - return; - } - } - - plsc->nms = nms; - for (i = 0; i < nms; i++) { - plsc->mark[i] = mark[i]; - plsc->space[i] = space[i]; - } - - plsc->curel = 0; - plsc->pendn = 1; - plsc->timecnt = 0; - plsc->alarm = nms > 0 ? mark[0] : 0; -} - -/*----------------------------------------------------------------------*\ - * void plP_movphy() - * - * Move to physical coordinates (x,y). -\*----------------------------------------------------------------------*/ - -void -plP_movphy(PLINT x, PLINT y) -{ - plsc->currx = x; - plsc->curry = y; -} - -/*----------------------------------------------------------------------*\ - * void plP_draphy() - * - * Draw to physical coordinates (x,y). -\*----------------------------------------------------------------------*/ - -void -plP_draphy(PLINT x, PLINT y) -{ - xline[0] = plsc->currx; - xline[1] = x; - yline[0] = plsc->curry; - yline[1] = y; - - pllclp(xline, yline, 2); -} - -/*----------------------------------------------------------------------*\ - * void plP_movwor() - * - * Move to world coordinates (x,y). -\*----------------------------------------------------------------------*/ - -void -plP_movwor(PLFLT x, PLFLT y) -{ - plsc->currx = plP_wcpcx(x); - plsc->curry = plP_wcpcy(y); -} - -/*----------------------------------------------------------------------*\ - * void plP_drawor() - * - * Draw to world coordinates (x,y). -\*----------------------------------------------------------------------*/ - -void -plP_drawor(PLFLT x, PLFLT y) -{ - xline[0] = plsc->currx; - xline[1] = plP_wcpcx(x); - yline[0] = plsc->curry; - yline[1] = plP_wcpcy(y); - - pllclp(xline, yline, 2); -} - -/*----------------------------------------------------------------------*\ - * void plP_draphy_poly() - * - * Draw polyline in physical coordinates. - * Need to draw buffers in increments of (PL_MAXPOLY-1) since the - * last point must be repeated (for solid lines). -\*----------------------------------------------------------------------*/ - -void -plP_draphy_poly(PLINT *x, PLINT *y, PLINT n) -{ - PLINT i, j, ib, ilim; - - for (ib = 0; ib < n; ib += PL_MAXPOLY - 1) { - ilim = MIN(PL_MAXPOLY, n - ib); - - for (i = 0; i < ilim; i++) { - j = ib + i; - xline[i] = x[j]; - yline[i] = y[j]; - } - pllclp(xline, yline, ilim); - } -} - -/*----------------------------------------------------------------------*\ - * void plP_drawor_poly() - * - * Draw polyline in world coordinates. - * Need to draw buffers in increments of (PL_MAXPOLY-1) since the - * last point must be repeated (for solid lines). -\*----------------------------------------------------------------------*/ - -void -plP_drawor_poly(PLFLT *x, PLFLT *y, PLINT n) -{ - PLINT i, j, ib, ilim; - - for (ib = 0; ib < n; ib += PL_MAXPOLY - 1) { - ilim = MIN(PL_MAXPOLY, n - ib); - - for (i = 0; i < ilim; i++) { - j = ib + i; - xline[i] = plP_wcpcx(x[j]); - yline[i] = plP_wcpcy(y[j]); - } - pllclp(xline, yline, ilim); - } -} - -/*----------------------------------------------------------------------*\ - * void pllclp() - * - * Draws a polyline within the clip limits. - * Merely a front-end to plP_pllclp(). -\*----------------------------------------------------------------------*/ - -static void -pllclp(PLINT *x, PLINT *y, PLINT npts) -{ - plP_pllclp(x, y, npts, plsc->clpxmi, plsc->clpxma, - plsc->clpymi, plsc->clpyma, genlin); -} - -/*----------------------------------------------------------------------*\ - * void plP_pllclp() - * - * Draws a polyline within the clip limits. -\*----------------------------------------------------------------------*/ - -void -plP_pllclp(PLINT *x, PLINT *y, PLINT npts, - PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, - void (*draw) (short *, short *, PLINT)) -{ - PLINT x1, x2, y1, y2; - PLINT i, iclp = 0; - short xclp[PL_MAXPOLY], yclp[PL_MAXPOLY]; - int drawable; - - for (i = 0; i < npts - 1; i++) { - x1 = x[i]; - x2 = x[i + 1]; - y1 = y[i]; - y2 = y[i + 1]; - - drawable = (INSIDE(x1, y1) && INSIDE(x2, y2)); - if ( ! drawable) - drawable = ! clipline(&x1, &y1, &x2, &y2, xmin, xmax, ymin, ymax); - - if (drawable) { - -/* First point of polyline. */ - - if (iclp == 0) { - xclp[iclp] = x1; - yclp[iclp] = y1; - iclp++; - xclp[iclp] = x2; - yclp[iclp] = y2; - } - -/* Not first point. Check if first point of this segment matches up to - previous point, and if so, add it to the current polyline buffer. */ - - else if (x1 == xclp[iclp] && y1 == yclp[iclp]) { - iclp++; - xclp[iclp] = x2; - yclp[iclp] = y2; - } - -/* Otherwise it's time to start a new polyline */ - - else { - if (iclp + 1 >= 2) - (*draw)(xclp, yclp, iclp + 1); - iclp = 0; - xclp[iclp] = x1; - yclp[iclp] = y1; - iclp++; - xclp[iclp] = x2; - yclp[iclp] = y2; - } - } - } - -/* Handle remaining polyline */ - - if (iclp + 1 >= 2) - (*draw)(xclp, yclp, iclp + 1); - - plsc->currx = x[npts-1]; - plsc->curry = y[npts-1]; -} - -/*----------------------------------------------------------------------*\ - * void plP_plfclp() - * - * Fills a polygon within the clip limits. -\*----------------------------------------------------------------------*/ - -void -plP_plfclp(PLINT *x, PLINT *y, PLINT npts, - PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, - void (*draw) (short *, short *, PLINT)) -{ - PLINT x1, x2, y1, y2; - PLINT i, iclp = -1; - short xclp[PL_MAXPOLY], yclp[PL_MAXPOLY]; - int drawable; - - for (i = 0; i < npts - 1; i++) { - x1 = x[i]; - x2 = x[i + 1]; - y1 = y[i]; - y2 = y[i + 1]; - - drawable = (INSIDE(x1, y1) && INSIDE(x2, y2)); - if ( ! drawable) - drawable = ! clipline(&x1, &y1, &x2, &y2, xmin, xmax, ymin, ymax); - - if (drawable) { - -/* Not first point. If first point of this segment matches up to the - previous point, just add it. */ - - if (iclp >= 0 && x1 == xclp[iclp] && y1 == yclp[iclp]) { - iclp++; - xclp[iclp] = x2; - yclp[iclp] = y2; - } - -/* First point of polyline, OR . */ - -/* If not, we need to add both points, to connect the points in the - * polygon along the clip boundary. If any of the previous points were - * outside one of the 4 corners, assume the corner was encircled and add - * it first. - */ - else { - iclp++; - xclp[iclp] = x1; - yclp[iclp] = y1; - - if ((x1 == xmin && y2 == ymin) || - (x2 == xmin && y1 == ymin)) { - iclp++; - xclp[iclp] = xmin; - yclp[iclp] = ymin; - } - else if ((x1 == xmax && y2 == ymin) || - (x2 == xmax && y1 == ymin)) { - iclp++; - xclp[iclp] = xmax; - yclp[iclp] = ymin; - } - else if ((x1 == xmax && y2 == ymax) || - (x2 == xmax && y1 == ymax)) { - iclp++; - xclp[iclp] = xmax; - yclp[iclp] = ymax; - } - else if ((x1 == xmin && y2 == ymax) || - (x2 == xmin && y1 == ymax)) { - iclp++; - xclp[iclp] = xmin; - yclp[iclp] = ymax; - } - /* Experimental code from way back. - Polygon clipping is HARD. - { - int j; - for (j = 0; j < i; j++) { - if (x[j] < xmin && y[j] < ymin) { - break; - } - else if (x[j] < xmin && y[j] > ymax) { - iclp++; - xclp[iclp] = xmin; - yclp[iclp] = ymax; - break; - } - else if (x[j] > xmax && y[j] < ymin) { - iclp++; - xclp[iclp] = xmax; - yclp[iclp] = ymin; - break; - } - else if (x[j] > xmax && y[j] > ymax) { - iclp++; - xclp[iclp] = xmax; - yclp[iclp] = ymax; - break; - } - } - } - */ - iclp++; - xclp[iclp] = x2; - yclp[iclp] = y2; - } - } - } - -/* Draw the sucker */ - - if (iclp + 1 >= 2) { - if ((xclp[0] == xmin && yclp[iclp] == ymin) || - (xclp[iclp] == xmin && yclp[0] == ymin)) { - iclp++; - xclp[iclp] = xmin; - yclp[iclp] = ymin; - } - else if ((xclp[0] == xmax && yclp[iclp] == ymin) || - (xclp[iclp] == xmax && yclp[0] == ymin)) { - iclp++; - xclp[iclp] = xmax; - yclp[iclp] = ymin; - } - else if ((xclp[0] == xmax && yclp[iclp] == ymax) || - (xclp[iclp] == xmax && yclp[0] == ymax)) { - iclp++; - xclp[iclp] = xmax; - yclp[iclp] = ymax; - } - else if ((xclp[0] == xmin && yclp[iclp] == ymax) || - (xclp[iclp] == xmin && yclp[0] == ymax)) { - iclp++; - xclp[iclp] = xmin; - yclp[iclp] = ymax; - } - } - if (iclp + 1 >= 3) { - if(draw) - (*draw)(xclp, yclp, iclp + 1); - } -} - -/*----------------------------------------------------------------------*\ - * int clipline() - * - * Get clipped endpoints -\*----------------------------------------------------------------------*/ - -static int -clipline(PLINT *p_x1, PLINT *p_y1, PLINT *p_x2, PLINT *p_y2, - PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax) -{ - PLINT t, dx, dy, flipx, flipy; - double dydx = 0, dxdy = 0; - -/* If both points are outside clip region with no hope of intersection, - return with an error */ - - if ((*p_x1 <= xmin && *p_x2 <= xmin) || - (*p_x1 >= xmax && *p_x2 >= xmax) || - (*p_y1 <= ymin && *p_y2 <= ymin) || - (*p_y1 >= ymax && *p_y2 >= ymax)) - return 1; - - flipx = 0; - flipy = 0; - - if (*p_x2 < *p_x1) { - *p_x1 = 2 * xmin - *p_x1; - *p_x2 = 2 * xmin - *p_x2; - xmax = 2 * xmin - xmax; - t = xmax; - xmax = xmin; - xmin = t; - flipx = 1; - } - - if (*p_y2 < *p_y1) { - *p_y1 = 2 * ymin - *p_y1; - *p_y2 = 2 * ymin - *p_y2; - ymax = 2 * ymin - ymax; - t = ymax; - ymax = ymin; - ymin = t; - flipy = 1; - } - - dx = *p_x2 - *p_x1; - dy = *p_y2 - *p_y1; - - if (dx != 0 && dy != 0) { - dydx = (double) dy / (double) dx; - dxdy = 1./ dydx; - } - - if (*p_x1 < xmin) { - if (dx != 0 && dy != 0) - *p_y1 = *p_y1 + ROUND((xmin - *p_x1) * dydx); - *p_x1 = xmin; - } - - if (*p_y1 < ymin) { - if (dx != 0 && dy != 0) - *p_x1 = *p_x1 + ROUND((ymin - *p_y1) * dxdy); - *p_y1 = ymin; - } - - if (*p_x1 >= xmax || *p_y1 >= ymax) - return 1; - - if (*p_y2 > ymax) { - if (dx != 0 && dy != 0) - *p_x2 = *p_x2 - ROUND((*p_y2 - ymax) * dxdy); - *p_y2 = ymax; - } - - if (*p_x2 > xmax) { - if (dx != 0 && dy != 0) - *p_y2 = *p_y2 - ROUND((*p_x2 - xmax) * dydx); - *p_x2 = xmax; - } - - if (flipx) { - *p_x1 = 2 * xmax - *p_x1; - *p_x2 = 2 * xmax - *p_x2; - } - - if (flipy) { - *p_y1 = 2 * ymax - *p_y1; - *p_y2 = 2 * ymax - *p_y2; - } - - return 0; -} - -/*----------------------------------------------------------------------*\ - * void genlin() - * - * General line-drawing routine. Takes line styles into account. - * If only 2 points are in the polyline, it is more efficient to use - * plP_line() rather than plP_polyline(). -\*----------------------------------------------------------------------*/ - -static void -genlin(short *x, short *y, PLINT npts) -{ -/* Check for solid line */ - - if (plsc->nms == 0) { - if (npts== 2) - plP_line(x, y); - else - plP_polyline(x, y, npts); - } - -/* Right now dashed lines don't use polyline capability -- this - should be improved */ - - else { - - PLINT i; - - /* Call escape sequence to draw dashed lines, only for drivers - that have this capability */ - if (plsc->dev_dash) { - plsc->dev_npts = npts; - plsc->dev_x = x; - plsc->dev_y = y; - plP_esc(PLESC_DASH, NULL); - return; - } - - for (i = 0; i < npts - 1; i++) { - grdashline(x+i, y+i); - } - } -} - -/*----------------------------------------------------------------------*\ - * void grdashline() - * - * Draws a dashed line to the specified point from the previous one. -\*----------------------------------------------------------------------*/ - -static void -grdashline(short *x, short *y) -{ - PLINT nx, ny, nxp, nyp, incr, temp; - PLINT modulo, dx, dy, i, xtmp, ytmp; - PLINT tstep, pix_distance, j; - int loop_x; - short xl[2], yl[2]; - double nxstep, nystep; - -/* Check if pattern needs to be restarted */ - - if (x[0] != lastx || y[0] != lasty) { - plsc->curel = 0; - plsc->pendn = 1; - plsc->timecnt = 0; - plsc->alarm = plsc->mark[0]; - } - - lastx = xtmp = x[0]; - lasty = ytmp = y[0]; - - if (x[0] == x[1] && y[0] == y[1]) - return; - - nx = x[1] - x[0]; - dx = (nx > 0) ? 1 : -1; - nxp = ABS(nx); - - ny = y[1] - y[0]; - dy = (ny > 0) ? 1 : -1; - nyp = ABS(ny); - - if (nyp > nxp) { - modulo = nyp; - incr = nxp; - loop_x = 0; - } - else { - modulo = nxp; - incr = nyp; - loop_x = 1; - } - - temp = modulo / 2; - -/* Compute the timer step */ - - nxstep = nxp * plsc->umx; - nystep = nyp * plsc->umy; - tstep = sqrt( nxstep * nxstep + nystep * nystep ) / modulo; - if (tstep < 1) tstep = 1; - - /* tstep is distance per pixel moved */ - - i = 0; - while (i < modulo) { - pix_distance = (plsc->alarm - plsc->timecnt + tstep - 1) / tstep; - i += pix_distance; - if (i > modulo) - pix_distance -= (i - modulo); - plsc->timecnt += pix_distance * tstep; - - temp += pix_distance * incr; - j = temp / modulo; - temp = temp % modulo; - - if (loop_x) { - xtmp += pix_distance * dx; - ytmp += j * dy; - } - else { - xtmp += j * dx; - ytmp += pix_distance * dy; - } - if (plsc->pendn != 0) { - xl[0] = lastx; - yl[0] = lasty; - xl[1] = xtmp; - yl[1] = ytmp; - plP_line(xl, yl); - } - -/* Update line style variables when alarm goes off */ - - while (plsc->timecnt >= plsc->alarm) { - if (plsc->pendn != 0) { - plsc->pendn = 0; - plsc->timecnt -= plsc->alarm; - plsc->alarm = plsc->space[plsc->curel]; - } - else { - plsc->pendn = 1; - plsc->timecnt -= plsc->alarm; - plsc->curel++; - if (plsc->curel >= plsc->nms) - plsc->curel = 0; - plsc->alarm = plsc->mark[plsc->curel]; - } - } - lastx = xtmp; - lasty = ytmp; - } -} diff --git a/src/plot/plplot/plmap.c b/src/plot/plplot/plmap.c deleted file mode 100644 index 399795a049..0000000000 --- a/src/plot/plplot/plmap.c +++ /dev/null @@ -1,312 +0,0 @@ -/* $Id: plmap.c,v 1.1 2004/03/01 20:54:52 cozmic Exp $ - - Continental Outline and Political Boundary Backgrounds - - Some plots need a geographical background such as the global - surface temperatures or the population density. The routine - plmap() will draw one of the following backgrounds: continental - outlines, political boundaries, the United States, and the United - States with the continental outlines. The routine plmeridians() - will add the latitudes and longitudes to the background. After - the background has been drawn, one can use a contour routine or a - symbol plotter to finish off the plot. - - Copyright (C) 1991, 1993, 1994 Wesley Ebisuzaki - Copyright (C) 1994, 2000, 2001 Maurice LeBrun - Copyright (C) 1999 Geoffrey Furnish - Copyright (C) 2000, 2001, 2002 Alan W. Irwin - Copyright (C) 2001 Andrew Roach - Copyright (C) 2001 Rafael Laboissiere - Copyright (C) 2002 Vincent Darley - Copyright (C) 2003 Joao Cardoso - - This file is part of PLplot. - - PLplot is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License - as published by the Free Software Foundation; version 2 of the - License. - - PLplot is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA - -*/ - -#include "plplotP.h" - -/*----------------------------------------------------------------------*\ - * void plmap(void (*mapform)(PLINT, PLFLT *, PLFLT *), char *type, - * PLFLT minlong, PLFLT maxlong, PLFLT minlat, PLFLT maxlat); - * - * plot continental outline in world coordinates - * - * v1.4: machine independent version - * v1.3: replaced plcontinent by plmap, added plmeridians - * v1.2: 2 arguments: mapform, type of plot - * - * mapform(PLINT n, PLFLT *x, PLFLT *y) is a routine to transform the - * coordinate longitudes and latitudes to a plot coordinate system. By - * using this transform, we can change from a longitude, latitude - * coordinate to a polar stereographic project, for example. Initially, - * x[0]..[n-1] are the longitudes and y[0]..y[n-1] are the corresponding - * latitudes. After the call to mapform(), x[] and y[] should be replaced - * by the corresponding plot coordinates. If no transform is desired, - * mapform can be replaced by NULL. - * - * type is a character string. The value of this parameter determines the - * type of background. The possible values are, - * - * "globe" continental outlines - * "usa" USA and state boundaries - * "cglobe" continental outlines and countries - * "usaglobe" USA, state boundaries and continental outlines - * - * minlong, maxlong are the values of the longitude on the left and right - * side of the plot, respectively. The value of minlong must be less than - * the values of maxlong, and the values of maxlong-minlong must be less - * or equal to 360. - * - * minlat, maxlat are the minimum and maximum latitudes to be plotted on - * the background. One can always use -90.0 and 90.0 as the boundary - * outside the plot window will be automatically eliminated. However, the - * program will be faster if one can reduce the size of the background - * plotted. -\*----------------------------------------------------------------------*/ - -#define MAP_FILE ".map" -#define OFFSET (180*100) -#define SCALE 100.0 -#define W_BUFSIZ (32*1024) - -void -plmap( void (*mapform)(PLINT, PLFLT *, PLFLT *), char *type, - PLFLT minlong, PLFLT maxlong, PLFLT minlat, PLFLT maxlat ) -{ - PLINT wrap, sign; - int i, j; - PLFLT bufx[200], bufy[200], x[2], y[2]; - short int test[400]; - register PDFstrm *in; - char filename[100]; - - unsigned char n_buff[2], buff[800]; - int n; - long int t; - - /* - * read map outline - */ - strcpy(filename,type); - strcat(filename,MAP_FILE); - - if ((in = plLibOpenPdfstrm(filename)) == NULL) - return; - - for (;;) { - /* read in # points in segment */ - if (pdf_rdx(n_buff, sizeof (unsigned char)* 2, in) == 0) break; - n = (n_buff[0] << 8) + n_buff[1]; - if (n == 0) break; - - pdf_rdx(buff, sizeof (unsigned char)*4*n, in); - if (n == 1) continue; - - for (j = i = 0; i < n; i++, j += 2) { - t = (buff[j] << 8) + buff[j+1]; - bufx[i] = (t - OFFSET) / SCALE; - } - for (i = 0; i < n; i++, j += 2) { - t = (buff[j] << 8) + buff[j+1]; - bufy[i] = (t - OFFSET) / SCALE; - } - - for (i = 0; i < n; i++) { - while (bufx[i] < minlong) { - bufx[i] += 360.0; - } - while (bufx[i] > maxlong) { - bufx[i] -= 360.0; - } - } - - /* remove last 2 points if both outside of domain and won't plot */ - -/* AR: 18/11/01 -* I have commented out the next section which supposedly -* removes points that do not plot within the domain. -* -* This code appears at any rate to be superseded by the next -* block of code that checks for wrapping problems. Removing -* this code seems to have fixed up the problems with mapping -* function, but I do not wish to delete it outright just now in -* case I have managed to miss something. -*/ - -/* while (n > 1) { - if ((bufx[n-1] < minlong && bufx[n-2] < minlong) || - (bufx[n-1] > maxlong && bufx[n-2] > maxlong) || - (bufy[n-1] < minlat && bufy[n-2] < minlat) || - (bufy[n-1] > maxlat && bufy[n-2] > maxlat)) { - n--; - } - else { - break; - } - } - if (n <= 1) continue; -*/ - - if (mapform != NULL) (*mapform)(n,bufx,bufy); /* moved transformation to here */ - /* so bound-checking worked right */ - - wrap = 0; - /* check for wrap around problems */ - for (i = 0; i < n-1; i++) { - - /* jc: this code is wrong, as the bufx/y are floats that are - converted to ints before abs() is called. Thus, small - differences are masked off. The proof that it is wrong is - that when replacing abs() with fabs(), as it should be, - the code works the wrong way. What a proof :-) - - test[i] = abs((bufx[i]-bufx[i+1])) > abs(bufy[i]/3); - - If the intended behaviour is *really* that, than an - explicit cast should be used to help other programmers, as - is done bellow!!! - */ - - test[i] = abs((int)(bufx[i]-bufx[i+1])) > abs((int)bufy[i]/3); /* Changed this from 30 degrees so it is now "polar sensitive" */ - if (test[i]) wrap = 1; - } - - if (wrap == 0) { - plline(n,bufx,bufy); - } - else { - for (i = 0; i < n-1; i++) { - x[0] = bufx[i]; - x[1] = bufx[i+1]; - y[0] = bufy[i]; - y[1] = bufy[i+1]; - if (test[i] == 0) { - plline(2,x,y); - } - else { /* this code seems to supercede the block commented out above */ - /* segment goes off the edge */ - sign = (x[1] > x[0]) ? 1 : -1; - x[1] -= sign * 360.0; - plline(2,x,y); - x[0] = bufx[i]; - x[1] = bufx[i+1]; - y[0] = bufy[i]; - y[1] = bufy[i+1]; - x[0] += sign * 360.0; - plline(2,x,y); - } - } - } - } -} - -/*----------------------------------------------------------------------*\ - * void plmeridians(void (*mapform)(PLINT, PLFLT *, PLFLT *), - * PLFLT dlong, PLFLT dlat, PLFLT minlong, PLFLT maxlong, - * PLFLT minlat, PLFLT maxlat); - * - * Plot the latitudes and longitudes on the background. The lines - * are plotted in the current color and line style. - * - * mapform(PLINT n, PLFLT *x, PLFLT *y) is a routine to transform the - * coordinate longitudes and latitudes to a plot coordinate system. By - * using this transform, we can change from a longitude, latitude - * coordinate to a polar stereographic project, for example. Initially, - * x[0]..x[n-1] are the longitudes and y[0]..y[n-1] are the corresponding - * latitudes. After the call to mapform(), x[] and y[] should be replaced - * by the corresponding plot coordinates. If no transform is desired, - * mapform can be replaced by NULL. - * - * dlat, dlong are the interval in degrees that the latitude and longitude - * lines are to be plotted. - * - * minlong, maxlong are the values of the longitude on the left and right - * side of the plot, respectively. The value of minlong must be less than - * the values of maxlong, and the values of maxlong-minlong must be less - * or equal to 360. - * - * minlat, maxlat are the minimum and maximum latitudes to be plotted on - * the background. One can always use -90.0 and 90.0 as the boundary - * outside the plot window will be automatically eliminated. However, the - * program will be faster if one can reduce the size of the background - * plotted. -\*----------------------------------------------------------------------*/ - -#define NSEG 100 - -void -plmeridians( void (*mapform)(PLINT, PLFLT *, PLFLT *), - PLFLT dlong, PLFLT dlat, - PLFLT minlong, PLFLT maxlong, PLFLT minlat, PLFLT maxlat ) -{ - PLFLT yy, xx, temp, x[2], y[2], dx, dy; - - if (minlong > maxlong) { - temp = minlong; - minlong = maxlong; - maxlong = temp; - } - if (minlat > maxlat) { - temp = minlat; - minlat = maxlat; - maxlat = temp; - } - dx = (maxlong - minlong) / NSEG; - dy = (maxlat - minlat) / NSEG; - - /* latitudes */ - - for (yy = dlat * ceil(minlat/dlat); yy <= maxlat; yy += dlat) { - if (mapform == NULL) { - y[0] = y[1] = yy; - x[0] = minlong; - x[1] = maxlong; - plline(2,x,y); - } - else { - for (xx = minlong; xx < maxlong; xx += dx) { - y[0] = y[1] = yy; - x[0] = xx; - x[1] = xx + dx; - (*mapform)(2,x,y); - plline(2,x,y); - } - } - } - - /* longitudes */ - - for (xx = dlong * ceil(minlong/dlong); xx <= maxlong; xx += dlong) { - if (mapform == NULL) { - x[0] = x[1] = xx; - y[0] = minlat; - y[1] = maxlat; - plline(2,x,y); - } - else { - for (yy = minlat; yy < maxlat; yy += dy) { - x[0] = x[1] = xx; - y[0] = yy; - y[1] = yy + dy; - (*mapform)(2,x,y); - plline(2,x,y); - } - } - } -} diff --git a/src/plot/plplot/plmeta.c b/src/plot/plplot/plmeta.c deleted file mode 100644 index d3fe9b8b8e..0000000000 --- a/src/plot/plplot/plmeta.c +++ /dev/null @@ -1,707 +0,0 @@ -/* $Id: plmeta.c,v 1.1 2004/03/01 20:54:52 cozmic Exp $ - - Copyright 1991, 1992, 1993, 1994, 1995 - Geoffrey Furnish furnish@dino.ph.utexas.edu - Maurice LeBrun mjl@dino.ph.utexas.edu - Institute for Fusion Studies University of Texas at Austin - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - This is a metafile writer for PLplot. - -*/ -#include "plDevs.h" - -/*#define DEBUG*/ - -#ifdef PLD_plmeta - -#define NEED_PLDEBUG -#include "plplotP.h" -#include "drivers.h" -#include "metadefs.h" -#include - -/* Device info */ -char* plD_DEVICE_INFO_plmeta = "plmeta:PLplot Native Meta-File:0:plmeta:26:plm"; - - -void plD_dispatch_init_plm ( PLDispatchTable *pdt ); - -void plD_init_plm (PLStream *); -void plD_line_plm (PLStream *, short, short, short, short); -void plD_polyline_plm (PLStream *, short *, short *, PLINT); -void plD_eop_plm (PLStream *); -void plD_bop_plm (PLStream *); -void plD_tidy_plm (PLStream *); -void plD_state_plm (PLStream *, PLINT); -void plD_esc_plm (PLStream *, PLINT, void *); - -/* Struct to hold device-specific info. */ - -typedef struct { - PLFLT pxlx, pxly; - PLINT xold, yold; - - PLINT xmin, xmax, xlen; - PLINT ymin, ymax, ylen; - - FPOS_T lp_offset, index_offset; - - int notfirst; -} PLmDev; - -/* Used for constructing error messages */ - -static char buffer[256]; - -/* Function prototypes */ - -static void WriteFileHeader (PLStream *pls); -static void UpdatePrevPagehdr (PLStream *pls); -static void WritePageInfo (PLStream *pls, FPOS_T pp_offset); -static void UpdateIndex (PLStream *pls, FPOS_T cp_offset); -static void plm_fill (PLStream *pls); -static void plm_swin (PLStream *pls); - -/* A little function to help with debugging */ - -#ifdef DEBUG -#define DEBUG_PRINT_LOCATION(a) PrintLocation(pls, a) - -static void PrintLocation(PLStream *pls, char *tag) -{ - int isfile = (pls->output_type == 0); - if (isfile) { - FILE *file = pls->OutFile; - FPOS_T current_offset; - - if (pl_fgetpos(file, ¤t_offset)) - plexit("PrintLocation (plmeta.c): fgetpos call failed"); - - pldebug(tag, "at offset %d in file %s\n", - (int) current_offset, pls->FileName); - } -} -#else -#define DEBUG_PRINT_LOCATION(a) -#endif - -void plD_dispatch_init_plm( PLDispatchTable *pdt ) -{ - pdt->pl_MenuStr = "PLplot Native Meta-File"; - pdt->pl_DevName = "plmeta"; - pdt->pl_type = plDevType_FileOriented; - pdt->pl_seq = 26; - pdt->pl_init = (plD_init_fp) plD_init_plm; - pdt->pl_line = (plD_line_fp) plD_line_plm; - pdt->pl_polyline = (plD_polyline_fp) plD_polyline_plm; - pdt->pl_eop = (plD_eop_fp) plD_eop_plm; - pdt->pl_bop = (plD_bop_fp) plD_bop_plm; - pdt->pl_tidy = (plD_tidy_fp) plD_tidy_plm; - pdt->pl_state = (plD_state_fp) plD_state_plm; - pdt->pl_esc = (plD_esc_fp) plD_esc_plm; -} - -/*--------------------------------------------------------------------------*\ - * plD_init_plm() - * - * Initialize device. -\*--------------------------------------------------------------------------*/ - -void -plD_init_plm(PLStream *pls) -{ - PLmDev *dev; - U_CHAR c = (U_CHAR) INITIALIZE; - - dbug_enter("plD_init_plm"); - - pls->color = 1; /* Is a color device */ - pls->dev_fill0 = 1; /* Handle solid fills */ - pls->dev_fill1 = 1; /* Handle pattern fills */ - -/* Initialize family file info */ - - plFamInit(pls); - -/* Prompt for a file name if not already set */ - - plOpenFile(pls); - pls->pdfs = pdf_finit(pls->OutFile); - -/* Allocate and initialize device-specific data */ - - pls->dev = calloc(1, (size_t) sizeof(PLmDev)); - if (pls->dev == NULL) - plexit("plD_init_plm: Out of memory."); - - dev = (PLmDev *) pls->dev; - - dev->xold = PL_UNDEFINED; - dev->yold = PL_UNDEFINED; - - dev->xmin = 0; - dev->xmax = PIXELS_X - 1; - dev->ymin = 0; - dev->ymax = PIXELS_Y - 1; - - dev->pxlx = (double) PIXELS_X / (double) LPAGE_X; - dev->pxly = (double) PIXELS_Y / (double) LPAGE_Y; - - plP_setpxl(dev->pxlx, dev->pxly); - plP_setphy(dev->xmin, dev->xmax, dev->ymin, dev->ymax); - -/* Write Metafile header. */ - - WriteFileHeader(pls); - -/* Write color map state info */ - - plD_state_plm(pls, PLSTATE_CMAP0); - plD_state_plm(pls, PLSTATE_CMAP1); - -/* Write initialization command. */ - - DEBUG_PRINT_LOCATION("before init"); - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); -} - -/*--------------------------------------------------------------------------*\ - * plD_line_plm() - * - * Draw a line in the current color from (x1,y1) to (x2,y2). -\*--------------------------------------------------------------------------*/ - -void -plD_line_plm(PLStream *pls, short x1, short y1, short x2, short y2) -{ - PLmDev *dev = (PLmDev *) pls->dev; - U_CHAR c; - U_SHORT xy[4]; - - /* dbug_enter("plD_line_plm"); */ - - /* Failsafe check */ - -#ifdef DEBUG - if (x1 < dev->xmin || x1 > dev->xmax || - x2 < dev->xmin || x2 > dev->xmax || - y1 < dev->ymin || y1 > dev->ymax || - y2 < dev->ymin || y2 > dev->ymax) { - - pldebug("plD_line_plm", - "coordinates out of bounds -- \nActual: (%i,%i), (%i,%i) Bounds: (%i,%i,%i,%i)\n", - x1, y1, x2, y2, dev->xmin, dev->xmax, dev->ymin, dev->ymax); - } -#endif - -/* If continuation of previous line send the LINETO command, which uses - the previous (x,y) point as it's starting location. This results in a - storage reduction of not quite 50%, since the instruction length for - a LINETO is 5/9 of that for the LINE command, and given that most - graphics applications use this command heavily. - - Still not quite as efficient as tektronix format since we also send the - command each time (so shortest command is 25% larger), but a lot easier - to implement than the tek method. - */ - if (x1 == dev->xold && y1 == dev->yold) { - - c = (U_CHAR) LINETO; - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - - xy[0] = x2; - xy[1] = y2; - plm_wr( pdf_wr_2nbytes(pls->pdfs, xy, 2) ); - } - else { - c = (U_CHAR) LINE; - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - - xy[0] = x1; - xy[1] = y1; - xy[2] = x2; - xy[3] = y2; - plm_wr( pdf_wr_2nbytes(pls->pdfs, xy, 4) ); - } - dev->xold = x2; - dev->yold = y2; -} - -/*--------------------------------------------------------------------------*\ - * plD_polyline_plm() - * - * Draw a polyline in the current color. -\*--------------------------------------------------------------------------*/ - -void -plD_polyline_plm(PLStream *pls, short *xa, short *ya, PLINT npts) -{ - PLmDev *dev = (PLmDev *) pls->dev; - U_CHAR c = (U_CHAR) POLYLINE; - - dbug_enter("plD_polyline_plm"); - - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) npts) ); - - plm_wr( pdf_wr_2nbytes(pls->pdfs, (U_SHORT *) xa, npts) ); - plm_wr( pdf_wr_2nbytes(pls->pdfs, (U_SHORT *) ya, npts) ); - - dev->xold = xa[npts - 1]; - dev->yold = ya[npts - 1]; -} - -/*--------------------------------------------------------------------------*\ - * plD_eop_plm() - * - * End of page. -\*--------------------------------------------------------------------------*/ - -void -plD_eop_plm(PLStream *pls) -{ - U_CHAR c = (U_CHAR) EOP; - - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); -} - -/*--------------------------------------------------------------------------*\ - * plD_bop_plm() - * - * Set up for the next page. - * - * Page header layout as follows: - * - * BOP (U_CHAR) - * page number (U_SHORT) - * prev page offset (U_LONG) - * next page offset (U_LONG) - * - * Each call after the first is responsible for updating the table of - * contents and the next page offset from the previous page. -\*--------------------------------------------------------------------------*/ - -void -plD_bop_plm(PLStream *pls) -{ - PLmDev *dev = (PLmDev *) pls->dev; - int isfile = (pls->output_type == 0); - FPOS_T pp_offset = dev->lp_offset;; - - dbug_enter("plD_bop_plm"); - - dev->xold = PL_UNDEFINED; - dev->yold = PL_UNDEFINED; - -/* Update previous page header */ - - if (isfile) - UpdatePrevPagehdr(pls); - -/* Start next family file if necessary. */ - - pls->bytecnt = pls->pdfs->bp; - plGetFam(pls); - -/* Update page counter */ - - pls->page++; - -/* Update table of contents info & write new page header. */ - - WritePageInfo(pls, pp_offset); -} - -/*--------------------------------------------------------------------------*\ - * WritePageInfo() - * - * Update table of contents info & write new page header. -\*--------------------------------------------------------------------------*/ - -static void -WritePageInfo(PLStream *pls, FPOS_T pp_offset) -{ - PLmDev *dev = (PLmDev *) pls->dev; - FILE *file = pls->OutFile; - int isfile = (pls->output_type == 0); - U_CHAR c; - FPOS_T cp_offset=0; - -/* Update table of contents. */ - - if (isfile) { - if (pl_fgetpos(file, &cp_offset)) - plexit("WritePageInfo (plmeta.c): fgetpos call failed"); - - UpdateIndex(pls, cp_offset); - } - -/* Write new page header */ - - if (dev->notfirst) - c = BOP; - else { - c = BOP0; - dev->notfirst = 1; - } - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) pls->page) ); - plm_wr( pdf_wr_4bytes(pls->pdfs, (U_LONG) pp_offset) ); - plm_wr( pdf_wr_4bytes(pls->pdfs, (U_LONG) 0) ); - -/* Update last page offset with current page value */ - - dev->lp_offset = cp_offset; - -/* Write some page state information just to make things nice later on */ -/* Eventually there will be more */ - - plD_state_plm(pls, PLSTATE_COLOR0); -} - -/*--------------------------------------------------------------------------*\ - * UpdatePrevPagehdr() - * - * Update previous page header. -\*--------------------------------------------------------------------------*/ - -static void -UpdatePrevPagehdr(PLStream *pls) -{ - PLmDev *dev = (PLmDev *) pls->dev; - FILE *file = pls->OutFile; - FPOS_T cp_offset=0; - - fflush(file); - -/* Determine where we are */ - - if (pl_fgetpos(file, &cp_offset)) - plexit("plD_bop_plm: fgetpos call failed"); - -/* Seek back to previous page header. */ - - if (dev->lp_offset > 0) { - FPOS_T fwbyte_offset=0; - - pldebug("UpdatePrevPagehdr 1 (plmeta.c)", - "Location: %d, seeking to: %d\n", - (int) cp_offset, (int) dev->lp_offset); - - /* The forward byte offset is located exactly 7 bytes after the BOP */ - fwbyte_offset = dev->lp_offset + 7; - if (pl_fsetpos(file, &fwbyte_offset)) { - sprintf(buffer, "UpdatePrevPagehdr (plmeta.c): fsetpos to fwbyte_offset (%d) failed", - (int) fwbyte_offset); - plexit(buffer); - } - - /* DEBUG: verify current location */ - -#ifdef DEBUG - if (pl_fgetpos(file, &fwbyte_offset)) - plexit("UpdatePrevPagehdr (plmeta.c): fgetpos call failed"); - - pldebug("UpdatePrevPagehdr 2 (plmeta.c)", - "Now at: %d, to write: %d\n", - (int) fwbyte_offset, (int) cp_offset); -#endif - - /* Write forward byte offset into previous page header. */ - - plm_wr( pdf_wr_4bytes(pls->pdfs, (U_LONG) cp_offset) ); - fflush(file); - - /* DEBUG: move back to before the write & read it to verify */ - -#ifdef DEBUG - if (pl_fsetpos(file, &fwbyte_offset)) { - sprintf(buffer, "UpdatePrevPagehdr (plmeta.c): fsetpos to fwbyte_offset (%d) failed", - (int) fwbyte_offset); - plexit(buffer); - } - { - U_LONG read_offset; - plm_rd(pdf_rd_4bytes(pls->pdfs, &read_offset)); - pldebug("UpdatePrevPagehdr 3 (plmeta.c)", - "Value read as: %d\n", read_offset); - } -#endif - - /* Return to current page offset */ - - if (pl_fsetpos(file, &cp_offset)) { - sprintf(buffer, "UpdatePrevPagehdr (plmeta.c): fsetpos to cp_offset (%d) failed", - (int) cp_offset); - plexit(buffer); - } - } -} - -/*--------------------------------------------------------------------------*\ - * UpdateIndex() - * - * Update file index. -\*--------------------------------------------------------------------------*/ - -static void -UpdateIndex(PLStream *pls, FPOS_T cp_offset) -{ - PLmDev *dev = (PLmDev *) pls->dev; - FILE *file = pls->OutFile; - -/* Update file index. Right now only number of pages. */ -/* The ordering here is critical */ - - if (dev->index_offset > 0) { - pldebug("UpdateIndex (plmeta.c)", - "Location: %d, seeking to: %d\n", - (int) cp_offset, (int) dev->lp_offset); - - if (pl_fsetpos(file, &dev->index_offset)) { - sprintf(buffer, "UpdateIndex (plmeta.c): fsetpos to index_offset (%d) failed", - (int) dev->index_offset); - plexit(buffer); - } - plm_wr( pdf_wr_header(pls->pdfs, "pages") ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) pls->page) ); - - pldebug("UpdateIndex (plmeta.c)", - "Location: %d, seeking to: %d\n", - (int) dev->lp_offset, (int) cp_offset); - - if (pl_fsetpos(file, &cp_offset)) { - sprintf(buffer, "UpdateIndex (plmeta.c): fsetpos to cp_offset (%d) failed", - (int) cp_offset); - plexit(buffer); - } - } -} - -/*--------------------------------------------------------------------------*\ - * plD_tidy_plm() - * - * Close graphics file -\*--------------------------------------------------------------------------*/ - -void -plD_tidy_plm(PLStream *pls) -{ - U_CHAR c = (U_CHAR) CLOSE; - - dbug_enter("plD_tidy_plm"); - - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - pdf_close(pls->pdfs); - free_mem(pls->dev); -} - -/*--------------------------------------------------------------------------*\ - * plD_state_plm() - * - * Handle change in PLStream state (color, pen width, fill attribute, etc). -\*--------------------------------------------------------------------------*/ - -void -plD_state_plm(PLStream *pls, PLINT op) -{ - U_CHAR c = (U_CHAR) CHANGE_STATE; - int i; - - dbug_enter("plD_state_plm"); - - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - plm_wr( pdf_wr_1byte(pls->pdfs, op) ); - - switch (op) { - - case PLSTATE_WIDTH: - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) (pls->width)) ); - break; - - case PLSTATE_COLOR0: - plm_wr( pdf_wr_1byte(pls->pdfs, (U_CHAR) pls->icol0) ); - - if (pls->icol0 == PL_RGB_COLOR) { - plm_wr( pdf_wr_1byte(pls->pdfs, pls->curcolor.r) ); - plm_wr( pdf_wr_1byte(pls->pdfs, pls->curcolor.g) ); - plm_wr( pdf_wr_1byte(pls->pdfs, pls->curcolor.b) ); - } - break; - - case PLSTATE_COLOR1: - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) pls->icol1) ); - break; - - case PLSTATE_FILL: - plm_wr( pdf_wr_1byte(pls->pdfs, (U_CHAR) pls->patt) ); - break; - - case PLSTATE_CMAP0: - plm_wr( pdf_wr_1byte(pls->pdfs, (U_CHAR) pls->ncol0) ); - for (i = 0; i < pls->ncol0; i++) { - plm_wr( pdf_wr_1byte(pls->pdfs, pls->cmap0[i].r) ); - plm_wr( pdf_wr_1byte(pls->pdfs, pls->cmap0[i].g) ); - plm_wr( pdf_wr_1byte(pls->pdfs, pls->cmap0[i].b) ); - } - break; - - case PLSTATE_CMAP1: - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) pls->ncol1) ); - for (i = 0; i < pls->ncol1; i++) { - plm_wr( pdf_wr_1byte(pls->pdfs, pls->cmap1[i].r) ); - plm_wr( pdf_wr_1byte(pls->pdfs, pls->cmap1[i].g) ); - plm_wr( pdf_wr_1byte(pls->pdfs, pls->cmap1[i].b) ); - } - break; - } -} - -/*--------------------------------------------------------------------------*\ - * plD_esc_plm() - * - * Escape function. Note that any data written must be in device - * independent form to maintain the transportability of the metafile. - * - * Functions: - * - * PLESC_FILL Fill polygon - * PLESC_SWIN Set window parameters - * -\*--------------------------------------------------------------------------*/ - -void -plD_esc_plm(PLStream *pls, PLINT op, void *ptr) -{ - U_CHAR c = (U_CHAR) ESCAPE; - - dbug_enter("plD_esc_plm"); - - plm_wr( pdf_wr_1byte(pls->pdfs, c) ); - plm_wr( pdf_wr_1byte(pls->pdfs, (U_CHAR) op) ); - - switch (op) { - case PLESC_FILL: - plm_fill(pls); - break; - - case PLESC_SWIN: - plm_swin(pls); - break; - } -} - -/*--------------------------------------------------------------------------*\ - * plm_fill() - * - * Fill polygon described in points pls->dev_x[] and pls->dev_y[]. -\*--------------------------------------------------------------------------*/ - -static void -plm_fill(PLStream *pls) -{ - PLmDev *dev = (PLmDev *) pls->dev; - - dbug_enter("plm_fill"); - - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) pls->dev_npts) ); - - plm_wr( pdf_wr_2nbytes(pls->pdfs, (U_SHORT *) pls->dev_x, pls->dev_npts) ); - plm_wr( pdf_wr_2nbytes(pls->pdfs, (U_SHORT *) pls->dev_y, pls->dev_npts) ); - - dev->xold = PL_UNDEFINED; - dev->yold = PL_UNDEFINED; -} - -/*--------------------------------------------------------------------------*\ - * plm_swin() - * - * Set window parameters. - * Each parameter or group of parameters is tagged to make backward - * compatibility easier. -\*--------------------------------------------------------------------------*/ - -static void -plm_swin(PLStream *pls) -{ - dbug_enter("plm_swin"); -} - -/*--------------------------------------------------------------------------*\ - * WriteFileHeader() - * - * Writes Metafile header. -\*--------------------------------------------------------------------------*/ - -static void -WriteFileHeader(PLStream *pls) -{ - PLmDev *dev = (PLmDev *) pls->dev; - FILE *file = pls->OutFile; - int isfile = (pls->output_type == 0); - - dbug_enter("WriteFileHeader(PLStream *pls"); - - plm_wr( pdf_wr_header(pls->pdfs, PLMETA_HEADER) ); - plm_wr( pdf_wr_header(pls->pdfs, PLMETA_VERSION) ); - -/* Write file index info. Right now only number of pages. */ -/* The order here is critical */ - - if (isfile) { - if (pl_fgetpos(file, &dev->index_offset)) - plexit("WriteFileHeader: fgetpos call failed"); - } - - plm_wr( pdf_wr_header(pls->pdfs, "pages") ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) 0) ); - -/* Write initialization info. Tag via strings to make backward - compatibility with old metafiles as easy as possible. */ - - plm_wr( pdf_wr_header(pls->pdfs, "xmin") ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) dev->xmin) ); - - plm_wr( pdf_wr_header(pls->pdfs, "xmax") ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) dev->xmax) ); - - plm_wr( pdf_wr_header(pls->pdfs, "ymin") ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) dev->ymin) ); - - plm_wr( pdf_wr_header(pls->pdfs, "ymax") ); - plm_wr( pdf_wr_2bytes(pls->pdfs, (U_SHORT) dev->ymax) ); - - plm_wr( pdf_wr_header(pls->pdfs, "pxlx") ); - plm_wr( pdf_wr_ieeef(pls->pdfs, (float) dev->pxlx) ); - - plm_wr( pdf_wr_header(pls->pdfs, "pxly") ); - plm_wr( pdf_wr_ieeef(pls->pdfs, (float) dev->pxly) ); - - plm_wr( pdf_wr_header(pls->pdfs, "") ); -} - -#else -int -pldummy_plmeta() -{ - return 0; -} - -#endif /* PLD_plmeta */ diff --git a/src/plot/plplot/plot3d.c b/src/plot/plplot/plot3d.c deleted file mode 100644 index f653bf7d2b..0000000000 --- a/src/plot/plplot/plot3d.c +++ /dev/null @@ -1,2087 +0,0 @@ -/* $Id: plot3d.c,v 1.2 2005/03/17 21:39:21 eli Exp $ - - 3d plot routines. -*/ - -#include "plplotP.h" - -/* Internal constants */ - -#define BINC 50 /* Block size for memory allocation */ - -static PLINT pl3mode = 0; /* 0 3d solid; 1 mesh plot */ -static PLINT pl3upv = 1; /* 1 update view; 0 no update */ - -static PLINT zbflg = 0, zbcol; -static PLFLT zbtck; - -static PLINT *oldhiview = NULL; -static PLINT *oldloview = NULL; -static PLINT *newhiview = NULL; -static PLINT *newloview = NULL; -static PLINT *utmp = NULL; -static PLINT *vtmp = NULL; -static PLFLT *ctmp = NULL; - -static PLINT mhi, xxhi, newhisize; -static PLINT mlo, xxlo, newlosize; - -/* Light source for shading */ -static PLFLT xlight, ylight, zlight; -static PLINT falsecolor=0; -static PLFLT fc_minz, fc_maxz; - -/* Prototypes for static functions */ - -static void plgrid3 (PLFLT); -static void plnxtv (PLINT *, PLINT *, PLFLT*, PLINT, PLINT); -static void plside3 (PLFLT *, PLFLT *, PLFLT **, PLINT, PLINT, PLINT); -static void plt3zz (PLINT, PLINT, PLINT, PLINT, - PLINT, PLINT *, PLFLT *, PLFLT *, PLFLT **, - PLINT, PLINT, PLINT *, PLINT *, PLFLT*); -static void plnxtvhi (PLINT *, PLINT *, PLFLT*, PLINT, PLINT); -static void plnxtvlo (PLINT *, PLINT *, PLFLT*, PLINT, PLINT); -static void plnxtvhi_draw(PLINT *u, PLINT *v, PLFLT* c, PLINT n); - -static void savehipoint (PLINT, PLINT); -static void savelopoint (PLINT, PLINT); -static void swaphiview (void); -static void swaploview (void); -static void myexit (char *); -static void myabort (char *); -static void freework (void); -static int plabv (PLINT, PLINT, PLINT, PLINT, PLINT, PLINT); -static void pl3cut (PLINT, PLINT, PLINT, PLINT, PLINT, - PLINT, PLINT, PLINT, PLINT *, PLINT *); -static PLFLT plGetAngleToLight(PLFLT* x, PLFLT* y, PLFLT* z); -static void plP_draw3d(PLINT x, PLINT y, PLFLT *c, PLINT j, PLINT move); - -/* #define MJL_HACK 1 */ -#if MJL_HACK -static void plP_fill3(PLINT x0, PLINT y0, PLINT x1, PLINT y1, - PLINT x2, PLINT y2, PLINT j); -static void plP_fill4(PLINT x0, PLINT y0, PLINT x1, PLINT y1, - PLINT x2, PLINT y2, PLINT x3, PLINT y3, PLINT j); -#endif - -/*--------------------------------------------------------------------------*\ - * void plsetlightsource(x, y, z) - * - * Sets the position of the light source. -\*--------------------------------------------------------------------------*/ - -void -c_pllightsource(PLFLT x, PLFLT y, PLFLT z) -{ - xlight = x; - ylight = y; - zlight = z; -} - -/*--------------------------------------------------------------------------*\ - * void plmesh(x, y, z, nx, ny, opt) - * - * Plots a mesh representation of the function z[x][y]. The x values - * are stored as x[0..nx-1], the y values as y[0..ny-1], and the - * z values are in the 2-d array z[][]. The integer "opt" specifies: - * see plmeshc() bellow. -\*--------------------------------------------------------------------------*/ - -void -c_plmesh(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT opt) -{ - c_plot3dc(x, y, z, nx, ny, opt | MESH, NULL, 0); -} - -/*--------------------------------------------------------------------------*\ - * void plmeshc(x, y, z, nx, ny, opt, clevel, nlevel) - * - * Plots a mesh representation of the function z[x][y]. The x values - * are stored as x[0..nx-1], the y values as y[0..ny-1], and the - * z values are in the 2-d array z[][]. The integer "opt" specifies: - * - * DRAW_LINEX draw lines parallel to the X axis - * DRAW_LINEY draw lines parallel to the Y axis - * DRAW_LINEXY draw lines parallel to both the X and Y axis - * MAG_COLOR draw the mesh with a color dependent of the magnitude - * BASE_CONT draw contour plot at bottom xy plane - * TOP_CONT draw contour plot at top xy plane (not yet) - * DRAW_SIDES draw sides - * - * or any bitwise combination, e.g. "MAG_COLOR | DRAW_LINEX" - * -\*--------------------------------------------------------------------------*/ - -MZ_DLLEXPORT -void -c_plmeshc(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT opt, - PLFLT *clevel, PLINT nlevel) -{ - plot3dc(x, y, z, nx, ny, opt | MESH, clevel, nlevel); -} - -/* clipping helper for 3d polygons */ - -int -plP_clip_poly(int Ni, PLFLT *Vi[3], int axis, PLFLT dir, PLFLT offset) -{ - int anyout = 0; - PLFLT in[PL_MAXPOLY], T[3][PL_MAXPOLY]; - int No = 0; - int i, j, k; - - for(i=0; i=0 && in[j]>=0) { - for(k=0; k<3; k++) - Vi[k][No] = T[k][j]; - No++; - } else if(in[i]>=0 && in[j]<0) { - PLFLT u = in[i] / (in[i] - in[j]); - for(k = 0; k<3; k++) - Vi[k][No] = T[k][i]*(1-u) + T[k][j]*u; - No++; - } else if(in[i]<0 && in[j]>=0) { - PLFLT u = in[i] / (in[i] - in[j]); - for(k = 0; k<3; k++) - Vi[k][No] = T[k][i]*(1-u) + T[k][j]*u; - No++; - for(k=0; k<3; k++) - Vi[k][No] = T[k][j]; - No++; - } - } - return No; -} - -/* helper for plsurf3d, similar to c_plfill3() */ -static void -shade_triangle(PLFLT x0, PLFLT y0, PLFLT z0, - PLFLT x1, PLFLT y1, PLFLT z1, - PLFLT x2, PLFLT y2, PLFLT z2) -{ - int i; - /* arrays for interface to core functions */ - short u[6], v[6]; - PLFLT x[6], y[6], z[6]; - int n; - PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale; - PLFLT *V[3]; - - plP_gdom(&xmin, &xmax, &ymin, &ymax); - plP_grange(&zscale, &zmin, &zmax); - - x[0] = x0; x[1] = x1; x[2] = x2; - y[0] = y0; y[1] = y1; y[2] = y2; - z[0] = z0; z[1] = z1; z[2] = z2; - n = 3; - - if (falsecolor) - plcol1(((z[0] + z[1] + z[2]) /3. - fc_minz) / (fc_maxz - fc_minz)); - else - plcol1(plGetAngleToLight(x, y, z)); - - V[0] = x; V[1] = y; V[2] = z; - - n = plP_clip_poly(n, V, 0, 1, -xmin); - n = plP_clip_poly(n, V, 0, -1, xmax); - n = plP_clip_poly(n, V, 1, 1, -ymin); - n = plP_clip_poly(n, V, 1, -1, ymax); - n = plP_clip_poly(n, V, 2, 1, -zmin); - n = plP_clip_poly(n, V, 2, -1, zmax); - - for(i=0; i