Project

General

Profile

1
/* This notice must be untouched at all times.
2

    
3

    
4

    
5
wz_jsgraphics.js    v. 2.3
6

    
7
The latest version is available at
8

    
9
http://www.walterzorn.com
10

    
11
or http://www.devira.com
12

    
13
or http://www.walterzorn.de
14

    
15

    
16

    
17
Copyright (c) 2002-2004 Walter Zorn. All rights reserved.
18

    
19
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
20

    
21
Last modified: 15. 3. 2004
22

    
23

    
24

    
25
Performance optimizations for Internet Explorer
26

    
27
by Thomas Frank and John Holdsworth.
28

    
29
fillPolygon method implemented by Matthieu Haller.
30

    
31

    
32

    
33
High Performance JavaScript Graphics Library.
34

    
35
Provides methods
36

    
37
- to draw lines, rectangles, ellipses, polygons
38

    
39
  with specifiable line thickness,
40

    
41
- to fill rectangles and ellipses
42

    
43
- to draw text.
44

    
45
NOTE: Operations, functions and branching have rather been optimized
46

    
47
to efficiency and speed than to shortness of source code.
48

    
49

    
50

    
51
This program is free software;
52

    
53
you can redistribute it and/or modify it under the terms of the
54

    
55
GNU General Public License as published by the Free Software Foundation;
56

    
57
either version 2 of the License, or (at your option) any later version.
58

    
59
This program is distributed in the hope that it will be useful,
60

    
61
but WITHOUT ANY WARRANTY;
62

    
63
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
64

    
65
See the GNU General Public License
66

    
67
at http://www.gnu.org/copyleft/lesser.html for more details.
68

    
69
*/
70

    
71

    
72

    
73

    
74

    
75
var jg_ihtm, jg_ie, jg_fast, jg_dom, jg_moz,
76

    
77
jg_n4 = (document.layers && typeof document.classes != "undefined");
78

    
79

    
80

    
81

    
82

    
83
function chkDHTM(x, i)
84

    
85
{
86

    
87
	x = document.body || null;
88

    
89
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined";
90

    
91
	jg_dom = (x && !jg_ie &&
92

    
93
		typeof x.appendChild != "undefined" &&
94

    
95
		typeof document.createRange != "undefined" &&
96

    
97
		typeof (i = document.createRange()).setStartBefore != "undefined" &&
98

    
99
		typeof i.createContextualFragment != "undefined");
100

    
101
	jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined";
102

    
103
	jg_fast = jg_ie && document.all && !window.opera;
104

    
105
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
106

    
107
}
108

    
109

    
110

    
111

    
112

    
113
function pntDoc()
114

    
115
{
116

    
117
	this.wnd.document.write(jg_fast? this.htmRpc() : this.htm);
118

    
119
	this.htm = '';
120

    
121
}
122

    
123

    
124

    
125

    
126

    
127
function pntCnvDom()
128

    
129
{
130

    
131
	var x = document.createRange();
132

    
133
	x.setStartBefore(this.cnv);
134

    
135
	x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm);
136

    
137
	this.cnv.appendChild(x);
138

    
139
	this.htm = '';
140

    
141
}
142

    
143

    
144

    
145

    
146

    
147
function pntCnvIe()
148

    
149
{
150

    
151
	this.cnv.insertAdjacentHTML("beforeEnd", jg_fast? this.htmRpc() : this.htm);
152

    
153
	this.htm = '';
154

    
155
}
156

    
157

    
158

    
159

    
160

    
161
function pntCnvIhtm()
162

    
163
{
164

    
165
	this.cnv.innerHTML += this.htm;
166

    
167
	this.htm = '';
168

    
169
}
170

    
171

    
172

    
173

    
174

    
175
function pntCnv()
176

    
177
{
178

    
179
	this.htm = '';
180

    
181
}
182

    
183

    
184

    
185

    
186

    
187
function mkDiv(x, y, w, h)
188

    
189
{
190

    
191
	this.htm += '<div style="position:absolute;'+
192

    
193
		'left:' + x + 'px;'+
194

    
195
		'top:' + y + 'px;'+
196

    
197
		'width:' + w + 'px;'+
198

    
199
		'height:' + h + 'px;'+
200

    
201
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
202

    
203
		'background-color:' + this.color +
204

    
205
		(!jg_moz? ';overflow:hidden' : '')+
206

    
207
		';"><\/div>';
208

    
209
}
210

    
211

    
212

    
213

    
214

    
215
function mkDivIe(x, y, w, h)
216

    
217
{
218

    
219
	this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
220

    
221
}
222

    
223

    
224

    
225

    
226

    
227
function mkDivPrt(x, y, w, h)
228

    
229
{
230

    
231
	this.htm += '<div style="position:absolute;'+
232

    
233
		'border-left:' + w + 'px solid ' + this.color + ';'+
234

    
235
		'left:' + x + 'px;'+
236

    
237
		'top:' + y + 'px;'+
238

    
239
		'width:0px;'+
240

    
241
		'height:' + h + 'px;'+
242

    
243
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
244

    
245
		'background-color:' + this.color +
246

    
247
		(!jg_moz? ';overflow:hidden' : '')+
248

    
249
		';"><\/div>';
250

    
251
}
252

    
253

    
254

    
255

    
256

    
257
function mkLyr(x, y, w, h)
258

    
259
{
260

    
261
	this.htm += '<layer '+
262

    
263
		'left="' + x + '" '+
264

    
265
		'top="' + y + '" '+
266

    
267
		'width="' + w + '" '+
268

    
269
		'height="' + h + '" '+
270

    
271
		'bgcolor="' + this.color + '"><\/layer>\n';
272

    
273
}
274

    
275

    
276

    
277

    
278

    
279
var regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
280

    
281
function htmRpc()
282

    
283
{
284

    
285
	return this.htm.replace(
286

    
287
		regex,
288

    
289
		'<div style="overflow:hidden;position:absolute;background-color:'+
290

    
291
		'$1;left:$2;top:$3;width:$4;height:$5"></div>\n');
292

    
293
}
294

    
295

    
296

    
297

    
298

    
299
function htmPrtRpc()
300

    
301
{
302

    
303
	return this.htm.replace(
304

    
305
		regex,
306

    
307
		'<div style="overflow:hidden;position:absolute;background-color:'+
308

    
309
		'$1;left:$2;top:$3;width:$4;height:$5;border-left:$4px solid $1"></div>\n');
310

    
311
}
312

    
313

    
314

    
315

    
316

    
317
function mkLin(x1, y1, x2, y2)
318

    
319
{
320

    
321
	if (x1 > x2)
322

    
323
	{
324

    
325
		var _x2 = x2;
326

    
327
		var _y2 = y2;
328

    
329
		x2 = x1;
330

    
331
		y2 = y1;
332

    
333
		x1 = _x2;
334

    
335
		y1 = _y2;
336

    
337
	}
338

    
339
	var dx = x2-x1, dy = Math.abs(y2-y1),
340

    
341
	x = x1, y = y1,
342

    
343
	yIncr = (y1 > y2)? -1 : 1;
344

    
345

    
346

    
347
	if (dx >= dy)
348

    
349
	{
350

    
351
		var pr = dy<<1,
352

    
353
		pru = pr - (dx<<1),
354

    
355
		p = pr-dx,
356

    
357
		ox = x;
358

    
359
		while ((dx--) > 0)
360

    
361
		{
362

    
363
			++x;
364

    
365
			if (p > 0)
366

    
367
			{
368

    
369
				this.mkDiv(ox, y, x-ox, 1);
370

    
371
				y += yIncr;
372

    
373
				p += pru;
374

    
375
				ox = x;
376

    
377
			}
378

    
379
			else p += pr;
380

    
381
		}
382

    
383
		this.mkDiv(ox, y, x2-ox+1, 1);
384

    
385
	}
386

    
387

    
388

    
389
	else
390

    
391
	{
392

    
393
		var pr = dx<<1,
394

    
395
		pru = pr - (dy<<1),
396

    
397
		p = pr-dy,
398

    
399
		oy = y;
400

    
401
		if (y2 <= y1)
402

    
403
		{
404

    
405
			while ((dy--) > 0)
406

    
407
			{
408

    
409
				if (p > 0)
410

    
411
				{
412

    
413
					this.mkDiv(x++, y, 1, oy-y+1);
414

    
415
					y += yIncr;
416

    
417
					p += pru;
418

    
419
					oy = y;
420

    
421
				}
422

    
423
				else
424

    
425
				{
426

    
427
					y += yIncr;
428

    
429
					p += pr;
430

    
431
				}
432

    
433
			}
434

    
435
			this.mkDiv(x2, y2, 1, oy-y2+1);
436

    
437
		}
438

    
439
		else
440

    
441
		{
442

    
443
			while ((dy--) > 0)
444

    
445
			{
446

    
447
				y += yIncr;
448

    
449
				if (p > 0)
450

    
451
				{
452

    
453
					this.mkDiv(x++, oy, 1, y-oy);
454

    
455
					p += pru;
456

    
457
					oy = y;
458

    
459
				}
460

    
461
				else p += pr;
462

    
463
			}
464

    
465
			this.mkDiv(x2, oy, 1, y2-oy+1);
466

    
467
		}
468

    
469
	}
470

    
471
}
472

    
473

    
474

    
475

    
476

    
477
function mkLin2D(x1, y1, x2, y2)
478

    
479
{
480

    
481
	if (x1 > x2)
482

    
483
	{
484

    
485
		var _x2 = x2;
486

    
487
		var _y2 = y2;
488

    
489
		x2 = x1;
490

    
491
		y2 = y1;
492

    
493
		x1 = _x2;
494

    
495
		y1 = _y2;
496

    
497
	}
498

    
499
	var dx = x2-x1, dy = Math.abs(y2-y1),
500

    
501
	x = x1, y = y1,
502

    
503
	yIncr = (y1 > y2)? -1 : 1;
504

    
505

    
506

    
507
	var s = this.stroke;
508

    
509
	if (dx >= dy)
510

    
511
	{
512

    
513
		if (s-3 > 0)
514

    
515
		{
516

    
517
			var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
518

    
519
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
520

    
521
		}
522

    
523
		else var _s = s;
524

    
525
		var ad = Math.ceil(s/2);
526

    
527

    
528

    
529
		var pr = dy<<1,
530

    
531
		pru = pr - (dx<<1),
532

    
533
		p = pr-dx,
534

    
535
		ox = x;
536

    
537
		while ((dx--) > 0)
538

    
539
		{
540

    
541
			++x;
542

    
543
			if (p > 0)
544

    
545
			{
546

    
547
				this.mkDiv(ox, y, x-ox+ad, _s);
548

    
549
				y += yIncr;
550

    
551
				p += pru;
552

    
553
				ox = x;
554

    
555
			}
556

    
557
			else p += pr;
558

    
559
		}
560

    
561
		this.mkDiv(ox, y, x2-ox+ad+1, _s);
562

    
563
	}
564

    
565

    
566

    
567
	else
568

    
569
	{
570

    
571
		if (s-3 > 0)
572

    
573
		{
574

    
575
			var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
576

    
577
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
578

    
579
		}
580

    
581
		else var _s = s;
582

    
583
		var ad = Math.round(s/2);
584

    
585

    
586

    
587
		var pr = dx<<1,
588

    
589
		pru = pr - (dy<<1),
590

    
591
		p = pr-dy,
592

    
593
		oy = y;
594

    
595
		if (y2 <= y1)
596

    
597
		{
598

    
599
			++ad;
600

    
601
			while ((dy--) > 0)
602

    
603
			{
604

    
605
				if (p > 0)
606

    
607
				{
608

    
609
					this.mkDiv(x++, y, _s, oy-y+ad);
610

    
611
					y += yIncr;
612

    
613
					p += pru;
614

    
615
					oy = y;
616

    
617
				}
618

    
619
				else
620

    
621
				{
622

    
623
					y += yIncr;
624

    
625
					p += pr;
626

    
627
				}
628

    
629
			}
630

    
631
			this.mkDiv(x2, y2, _s, oy-y2+ad);
632

    
633
		}
634

    
635
		else
636

    
637
		{
638

    
639
			while ((dy--) > 0)
640

    
641
			{
642

    
643
				y += yIncr;
644

    
645
				if (p > 0)
646

    
647
				{
648

    
649
					this.mkDiv(x++, oy, _s, y-oy+ad);
650

    
651
					p += pru;
652

    
653
					oy = y;
654

    
655
				}
656

    
657
				else p += pr;
658

    
659
			}
660

    
661
			this.mkDiv(x2, oy, _s, y2-oy+ad+1);
662

    
663
		}
664

    
665
	}
666

    
667
}
668

    
669

    
670

    
671

    
672

    
673
function mkLinDott(x1, y1, x2, y2)
674

    
675
{
676

    
677
	if (x1 > x2)
678

    
679
	{
680

    
681
		var _x2 = x2;
682

    
683
		var _y2 = y2;
684

    
685
		x2 = x1;
686

    
687
		y2 = y1;
688

    
689
		x1 = _x2;
690

    
691
		y1 = _y2;
692

    
693
	}
694

    
695
	var dx = x2-x1, dy = Math.abs(y2-y1),
696

    
697
	x = x1, y = y1,
698

    
699
	yIncr = (y1 > y2)? -1 : 1,
700

    
701
	drw = true;
702

    
703
	if (dx >= dy)
704

    
705
	{
706

    
707
		var pr = dy<<1,
708

    
709
		pru = pr - (dx<<1),
710

    
711
		p = pr-dx;
712

    
713
		while ((dx--) > 0)
714

    
715
		{
716

    
717
			if (drw) this.mkDiv(x, y, 1, 1);
718

    
719
			drw = !drw;
720

    
721
			if (p > 0)
722

    
723
			{
724

    
725
				y += yIncr;
726

    
727
				p += pru;
728

    
729
			}
730

    
731
			else p += pr;
732

    
733
			++x;
734

    
735
		}
736

    
737
		if (drw) this.mkDiv(x, y, 1, 1);
738

    
739
	}
740

    
741

    
742

    
743
	else
744

    
745
	{
746

    
747
		var pr = dx<<1,
748

    
749
		pru = pr - (dy<<1),
750

    
751
		p = pr-dy;
752

    
753
		while ((dy--) > 0)
754

    
755
		{
756

    
757
			if (drw) this.mkDiv(x, y, 1, 1);
758

    
759
			drw = !drw;
760

    
761
			y += yIncr;
762

    
763
			if (p > 0)
764

    
765
			{
766

    
767
				++x;
768

    
769
				p += pru;
770

    
771
			}
772

    
773
			else p += pr;
774

    
775
		}
776

    
777
		if (drw) this.mkDiv(x, y, 1, 1);
778

    
779
	}
780

    
781
}
782

    
783

    
784

    
785

    
786

    
787
function mkOv(left, top, width, height)
788

    
789
{
790

    
791
	var a = width>>1, b = height>>1,
792

    
793
	wod = width&1, hod = (height&1)+1,
794

    
795
	cx = left+a, cy = top+b,
796

    
797
	x = 0, y = b,
798

    
799
	ox = 0, oy = b,
800

    
801
	aa = (a*a)<<1, bb = (b*b)<<1,
802

    
803
	st = (aa>>1)*(1-(b<<1)) + bb,
804

    
805
	tt = (bb>>1) - aa*((b<<1)-1),
806

    
807
	w, h;
808

    
809
	while (y > 0)
810

    
811
	{
812

    
813
		if (st < 0)
814

    
815
		{
816

    
817
			st += bb*((x<<1)+3);
818

    
819
			tt += (bb<<1)*(++x);
820

    
821
		}
822

    
823
		else if (tt < 0)
824

    
825
		{
826

    
827
			st += bb*((x<<1)+3) - (aa<<1)*(y-1);
828

    
829
			tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
830

    
831
			w = x-ox;
832

    
833
			h = oy-y;
834

    
835
			if (w&2 && h&2)
836

    
837
			{
838

    
839
				this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1);
840

    
841
				this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
842

    
843
			}
844

    
845
			else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
846

    
847
			ox = x;
848

    
849
			oy = y;
850

    
851
		}
852

    
853
		else
854

    
855
		{
856

    
857
			tt -= aa*((y<<1)-3);
858

    
859
			st -= (aa<<1)*(--y);
860

    
861
		}
862

    
863
	}
864

    
865
	this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
866

    
867
	this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
868

    
869
}
870

    
871

    
872

    
873

    
874

    
875
function mkOv2D(left, top, width, height)
876

    
877
{
878

    
879
	var s = this.stroke;
880

    
881
	width += s-1;
882

    
883
	height += s-1;
884

    
885
	var a = width>>1, b = height>>1,
886

    
887
	wod = width&1, hod = (height&1)+1,
888

    
889
	cx = left+a, cy = top+b,
890

    
891
	x = 0, y = b,
892

    
893
	aa = (a*a)<<1, bb = (b*b)<<1,
894

    
895
	st = (aa>>1)*(1-(b<<1)) + bb,
896

    
897
	tt = (bb>>1) - aa*((b<<1)-1);
898

    
899

    
900

    
901
	if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
902

    
903
	{
904

    
905
		var ox = 0, oy = b,
906

    
907
		w, h,
908

    
909
		pxl, pxr, pxt, pxb, pxw;
910

    
911
		while (y > 0)
912

    
913
		{
914

    
915
			if (st < 0)
916

    
917
			{
918

    
919
				st += bb*((x<<1)+3);
920

    
921
				tt += (bb<<1)*(++x);
922

    
923
			}
924

    
925
			else if (tt < 0)
926

    
927
			{
928

    
929
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
930

    
931
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
932

    
933
				w = x-ox;
934

    
935
				h = oy-y;
936

    
937

    
938

    
939
				if (w-1)
940

    
941
				{
942

    
943
					pxw = w+1+(s&1);
944

    
945
					h = s;
946

    
947
				}
948

    
949
				else if (h-1)
950

    
951
				{
952

    
953
					pxw = s;
954

    
955
					h += 1+(s&1);
956

    
957
				}
958

    
959
				else pxw = h = s;
960

    
961
				this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
962

    
963
				ox = x;
964

    
965
				oy = y;
966

    
967
			}
968

    
969
			else
970

    
971
			{
972

    
973
				tt -= aa*((y<<1)-3);
974

    
975
				st -= (aa<<1)*(--y);
976

    
977
			}
978

    
979
		}
980

    
981
		this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
982

    
983
		this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
984

    
985
	}
986

    
987

    
988

    
989
	else
990

    
991
	{
992

    
993
		var _a = (width-((s-1)<<1))>>1,
994

    
995
		_b = (height-((s-1)<<1))>>1,
996

    
997
		_x = 0, _y = _b,
998

    
999
		_aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
1000

    
1001
		_st = (_aa>>1)*(1-(_b<<1)) + _bb,
1002

    
1003
		_tt = (_bb>>1) - _aa*((_b<<1)-1),
1004

    
1005

    
1006

    
1007
		pxl = new Array(),
1008

    
1009
		pxt = new Array(),
1010

    
1011
		_pxb = new Array();
1012

    
1013
		pxl[0] = 0;
1014

    
1015
		pxt[0] = b;
1016

    
1017
		_pxb[0] = _b-1;
1018

    
1019
		while (y > 0)
1020

    
1021
		{
1022

    
1023
			if (st < 0)
1024

    
1025
			{
1026

    
1027
				st += bb*((x<<1)+3);
1028

    
1029
				tt += (bb<<1)*(++x);
1030

    
1031
				pxl[pxl.length] = x;
1032

    
1033
				pxt[pxt.length] = y;
1034

    
1035
			}
1036

    
1037
			else if (tt < 0)
1038

    
1039
			{
1040

    
1041
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
1042

    
1043
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
1044

    
1045
				pxl[pxl.length] = x;
1046

    
1047
				pxt[pxt.length] = y;
1048

    
1049
			}
1050

    
1051
			else
1052

    
1053
			{
1054

    
1055
				tt -= aa*((y<<1)-3);
1056

    
1057
				st -= (aa<<1)*(--y);
1058

    
1059
			}
1060

    
1061

    
1062

    
1063
			if (_y > 0)
1064

    
1065
			{
1066

    
1067
				if (_st < 0)
1068

    
1069
				{
1070

    
1071
					_st += _bb*((_x<<1)+3);
1072

    
1073
					_tt += (_bb<<1)*(++_x);
1074

    
1075
					_pxb[_pxb.length] = _y-1;
1076

    
1077
				}
1078

    
1079
				else if (_tt < 0)
1080

    
1081
				{
1082

    
1083
					_st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1);
1084

    
1085
					_tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3);
1086

    
1087
					_pxb[_pxb.length] = _y-1;
1088

    
1089
				}
1090

    
1091
				else
1092

    
1093
				{
1094

    
1095
					_tt -= _aa*((_y<<1)-3);
1096

    
1097
					_st -= (_aa<<1)*(--_y);
1098

    
1099
					_pxb[_pxb.length-1]--;
1100

    
1101
				}
1102

    
1103
			}
1104

    
1105
		}
1106

    
1107

    
1108

    
1109
		var ox = 0, oy = b,
1110

    
1111
		_oy = _pxb[0],
1112

    
1113
		l = pxl.length,
1114

    
1115
		w, h;
1116

    
1117
		for (var i = 0; i < l; i++)
1118

    
1119
		{
1120

    
1121
			if (typeof _pxb[i] != "undefined")
1122

    
1123
			{
1124

    
1125
				if (_pxb[i] < _oy || pxt[i] < oy)
1126

    
1127
				{
1128

    
1129
					x = pxl[i];
1130

    
1131
					this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
1132

    
1133
					ox = x;
1134

    
1135
					oy = pxt[i];
1136

    
1137
					_oy = _pxb[i];
1138

    
1139
				}
1140

    
1141
			}
1142

    
1143
			else
1144

    
1145
			{
1146

    
1147
				x = pxl[i];
1148

    
1149
				this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
1150

    
1151
				this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
1152

    
1153
				ox = x;
1154

    
1155
				oy = pxt[i];
1156

    
1157
			}
1158

    
1159
		}
1160

    
1161
		this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
1162

    
1163
		this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
1164

    
1165
	}
1166

    
1167
}
1168

    
1169

    
1170

    
1171

    
1172

    
1173
function mkOvDott(left, top, width, height)
1174

    
1175
{
1176

    
1177
	var a = width>>1, b = height>>1,
1178

    
1179
	wod = width&1, hod = height&1,
1180

    
1181
	cx = left+a, cy = top+b,
1182

    
1183
	x = 0, y = b,
1184

    
1185
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
1186

    
1187
	st = (aa2>>1)*(1-(b<<1)) + bb,
1188

    
1189
	tt = (bb>>1) - aa2*((b<<1)-1),
1190

    
1191
	drw = true;
1192

    
1193
	while (y > 0)
1194

    
1195
	{
1196

    
1197
		if (st < 0)
1198

    
1199
		{
1200

    
1201
			st += bb*((x<<1)+3);
1202

    
1203
			tt += (bb<<1)*(++x);
1204

    
1205
		}
1206

    
1207
		else if (tt < 0)
1208

    
1209
		{
1210

    
1211
			st += bb*((x<<1)+3) - aa4*(y-1);
1212

    
1213
			tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
1214

    
1215
		}
1216

    
1217
		else
1218

    
1219
		{
1220

    
1221
			tt -= aa2*((y<<1)-3);
1222

    
1223
			st -= aa4*(--y);
1224

    
1225
		}
1226

    
1227
		if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
1228

    
1229
		drw = !drw;
1230

    
1231
	}
1232

    
1233
}
1234

    
1235

    
1236

    
1237

    
1238

    
1239
function mkRect(x, y, w, h)
1240

    
1241
{
1242

    
1243
	var s = this.stroke;
1244

    
1245
	this.mkDiv(x, y, w, s);
1246

    
1247
	this.mkDiv(x+w, y, s, h);
1248

    
1249
	this.mkDiv(x, y+h, w+s, s);
1250

    
1251
	this.mkDiv(x, y+s, s, h-s);
1252

    
1253
}
1254

    
1255

    
1256

    
1257

    
1258

    
1259
function mkRectDott(x, y, w, h)
1260

    
1261
{
1262

    
1263
	this.drawLine(x, y, x+w, y);
1264

    
1265
	this.drawLine(x+w, y, x+w, y+h);
1266

    
1267
	this.drawLine(x, y+h, x+w, y+h);
1268

    
1269
	this.drawLine(x, y, x, y+h);
1270

    
1271
}
1272

    
1273

    
1274

    
1275

    
1276

    
1277
function jsgFont()
1278

    
1279
{
1280

    
1281
	this.PLAIN = 'font-weight:normal;';
1282

    
1283
	this.BOLD = 'font-weight:bold;';
1284

    
1285
	this.ITALIC = 'font-style:italic;';
1286

    
1287
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
1288

    
1289
	this.BOLD_ITALIC = this.ITALIC_BOLD;
1290

    
1291
}
1292

    
1293
var Font = new jsgFont();
1294

    
1295

    
1296

    
1297

    
1298

    
1299
function jsgStroke()
1300

    
1301
{
1302

    
1303
	this.DOTTED = -1;
1304

    
1305
}
1306

    
1307
var Stroke = new jsgStroke();
1308

    
1309

    
1310

    
1311

    
1312

    
1313
function jsGraphics(id, wnd)
1314

    
1315
{
1316

    
1317
	this.setColor = new Function('arg', 'this.color = arg.toLowerCase();');
1318

    
1319

    
1320

    
1321
	this.setStroke = function(x)
1322

    
1323
	{
1324

    
1325
		this.stroke = x;
1326

    
1327
		if (!(x+1))
1328

    
1329
		{
1330

    
1331
			this.drawLine = mkLinDott;
1332

    
1333
			this.mkOv = mkOvDott;
1334

    
1335
			this.drawRect = mkRectDott;
1336

    
1337
		}
1338

    
1339
		else if (x-1 > 0)
1340

    
1341
		{
1342

    
1343
			this.drawLine = mkLin2D;
1344

    
1345
			this.mkOv = mkOv2D;
1346

    
1347
			this.drawRect = mkRect;
1348

    
1349
		}
1350

    
1351
		else
1352

    
1353
		{
1354

    
1355
			this.drawLine = mkLin;
1356

    
1357
			this.mkOv = mkOv;
1358

    
1359
			this.drawRect = mkRect;
1360

    
1361
		}
1362

    
1363
	};
1364

    
1365

    
1366

    
1367

    
1368

    
1369
	this.setPrintable = function(arg)
1370

    
1371
	{
1372

    
1373
		this.printable = arg;
1374

    
1375
		if (jg_fast)
1376

    
1377
		{
1378

    
1379
			this.mkDiv = mkDivIe;
1380

    
1381
			this.htmRpc = arg? htmPrtRpc : htmRpc;
1382

    
1383
		}
1384

    
1385
		else this.mkDiv = jg_n4? mkLyr : arg? mkDivPrt : mkDiv;
1386

    
1387
	};
1388

    
1389

    
1390

    
1391

    
1392

    
1393
	this.setFont = function(fam, sz, sty)
1394

    
1395
	{
1396

    
1397
		this.ftFam = fam;
1398

    
1399
		this.ftSz = sz;
1400

    
1401
		this.ftSty = sty || Font.PLAIN;
1402

    
1403
	};
1404

    
1405

    
1406

    
1407

    
1408

    
1409
	this.drawPolyline = this.drawPolyLine = function(x, y, s)
1410

    
1411
	{
1412

    
1413
		for (var i=0 ; i<x.length-1 ; i++ )
1414

    
1415
			this.drawLine(x[i], y[i], x[i+1], y[i+1]);
1416

    
1417
	};
1418

    
1419

    
1420

    
1421

    
1422

    
1423
	this.fillRect = function(x, y, w, h)
1424

    
1425
	{
1426

    
1427
		this.mkDiv(x, y, w, h);
1428

    
1429
	};
1430

    
1431

    
1432

    
1433

    
1434

    
1435
	this.drawPolygon = function(x, y)
1436

    
1437
	{
1438

    
1439
		this.drawPolyline(x, y);
1440

    
1441
		this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
1442

    
1443
	};
1444

    
1445

    
1446

    
1447

    
1448

    
1449
	this.drawEllipse = this.drawOval = function(x, y, w, h)
1450

    
1451
	{
1452

    
1453
		this.mkOv(x, y, w, h);
1454

    
1455
	};
1456

    
1457

    
1458

    
1459

    
1460

    
1461
	this.fillEllipse = this.fillOval = function(left, top, w, h)
1462

    
1463
	{
1464

    
1465
		var a = (w -= 1)>>1, b = (h -= 1)>>1,
1466

    
1467
		wod = (w&1)+1, hod = (h&1)+1,
1468

    
1469
		cx = left+a, cy = top+b,
1470

    
1471
		x = 0, y = b,
1472

    
1473
		ox = 0, oy = b,
1474

    
1475
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
1476

    
1477
		st = (aa2>>1)*(1-(b<<1)) + bb,
1478

    
1479
		tt = (bb>>1) - aa2*((b<<1)-1),
1480

    
1481
		pxl, dw, dh;
1482

    
1483
		if (w+1) while (y > 0)
1484

    
1485
		{
1486

    
1487
			if (st < 0)
1488

    
1489
			{
1490

    
1491
				st += bb*((x<<1)+3);
1492

    
1493
				tt += (bb<<1)*(++x);
1494

    
1495
			}
1496

    
1497
			else if (tt < 0)
1498

    
1499
			{
1500

    
1501
				st += bb*((x<<1)+3) - aa4*(y-1);
1502

    
1503
				pxl = cx-x;
1504

    
1505
				dw = (x<<1)+wod;
1506

    
1507
				tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
1508

    
1509
				dh = oy-y;
1510

    
1511
				this.mkDiv(pxl, cy-oy, dw, dh);
1512

    
1513
				this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
1514

    
1515
				ox = x;
1516

    
1517
				oy = y;
1518

    
1519
			}
1520

    
1521
			else
1522

    
1523
			{
1524

    
1525
				tt -= aa2*((y<<1)-3);
1526

    
1527
				st -= aa4*(--y);
1528

    
1529
			}
1530

    
1531
		}
1532

    
1533
		this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
1534

    
1535
	};
1536

    
1537

    
1538

    
1539

    
1540

    
1541

    
1542

    
1543
/* fillPolygon method, implemented by Matthieu Haller.
1544

    
1545
This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
1546

    
1547
C source of GD 1.8.4 found at http://www.boutell.com/gd/
1548

    
1549

    
1550

    
1551
THANKS to Kirsten Schulz for the polygon fixes!
1552

    
1553

    
1554

    
1555
The intersection finding technique of this code could be improved
1556

    
1557
by remembering the previous intertersection, and by using the slope.
1558

    
1559
That could help to adjust intersections to produce a nice
1560

    
1561
interior_extrema. */
1562

    
1563
	this.fillPolygon = function(array_x, array_y)
1564

    
1565
	{
1566

    
1567
		var i;
1568

    
1569
		var y;
1570

    
1571
		var miny, maxy;
1572

    
1573
		var x1, y1;
1574

    
1575
		var x2, y2;
1576

    
1577
		var ind1, ind2;
1578

    
1579
		var ints;
1580

    
1581

    
1582

    
1583
		var n = array_x.length;
1584

    
1585

    
1586

    
1587
		if (!n) return;
1588

    
1589

    
1590

    
1591

    
1592

    
1593
		miny = array_y[0];
1594

    
1595
		maxy = array_y[0];
1596

    
1597
		for (i = 1; i < n; i++)
1598

    
1599
		{
1600

    
1601
			if (array_y[i] < miny)
1602

    
1603
				miny = array_y[i];
1604

    
1605

    
1606

    
1607
			if (array_y[i] > maxy)
1608

    
1609
				maxy = array_y[i];
1610

    
1611
		}
1612

    
1613
		for (y = miny; y <= maxy; y++)
1614

    
1615
		{
1616

    
1617
			var polyInts = new Array();
1618

    
1619
			ints = 0;
1620

    
1621
			for (i = 0; i < n; i++)
1622

    
1623
			{
1624

    
1625
				if (!i)
1626

    
1627
				{
1628

    
1629
					ind1 = n-1;
1630

    
1631
					ind2 = 0;
1632

    
1633
				}
1634

    
1635
				else
1636

    
1637
				{
1638

    
1639
					ind1 = i-1;
1640

    
1641
					ind2 = i;
1642

    
1643
				}
1644

    
1645
				y1 = array_y[ind1];
1646

    
1647
				y2 = array_y[ind2];
1648

    
1649
				if (y1 < y2)
1650

    
1651
				{
1652

    
1653
					x1 = array_x[ind1];
1654

    
1655
					x2 = array_x[ind2];
1656

    
1657
				}
1658

    
1659
				else if (y1 > y2)
1660

    
1661
				{
1662

    
1663
					y2 = array_y[ind1];
1664

    
1665
					y1 = array_y[ind2];
1666

    
1667
					x2 = array_x[ind1];
1668

    
1669
					x1 = array_x[ind2];
1670

    
1671
				}
1672

    
1673
				else continue;
1674

    
1675

    
1676

    
1677
				 // modified 11. 2. 2004 Walter Zorn
1678

    
1679
				if ((y >= y1) && (y < y2))
1680

    
1681
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
1682

    
1683

    
1684

    
1685
				else if ((y == maxy) && (y > y1) && (y <= y2))
1686

    
1687
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
1688

    
1689
			}
1690

    
1691
			polyInts.sort(integer_compare);
1692

    
1693

    
1694

    
1695
			for (i = 0; i < ints; i+=2)
1696

    
1697
			{
1698

    
1699
				w = polyInts[i+1]-polyInts[i]
1700

    
1701
				this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
1702

    
1703
			}
1704

    
1705
		}
1706

    
1707
	};
1708

    
1709

    
1710

    
1711

    
1712

    
1713
	this.drawString = function(txt, x, y)
1714

    
1715
	{
1716

    
1717
		this.htm += '<div style="position:absolute;white-space:nowrap;'+
1718

    
1719
			'left:' + x + 'px;'+
1720

    
1721
			'top:' + y + 'px;'+
1722

    
1723
			'font-family:' +  this.ftFam + ';'+
1724

    
1725
			'font-size:' + this.ftSz + ';'+
1726

    
1727
			'color:' + this.color + ';' + this.ftSty + '">'+
1728

    
1729
			txt +
1730

    
1731
			'<\/div>';
1732

    
1733
	}
1734

    
1735

    
1736

    
1737

    
1738

    
1739
	this.drawImage = function(imgSrc, x, y, w, h)
1740

    
1741
	{
1742

    
1743
		this.htm += '<div style="position:absolute;'+
1744

    
1745
			'left:' + x + 'px;'+
1746

    
1747
			'top:' + y + 'px;'+
1748

    
1749
			'width:' +  w + ';'+
1750

    
1751
			'height:' + h + ';">'+
1752

    
1753
			'<img src="' + imgSrc + '" width="' + w + '" height="' + h + '">'+
1754

    
1755
			'<\/div>';
1756

    
1757
	}
1758

    
1759

    
1760

    
1761

    
1762

    
1763
	this.clear = function()
1764

    
1765
	{
1766

    
1767
		this.htm = "";
1768

    
1769
		if (this.cnv) this.cnv.innerHTML = this.defhtm;
1770

    
1771
	};
1772

    
1773

    
1774

    
1775

    
1776

    
1777
	this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
1778

    
1779
	{
1780

    
1781
		this.mkDiv(xr+cx, yt+cy, w, h);
1782

    
1783
		this.mkDiv(xr+cx, yb+cy, w, h);
1784

    
1785
		this.mkDiv(xl+cx, yb+cy, w, h);
1786

    
1787
		this.mkDiv(xl+cx, yt+cy, w, h);
1788

    
1789
	};
1790

    
1791

    
1792

    
1793
	this.setStroke(1);
1794

    
1795
	this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
1796

    
1797
	this.color = '#000000';
1798

    
1799
	this.htm = '';
1800

    
1801
	this.wnd = wnd || window;
1802

    
1803

    
1804

    
1805
	if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
1806

    
1807
	if (typeof id != 'string' || !id) this.paint = pntDoc;
1808

    
1809
	else
1810

    
1811
	{
1812

    
1813
		this.cnv = document.all? (this.wnd.document.all[id] || null)
1814

    
1815
			: document.getElementById? (this.wnd.document.getElementById(id) || null)
1816

    
1817
			: null;
1818

    
1819
		this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
1820

    
1821
		this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
1822

    
1823
	}
1824

    
1825

    
1826

    
1827
	this.setPrintable(false);
1828

    
1829
}
1830

    
1831

    
1832

    
1833

    
1834

    
1835

    
1836

    
1837
function integer_compare(x,y)
1838

    
1839
{
1840

    
1841
	return (x < y) ? -1 : ((x > y)*1);
1842

    
1843
}
1844

    
1845

    
1846

    
    (1-1/1)