diff --git a/pd/doc/5.reference/draw-help.pd b/pd/doc/5.reference/draw-help.pd index 021c4168225ff5846ced57181040e51854f587a5..b782e59c9824916b84cb2a6c0aa6c69622608104 100644 --- a/pd/doc/5.reference/draw-help.pd +++ b/pd/doc/5.reference/draw-help.pd @@ -1,10 +1,10 @@ #N struct draw-help-struct float x float y; -#N canvas 270 52 555 619 10; +#N canvas 212 53 555 619 10; #X obj 0 595 cnv 15 552 21 empty \$0-pddp.cnv.footer empty 20 12 0 14 -228856 -66577 0; #X obj 0 0 cnv 15 552 40 empty \$0-pddp.cnv.header draw 3 12 0 18 -204280 -1 0; -#X obj 0 339 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13 +#X obj 0 309 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13 -228856 -1 0; #N canvas 494 296 482 332 META 0; #X text 12 115 LIBRARY internal; @@ -17,13 +17,13 @@ rx ry; #X text 12 135 AUTHOR Jonathan Wilkes; #X text 13 155 HELP_PATCH_AUTHORS Jonathan Wilkes; #X restore 500 597 pd META; -#X obj 0 436 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0 +#X obj 0 406 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0 13 -228856 -1 0; -#X obj 0 473 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12 +#X obj 0 443 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12 0 13 -228856 -1 0; -#X obj 0 573 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12 +#X obj 0 543 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12 0 13 -228856 -1 0; -#X obj 78 347 cnv 17 3 80 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +#X obj 78 317 cnv 17 3 80 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 -162280 0; #N canvas 212 516 428 108 Related_objects 0; #X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 @@ -34,37 +34,37 @@ rx ry; #X obj 162 36 drawsymbol; #X obj 232 36 plot; #X restore 101 597 pd Related_objects; -#X text 99 445 float; -#X obj 78 445 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +#X text 99 415 float; +#X obj 78 415 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 -162280 0; -#X text 169 445 - outputs the stored value as a float message.; +#X text 169 415 - outputs the stored value as a float message.; #X obj 4 597 pddp/pddplink all_about_help_patches.pd -text Usage Guide ; #X text 11 20 draw an svg shape to represent a scalar; #X obj 492 12 draw; -#X text 101 554 float; -#X text 171 525 - [draw] accepts a list of coordinates and/or shape +#X text 101 524 float; +#X text 171 495 - [draw] accepts a list of coordinates and/or shape data used to specify where and how to draw the object; -#X scalar draw-help-struct 322 277 \;; -#X obj 117 64 struct draw-help-struct float x float y; -#X msg 128 201 stroke-width \$1; -#X floatatom 128 177 5 0 0 0 - - -, f 5; -#X floatatom 128 238 5 0 0 0 - - -, f 5; -#X msg 128 262 transform skewx \$1; -#X text 98 346 float; -#X text 168 347 - any nonzero number will display the drawing to represent +#X scalar draw-help-struct 322 250 \;; +#X obj 117 59 struct draw-help-struct float x float y; +#X msg 128 174 stroke-width \$1; +#X floatatom 128 150 5 0 0 0 - - -, f 5; +#X floatatom 128 211 5 0 0 0 - - -, f 5; +#X msg 128 235 transform skewx \$1; +#X text 98 316 float; +#X text 168 317 - any nonzero number will display the drawing to represent the corresponding scalar. SSending a "0" will hide it.; -#X text 98 386 [draw] also takes a number of messages. These are svg +#X text 98 356 [draw] also takes a number of messages. These are svg attributes that define how the object is drawn. See the subpatch above for a full list.; -#X text 81 490 1) symbol; -#X text 81 525 n) symbol; -#X text 107 539 or; -#X text 171 490 - name of an svg shape. Can be circle \, ellipse \, +#X text 81 460 1) symbol; +#X text 81 495 n) symbol; +#X text 107 509 or; +#X text 171 460 - name of an svg shape. Can be circle \, ellipse \, line \, path \, polygon \, polyline \, rectangle \, or group.; -#X obj 80 293 draw circle 40 40; -#X obj 299 158 draw rect 80 80 100 -40; -#X msg 80 112 fill red \, stroke blue; +#X obj 80 266 draw circle 40 40; +#X obj 299 138 draw rect 80 80 100 -40; +#X msg 80 92 fill red \, stroke blue; #N canvas 326 113 587 553 more_messages 0; #X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 14 -204280 -1 0; @@ -125,8 +125,13 @@ line \, path \, polygon \, polyline \, rectangle \, or group.; #X connect 30 0 32 0; #X connect 31 0 32 0; #X connect 33 0 32 0; -#X restore 299 112 pd more_messages; -#X msg 89 137 fill blue \, stroke black; +#X restore 299 92 pd more_messages; +#X msg 89 117 fill blue \, stroke black; +#X obj 172 553 pddp/pddplink drawarray-help.pd -text draw array; +#X text 101 555 See also:; +#X obj 172 573 pddp/pddplink drawimage-help.pd -text draw image; +#X obj 242 553 pddp/pddplink drawsprite-help.pd -text draw sprite; +#X obj 242 573 pddp/pddplink ./drawsvg-help.pd -text draw svg; #X connect 19 0 30 0; #X connect 20 0 19 0; #X connect 21 0 22 0; diff --git a/pd/doc/5.reference/drawarray-help.pd b/pd/doc/5.reference/drawarray-help.pd new file mode 100644 index 0000000000000000000000000000000000000000..d7b16103717e042bb1d83dead56ff8b0235606cb --- /dev/null +++ b/pd/doc/5.reference/drawarray-help.pd @@ -0,0 +1,73 @@ +#N struct draw-array-help-element float y; +#N struct draw-array-help-struct float x float y array a draw-array-help-element +; +#N canvas 245 53 555 619 10; +#X obj 0 595 cnv 15 552 21 empty \$0-pddp.cnv.footer empty 20 12 0 +14 -228856 -66577 0; +#X obj 0 0 cnv 15 552 40 empty \$0-pddp.cnv.header draw\ array 3 12 +0 18 -204280 -1 0; +#X obj 0 339 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13 +-228856 -1 0; +#N canvas 494 296 482 332 META 0; +#X text 12 115 LIBRARY internal; +#X text 12 25 LICENSE SIBSD; +#X text 12 5 KEYWORDS control GUI data-structure; +#X text 12 45 DESCRIPTION draw an svg shape to represent a scalar; +#X text 12 65 INLET_0 float fill fill-opacity fill-rule stroke stroke-dasharray +stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width +rx ry; +#X text 12 135 AUTHOR Jonathan Wilkes; +#X text 13 155 HELP_PATCH_AUTHORS Jonathan Wilkes; +#X restore 500 597 pd META; +#X obj 0 436 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0 +13 -228856 -1 0; +#X obj 0 473 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12 +0 13 -228856 -1 0; +#X obj 0 573 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12 +0 13 -228856 -1 0; +#X obj 78 347 cnv 17 3 80 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#N canvas 212 516 428 108 Related_objects 0; +#X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 +14 -204280 -1 0; +#X text 7 1 [draw] Related Objects; +#X obj 27 35 drawcurve; +#X obj 92 36 drawnumber; +#X obj 162 36 drawsymbol; +#X obj 232 36 plot; +#X restore 101 597 pd Related_objects; +#X text 99 445 float; +#X obj 78 445 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#X text 169 445 - outputs the stored value as a float message.; +#X obj 4 597 pddp/pddplink all_about_help_patches.pd -text Usage Guide +; +#X text 101 554 float; +#X text 171 525 - [draw] accepts a list of coordinates and/or shape +data used to specify where and how to draw the object; +#X text 98 346 float; +#X text 168 347 - any nonzero number will display the drawing to represent +the corresponding scalar. SSending a "0" will hide it.; +#X text 98 386 [draw] also takes a number of messages. These are svg +attributes that define how the object is drawn. See the subpatch above +for a full list.; +#X text 81 490 1) symbol; +#X text 81 525 n) symbol; +#X text 107 539 or; +#X text 171 490 - name of an svg shape. Can be circle \, ellipse \, +line \, path \, polygon \, polyline \, rectangle \, or group.; +#X text 11 20 draw an array of svg shapes; +#N canvas 731 197 450 323 draw-array-help-element 1; +#X obj 68 15 struct draw-array-help-element float y; +#X obj 149 89 draw circle 5; +#X restore 117 104 pd draw-array-help-element; +#X obj 117 64 struct draw-array-help-struct float x float y array a +draw-array-help-element; +#X scalar draw-array-help-struct 121 134 \; 0 \; 20 \; 25 \; 17 \; +8 \; 29 \; 30 \; 12 \; 14 \; 9 \; \;; +#X obj 118 271 draw array a 50 50; +#X floatatom 118 211 5 0 0 0 - - -, f 5; +#X msg 118 237 viewBox \$1 0 50 50; +#X text 261 245 Note: still a work-in-progress; +#X connect 27 0 28 0; +#X connect 28 0 26 0; diff --git a/pd/doc/5.reference/drawimage-help.pd b/pd/doc/5.reference/drawimage-help.pd new file mode 100644 index 0000000000000000000000000000000000000000..f0e309a72368d72127fb1921d6e911314662903c --- /dev/null +++ b/pd/doc/5.reference/drawimage-help.pd @@ -0,0 +1,62 @@ +#N struct draw-image-help-struct float x float y; +#N canvas 238 53 555 619 10; +#X obj 0 595 cnv 15 552 21 empty \$0-pddp.cnv.footer empty 20 12 0 +14 -228856 -66577 0; +#X obj 0 0 cnv 15 552 40 empty \$0-pddp.cnv.header draw\ image 3 12 +0 18 -204280 -1 0; +#X obj 0 329 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13 +-228856 -1 0; +#N canvas 494 296 482 332 META 0; +#X text 12 115 LIBRARY internal; +#X text 12 25 LICENSE SIBSD; +#X text 12 5 KEYWORDS control GUI data-structure; +#X text 12 45 DESCRIPTION draw an svg shape to represent a scalar; +#X text 12 65 INLET_0 float fill fill-opacity fill-rule stroke stroke-dasharray +stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width +rx ry; +#X text 12 135 AUTHOR Jonathan Wilkes; +#X text 13 155 HELP_PATCH_AUTHORS Jonathan Wilkes; +#X restore 500 597 pd META; +#X obj 0 396 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0 +13 -228856 -1 0; +#X obj 0 433 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12 +0 13 -228856 -1 0; +#X obj 0 533 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12 +0 13 -228856 -1 0; +#X obj 78 337 cnv 17 3 50 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#N canvas 212 516 428 108 Related_objects 0; +#X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 +14 -204280 -1 0; +#X obj 27 35 draw; +#X text 7 1 [draw image] Related Objects; +#X restore 101 597 pd Related_objects; +#X text 99 405 float; +#X obj 78 405 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#X text 169 405 - outputs the stored value as a float message.; +#X obj 4 597 pddp/pddplink all_about_help_patches.pd -text Usage Guide +; +#X floatatom 80 168 5 0 0 0 - - -, f 5; +#X msg 80 192 transform skewx \$1; +#X text 98 336 float; +#X text 81 450 1) symbol; +#X text 11 20 draw an svg image or sequence of images; +#X obj 117 64 struct draw-image-help-struct float x float y; +#X obj 80 253 draw image; +#X scalar draw-image-help-struct 324 189 \;; +#X text 168 337 - for [draw sprite] \, the index of the image to display. +This has no effect for [draw image]; +#X text 171 450 - path to the image to display. Or for [draw sprite] +the path which contains a sequence of images; +#X text 81 485 2) float; +#X text 171 485 - x origin for the image; +#X text 81 505 3) float; +#X text 171 505 - y origin for the image; +#X obj 162 541 pddp/pddplink drawarray-help.pd -text draw array; +#X text 91 543 See also:; +#X obj 162 561 pddp/pddplink drawimage-help.pd -text draw image; +#X obj 232 541 pddp/pddplink drawsprite-help.pd -text draw sprite; +#X obj 232 561 pddp/pddplink ./drawsvg-help.pd -text draw svg; +#X connect 13 0 14 0; +#X connect 14 0 19 0; diff --git a/pd/doc/5.reference/drawsprite-help.pd b/pd/doc/5.reference/drawsprite-help.pd new file mode 100644 index 0000000000000000000000000000000000000000..08569c970da5e8e64b16c6ce84ee99a4196e83ef --- /dev/null +++ b/pd/doc/5.reference/drawsprite-help.pd @@ -0,0 +1,139 @@ +#N struct draw-sprite-help float x float y; +#N canvas 255 53 555 619 10; +#X obj 0 595 cnv 15 552 21 empty \$0-pddp.cnv.footer empty 20 12 0 +14 -228856 -66577 0; +#X obj 0 0 cnv 15 552 40 empty \$0-pddp.cnv.header draw\ sprite 3 12 +0 18 -204280 -1 0; +#X obj 0 349 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13 +-228856 -1 0; +#N canvas 466 266 482 355 META 0; +#X text 12 115 LIBRARY internal; +#X text 12 25 LICENSE SIBSD; +#X text 12 5 KEYWORDS control GUI data-structure; +#X text 12 45 DESCRIPTION draw an svg shape to represent a scalar; +#X text 12 65 INLET_0 float fill fill-opacity fill-rule stroke stroke-dasharray +stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width +rx ry; +#X text 12 135 AUTHOR Jonathan Wilkes; +#X text 13 155 HELP_PATCH_AUTHORS Jonathan Wilkes; +#X restore 500 597 pd META; +#X obj 0 446 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0 +13 -228856 -1 0; +#X obj 0 483 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12 +0 13 -228856 -1 0; +#X obj 0 553 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12 +0 13 -228856 -1 0; +#X obj 78 357 cnv 17 3 80 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#N canvas 212 516 428 108 Related_objects 0; +#X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 +14 -204280 -1 0; +#X obj 17 35 draw image; +#X obj 92 36 draw; +#X text 7 1 [draw sprite] Related Objects; +#X restore 101 597 pd Related_objects; +#X obj 78 455 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#X obj 4 597 pddp/pddplink all_about_help_patches.pd -text Usage Guide +; +#X obj 115 56 struct draw-sprite-help float x float y; +#X obj 293 81 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 293 101 metro 72; +#X obj 293 123 f; +#X obj 333 123 + 1; +#X obj 293 150 % 22; +#X msg 293 235 index \$1; +#N canvas 681 181 450 323 earth 0; +#X obj 62 8 loadbang; +#X msg 62 30 fill white \, stroke black \, stroke-width 3.98213; +#X obj 62 52 draw path m 125.441 64.4134 a 60.2251 60.2251 0 1 1 -120.45 +0 a 60.2251 60.2251 0 1 1 120.45 0 z; +#X obj 62 120 draw path m 36.6489 11.9887 c 4.57718 -3.98317 10.7935 +-5.0472 16.5767 -5.81134 c 3.18504 -1.70824 6.31674 0.661606 7.88578 +1.63077 c 1.39674 -2.8954 6.10067 1.22814 5.64238 -2.96455 c 2.59712 +-0.816215 4.03226 4.04543 6.8129 1.44597 c 3.1605 3.03694 -5.06567 +3.97271 -3.48434 6.17877 c 4.74075 -0.533508 7.14687 3.59104 10.9833 +5.05019 c -1.77232 -2.9487 -0.236351 -3.0666 -1.08089 -4.33422 c -1.70082 +-2.55124 -4.04772 -4.10695 0.967781 -2.90709 c 5.74748 3.20745 3.22719 +-1.26601 10.1905 4.28407 c 2.07054 -0.295027 2.88148 1.63521 2.82493 +2.80785 c -0.044815 0.936308 -0.633278 1.74884 -2.82493 0.431078 c +-2.9471 2.10148 -3.04153 3.66146 -0.571915 1.14331 c 2.42639 0.024004 +2.46533 4.76796 5.33081 2.10042 c -0.071487 0.805065 -0.488159 1.82406 +-1.03928 2.06894 c -0.724503 0.322243 -1.68161 -0.250748 -2.39651 0.004803 +c -0.856285 0.306236 -1.03821 0.967253 -1.3231 2.68515 c -1.97984 0.488155 +-2.80679 1.55197 -2.74276 2.97484 c 0.102966 2.28127 1.64961 5.16915 +-1.95638 5.70373 c -4.16509 2.05453 4.11335 9.57379 0.125908 9.42281 +c -2.49682 -2.52563 -3.15836 -6.4101 -7.54754 -5.47752 c -1.92757 -0.336651 +-2.34103 2.93749 -5.05071 0.927769 c -5.55862 -0.333981 -6.88439 6.72913 +-4.55029 10.4562 c 1.51356 4.85706 7.67611 1.85447 8.48598 -1.4058 +c 7.43977 -1.17158 -2.99565 9.21956 5.04272 7.69373 c 5.22891 -0.359581 +0.569252 8.99388 7.2285 7.77055 c 3.93409 0.47855 8.10132 -7.83297 +11.7628 -2.46001 c 2.07641 -0.521767 4.44412 -1.20785 6.30073 -0.417732 +c 2.1479 0.914429 3.74896 3.43952 5.6221 4.62178 c 6.18336 -0.486023 +1.35885 7.8399 7.38376 7.29892 c 6.32047 -0.660477 1.77445 6.23991 +1.39778 9.54607 c -1.61172 4.81811 -3.62944 9.54338 -6.3514 13.844 +c -4.9643 2.33623 -7.06739 8.11413 -11.0516 11.623 c -4.88587 1.42712 +-8.13493 5.76881 -12.4457 8.1584 c -2.41359 2.19859 -7.34267 5.98543 +-9.65596 5.20863 c 2.23113 -4.06532 5.00697 -7.37788 7.69212 -11.2389 +c 2.08067 -4.69486 9.2889 -10.9513 6.09533 -15.8004 c -5.09981 -2.38317 +-5.30521 -9.2857 -8.58522 -13.4289 c 2.15698 -2.10842 -0.325966 -6.02116 +3.56171 -7.95834 c 1.90089 -1.61653 2.04974 -9.53913 -1.85608 -7.05512 +c -5.60664 -1.25427 -8.09438 -7.61102 -13.9587 -7.99727 c -3.67107 +-3.2544 -9.10806 -1.65655 -13.5826 -4.74289 c -4.299 -1.90676 -3.89513 +-8.03836 -7.90979 -10.5848 c -0.979523 -1.29376 -3.42725 -6.86838 -4.23018 +-3.91649 c 0.296097 2.15163 6.10867 10.2364 1.52423 5.52554 c -3.09061 +-4.2766 -4.67299 -9.39934 -7.4307 -13.9096 c -2.43407 -4.04186 2.31276 +-7.36615 1.52424 -11.0511 c 2.66701 -0.489227 -2.42106 -4.53055 -1.79099 +-7.16448 c -1.94709 -2.7337 -2.29984 0.273157 -4.68734 -0.457218 c +-0.184116 2.0284 -1.78496 1.17265 -2.85816 0.476421 z; +#X connect 0 0 1 0; +#X connect 1 0 2 0; +#X restore 335 177 draw g earth; +#X scalar draw-sprite-help 87 105 \;; +#X floatatom 293 175 5 0 0 0 - - -, f 5; +#N canvas 0 0 450 300 rotate 0; +#X obj 98 21 inlet; +#X obj 98 182 outlet; +#X obj 108 115 loadbang; +#X msg 98 158 transform translate -30 85 rotate \$1 65 63; +#X msg 98 46 360 \$1; +#X obj 98 68 -; +#X obj 98 90 * 2.5; +#X msg 108 137 0; +#X connect 0 0 4 0; +#X connect 2 0 7 0; +#X connect 3 0 1 0; +#X connect 4 0 5 0; +#X connect 5 0 6 0; +#X connect 6 0 3 0; +#X connect 7 0 3 0; +#X restore 335 150 pd rotate; +#X text 98 356 index; +#X text 168 357 - index of the image to display from the loaded image +sequence. Indices are zero-based.; +#X text 98 396 [draw] also takes a number of messages. These are svg +attributes that define how the object is drawn. See the [draw] object +for more information about them.; +#X text 99 455 -; +#X text 169 455 - -; +#X text 81 500 1) directory; +#X text 91 570 Images may be: png \, jpg \, gif \, or svg; +#X text 171 500 - directory in which a sequence of images may be found. +Purr Data will load the images files found there in alphabetical order. +Relative paths are relative to the patch.; +#X obj 179 327 pddp/pddplink http://millionthvector.blogspot.com/p/free-sprites_12.html +; +#X text 237 309 Sprite from; +#X obj 293 259 draw sprite ./drawsprite_images; +#X text 11 20 draw a sprite from an image sequence; +#X connect 12 0 13 0; +#X connect 13 0 14 0; +#X connect 14 0 15 0; +#X connect 14 0 16 0; +#X connect 14 0 21 0; +#X connect 15 0 14 1; +#X connect 16 0 20 0; +#X connect 17 0 32 0; +#X connect 20 0 17 0; +#X connect 21 0 18 0; diff --git a/pd/doc/5.reference/drawsprite_images/longneck01.png b/pd/doc/5.reference/drawsprite_images/longneck01.png new file mode 100644 index 0000000000000000000000000000000000000000..c97e62d0047e02949c546856ba42fa88817bc09c Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck01.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck02.png b/pd/doc/5.reference/drawsprite_images/longneck02.png new file mode 100644 index 0000000000000000000000000000000000000000..b0fea79b0247be652881ff221655a483f7a1023f Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck02.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck03.png b/pd/doc/5.reference/drawsprite_images/longneck03.png new file mode 100644 index 0000000000000000000000000000000000000000..2a636593f6bd78eb875bbff4ef564320dc59e64b Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck03.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck04.png b/pd/doc/5.reference/drawsprite_images/longneck04.png new file mode 100644 index 0000000000000000000000000000000000000000..a54afa16392ec9eeb989621240af61f560ad14aa Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck04.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck05.png b/pd/doc/5.reference/drawsprite_images/longneck05.png new file mode 100644 index 0000000000000000000000000000000000000000..3f0b1dd8c6cfa51059fcab7c98cb46973cd3d31a Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck05.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck06.png b/pd/doc/5.reference/drawsprite_images/longneck06.png new file mode 100644 index 0000000000000000000000000000000000000000..d480183b9239304f5fd94c5f01feb5ed2e0cd13a Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck06.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck07.png b/pd/doc/5.reference/drawsprite_images/longneck07.png new file mode 100644 index 0000000000000000000000000000000000000000..0546715d7f1fb44f1d2037da8cd603769815f1b9 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck07.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck08.png b/pd/doc/5.reference/drawsprite_images/longneck08.png new file mode 100644 index 0000000000000000000000000000000000000000..921004eb1799a70bcd30410be03d48fd109a471d Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck08.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck09.png b/pd/doc/5.reference/drawsprite_images/longneck09.png new file mode 100644 index 0000000000000000000000000000000000000000..289de0feafb178cd7c675c41da5c37ecbddea646 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck09.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck10.png b/pd/doc/5.reference/drawsprite_images/longneck10.png new file mode 100644 index 0000000000000000000000000000000000000000..97ffe0c6acf97fda816b062b853d78e56b55d9d3 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck10.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck11.png b/pd/doc/5.reference/drawsprite_images/longneck11.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8fd71bb79005eab7df7ce9cf4562fa19d14848 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck11.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck12.png b/pd/doc/5.reference/drawsprite_images/longneck12.png new file mode 100644 index 0000000000000000000000000000000000000000..aca29148b26a588e8b9b4160fffb895ad20df7ae Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck12.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck13.png b/pd/doc/5.reference/drawsprite_images/longneck13.png new file mode 100644 index 0000000000000000000000000000000000000000..50bfdd8a761ea0837f2d765717aa2b8a47d78148 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck13.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck14.png b/pd/doc/5.reference/drawsprite_images/longneck14.png new file mode 100644 index 0000000000000000000000000000000000000000..98dc9229b06dc091e0b4a8103e0a56716d0c4df6 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck14.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck15.png b/pd/doc/5.reference/drawsprite_images/longneck15.png new file mode 100644 index 0000000000000000000000000000000000000000..8b658c106b178555b1a4d9e81353606cba9aafea Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck15.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck16.png b/pd/doc/5.reference/drawsprite_images/longneck16.png new file mode 100644 index 0000000000000000000000000000000000000000..071909bb8d838dba0face63c49c749479c6be4fc Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck16.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck17.png b/pd/doc/5.reference/drawsprite_images/longneck17.png new file mode 100644 index 0000000000000000000000000000000000000000..14e46774acd10a4dd14f81d09de04d33aeeb7219 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck17.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck18.png b/pd/doc/5.reference/drawsprite_images/longneck18.png new file mode 100644 index 0000000000000000000000000000000000000000..2977fe30266c494af4e72ba8b315c7c21fc9f215 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck18.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck19.png b/pd/doc/5.reference/drawsprite_images/longneck19.png new file mode 100644 index 0000000000000000000000000000000000000000..9c75d7a038c843ee1722e1301be94c5aea17142d Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck19.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck20.png b/pd/doc/5.reference/drawsprite_images/longneck20.png new file mode 100644 index 0000000000000000000000000000000000000000..024eb0fd9acd98bd257d2a24b5619a54b436d91a Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck20.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck21.png b/pd/doc/5.reference/drawsprite_images/longneck21.png new file mode 100644 index 0000000000000000000000000000000000000000..5810c8723e39de66790e44631aff94b05bce50e6 Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck21.png differ diff --git a/pd/doc/5.reference/drawsprite_images/longneck22.png b/pd/doc/5.reference/drawsprite_images/longneck22.png new file mode 100644 index 0000000000000000000000000000000000000000..ef61f97e3fe96d11b7abc9151bd344191199eb1e Binary files /dev/null and b/pd/doc/5.reference/drawsprite_images/longneck22.png differ diff --git a/pd/doc/5.reference/drawsvg-help.pd b/pd/doc/5.reference/drawsvg-help.pd new file mode 100644 index 0000000000000000000000000000000000000000..ed2ba4d654a10c37151cd250320db1c0adf83c6f --- /dev/null +++ b/pd/doc/5.reference/drawsvg-help.pd @@ -0,0 +1,171 @@ +#N struct draw-svg-help-struct float x float y; +#N canvas 157 53 555 619 10; +#X obj 0 595 cnv 15 552 21 empty \$0-pddp.cnv.footer empty 20 12 0 +14 -228856 -66577 0; +#X obj 0 0 cnv 15 552 40 empty \$0-pddp.cnv.header draw\ svg 3 12 0 +18 -204280 -1 0; +#X obj 0 347 cnv 3 550 3 empty \$0-pddp.cnv.inlets inlets 8 12 0 13 +-228856 -1 0; +#N canvas 494 296 482 332 META 0; +#X text 12 115 LIBRARY internal; +#X text 12 25 LICENSE SIBSD; +#X text 12 5 KEYWORDS control GUI data-structure; +#X text 12 45 DESCRIPTION draw an svg shape to represent a scalar; +#X text 12 65 INLET_0 float fill fill-opacity fill-rule stroke stroke-dasharray +stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width +rx ry; +#X text 12 135 AUTHOR Jonathan Wilkes; +#X text 13 155 HELP_PATCH_AUTHORS Jonathan Wilkes; +#X restore 500 597 pd META; +#X obj 0 444 cnv 3 550 3 empty \$0-pddp.cnv.outlets outlets 8 12 0 +13 -228856 -1 0; +#X obj 0 481 cnv 3 550 3 empty \$0-pddp.cnv.argument arguments 8 12 +0 13 -228856 -1 0; +#X obj 0 542 cnv 3 550 3 empty \$0-pddp.cnv.more_info more_info 8 12 +0 13 -228856 -1 0; +#X obj 78 355 cnv 17 3 80 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#N canvas 212 516 428 108 Related_objects 0; +#X obj 1 1 cnv 15 425 20 empty \$0-pddp.cnv.subheading empty 3 12 0 +14 -204280 -1 0; +#X obj 27 35 draw; +#X text 7 1 [draw svg] Related Objects; +#X restore 101 597 pd Related_objects; +#X obj 78 453 cnv 17 3 17 empty \$0-pddp.cnv.let.0 0 5 9 0 16 -228856 +-162280 0; +#X obj 4 597 pddp/pddplink all_about_help_patches.pd -text Usage Guide +; +#X text 98 394 [draw] also takes a number of messages. These are svg +attributes that define how the object is drawn. See the subpatch above +for a full list.; +#X obj 172 552 pddp/pddplink drawarray-help.pd -text draw array; +#X text 101 554 See also:; +#X obj 172 572 pddp/pddplink drawimage-help.pd -text draw image; +#X obj 242 552 pddp/pddplink drawsprite-help.pd -text draw sprite; +#X text 11 20 draw shapes inside an svg container; +#X obj 146 52 struct draw-svg-help-struct float x float y; +#X scalar draw-svg-help-struct 207 120 \;; +#X obj 34 137 r \$0-drag; +#X obj 34 159 route drag; +#N canvas 0 0 450 300 pan 0; +#X obj 50 51 unpack p 0 0; +#X floatatom 82 75 5 0 0 0 - - -, f 5; +#X floatatom 123 72 5 0 0 0 - - -, f 5; +#X obj 47 20 inlet; +#X obj 71 122 * -1; +#X obj 128 120 * -1; +#X obj 71 154 +; +#X obj 128 152 +; +#X obj 71 176 t a; +#X obj 128 174 t a; +#X obj 71 198 outlet; +#X obj 128 196 outlet; +#X connect 0 1 1 0; +#X connect 0 1 4 0; +#X connect 0 2 2 0; +#X connect 0 2 5 0; +#X connect 3 0 0 0; +#X connect 4 0 6 0; +#X connect 5 0 7 0; +#X connect 6 0 8 0; +#X connect 7 0 9 0; +#X connect 8 0 6 1; +#X connect 8 0 10 0; +#X connect 9 0 7 1; +#X connect 9 0 11 0; +#X restore 34 181 pd pan; +#X obj 33 211 pack; +#X text 98 354 viewBox; +#X text 168 355 - Four floats to define the viewport of the container: +xOrigin yOrigin width height. See svg spec for more details; +#X text 99 453 anything; +#X text 169 453 - messages in response to any events set for the object +; +#X text 81 498 1) float; +#X text 171 498 - initial width of the container; +#X text 81 515 2) float; +#X text 171 515 - initial height of the container; +#N canvas 492 53 686 639 (subpatch) 0; +#X obj 41 52 draw path m 5 194.088 l 666.819 0 l 0 -36.9314 l -3.12158 +0 l 0 3.03125 l -5.96875 0 l 0 -1.5 l -7.40625 0 l 0 5.40625 l -5.65625 +0 l 0 1.6875 l -3.125 0 l 0 -1.65625 l -5.40625 0 l -6.84375 -6.84375 +l -1.84375 3.21875 l -2.5625 0 l 0 -19.1562 c 1.11498 -0.60865 1.90625 +-1.76523 1.90625 -3.125 c 0 -1.35977 -0.79127 -2.51635 -1.90625 -3.125 +l 0 -13.4375 l 2.03125 0 l 0 -2.3125 l -2.6938 0 l -0.99404 -12.4839 +l -0.90632 12.4839 l -3.62459 0 l 0 1.84375 l 2.51562 0 l 0 1.79466 +l -1.23437 0 l 0 1.99861 l 1.5625 0 l 0 10.0817 c -1.14211 0.60033 +-1.9375 1.77639 -1.9375 3.15625 c 0 1.37986 0.79539 2.55592 1.9375 +3.15625 l 0 19.625 l -2.90625 0 l 0 -5.59375 l -3.875 -3.90625 l -6.65625 +3.84375 l 0 -2.5 l -3.53125 0.96875 l 0 7.4375 l -2.59375 0 l 0 -3.8125 +l -17.5938 0 l 0 4 l -5.03125 0 l 0 -3.75 l -11.875 0 l 0 3.3125 l +-3.78125 0 l -0.78125 -26.4688 l -0.78125 25.1875 l -2.3125 0 l 0 -3.96875 +l -2.9375 0 l 0 3.5 l -3.5 0 l 0 -2.1875 l -5.21875 0 l 0 5.1875 l +-7.8125 0 l 0 -2.53125 l -7.53125 0 l 0.25 -20.8438 l -1.28125 21.3438 +l -4.09375 0 l 0 -6.3125 l -3.1875 0 l -0.9375 3.5 l -3.875 0 l 0 4.3125 +l -2.3125 0 l 0 -6.34375 l -2.03125 -0.53125 l 0 4.875 l -1.28125 0 +l 0 2.40625 l -1.59375 0 l 0 3.5 l -4.59375 0 l 0 -23.125 l -11.6875 +0 l 0 -3.15625 l -3.46875 0 l 0 3.15625 l -3.875 0 l 0 8.71875 l -4.09375 +0 l 0 5.15625 l -3.09375 0 l 0 4.375 l -2.125 0 l 0 -3.375 l -1.71875 +0 l 0 -5.40625 l -6.59375 0 l 0 2.59375 l -8.59375 0 l 0 3.34375 l +-9.75 0 l 0 -14.7188 l -3.90625 0 l 0 -1.71875 l -3.5625 0 l 0 2.3125 +l -2.0625 0 l 0 -2.59375 l -6.15625 0 l 0 6.96875 l -3.125 0 l 0 5.1875 +l -1.5625 0 l 0 -9 l -1.5 0 l 0 -2.15625 l -5.75 0 l -0.65625 -2.53125 +l -12.0938 0 l 0 5.15625 l -2.0625 0 l 0 6.6875 l -4.375 0 l -1.84375 +-3.09375 l 0 -77.75 l -1.46875 0 l 0 -1.96875 l 3.15625 0 l 0 -5.1875 +l 1.6875 0 l 0 -3.84375 l -1.6875 0 l 0 -8.28125 l -1.375 0 l 0 -3.5 +l 6.03125 0 l 0 -2.5625 l -2.4375 0 l 0 -5.0625 l 2.1875 0 l 0 -2.1875 +l -4.03125 0 l 0 -1.21875 l -2.78125 0 l 0 -3.125 l 1.71875 0 l 0 -1.9375 +l -4.28125 0 L 405.166 5 l -1.40625 26.7812 l -5.34375 0 l 0 1.9375 +l 1.96875 0 l 0 3.4375 c -2.95107 0.40253 -5.2699 1.439 -6.375 3.6875 +l 0 2.96875 l 2.03125 0 l 0 2.78125 l -1.40625 0 l 0 1.78125 l 5.09375 +0 l 0 3 l -2.125 0 l 0 8.28125 l -1.9375 0 l 0 3.84375 l 1.9375 0 l +0 4.6875 l 3.53125 0 l 0 2.46875 l -2.0625 0 l 0 78.25 l -12.4062 0 +l 0 11.8438 l -5.65625 0 l 0 -22.125 l -5.40625 0 l 0 -1.53125 l -6.375 +0 l -0.46875 -9.625 l -0.4375 9.625 l -8.57193 0 l 0 3.09375 l -3.0625 +0 l 0 5.375 l -16.6191 0 l 0 5.65625 l -5.125 0 l 0 -2.90625 l -0.78125 +-3 l -5.65625 0 l 0 2.84375 l -1.37218 0 l 0 15.3442 l -3.41612 0 l +0 -18.438 l -8.0867 0 l 0 -3.59375 l -4 0 l 0 3.78125 l -1.90625 1.09375 +l 0 5.65625 l -33.2439 0 l 0 1.3125 l -1.8125 0 l 0 -4.40625 l -4.875 +0 l 0 -1.03125 l -3.875 0 l 0 -2.5625 l -4.375 0 l 0 6.6875 l -12.1514 +0 l 0 -2.5625 l -3.84375 0 l 0 -3.34375 l -4.25 0 l 0 10.4062 l -3.21875 +-3.21875 l 0 -25.9688 l -6.15625 0 l 0 -6.15625 l -5.15625 0 l 0 13.375 +l -6.99996 0 l 0 28.0945 l -6.09379 0 l 0 -8.06316 l -2.90625 -3.28125 +l -3.53125 3.28125 l 0 -8.8125 l -5.28125 0 l 0 -2.875 l -5.59375 0 +l 0 3.96875 l -3.5625 0 l 0 4.6875 l -1.5 0 l 0 -1.84375 l -10.7927 +0 l 0 3.125 l -17.4334 0 l 0 -3.34375 l -3.96875 0 l 0 -2.34375 l -6.9375 +0 l 0 -3.34375 l -3.84375 0 l -0.90625 -32.4375 c 1.7461 -0.54309 3.03125 +-2.16894 3.03125 -4.09375 c 0 -2.01445 -1.409 -3.66423 -3.28125 -4.125 +l -0.84375 -30.25 l -1.375 30.2812 c -1.77984 0.52232 -3.09375 2.14493 +-3.09375 4.09375 c 0 1.81116 1.13148 3.37093 2.71875 4 l -1.96875 43.7812 +l -4.46905 4.75707 l 0 3.18537 l -6.03095 -4.03614 l 0 -11.5625 l -19.25 +0 l 0 6.0625 l -2.59375 0 l 0 -78.5 l -32.9688 0 l 0 74.2188 l -4.53125 +0 l 0 2.5625 l -4.03125 0 l 0 2.34375 l -3.46875 0 l 0 -4.375 l -2.3125 +0 l 0 -5.40625 l -3.34375 0 l 0 -6.6875 l -6.0746 0 l 0 22.754 l -4.59819 +0 l 0 -1.83383 l -8.10846 0.0134 l 0 1.97273 l -4.875 0 l 0 8.96875 +l -4.875 0 l 0 -8.96878 l -4.15862 0 l 0 -3.01004 l -2.34138 0 l 0 +3.01004 l -11.75 0 l 0 7.43748 l -2.3125 0 l 0 3.34375 l -5.50958 0 +z; +#X obj 41 9 loadbang; +#X msg 41 31 drag 1; +#X obj 41 981 s \$0-drag; +#X text 135 6 Skyline from:; +#X obj 135 26 pddp/pddplink https://upload.wikimedia.org/wikipedia/commons/1/13/JohannesburgArtisticSilhouette.svg +; +#X connect 0 0 3 0; +#X connect 1 0 2 0; +#X connect 2 0 0 0; +#X restore 33 285 draw svg 300 200; +#X msg 33 233 viewBox \$1 \$2 300 200; +#X obj 34 52 loadbang; +#X msg 34 84 fill none \, stroke-width 2 \, stroke black \, stroke-dasharray +5 5, f 61; +#X obj 34 107 draw rect 300 200; +#X text 270 322 Click to drag the skyline; +#X connect 19 0 20 0; +#X connect 20 0 21 0; +#X connect 21 0 22 0; +#X connect 21 1 22 1; +#X connect 22 0 32 0; +#X connect 32 0 31 0; +#X connect 33 0 34 0; +#X connect 34 0 35 0; diff --git a/pd/nw/css/default.css b/pd/nw/css/default.css index c40f4e37dea875f3f372f32afbbe0b921f333845..4df1ccc685a781c50eff018628c1243e7bfdb85e 100644 --- a/pd/nw/css/default.css +++ b/pd/nw/css/default.css @@ -381,7 +381,7 @@ text { stroke: #ccc; } -/* A little hack for special canvas of [cnv]. +/* A little hack for special case of [cnv]. All other iemguis have a black border, but [cnv] sets its selection rectangle to the user-supplied fill color when the object diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index b3f2d9f9567c386437a786655ef542726ec02b10..b849fd4144e0a13fb3fb0f595da7619e2e3f6234 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -3264,9 +3264,9 @@ function gui_scalar_draw_select_rect(cid, tag, state, x1, y1, x2, y2, basex, bas } } -function gui_scalar_draw_group(cid, tag, parent_tag, attr_array) { +function gui_scalar_draw_group(cid, tag, parent_tag, type, attr_array) { var parent_elem, - g; + group; if (!patchwin[cid]) { return; } @@ -3275,9 +3275,9 @@ function gui_scalar_draw_group(cid, tag, parent_tag, attr_array) { attr_array = []; } attr_array.push("id", tag); - g = create_item(cid, "g", attr_array); - parent_elem.appendChild(g); - return g; + group = create_item(cid, type, attr_array); + parent_elem.appendChild(group); + return group; } function gui_scalar_configure_gobj(cid, tag, isselected, t1, t2, t3, t4, t5, t6) { @@ -3383,6 +3383,19 @@ function gui_draw_configure(cid, tag, attr, val) { configure_item(item, obj); } +// Special case for viewBox which, in addition to its inexplicably inconsistent +// camelcasing also has no "none" value in the spec. This requires us to create +// a special case to remove the attribute if the user wants to get back to +// the default behavior. +function gui_draw_viewbox(cid, tag, attr, val) { + // Value will be an empty array if the user provided no values + if (val.length) { + gui_draw_configure(cid, tag, attr, val) + } else { + get_item(cid, tag).removeAttribute("viewBox"); + } +} + // Configure multiple attr/val pairs (this should be merged with gui_draw_configure at some point function gui_draw_configure_all(cid, tag, attr_array) { var item = get_item(cid, tag); @@ -3507,55 +3520,58 @@ function gui_drawimage_new(obj_tag, file_path, canvasdir, flags) { var drawsprite = 1, drawimage_data = [], // array for base64 image data image_seq, - i, + count = 0, matchchar = "*", files, ext, + img_types = [".gif", ".jpeg", ".jpg", ".png", ".svg"], img; // dummy image to measure width and height image_seq = flags & drawsprite; - if (!path.isAbsolute(file_path)) { - file_path = path.join(canvasdir, file_path); + if (file_path !== "") { + if(!path.isAbsolute(file_path)) { + file_path = path.join(canvasdir, file_path); + } + file_path = path.normalize(file_path); } - file_path = path.normalize(file_path); - if (fs.existsSync(file_path) && fs.lstatSync(file_path).isDirectory()) { + if (file_path !== "" && + fs.existsSync(file_path) && + fs.lstatSync(file_path).isDirectory()) { files = fs.readdirSync(file_path) .sort(); // Note that js's "sort" method doesn't do the // "right thing" for numbers. For that we'd need // to provide our own sorting function // todo: warn about image sequence with > 999 - for (i = 0; i < files.length && i < 1000; i++) { - ext = path.extname(files[i]); - - // todo: tolower() - - if (ext === ".gif" || - ext === ".jpg" || - ext === ".png" || - ext === ".jpeg" || - ext === ".svg") { - + files.forEach(function(file) { + ext = path.extname(file).toLowerCase(); + if (img_types.indexOf(ext) != -1) { // Now add an element to that array with the image data drawimage_data.push({ type: ext === ".jpeg" ? "jpg" : ext.slice(1), - data: fs.readFileSync(path.join(file_path, files[i]),"base64") + data: fs.readFileSync(path.join(file_path, file),"base64") }); + count++; } - } - } else { - i = 0; + }); } - //post("no of files: " + i); + post("no of files: " + count); - if (i > 0) { - img = new pd_window.Image(); // create an image in the pd_window context - img.onload = function() { - pdsend(obj_tag, "size", this.width, this.height); - }; - img.src = "data:image/" + drawimage_data[0].type + - ";base64," + drawimage_data[0].data; - } else { - post("drawimage: warning: no images loaded"); + if (count === 0) { + // set a default image + drawimage_data.push({ + type: "png", + data: get_default_png_data() + }); + if (file_path !== "") { + post("draw image: error: couldn't load image"); + } + post("draw image: warning: no image loaded. Using default png"); } + img = new pd_window.Image(); // create an image in the pd_window context + img.onload = function() { + pdsend(obj_tag, "size", this.width, this.height); + }; + img.src = "data:image/" + drawimage_data[0].type + + ";base64," + drawimage_data[0].data; pd_cache.set(obj_tag, drawimage_data); // add the data to container } @@ -3648,18 +3664,23 @@ function gui_drawimage_index(cid, obj, data, index) { configure_item(image, { visibility: "visible" }); } +// Default png image data +function get_default_png_data() { + return ["iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAb1BMVEWBgYHX19", + "f///8vLy/8/Pzx8PH3+Pf19fXz8/Pu7u7l5eXj4+Pn5+fs7Oza2tr6+vnq6urh", + "4eHe3t7c3Nza2dr6+fro6Og1NTXr6+xYWFi1tbWjo6OWl5aLjItDQ0PPz8+/v7", + "+wsLCenZ5zc3NOTk4Rpd0DAAAAqElEQVQoz62L2Q6CMBBFhcFdCsomq+v/f6Mn", + "bdOSBn3ypNO5Nyez+kG0zN9NWZZK8RRbB/2XmMLSvSZp2mehTMVcLGIYbcWcLW", + "1/U4PIZCvmOCMSaWzEHGaMIq2NmJNn4ORuMybP6xxYD0SnE4NJDdc0fYv0LCJg", + "9g4RqV3BrJfB7Bzc+ILZOjC+YDYOjC+YKqsyHlOZAX5Msgwm1iRxgDYBSWjCm+", + "98AAfDEgD0K69gAAAAAElFTkSuQmCC" + ].join(""); +} + function gui_load_default_image(dummy_cid, key) { pd_cache.set(key, { type: "png", - data: ["iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAAb1BMVEWBgYHX19", - "f///8vLy/8/Pzx8PH3+Pf19fXz8/Pu7u7l5eXj4+Pn5+fs7Oza2tr6+vnq6urh", - "4eHe3t7c3Nza2dr6+fro6Og1NTXr6+xYWFi1tbWjo6OWl5aLjItDQ0PPz8+/v7", - "+wsLCenZ5zc3NOTk4Rpd0DAAAAqElEQVQoz62L2Q6CMBBFhcFdCsomq+v/f6Mn", - "bdOSBn3ypNO5Nyez+kG0zN9NWZZK8RRbB/2XmMLSvSZp2mehTMVcLGIYbcWcLW", - "1/U4PIZCvmOCMSaWzEHGaMIq2NmJNn4ORuMybP6xxYD0SnE4NJDdc0fYv0LCJg", - "9g4RqV3BrJfB7Bzc+ILZOjC+YDYOjC+YKqsyHlOZAX5Msgwm1iRxgDYBSWjCm+", - "98AAfDEgD0K69gAAAAAElFTkSuQmCC" - ].join("") + data: get_default_png_data() }); } diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index e9c8f2d27c0b4a8a0e212cc07fcf79a6df5cb2ed..fb50bb6c253d2585e58295a619cf219b8b14c013 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -1101,9 +1101,9 @@ static void canvas_pop(t_canvas *x, t_floatarg fvis) extern void *svg_new(t_pd *x, t_symbol *s, int argc, t_atom *argv); extern t_pd *svg_header(t_pd *x); -static void group_svginit(t_glist *gl) +static void group_svginit(t_glist *gl, t_symbol *type, int argc, t_atom *argv) { - gl->gl_svg = (t_pd *)(svg_new((t_pd *)gl, gensym("g"), 0, 0)); + gl->gl_svg = (t_pd *)(svg_new((t_pd *)gl, type, argc, argv)); t_pd *proxy = svg_header(gl->gl_svg); inlet_new(&gl->gl_obj, proxy, 0, 0); outlet_new(&gl->gl_obj, &s_anything); @@ -1116,10 +1116,14 @@ void canvas_restore(t_canvas *x, t_symbol *s, int argc, t_atom *argv) t_pd *z; int is_draw_command = 0; //fprintf(stderr,"canvas_restore %lx\n", x); - /* for [draw group] we add an inlet to the svg attr proxy */ - if (argc > 2 && argv[2].a_w.w_symbol == gensym("draw")) - { - group_svginit(x); + /* for [draw g] and [draw svg] we add an inlet to the svg attr proxy */ + if (atom_getsymbolarg(2, argc, argv) == gensym("draw")) + { + t_symbol *type = (atom_getsymbolarg(3, argc, argv) == gensym("svg")) ? + gensym("svg") : gensym("g"); + group_svginit(x, type, + (type == gensym("svg") && argc > 4) ? argc-4 : 0, + (type == gensym("svg") && argc > 4) ? argv+4 : 0); is_draw_command = 1; } if (argc > 3 || (is_draw_command && argc > 4)) @@ -1352,12 +1356,18 @@ static void *subcanvas_new(t_symbol *s) return (x); } -void *group_new(t_symbol *s) +void *group_new(t_symbol *type, int argc, t_atom *argv) { - t_canvas *x = subcanvas_new(s); - group_svginit(x); + t_symbol *groupname; + if (type == gensym("g")) + groupname = atom_getsymbolarg(0, argc, argv); + else /* no name for inner svg */ + groupname = &s_; + t_canvas *x = subcanvas_new(groupname); + group_svginit(x, type, argc, argv); return (x); } + static void canvas_click(t_canvas *x, t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl, t_floatarg alt) @@ -1376,6 +1386,14 @@ void canvas_fattensub(t_canvas *x, static void canvas_rename_method(t_canvas *x, t_symbol *s, int ac, t_atom *av) { + /* special case for [draw g] where the 3rd arg is the receiver name */ + if (x->gl_svg) + { + if (atom_getsymbolarg(0, ac, av) == gensym("g") && ac > 1) + ac--, av++; + else + ac = 0; + } if (ac && av->a_type == A_SYMBOL) canvas_rename(x, av->a_w.w_symbol, 0); else if (ac && av->a_type == A_DOLLSYM) diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c index 38463cd52709b9ce0d476255e2280b1bf2a54636..7432aa57e6ae483010ce9c3025c5392b1caa029a 100644 --- a/pd/src/g_scalar.c +++ b/pd/src/g_scalar.c @@ -409,6 +409,11 @@ extern int array_joc; extern void template_notifyforscalar(t_template *template, t_glist *owner, t_scalar *sc, t_symbol *s, int argc, t_atom *argv); +extern void scalar_getinnersvgrect(t_gobj *z, t_glist *owner, t_word *data, + t_template *template, t_float basex, t_float basey, + int *xp1, int *yp1, int *xp2, int *yp2); + +extern t_symbol *group_gettype(t_glist *glist); static void scalar_getgrouprect(t_glist *owner, t_glist *groupcanvas, t_word *data, t_template *template, int basex, int basey, int *x1, int *x2, int *y1, int *y2) @@ -420,8 +425,12 @@ static void scalar_getgrouprect(t_glist *owner, t_glist *groupcanvas, ((t_canvas *)y)->gl_svg) { /* todo: accumulate basex and basey for correct offset */ - scalar_getgrouprect(owner, (t_glist *)y, data, template, - basex, basey, x1, x2, y1, y2); + if (group_gettype((t_canvas *)y) == gensym("g")) + scalar_getgrouprect(owner, (t_glist *)y, data, template, + basex, basey, x1, x2, y1, y2); + else /* inner svg */ + scalar_getinnersvgrect(y, owner, data, template, basex, basey, + x1, y1, x2, y2); } else { @@ -876,8 +885,9 @@ static void scalar_groupvis(t_scalar *x, t_glist *owner, t_template *template, char parentbuf[MAXPDSTRING]; sprintf(parentbuf, "dgroup%lx.%lx", (long unsigned int)parent, (long unsigned int)x->sc_vec); - gui_start_vmess("gui_scalar_draw_group", "xss", - glist_getcanvas(owner), tagbuf, parentbuf); + gui_start_vmess("gui_scalar_draw_group", "xsss", + glist_getcanvas(owner), tagbuf, parentbuf, + group_gettype(gl)->s_name); svg_grouptogui(gl, template, x->sc_vec); gui_end_vmess(); @@ -998,8 +1008,8 @@ static void scalar_vis(t_gobj *z, t_glist *owner, int vis) sprintf(tagbuf, "scalar%lxgobj", (long unsigned int)x->sc_vec); sprintf(groupbuf, "dgroup%lx.%lx", (long unsigned int)templatecanvas, (long unsigned int)x->sc_vec); - gui_vmess("gui_scalar_draw_group", "xss", - glist_getcanvas(owner), groupbuf, tagbuf); + gui_vmess("gui_scalar_draw_group", "xsss", + glist_getcanvas(owner), groupbuf, tagbuf, "g"); pd_bind(&x->sc_gobj.g_pd, gensym(buf)); } diff --git a/pd/src/g_template.c b/pd/src/g_template.c index 866f6778722fafe1c29b3b6c8c5cc1489c2c02f0..dec213da843cdb96cfe5c3a719ee62848992c7e8 100644 --- a/pd/src/g_template.c +++ b/pd/src/g_template.c @@ -1102,6 +1102,8 @@ t_class *draw_class; t_class *drawimage_class; +t_class *drawarray_class; + t_class *svg_class; /* this is a wrapper around t_fielddesc-- it adds a flag for two reasons: @@ -1187,6 +1189,7 @@ typedef struct _svg t_svg_attr x_width; t_svg_attr x_height; t_svg_attr x_vis; + t_svg_attr x_viewbox[4]; t_fielddesc x_bbox; /* turn bbox calculation on or off */ int x_pathrect_cache; /* 0 to recalc on next draw_getrect call 1 for cached @@ -1214,18 +1217,23 @@ typedef struct _drawimage { t_object x_obj; t_fielddesc x_value; /* todo: rename to index */ - t_fielddesc x_xloc; - t_fielddesc x_yloc; t_fielddesc x_vis; t_symbol *x_img; t_float x_w; t_float x_h; int x_flags; - int x_deleteme; t_canvas *x_canvas; t_pd *x_attr; } t_drawimage; +typedef struct _drawarray +{ + t_object x_obj; + t_canvas *x_canvas; + t_fielddesc x_data; + t_pd *x_attr; +} t_drawarray; + extern t_outlet *obj_rightmost_outlet(t_object *x); void draw_notifyforscalar(t_object *x, t_glist *owner, @@ -1287,9 +1295,9 @@ void svg_attr_setfloatarg(t_svg_attr *a, int argc, t_atom *argv) a->a_flag = 1; } -void svg_attr_setfloat_const(t_svg_attr *a, float n) +void svg_attr_setfloat_const(t_svg_attr *a, t_float n) { - fielddesc_setfloat_const(&a->a_attr, 0); + fielddesc_setfloat_const(&a->a_attr, n); a->a_flag = 0; } @@ -1309,9 +1317,10 @@ void *svg_new(t_pd *parent, t_symbol *s, int argc, t_atom *argv) if (type == gensym("rect") || type == gensym("circle") || type == gensym("ellipse") || - type == gensym("line")) + type == gensym("line") || + type == gensym("svg")) { - if (type == gensym("rect")) + if (type == gensym("rect") || type == gensym("svg")) { if (argc) svg_attr_setfloatarg(&x->x_width, argc--, argv++); else svg_attr_setfloat_const(&x->x_width, 0); @@ -1349,10 +1358,13 @@ void *svg_new(t_pd *parent, t_symbol *s, int argc, t_atom *argv) for (i = 0; i < ncmds; i++) x->x_nargs_per_cmd[i] = 0; x->x_nargs = argc - ncmds; } - else if (x->x_type == gensym("g")) + else if (type == gensym("g") || type == gensym("svg")) { x->x_nargs = 0; x->x_vec = 0; + /* Hack to get around the path parsing below, which should really + be split out... */ + argc = 0; } else { @@ -1407,6 +1419,8 @@ void *svg_new(t_pd *parent, t_symbol *s, int argc, t_atom *argv) x->x_strokemiterlimit.a_flag = 0; x->x_strokeopacity.a_flag = 0; x->x_strokewidth.a_flag = 0; + /* set the flag of the first array element... */ + x->x_viewbox->a_flag = 0; x->x_x1 = 0; x->x_x2 = 0; x->x_y1 = 0; @@ -1466,7 +1480,8 @@ static int symbol_isdrawtype(t_symbol *s) s == gensym("line") || s == gensym("path") || s == gensym("polygon") || s == gensym("polyline") || s == gensym("rect") || s == gensym("image") || - s == gensym("sprite") || s == gensym("g")) + s == gensym("sprite") || s == gensym("g") || + s == gensym("svg") || s == gensym("array")) { return 1; } @@ -1475,7 +1490,8 @@ static int symbol_isdrawtype(t_symbol *s) } static void *drawimage_new(t_symbol *classsym, int argc, t_atom *argv); -extern void *group_new(t_symbol *s); +static void *drawarray_new(t_symbol *s, int argc, t_atom *argv); +extern void *group_new(t_symbol *type, int argc, t_atom *argv); static void *draw_new(t_symbol *classsym, t_int argc, t_atom *argv) { @@ -1484,19 +1500,14 @@ static void *draw_new(t_symbol *classsym, t_int argc, t_atom *argv) symbol_isdrawtype(argv[0].a_w.w_symbol)) { type = atom_getsymbolarg(0, argc--, argv++); - /* sprite and image have their own widgetbehavior, so they - have their own class and new function */ + /* sprite and image have their own widgetbehavior, and so does + array. They also have their own classes and constructors... */ if (type == gensym("sprite") || type == gensym("image")) return (drawimage_new(type, argc, argv)); - else if (type == gensym("g")) - { - t_symbol *group_name; - if (argc > 0 && argv->a_type == A_SYMBOL) - group_name = atom_getsymbolarg(0, argc, argv); - else group_name = &s_; - post("group name is %s", group_name->s_name); - return (group_new(group_name)); - } + else if (type == gensym("array")) + return (drawarray_new(type, argc, argv)); + else if (type == gensym("g") || type == gensym("svg")) + return (group_new(type, argc, argv)); } else { @@ -1537,7 +1548,7 @@ t_canvas *svg_parentcanvas(t_svg *x) use case, but that doesn't seem like a sensible interface in general. */ t_canvas *ret = 0; - if (x->x_type == gensym("g")) + if (x->x_type == gensym("g") || x->x_type == gensym("svg")) { t_canvas *c = (t_canvas *)x->x_parent; if (c->gl_owner) @@ -1551,6 +1562,11 @@ t_canvas *svg_parentcanvas(t_svg *x) t_drawimage *d = (t_drawimage *)x->x_parent; ret = d->x_canvas; } + else if (x->x_type == gensym("array")) + { + t_drawarray *d = (t_drawarray *)x->x_parent; + ret = d->x_canvas; + } else { t_draw *d = (t_draw *)x->x_parent; @@ -1705,6 +1721,11 @@ t_svg_attr *svg_getattr(t_svg *x, t_symbol *s) return 0; } +t_symbol *group_gettype(t_glist *glist) +{ + return ((t_svg *)glist->gl_svg)->x_type; +} + void svg_parsetransform(t_svg *x, t_template *template, t_word *data, t_float *mp1, t_float *mp2, t_float *mp3, t_float *mp4, t_float *mp5, t_float *mp6); @@ -1723,7 +1744,7 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s, int in_array = (sc->sc_vec != data); //post("in_array is %d", in_array); char tag[MAXPDSTRING]; - if (x->x_type == gensym("g")) + if (x->x_type == gensym("g") || x->x_type == gensym("svg")) { sprintf(tag, "%s%lx.%lx", (in_array ? "scelem" : "dgroup"), @@ -1797,7 +1818,18 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s, t_float m1, m2, m3, m4, m5, m6; /* we'll probably get a different bbox now, so we will calculate a new one the next time we call draw_getrect for this draw command. - For groups we need to do it for all of the draw commands inside it. + For g we need to do it for all of the draw commands inside it. + + For inner svgs, however, we can ignore the inner content since + it will never appear outside the width/height specified for the + container. (At least not for now, since we don't allow the user + to set an overflow style of "visible.") This allows us to get + a speedup when interacting with content inside an inner svg, as + Pd doesn't have to do any complex bbox calculations. + + Unfortunately, the HTML5 getBBox() method calculates the boundaries + _without_ regard to clipping, so clipped content in inner svg will + still trigger scrollbars. */ if (x->x_type == gensym("g")) svg_group_pathrect_cache(x, 0); @@ -1930,6 +1962,25 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s, gui_vmess("gui_drawimage_index", "xxxi", glist_getcanvas(c), parent, data, drawimage_getindex(parent, template, data)); } + else if (s == gensym("viewbox")) + { + gui_start_vmess("gui_draw_viewbox", "xss", + glist_getcanvas(c), tag, "viewBox"); + gui_start_array(); + if (x->x_viewbox->a_flag) + { + gui_f(fielddesc_getcoord(&x->x_viewbox[0].a_attr, + template, data, 0)); + gui_f(fielddesc_getcoord(&x->x_viewbox[1].a_attr, + template, data, 0)); + gui_f(fielddesc_getcoord(&x->x_viewbox[2].a_attr, + template, data, 0)); + gui_f(fielddesc_getcoord(&x->x_viewbox[3].a_attr, + template, data, 0)); + } + gui_end_array(); + gui_end_vmess(); + } else if (s == gensym("points")) { char tagbuf[MAXPDSTRING]; @@ -2175,6 +2226,22 @@ void svg_setattr(t_svg *x, t_symbol *s, t_int argc, t_atom *argv) } } +/* Currently used just to update the arguments when the user changes + the arguments in an existing [draw svg] object. */ +void svg_update_args(t_svg *x, t_symbol *s, int argc, t_atom *argv) +{ +post("made it to args"); +if (argc) post("first arg is %s", atom_getsymbolarg(0, argc, argv)->s_name); + /* "g" doesn't take any args, so check for "svg" arg */ + if (atom_getsymbolarg(0, argc, argv) == gensym("svg")) + { + argc--, argv++; + if (argc) svg_setattr(x, gensym("width"), argc--, argv++), post("did width"); + if (argc) svg_setattr(x, gensym("height"), argc--, argv++); + if (argc) svg_setattr(x, gensym("x"), argc--, argv++); + if (argc) svg_setattr(x, gensym("y"), argc--, argv++); + } +} void svg_vis(t_svg *x, t_symbol *s, int argc, t_atom *argv) { @@ -2577,6 +2644,29 @@ void svg_linepoints(t_svg *x, t_symbol *s, int argc, t_atom *argv) } } +void svg_viewbox(t_svg *x, t_symbol *s, int argc, t_atom *argv) +{ + if (argc) + { + t_svg_attr *vbx = x->x_viewbox; + svg_attr_setfloatarg(vbx++, argc--, argv++); + + if (argc) svg_attr_setfloatarg(vbx++, argc--, argv++); + else svg_attr_setfloat_const(vbx++, 0); + + if (argc) svg_attr_setfloatarg(vbx++, argc--, argv++); + else svg_attr_setfloat_const(vbx++, 0); + + if (argc) svg_attr_setfloatarg(vbx, argc, argv); + else svg_attr_setfloat_const(vbx, 0); + } + else + { + x->x_viewbox->a_flag = 0; + } + svg_update(x, gensym("viewbox")); +} + static int minv(t_float a[][3], t_float b[][3]) { t_float tmp[3][3], determinant = 0; @@ -3513,6 +3603,90 @@ static void svg_getpathrect(t_svg *x, t_glist *glist, *yp2 = (int)(finaly2 + basey); } +static void svg_getrectrect(t_svg *x, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + int width, height, xoff, yoff; + int x1, y1, x2, y2; + x1 = y1 = 0x7fffffff; + x2 = y2 = -0x7fffffff; + + t_float mtx1[3][3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }; + t_float mtx2[3][3] = { {1, 0, 0}, {0, 1, 0}, {1, 0, 1} }; + t_float m1, m2, m3, m4, m5, m6, + tx1, ty1, tx2, ty2, t5, t6; + if (!fielddesc_getfloat(&x->x_bbox, template, data, 0) || + (x->x_vis.a_flag && !fielddesc_getfloat(&x->x_vis.a_attr, + template, data, 0))) + { + *xp1 = *yp1 = 0x7fffffff; + *xp2 = *yp2 = -0x7fffffff; + return; + } + + svg_groupmtx(x, template, data, mtx1); + width = fielddesc_getcoord(&x->x_width.a_attr, template, data, 0); + height = fielddesc_getcoord(&x->x_height.a_attr, template, data, 0); + xoff = fielddesc_getcoord(&x->x_x.a_attr, template, data, 0); + yoff = fielddesc_getcoord(&x->x_y.a_attr, template, data, 0); + + mset(mtx2, xoff, yoff, xoff + width, yoff + height, 0, 0); + mtx2[2][0] = 1; mtx2[2][1] = 1; + mmult(mtx1, mtx2, mtx2); + mget(mtx2, &tx1, &ty1, &tx2, &ty2, &t5, &t6); + if (tx1 < x1) x1 = tx1; + if (tx2 < x1) x1 = tx2; + if (ty1 < y1) y1 = ty1; + if (ty2 < y1) y1 = ty2; + if (tx1 > x2) x2 = tx1; + if (tx2 > x2) x2 = tx2; + if (ty1 > y2) y2 = ty1; + if (ty2 > y2) y2 = ty2; + mset(mtx2, xoff, yoff + height, xoff + width, yoff, 0, 0); + mtx2[2][0] = 1; mtx2[2][1] = 1; + mmult(mtx1, mtx2, mtx2); + mget(mtx2, &tx1, &ty1, &tx2, &ty2, &t5, &t6); + if (tx1 < x1) x1 = tx1; + if (tx2 < x1) x1 = tx2; + if (ty1 < y1) y1 = ty1; + if (ty2 < y1) y1 = ty2; + if (tx1 > x2) x2 = tx1; + if (tx2 > x2) x2 = tx2; + if (ty1 > y2) y2 = ty1; + if (ty2 > y2) y2 = ty2; + //x1 = glist_xtopixels(glist, basex + x1); + //x2 = glist_xtopixels(glist, basex + x2); + //y1 = glist_ytopixels(glist, basey + y1); + //y2 = glist_ytopixels(glist, basey + y2); + + x1 = basex + x1; + x2 = basex + x2; + y1 = basey + y1; + y2 = basey + y2; + + /* todo: put these up top */ + if (!fielddesc_getfloat(&x->x_vis.a_attr, template, data, 0)) + { + *xp1 = *yp1 = 0x7fffffff; + *xp2 = *yp2 = -0x7fffffff; + return; + } + *xp1 = x1; + *yp1 = y1; + *xp2 = x2; + *yp2 = y2; +} + +void scalar_getinnersvgrect(t_gobj *z, t_glist *owner, t_word *data, + t_template *template, t_float basex, t_float basey, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + t_canvas *c = (t_canvas *)z; + svg_getrectrect((t_svg *)c->gl_svg, + owner, data, template, basex, basey, xp1, yp1, xp2, yp2); +} + static void draw_getrect(t_gobj *z, t_glist *glist, t_word *data, t_template *template, t_float basex, t_float basey, int *xp1, int *yp1, int *xp2, int *yp2) @@ -3811,13 +3985,13 @@ static void svg_togui(t_svg *x, t_template *template, t_word *data) } if (x->x_x.a_flag) { - gui_s(x->x_type == gensym("rect") ? "x" : + gui_s(x->x_type == gensym("rect") || x->x_type == gensym("svg") ? "x" : x->x_type == gensym("line") ? "x1" : "cx"); gui_f(fielddesc_getcoord(&x->x_x.a_attr, template, data, 0)); } if (x->x_y.a_flag) { - gui_s(x->x_type == gensym("rect") ? "y" : + gui_s(x->x_type == gensym("rect") || x->x_type == gensym("svg") ? "y" : x->x_type == gensym("line") ? "y1" : "cy"); gui_f(fielddesc_getcoord(&x->x_y.a_attr, template, data, 0)); } @@ -3944,6 +4118,20 @@ static void svg_togui(t_svg *x, t_template *template, t_word *data) gui_f(fielddesc_getcoord(&x->x_ry.a_attr, template, data, 0)); } + if (x->x_viewbox->a_flag) + { + gui_s("viewBox"); + gui_start_array(); + gui_f(fielddesc_getcoord(&x->x_viewbox[0].a_attr, + template, data, 0)); + gui_f(fielddesc_getcoord(&x->x_viewbox[1].a_attr, + template, data, 0)); + gui_f(fielddesc_getcoord(&x->x_viewbox[2].a_attr, + template, data, 0)); + gui_f(fielddesc_getcoord(&x->x_viewbox[3].a_attr, + template, data, 0)); + gui_end_array(); + } // Not sure why display attr is here... gui_s("display"); gui_s("inline"); @@ -4564,6 +4752,8 @@ static void draw_setup(void) gensym("stroke-width"), A_GIMME, 0); class_addmethod(svg_class, (t_method)svg_transform, gensym("transform"), A_GIMME, 0); + class_addmethod(svg_class, (t_method)svg_viewbox, + gensym("viewBox"), A_GIMME, 0); class_addmethod(svg_class, (t_method)svg_setattr, gensym("vis"), A_GIMME, 0); class_addmethod(svg_class, (t_method)svg_setattr, @@ -4580,6 +4770,8 @@ static void draw_setup(void) gensym("y1"), A_GIMME, 0); class_addmethod(svg_class, (t_method)svg_setattr, gensym("y2"), A_GIMME, 0); + class_addmethod(svg_class, (t_method)svg_update_args, + gensym("update_svg"), A_GIMME, 0); } /* ------------------------------ event --------------------------------- */ @@ -5513,8 +5705,6 @@ static void plot_getgrouprect(t_glist *glist, t_template *elemtemplate, } } - - static void plot_getrect(t_gobj *z, t_glist *glist, t_word *data, t_template *template, t_float basex, t_float basey, int *xp1, int *yp1, int *xp2, int *yp2) @@ -5697,10 +5887,11 @@ static void plot_groupvis(t_scalar *x, t_glist *owner, t_word *data, (long unsigned int)data); sprintf(parent_tagbuf, "scelem%lx.%lx", (long unsigned int)parent, (long unsigned int)data); - gui_start_vmess("gui_create_scalar_group", "xss", + gui_start_vmess("gui_scalar_draw_group", "xsss", glist_getcanvas(owner), tagbuf, - parent_tagbuf); + parent_tagbuf, + "g"); svg_grouptogui(groupcanvas, template, data); gui_end_vmess(); for (y = groupcanvas->gl_list; y; y = y->g_next) @@ -6325,148 +6516,660 @@ static void plot_setup(void) class_setparentwidget(plot_class, &plot_widgetbehavior); } -/* ---------------- drawnumber: draw a number (or symbol) ---------------- */ - -/* - drawnumbers draw numeric fields at controllable locations, with - controllable color and label. invocation: - (drawnumber|drawsymbol) [-v <visible>] variable x y color label -*/ - -t_class *drawnumber_class; - -#define DRAW_SYMBOL 1 +/* --------- generic draw command for showing arrays --------------- */ -typedef struct _drawnumber +static void *drawarray_new(t_symbol *s, int argc, t_atom *argv) { - t_object x_obj; - t_fielddesc x_value; - t_fielddesc x_xloc; - t_fielddesc x_yloc; - t_fielddesc x_color; - t_fielddesc x_vis; - t_fielddesc x_fontsize; - t_symbol *x_label; - int x_flags; - t_canvas *x_canvas; -} t_drawnumber; + t_drawarray *x = (t_drawarray *)pd_new(drawarray_class); -static void *drawnumber_new(t_symbol *classsym, t_int argc, t_atom *argv) -{ - if (legacy_draw_in_group(canvas_getcurrent())) - return 0; + /* We need a t_svg to associate with it */ + x->x_attr = (t_pd *)svg_new((t_pd *)x, s, 0, 0); + t_svg *sa = (t_svg *)x->x_attr; - t_drawnumber *x = (t_drawnumber *)pd_new(drawnumber_class); - char *classname = classsym->s_name; - int flags = 0; - int got_font_size = 0; - - if (classname[4] == 's') - flags |= DRAW_SYMBOL; - x->x_flags = flags; - fielddesc_setfloat_const(&x->x_vis, 1); x->x_canvas = canvas_getcurrent(); - while (1) - { - t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); - if (!strcmp(firstarg->s_name, "-v") && argc > 1) - { - fielddesc_setfloatarg(&x->x_vis, 1, argv+1); - argc -= 2; argv += 2; - } - else break; - } - if (flags & DRAW_SYMBOL) - { - if (argc) fielddesc_setsymbolarg(&x->x_value, argc--, argv++); - else fielddesc_setsymbol_const(&x->x_value, &s_); - } - else - { - if (argc) fielddesc_setfloatarg(&x->x_value, argc--, argv++); - else fielddesc_setfloat_const(&x->x_value, 0); - } - if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++); - else fielddesc_setfloat_const(&x->x_xloc, 0); - if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++); - else fielddesc_setfloat_const(&x->x_yloc, 0); - if (argc) fielddesc_setfloatarg(&x->x_color, argc--, argv++); - else fielddesc_setfloat_const(&x->x_color, 1); + t_template *t = template_findbyname( + canvas_makebindsym(x->x_canvas->gl_name)); - if (argc == 2) - { - fielddesc_setfloatarg(&x->x_fontsize, argc--, argv++); - got_font_size = 1; - } - if (argc) - { - if (argv->a_type == A_SYMBOL || got_font_size) - { - x->x_label = atom_getsymbolarg(0, argc, argv); - if (!got_font_size) - fielddesc_setfloatarg(&x->x_fontsize, 0, NULL); - } - else if (argv->a_type == A_FLOAT) - { - fielddesc_setfloatarg(&x->x_fontsize, argc, argv); - x->x_label = &s_; - } - } else { - fielddesc_setfloatarg(&x->x_fontsize, 0, NULL); - x->x_label = &s_; - } + if (argc) fielddesc_setarrayarg(&x->x_data, argc--, argv++); + else fielddesc_setfloat_const(&x->x_data, 1); + + /* Default dimensions for SVG: 150x100 */ + if (argc) svg_attr_setfloatarg(&sa->x_width, argc--, argv++); + else svg_attr_setfloat_const(&sa->x_width, 150); + if (argc) svg_attr_setfloatarg(&sa->x_height, argc--, argv++); + else svg_attr_setfloat_const(&sa->x_height, 100); return (x); } -void drawnumber_float(t_drawnumber *x, t_floatarg f) +void drawarray_float(t_drawarray *x, t_floatarg f) { - int viswas; - if (x->x_vis.fd_type != A_FLOAT || x->x_vis.fd_var) - { - pd_error(x, "global vis/invis for a template with variable visibility"); - return; - } - viswas = (x->x_vis.fd_un.fd_float != 0); - - if ((f != 0 && viswas) || (f == 0 && !viswas)) - return; - canvas_redrawallfortemplatecanvas(x->x_canvas, 2); - fielddesc_setfloat_const(&x->x_vis, (f != 0)); - canvas_redrawallfortemplatecanvas(x->x_canvas, 1); + /* toggle visibility on and off */ } -/* -------------------- widget behavior for drawnumber ------------ */ - -/*#define DRAWNUMBER_BUFSIZE 80 -static void drawnumber_sprintf(t_drawnumber *x, char *buf, t_atom *ap) +void drawarray_transform(t_drawarray *x, t_floatarg f) { - int nchars; - strncpy(buf, x->x_label->s_name, DRAWNUMBER_BUFSIZE); - buf[DRAWNUMBER_BUFSIZE - 1] = 0; - nchars = strlen(buf); - atom_string(ap, buf + nchars, DRAWNUMBER_BUFSIZE - nchars); -}*/ + /* draw array uses an inner svg as the container, which + has no transform attribute */ + pd_error(x, "draw array: no method for 'transform'"); +} -static int drawnumber_gettype(t_drawnumber *x, t_word *data, - t_template *template, int *onsetp) +static void drawarray_anything(t_drawarray *x, t_symbol *s, int argc, + t_atom *argv) { - int type; - t_symbol *arraytype; - if (template_find_field(template, /*x->x_fieldname*/ x->x_value.fd_un.fd_varsym, onsetp, &type, - &arraytype) && type != DT_ARRAY) - return (type); - else return (-1); + /* forward to t_svg thingy */ + pd_typedmess(x->x_attr, s, argc, argv); } -#define DRAWNUMBER_BUFSIZE 1024 -static void drawnumber_getbuf(t_drawnumber *x, t_word *data, - t_template *template, char *buf) +/* -------------------- widget behavior for drawarray ------------ */ + + + /* get everything we'll need from the owner template of the array being + drawn. Not used for garrays, but see below */ +static int drawarray_readownertemplate(t_drawarray *x, + t_word *data, t_template *ownertemplate, + t_symbol **elemtemplatesymp, t_array **arrayp) { - int nchars, onset, type = drawnumber_gettype(x, data, template, &onset); - if (type < 0) - buf[0] = 0; - else + int arrayonset, type; + t_symbol *elemtemplatesym; + t_array *array; + + /* find the data and verify it's an array */ + if (x->x_data.fd_type != A_ARRAY || !x->x_data.fd_var) + { + error("draw array: needs an array field"); + return (-1); + } + if (!template_find_field(ownertemplate, x->x_data.fd_un.fd_varsym, + &arrayonset, &type, &elemtemplatesym)) + { + error("draw array: %s: no such field", x->x_data.fd_un.fd_varsym->s_name); + return (-1); + } + if (type != DT_ARRAY) + { + error("draw array: %s: not an array", x->x_data.fd_un.fd_varsym->s_name); + return (-1); + } + array = *(t_array **)(((char *)data) + arrayonset); + *elemtemplatesymp = elemtemplatesym; + *arrayp = array; + + return (0); +} + +static void drawarray_getgrouprect(t_glist *glist, t_template *elemtemplate, + t_canvas *groupcanvas, int elemsize, + t_array *array, int i, t_float usexloc, t_float useyloc, + int *x1, int *y1, int *x2, int *y2) +{ + t_gobj *y; + for (y = groupcanvas->gl_list; y; y = y->g_next) + { + if (pd_class(&y->g_pd) == canvas_class && + ((t_canvas *)y)->gl_svg) + { + drawarray_getgrouprect(glist, elemtemplate, (t_canvas *)y, + elemsize, array, i, usexloc, useyloc, x1, y1, x2, y2); + } + //fprintf(stderr,".-.-. usexloc %f useyloc %f " + // "(alt %f %f)\n", + // usexloc, useyloc, + // basex + xloc + + // fielddesc_cvttocoord(xfielddesc, + // *(t_float *)(((char *)(array->a_vec) + elemsize * i) + // + xonset)), + // *(t_float *)(((char *)(array->a_vec) + elemsize * i) + + // yonset)); + int xx1, xx2, yy1, yy2; + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentgetrectfn)(y, glist, + (t_word *)((char *)(array->a_vec) + elemsize * i), + elemtemplate, usexloc, useyloc, + &xx1, &yy1, &xx2, &yy2); + //fprintf(stderr," .....drawarray_getrect %d %d %d %d\n", + // xx1, yy1, xx2, yy2); + if (xx1 < *x1) + *x1 = xx1; + if (yy1 < *y1) + *y1 = yy1; + if (xx2 > *x2) + *x2 = xx2; + if (yy2 > *y2) + *y2 = yy2; + //fprintf(stderr," ....drawarray_getrect %d %d %d %d\n", + // x1, y1, x2, y2); + } +} + +static void drawarray_getrect(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + t_drawarray *x = (t_drawarray *)z; + int width, height, xoff, yoff; + int x1, y1, x2, y2; + x1 = y1 = 0x7fffffff; + x2 = y2 = -0x7fffffff; + + t_float mtx1[3][3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }; + t_float mtx2[3][3] = { {1, 0, 0}, {0, 1, 0}, {1, 0, 1} }; + t_float m1, m2, m3, m4, m5, m6, + tx1, ty1, tx2, ty2, t5, t6; + t_svg *sa = (t_svg *)x->x_attr; + if (!fielddesc_getfloat(&sa->x_bbox, template, data, 0) || + (sa->x_vis.a_flag && !fielddesc_getfloat(&sa->x_vis.a_attr, + template, data, 0))) + { + *xp1 = *yp1 = 0x7fffffff; + *xp2 = *yp2 = -0x7fffffff; + return; + } + + svg_groupmtx(sa, template, data, mtx1); + width = fielddesc_getcoord(&sa->x_width.a_attr, template, data, 0); + height = fielddesc_getcoord(&sa->x_height.a_attr, template, data, 0); + xoff = fielddesc_getcoord(&sa->x_x.a_attr, template, data, 0); + yoff = fielddesc_getcoord(&sa->x_y.a_attr, template, data, 0); + + mset(mtx2, xoff, yoff, xoff + width, yoff + height, 0, 0); + mtx2[2][0] = 1; mtx2[2][1] = 1; + mmult(mtx1, mtx2, mtx2); + mget(mtx2, &tx1, &ty1, &tx2, &ty2, &t5, &t6); + if (tx1 < x1) x1 = tx1; + if (tx2 < x1) x1 = tx2; + if (ty1 < y1) y1 = ty1; + if (ty2 < y1) y1 = ty2; + if (tx1 > x2) x2 = tx1; + if (tx2 > x2) x2 = tx2; + if (ty1 > y2) y2 = ty1; + if (ty2 > y2) y2 = ty2; + mset(mtx2, xoff, yoff + height, xoff + width, yoff, 0, 0); + mtx2[2][0] = 1; mtx2[2][1] = 1; + mmult(mtx1, mtx2, mtx2); + mget(mtx2, &tx1, &ty1, &tx2, &ty2, &t5, &t6); + if (tx1 < x1) x1 = tx1; + if (tx2 < x1) x1 = tx2; + if (ty1 < y1) y1 = ty1; + if (ty2 < y1) y1 = ty2; + if (tx1 > x2) x2 = tx1; + if (tx2 > x2) x2 = tx2; + if (ty1 > y2) y2 = ty1; + if (ty2 > y2) y2 = ty2; + //x1 = glist_xtopixels(glist, basex + x1); + //x2 = glist_xtopixels(glist, basex + x2); + //y1 = glist_ytopixels(glist, basey + y1); + //y2 = glist_ytopixels(glist, basey + y2); + + x1 = basex + x1; + x2 = basex + x2; + y1 = basey + y1; + y2 = basey + y2; + + /* todo: put these up top */ + if (!fielddesc_getfloat(&sa->x_vis.a_attr, template, data, 0)) + { + *xp1 = *yp1 = 0x7fffffff; + *xp2 = *yp2 = -0x7fffffff; + return; + } + *xp1 = x1; + *yp1 = y1; + *xp2 = x2; + *yp2 = y2; +} + +static void drawarray_displace(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int dx, int dy) +{ + /* not yet */ +} + +static void drawarray_select(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int state) +{ + //fprintf(stderr,"drawarray_select %d\n", state); + /* not yet */ +} + +static void drawarray_activate(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_float basex, t_float basey, + int state) +{ + /* not yet */ +} + +static void drawarray_groupvis(t_scalar *x, t_glist *owner, t_word *data, + t_template *template, + t_glist *groupcanvas, t_glist *parent, t_float basex, t_float basey) +{ + t_gobj *y; + char tagbuf[MAXPDSTRING], parent_tagbuf[MAXPDSTRING]; + sprintf(tagbuf, "scelem%lx.%lx", (long unsigned int)groupcanvas, + (long unsigned int)data); + sprintf(parent_tagbuf, "scelem%lx.%lx", (long unsigned int)parent, + (long unsigned int)data); + gui_start_vmess("gui_scalar_draw_group", "xsss", + glist_getcanvas(owner), + tagbuf, + parent_tagbuf, + "g"); + svg_grouptogui(groupcanvas, template, data); + gui_end_vmess(); + for (y = groupcanvas->gl_list; y; y = y->g_next) + { + if (pd_class(&y->g_pd) == canvas_class && + ((t_glist *)y)->gl_svg) + { + drawarray_groupvis(x, owner, data, template, (t_glist *)y, + groupcanvas, basex, basey); + } + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentvisfn)(y, owner, groupcanvas, x, data, template, + basex, basey, 1); + } +} + +/* todo: merge this with plot_has_drawcommand */ +/* see if the elements we're plotting have any drawing commands */ +int drawarray_has_drawcommand(t_canvas *elemtemplatecanvas) +{ + t_gobj *y; + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + if (pd_class(&y->g_pd) == canvas_class && ((t_glist *)y)->gl_svg) + return 1; + else if (class_isdrawcommand(y->g_pd)) + return 1; + } + return 0; +} + +static void drawarray_vis(t_gobj *z, t_glist *glist, t_glist *parentglist, + t_scalar *sc, t_word *data, t_template *template, + t_float basex, t_float basey, int tovis) +{ + t_drawarray *x = (t_drawarray *)z; + int elemsize, yonset, wonset, xonset, i; + t_canvas *elemtemplatecanvas; + t_template *elemtemplate; + t_symbol *elemtemplatesym; + t_fielddesc *xfielddesc, *yfielddesc, *wfielddesc; + /* Let's just set constant increment values and see how they + play out before adding xinc and yinc to the public interface... */ + t_float xinc = 40, yinc = 40, xsum, yval; + t_array *array; + int nelem; + char *elem; + + if (drawarray_readownertemplate(x, data, template, + &elemtemplatesym, &array) + || array_getfields(elemtemplatesym, &elemtemplatecanvas, + &elemtemplate, &elemsize, 0, 0, 0, + &xonset, &yonset, &wonset)) + return; + nelem = array->a_n; + elem = (char *)array->a_vec; + + /* id for the the viewport-- we prefix it with "draw" to be + compatible with the other svg-based drawcommands */ + char viewport_tagbuf[MAXPDSTRING]; + sprintf(viewport_tagbuf, "draw%lx.%lx", + (long unsigned int)x, (long unsigned int)data); + + if (tovis) + { + int in_array = (sc->sc_vec == data) ? 0 : 1; + int draw_scalars = plot_has_drawcommand(elemtemplatecanvas); + + /* make sure the array drawings are behind the graph */ + /* not doing this yet with the GUI port... */ + //sys_vgui(".x%lx.c lower plot%lx graph%lx\n", glist_getcanvas(glist), + // data, glist); + + /* 1. Set up the main <g> for this widget */ + char parent_tagbuf[MAXPDSTRING]; + if (in_array) + { + sprintf(parent_tagbuf, "scelem%lx.%lx", + (long unsigned int)parentglist, + (long unsigned int)data); + } + else + { + sprintf(parent_tagbuf, "dgroup%lx.%lx", + (long unsigned int)x->x_canvas, + (long unsigned int)data); + } + + t_svg *sa = (t_svg *)x->x_attr; + gui_start_vmess("gui_draw_vis", "xs", + glist_getcanvas(glist), "g"); + svg_togui(sa, template, data); + + gui_start_array(); + gui_s(parent_tagbuf); + gui_s(viewport_tagbuf); + gui_end_array(); + gui_end_vmess(); + + /* 2. Draw the individual elements */ + /* This code is inefficient since the template has to be + searched for drawing instructions for every last point. */ + if (draw_scalars) + { + //t_float xoffset = in_array ? basex: 0; + //t_float yoffset = in_array ? basey: 0; + t_float xoffset = 0; + t_float yoffset = 0; + + for (xsum = 0, i = 0; i < nelem; i++) + { + t_float usexloc, useyloc; + t_gobj *y; + if (xonset >= 0) + usexloc = xoffset + + *(t_float *)((elem + elemsize * i) + xonset); + else usexloc = xoffset + xsum, xsum += xinc; + if (yonset >= 0) + yval = *(t_float *)((elem + elemsize * i) + yonset); + else yval = 0; + useyloc = yoffset + yval; + /* fielddesc_cvttocoord(yfielddesc, yval); */ + /* We're setting up a special group that will get set as + the parent by array elements */ + + /* todo: need to check if drawarray itself is in an array */ + char tagbuf[MAXPDSTRING]; + sprintf(tagbuf, "scelem%lx.%lx", + (long unsigned int)elemtemplatecanvas, + (long unsigned int)((t_word *)(elem + elemsize * i))); + char transform_buf[MAXPDSTRING]; + sprintf(transform_buf, "translate(%g,%g)", usexloc, useyloc); + + gui_start_vmess("gui_draw_vis", "xs", + glist_getcanvas(glist), "g"); + gui_start_array(); + gui_s("transform"); + gui_s(transform_buf); + gui_end_array(); + gui_start_array(); + gui_s(viewport_tagbuf); + gui_s(tagbuf); + gui_end_array(); + gui_end_vmess(); + + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + if (pd_class(&y->g_pd) == canvas_class && + ((t_glist *)y)->gl_svg) + { + drawarray_groupvis(sc, glist, + (t_word *)(elem + elemsize * i), + template, (t_glist *)y, + elemtemplatecanvas, usexloc, useyloc); + } + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentvisfn)(y, glist, elemtemplatecanvas, sc, + (t_word *)(elem + elemsize * i), + elemtemplate, usexloc, useyloc, tovis); + } + } + } + if (!glist_istoplevel(glist)) + { + t_canvas *gl = glist_getcanvas(glist); + char objtag[64]; + sprintf(objtag, ".x%lx.x%lx.template%lx", + (t_int)gl, (t_int)glist, (t_int)data); + canvas_restore_original_position(gl, (t_gobj *)glist, objtag, -1); + } + } + else + { + /* un-draw the individual points */ + //fprintf(stderr,"drawarray_vis UNVIS\n"); + + int i; + for (i = 0; i < nelem; i++) + { + t_gobj *y; + for (y = elemtemplatecanvas->gl_list; y; y = y->g_next) + { + t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); + if (!wb) continue; + (*wb->w_parentvisfn)(y, glist, elemtemplatecanvas, sc, + (t_word *)(elem + elemsize * i), elemtemplate, + 0, 0, 0); + } + } + /* Now remove our drawarray svg container */ + gui_vmess("gui_draw_erase_item", "xs", glist_getcanvas(glist), + viewport_tagbuf); + } +} + +static int drawarray_click(t_gobj *z, t_glist *glist, + t_word *data, t_template *template, t_scalar *sc, t_array *ap, + t_float basex, t_float basey, + int xpix, int ypix, int shift, int alt, int dbl, int doit) +{ +/* Let's hold off on this for a bit... + //fprintf(stderr,"drawarray_click %lx %lx %f %f %d %d\n", + // (t_int)z, (t_int)glist, basex, basey, xpix, ypix); + t_drawarray *x = (t_drawarray *)z; + t_symbol *elemtemplatesym; + t_float linewidth, xloc, xinc, yloc, style, vis, scalarvis; + t_array *array; + t_fielddesc *xfielddesc, *yfielddesc, *wfielddesc; + t_symbol *symfillcolor; + t_symbol *symoutlinecolor; + + if (!drawarray_readownertemplate(x, data, template, + &elemtemplatesym, &array) + && (vis != 0)) + { + //fprintf(stderr," ->array_doclick\n"); + return (array_doclick(array, glist, sc, ap, + elemtemplatesym, + linewidth, basex + xloc, xinc, basey + yloc, scalarvis, + xfielddesc, yfielddesc, wfielddesc, + xpix, ypix, shift, alt, dbl, doit)); + } + else return (0); +*/ + return 0; +} + +static void drawarray_free(t_drawarray *x) +{ + //sys_queuegui(x->x_canvas, 0, canvas_redrawallfortemplatecanvas); + /* decrement variable of the template + to prevent transform as that would + make arrays break their hitboxes + and all kinds of other bad stuff */ + t_template *t = template_findbyname( + canvas_makebindsym(x->x_canvas->gl_name) + ); + if (t) + { + t->t_transformable--; + //fprintf(stderr,"drawarray_free > template:%lx(%s) transform:%d\n", + // (t_int)t, canvas_makebindsym(x->x_canvas->gl_name)->s_name, + // t->t_transformable); + } +} + +t_parentwidgetbehavior drawarray_widgetbehavior = +{ + drawarray_getrect, + drawarray_displace, + drawarray_select, + drawarray_activate, + drawarray_vis, + drawarray_click, +}; + +static void drawarray_setup(void) +{ + drawarray_class = class_new(gensym("drawarray"), + 0, + (t_method)drawarray_free, sizeof(t_drawarray), 0, A_GIMME, 0); + class_setdrawcommand(drawarray_class); + class_addfloat(drawarray_class, drawarray_float); + class_addmethod(drawarray_class, (t_method)drawarray_transform, + gensym("transform"), A_GIMME, 0); + class_addanything(drawarray_class, drawarray_anything); + class_setparentwidget(drawarray_class, &drawarray_widgetbehavior); +} + +/* ---------------- drawnumber: draw a number (or symbol) ---------------- */ + +/* + drawnumbers draw numeric fields at controllable locations, with + controllable color and label. invocation: + (drawnumber|drawsymbol) [-v <visible>] variable x y color label +*/ + +t_class *drawnumber_class; + +#define DRAW_SYMBOL 1 + +typedef struct _drawnumber +{ + t_object x_obj; + t_fielddesc x_value; + t_fielddesc x_xloc; + t_fielddesc x_yloc; + t_fielddesc x_color; + t_fielddesc x_vis; + t_fielddesc x_fontsize; + t_symbol *x_label; + int x_flags; + t_canvas *x_canvas; +} t_drawnumber; + +static void *drawnumber_new(t_symbol *classsym, t_int argc, t_atom *argv) +{ + if (legacy_draw_in_group(canvas_getcurrent())) + return 0; + + t_drawnumber *x = (t_drawnumber *)pd_new(drawnumber_class); + char *classname = classsym->s_name; + int flags = 0; + int got_font_size = 0; + + if (classname[4] == 's') + flags |= DRAW_SYMBOL; + x->x_flags = flags; + fielddesc_setfloat_const(&x->x_vis, 1); + x->x_canvas = canvas_getcurrent(); + while (1) + { + t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); + if (!strcmp(firstarg->s_name, "-v") && argc > 1) + { + fielddesc_setfloatarg(&x->x_vis, 1, argv+1); + argc -= 2; argv += 2; + } + else break; + } + if (flags & DRAW_SYMBOL) + { + if (argc) fielddesc_setsymbolarg(&x->x_value, argc--, argv++); + else fielddesc_setsymbol_const(&x->x_value, &s_); + } + else + { + if (argc) fielddesc_setfloatarg(&x->x_value, argc--, argv++); + else fielddesc_setfloat_const(&x->x_value, 0); + } + if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++); + else fielddesc_setfloat_const(&x->x_xloc, 0); + if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++); + else fielddesc_setfloat_const(&x->x_yloc, 0); + if (argc) fielddesc_setfloatarg(&x->x_color, argc--, argv++); + else fielddesc_setfloat_const(&x->x_color, 1); + + if (argc == 2) + { + fielddesc_setfloatarg(&x->x_fontsize, argc--, argv++); + got_font_size = 1; + } + if (argc) + { + if (argv->a_type == A_SYMBOL || got_font_size) + { + x->x_label = atom_getsymbolarg(0, argc, argv); + if (!got_font_size) + fielddesc_setfloatarg(&x->x_fontsize, 0, NULL); + } + else if (argv->a_type == A_FLOAT) + { + fielddesc_setfloatarg(&x->x_fontsize, argc, argv); + x->x_label = &s_; + } + } else { + fielddesc_setfloatarg(&x->x_fontsize, 0, NULL); + x->x_label = &s_; + } + + return (x); +} + +void drawnumber_float(t_drawnumber *x, t_floatarg f) +{ + int viswas; + if (x->x_vis.fd_type != A_FLOAT || x->x_vis.fd_var) + { + pd_error(x, "global vis/invis for a template with variable visibility"); + return; + } + viswas = (x->x_vis.fd_un.fd_float != 0); + + if ((f != 0 && viswas) || (f == 0 && !viswas)) + return; + canvas_redrawallfortemplatecanvas(x->x_canvas, 2); + fielddesc_setfloat_const(&x->x_vis, (f != 0)); + canvas_redrawallfortemplatecanvas(x->x_canvas, 1); +} + +/* -------------------- widget behavior for drawnumber ------------ */ + +/*#define DRAWNUMBER_BUFSIZE 80 +static void drawnumber_sprintf(t_drawnumber *x, char *buf, t_atom *ap) +{ + int nchars; + strncpy(buf, x->x_label->s_name, DRAWNUMBER_BUFSIZE); + buf[DRAWNUMBER_BUFSIZE - 1] = 0; + nchars = strlen(buf); + atom_string(ap, buf + nchars, DRAWNUMBER_BUFSIZE - nchars); +}*/ + +static int drawnumber_gettype(t_drawnumber *x, t_word *data, + t_template *template, int *onsetp) +{ + int type; + t_symbol *arraytype; + if (template_find_field(template, /*x->x_fieldname*/ x->x_value.fd_un.fd_varsym, onsetp, &type, + &arraytype) && type != DT_ARRAY) + return (type); + else return (-1); +} + +#define DRAWNUMBER_BUFSIZE 1024 +static void drawnumber_getbuf(t_drawnumber *x, t_word *data, + t_template *template, char *buf) +{ + int nchars, onset, type = drawnumber_gettype(x, data, template, &onset); + if (type < 0) + buf[0] = 0; + else { strncpy(buf, x->x_label->s_name, DRAWNUMBER_BUFSIZE); buf[DRAWNUMBER_BUFSIZE - 1] = 0; @@ -7331,9 +8034,8 @@ static void *drawimage_new(t_symbol *classsym, int argc, t_atom *argv) t_drawimage *x = (t_drawimage *)pd_new(drawimage_class); /* we need a t_svg to associate with it */ - x->x_attr = (t_pd *)svg_new((t_pd *)x, classsym, 0, 0); - - x->x_deleteme = 0; + t_svg *sa = (t_svg *)svg_new((t_pd *)x, classsym, 0, 0); + char *classname = classsym->s_name; char buf[50]; sprintf(buf, "x%lx", (t_int)x); @@ -7343,16 +8045,17 @@ static void *drawimage_new(t_symbol *classsym, int argc, t_atom *argv) if (classname[0] == 's') flags |= DRAW_SPRITE; x->x_flags = flags; + x->x_attr = (t_pd *)sa; fielddesc_setfloat_const(&x->x_vis, 1); x->x_canvas = canvas_getcurrent(); t_symbol *dir = canvas_getdir(x->x_canvas); if (argc && argv->a_type == A_SYMBOL) x->x_img = atom_getsymbolarg(0, argc--, argv++); else x->x_img = &s_; - if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++); - else fielddesc_setfloat_const(&x->x_xloc, 0); - if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++); - else fielddesc_setfloat_const(&x->x_yloc, 0); + if (argc) svg_attr_setfloatarg(&sa->x_x, argc--, argv++); + else svg_attr_setfloat_const(&sa->x_x, 0); + if (argc) svg_attr_setfloatarg(&sa->x_y, argc--, argv++); + else svg_attr_setfloat_const(&sa->x_y, 0); /* [drawimage] allocates memory for an image or image sequence while the object is creating. The corresponding scalar gets drawn as a canvas image item using the "parent" tk image as @@ -7364,7 +8067,6 @@ static void *drawimage_new(t_symbol *classsym, int argc, t_atom *argv) x->x_img->s_name, dir->s_name, x->x_flags); - //post("deleteme is %d", x->x_deleteme); return (x); } @@ -7412,31 +8114,31 @@ void drawimage_symbol(t_drawimage *x, t_symbol *s) drawimage_index(x, 0, 1, at); } -static void drawimage_x(t_drawimage *x, t_symbol *s, int argc, +static void drawimage_forward(t_drawimage *x, t_symbol *s, int argc, t_atom *argv) { - if (argv[0].a_type == A_FLOAT || argv[0].a_type == A_SYMBOL) - { - fielddesc_setfloatarg(&x->x_xloc, argc, argv); - canvas_redrawallfortemplatecanvas(x->x_canvas, 0); - } + /* forward to t_svg thingy */ + pd_typedmess(x->x_attr, s, argc, argv); } -static void drawimage_y(t_drawimage *x, t_symbol *s, int argc, +/* With the current drawimage/sprite implementation we can't easily support + the x and y attributes. The reason is that we're currently just applying + attributes to the parent <g> for convenience, but <g> has no x/y atty. + + We could just forward everything to the child <image> element, but that + could get clunky when dealing with large image sequences. So for now we + just disallow setting the x/y with the knowledge that the user can get + the same functionality using a transform. */ +static void drawimage_x(t_drawimage *x, t_symbol *s, int argc, t_atom *argv) { - if (argv[0].a_type == A_FLOAT || argv[0].a_type == A_SYMBOL) - { - fielddesc_setfloatarg(&x->x_yloc, argc, argv); - canvas_redrawallfortemplatecanvas(x->x_canvas, 0); - } + pd_error(x, "draw: x attribute for image type not supported"); } -static void drawimage_forward(t_drawimage *x, t_symbol *s, int argc, +static void drawimage_y(t_drawimage *x, t_symbol *s, int argc, t_atom *argv) { - /* forward to t_svg thingy */ - pd_typedmess(x->x_attr, s, argc, argv); + pd_error(x, "draw: y attribute for image type not supported"); } static void drawimage_anything(t_drawimage *x, t_symbol *s, int argc, @@ -7492,8 +8194,8 @@ static void drawimage_getrect(t_gobj *z, t_glist *glist, &m4, &m5, &m6); mset(mtx2, m1, m2, m3, m4, m5, m6); mmult(mtx1, mtx2, mtx1); - xloc = fielddesc_getcoord(&x->x_xloc, template, data, 0); - yloc = fielddesc_getcoord(&x->x_yloc, template, data, 0); + xloc = fielddesc_getcoord(&sa->x_x.a_attr, template, data, 0); + yloc = fielddesc_getcoord(&sa->x_y.a_attr, template, data, 0); mset(mtx2, xloc, yloc, xloc + x->x_w, yloc + x->x_h, 0, 0); mtx2[2][0] = 1; mtx2[2][1] = 1; @@ -7578,13 +8280,15 @@ static void drawimage_vis(t_gobj *z, t_glist *glist, t_glist *parentglist, { int in_array = (sc->sc_vec == data) ? 0: 1; /*int xloc = glist_xtopixels(glist, - basex + fielddesc_getcoord(&x->x_xloc, template, data, 0)); + basex + fielddesc_getcoord(&svg->x_x.a_attr, template, data, 0)); int yloc = glist_ytopixels(glist, - basey + fielddesc_getcoord(&x->x_yloc, template, data, 0)); + basey + fielddesc_getcoord(&svg->x_y.a_attr, template, data, 0)); sys_vgui("pdtk_drawimage_vis .x%lx.c %d %d .x%lx .x%lx.i %d ",*/ - int xloc = fielddesc_getcoord(&x->x_xloc, template, data, 0); - int yloc = fielddesc_getcoord(&x->x_yloc, template, data, 0); + t_float xloc = fielddesc_getcoord(&svg->x_x.a_attr, template, data, 0); + t_float yloc = fielddesc_getcoord(&svg->x_y.a_attr, template, data, 0); +fprintf(stderr, "xloc is %g\n", xloc); +fprintf(stderr, "yloc is %g\n", yloc); char tagbuf[MAXPDSTRING]; char parent_tagbuf[MAXPDSTRING]; sprintf(tagbuf, "draw%lx.%lx", @@ -7594,7 +8298,7 @@ static void drawimage_vis(t_gobj *z, t_glist *glist, t_glist *parentglist, in_array ? (long unsigned int)parentglist : (long unsigned int)parent, (long unsigned int)data); - gui_vmess("gui_drawimage_vis", "xiixxis", + gui_vmess("gui_drawimage_vis", "xffxxis", glist_getcanvas(glist), xloc, yloc, @@ -7846,24 +8550,19 @@ t_canvas *canvas_templatecanvas_forgroup(t_canvas *c) { t_canvas *templatecanvas = c; if (!c->gl_owner) - { - return templatecanvas; - } + return templatecanvas; /* warning: this needs to be carefully considered-- seems like canvas's struct may not be initialized before the objects within it. */ t_binbuf *b = c->gl_obj.te_binbuf; if (!b) - { return c; - } t_atom *argv = binbuf_getvec(b); if (binbuf_getnatom(b) > 1 && - argv[0].a_type == A_SYMBOL && - argv[0].a_w.w_symbol == gensym("draw") && - argv[1].a_type == A_SYMBOL && - argv[1].a_w.w_symbol == gensym("g")) + atom_getsymbol(argv) == gensym("draw") && + (atom_getsymbol(argv+1) == gensym("g") || + atom_getsymbol(argv+1) == gensym("svg"))) { templatecanvas = canvas_templatecanvas_forgroup(c->gl_owner); } @@ -7886,6 +8585,8 @@ t_template *template_findbydrawcommand(t_gobj *g) c = ((t_drawimage *)g)->x_canvas; else if (g->g_pd == plot_class) c = ((t_plot *)g)->x_canvas; + else if (g->g_pd == drawarray_class) + c = ((t_drawarray *)g)->x_canvas; else if (g->g_pd == canvas_class) c = (t_canvas *)g; else return (0); @@ -7963,5 +8664,6 @@ void g_template_setup(void) drawnumber_setup(); drawsymbol_setup(); drawimage_setup(); + drawarray_setup(); } diff --git a/pd/src/g_text.c b/pd/src/g_text.c index 074d5aed7b4bb9ee06f5713abdf3858458c88d4e..6b735f3ac19c3080b04addce650589dbc7204b46 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -3018,6 +3018,10 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos) (void *)canvas_undo_set_recreate(glist_getcanvas(glist), &x->te_g, pos)); typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1); + // Special case for [draw svg] -- update the args + if (((t_canvas *)x)->gl_svg) + typedmess(((t_canvas *)x)->gl_svg, gensym("update_svg"), + natom2-1, vec2+1); binbuf_free(x->te_binbuf); x->te_binbuf = b; glob_preset_node_list_seek_hub();