Sfoglia il codice sorgente

made corrections in clipping: in case of ClipRect mode use "clipRect", otherwise use "limits"
introduced protection against invalid drawing specifications (e.g. presence of NaN's)

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7217 8c9fc860-2736-0410-a75d-ab315db34111

eth.morozova 8 anni fa
parent
commit
a137bbcccf
1 ha cambiato i file con 38 aggiunte e 18 eliminazioni
  1. 38 18
      source/WMGraphicsSmooth.Mod

+ 38 - 18
source/WMGraphicsSmooth.Mod

@@ -4,7 +4,7 @@
 *)
 MODULE WMGraphicsSmooth;
 
-IMPORT SYSTEM, Raster, Strings, WMGraphics, WMRectangles;
+IMPORT SYSTEM, Raster, Strings, WMGraphics, WMRectangles, Reals;
 
 CONST
 	(** Line cap types *)
@@ -45,8 +45,8 @@ TYPE
 				SetColor(WMGraphics.Blue);
 
 				Raster.InitMode(rasterMode,Raster.srcOverDst);
-				Raster.Bind(rasterMode, Raster.PixelFormat, img.fmt);
 			END;
+			Raster.Bind(rasterMode, Raster.PixelFormat, img.fmt);
 		END New;
 
 		PROCEDURE SetColor(x: WMGraphics.Color);
@@ -66,13 +66,15 @@ TYPE
 		*)
 		PROCEDURE SetLineWidth*(w: Real);
 		BEGIN
+			IF w < 0.5 THEN w := 0.5; END;
 			IF w # lineWidth THEN
-				IF w < 0.1 THEN w := 0.1; END;
+				IF w > 0.5 THEN
+					halfLineWidth := 0.5*w;
+					halfLineWidthBy255 := 255*halfLineWidth;
+					invLineWidthBy255 := 255/w;
+					halfLineWidthSqr := halfLineWidth*halfLineWidth;
+				END;
 				lineWidth := w;
-				halfLineWidth := 0.5*lineWidth;
-				halfLineWidthBy255 := 255*halfLineWidth;
-				invLineWidthBy255 := 255/lineWidth;
-				halfLineWidthSqr := halfLineWidth*halfLineWidth;
 			END;
 		END SetLineWidth;
 
@@ -90,6 +92,11 @@ TYPE
 		PROCEDURE LineReal*(x0, y0, x1, y1: Real; lineColor: WMGraphics.Color; mode: LONGINT);
 		BEGIN
 
+			(*! do not do anything in case of an invalid line specification *)
+			IF Reals.IsNaN(x0) OR Reals.IsNaN(y0) OR Reals.IsNaN(x1) OR Reals.IsNaN(y1) THEN
+				RETURN;
+			END;
+
 			IF lineColor # color THEN SetColor(lineColor); END;
 
 			(* transform local coordinates to the global coordinate system *)
@@ -97,9 +104,14 @@ TYPE
 			x1 := x1 + dx; y1 := y1 + dy;
 
 			(* check whether the line crosses the canvas rectangle with account of line width and a few pixels for antialiasing *)
-			IF ~ClipLineReal(limits.l-lineWidth-2,limits.t-lineWidth-2,limits.r+lineWidth+1,limits.b+lineWidth+1, x0,y0,x1,y1) THEN
+			IF WMGraphics.ClipRect IN clipMode THEN
+				IF ~ClipLineReal((clipRect.l-2)-lineWidth,(clipRect.t-2)-lineWidth,(clipRect.r+1)+lineWidth,(clipRect.b+1)+lineWidth, x0,y0,x1,y1) THEN
+					RETURN;
+				END;
+			ELSIF ~ClipLineReal((limits.l-2)-lineWidth,(limits.t-2)-lineWidth,(limits.r+1)+lineWidth,(limits.b+1)+lineWidth, x0,y0,x1,y1) THEN
 				RETURN;
 			END;
+
 			IF x0 <= x1 THEN
 				IF lineWidth <= 0.5 THEN
 					DrawThinLine(x0,y0, x1,y1);
@@ -117,6 +129,10 @@ TYPE
 
 		PROCEDURE Disk*(x0, y0: Real; radius: Real; color: WMGraphics.Color; mode: LONGINT);
 		BEGIN
+			(*! do not do anything in case of an invalid disk specification *)
+			IF Reals.IsNaN(x0) OR Reals.IsNaN(y0) OR Reals.IsNaN(radius) OR (radius <= 0) THEN
+				RETURN;
+			END;
 			IF color # SELF.color THEN SetColor(color); END;
 			DrawDisk(x0,y0,radius);
 		END Disk;
@@ -197,8 +213,12 @@ TYPE
 			outer.t := ENTIER(y0-radius)-4;
 			outer.b := ENTIER(y0+radius)+3;
 
-			IF WMGraphics.ClipRect IN clipMode THEN WMRectangles.ClipRect(outer, clipRect);END;
-			WMRectangles.ClipRect(outer, limits);
+			IF WMGraphics.ClipRect IN clipMode THEN
+				WMRectangles.ClipRect(outer, clipRect);
+			ELSE
+				WMRectangles.ClipRect(outer, limits);
+			END;
+
 			IF ~WMRectangles.RectEmpty(outer) THEN
 				(* inner rectangle *)
 				d := radius*0.707106781186547; (* half of the edge of the square inside the circle *)
@@ -940,11 +960,11 @@ TYPE
 								(* intersection with x = left *)
 								y0 := y00 + (dy*(l-x00)) / dx; x0 := l;
 								IF y0 < t THEN
-									(* intersection with y = tody *)
+									(* intersection with y = top *)
 									x0 := x00 + (dx*(t-y00)) / dy; y0 := t;
 								END;
 							ELSIF y0 < t THEN
-								(* intersection with y = tody *)
+								(* intersection with y = top *)
 								x0 := x00 + (dx*(t-y00)) / dy; y0 := t;
 								IF x0 < l THEN
 									(* intersection with x = left *)
@@ -1004,11 +1024,11 @@ TYPE
 							(* intersection with x = right *)
 							y1 := y00 - (dy*(r-x00)) / dx; x1 := r;
 							IF y1 < t THEN
-								(* intersection with y = tody *)
+								(* intersection with y = top *)
 								x1 := x00 - (dx*(t-y00)) / dy; y1 := t;
 							END;
 						ELSIF y1 < t THEN
-							(* intersection with y = tody *)
+							(* intersection with y = top *)
 							x1 := x00 - (dx*(t-y00)) / dy; y1 := t;
 							IF x1 > r THEN
 								(* intersection with x = right *)
@@ -1044,11 +1064,11 @@ TYPE
 								(* intersection with x = right *)
 								y0 := y00 - (dy*(r-x00)) / dx; x0 := r;
 								IF y0 < t THEN
-									(* intersection with y = tody *)
+									(* intersection with y = top *)
 									x0 := x00 - (dx*(t-y00)) / dy; y0 := t;
 								END;
 							ELSIF y0 < t THEN
-								(* intersection with y = tody *)
+								(* intersection with y = top *)
 								x0 := x00 - (dx*(t-y00)) / dy; y0 := t;
 								IF x0 > r THEN
 									(* intersection with x = right *)
@@ -1108,11 +1128,11 @@ TYPE
 							(* intersection with x = left *)
 							y1 := y00 + (dy*(l-x00)) / dx; x1 := l;
 							IF y1 < t THEN
-								(* intersection with y = tody *)
+								(* intersection with y = top *)
 								x1 := x00 + (dx*(t-y00)) / dy; y1 := t;
 							END;
 						ELSIF y1 < t THEN
-							(* intersection with y = tody *)
+							(* intersection with y = top *)
 							x1 := x00 + (dx*(t-y00)) / dy; y1 := t;
 							IF x1 < l THEN
 								(* intersection with x = left *)