2
0
Эх сурвалжийг харах

prevent crash with invalid matrix

Johann 5 жил өмнө
parent
commit
f785dbefa7

+ 2 - 0
lazpaintcontrols/lcvectororiginal.pas

@@ -2427,6 +2427,7 @@ var
   sb: TRectF;
   sb: TRectF;
   m: TAffineMatrix;
   m: TAffineMatrix;
 begin
 begin
+  if not IsAffineMatrixInversible(AMatrix) then exit;
   sb := GetAlignBounds(ABounds, AMatrix);
   sb := GetAlignBounds(ABounds, AMatrix);
   case AAlign of
   case AAlign of
   taRightJustify: m := AffineMatrixTranslation(ABounds.Right-sb.Right,0);
   taRightJustify: m := AffineMatrixTranslation(ABounds.Right-sb.Right,0);
@@ -2442,6 +2443,7 @@ var
   sb: TRectF;
   sb: TRectF;
   m: TAffineMatrix;
   m: TAffineMatrix;
 begin
 begin
+  if not IsAffineMatrixInversible(AMatrix) then exit;
   sb := GetAlignBounds(ABounds, AMatrix);
   sb := GetAlignBounds(ABounds, AMatrix);
   case AAlign of
   case AAlign of
   tlBottom: m := AffineMatrixTranslation(0,ABounds.Bottom-sb.Bottom);
   tlBottom: m := AffineMatrixTranslation(0,ABounds.Bottom-sb.Bottom);

+ 1 - 0
lazpaintcontrols/lcvectorpolyshapes.pas

@@ -1102,6 +1102,7 @@ var
   i, nbTotal: Integer;
   i, nbTotal: Integer;
 begin
 begin
   FViewMatrix := AEditor.Matrix;
   FViewMatrix := AEditor.Matrix;
+  if not IsAffineMatrixInversible(FViewMatrix) then exit;
   FViewMatrixInverse := AffineMatrixInverse(FViewMatrix);
   FViewMatrixInverse := AffineMatrixInverse(FViewMatrix);
   FGridMatrix := AEditor.GridMatrix;
   FGridMatrix := AEditor.GridMatrix;
 
 

+ 7 - 5
lazpaintcontrols/lcvectorrectshapes.pas

@@ -1626,7 +1626,7 @@ var
   mapWidth,mapHeight: integer;
   mapWidth,mapHeight: integer;
   shader: TPhongShading;
   shader: TPhongShading;
   approxFactor,borderSize: single;
   approxFactor,borderSize: single;
-  m: TAffineMatrix;
+  m,mInv: TAffineMatrix;
   h, lightPosZ: single;
   h, lightPosZ: single;
   map,raster: TBGRABitmap;
   map,raster: TBGRABitmap;
   u,v,lightPosF: TPointF;
   u,v,lightPosF: TPointF;
@@ -1646,9 +1646,9 @@ begin
 
 
   //determine map size before transform
   //determine map size before transform
   ab := GetAffineBox(AMatrix, false);
   ab := GetAffineBox(AMatrix, false);
+  if (ab.Width = 0) or (ab.Height = 0) then exit;
   if ab.Width > ab.Height then
   if ab.Width > ab.Height then
   begin
   begin
-    if ab.Width = 0 then exit;
     mapWidth := ceil(ab.Width);
     mapWidth := ceil(ab.Width);
     mapHeight := ceil(ab.Surface/ab.Width);
     mapHeight := ceil(ab.Surface/ab.Width);
   end else
   end else
@@ -1674,6 +1674,8 @@ begin
   v := (ab.BottomLeft-ab.TopLeft)*(1/ab.Height);
   v := (ab.BottomLeft-ab.TopLeft)*(1/ab.Height);
   m := AffineMatrix(u,v,ab.TopLeft)*AffineMatrixScale(ab.Width/mapWidth,ab.Height/mapHeight);
   m := AffineMatrix(u,v,ab.TopLeft)*AffineMatrixScale(ab.Width/mapWidth,ab.Height/mapHeight);
   borderSize := FBorderSizePercent/200*min(ab.Width,ab.Height);
   borderSize := FBorderSizePercent/200*min(ab.Width,ab.Height);
+  if not IsAffineMatrixInversible(m) then exit;
+  mInv := AffineMatrixInverse(m);
 
 
   try
   try
     //create height map
     //create height map
@@ -1715,7 +1717,7 @@ begin
       end;
       end;
     end;
     end;
 
 
-    abRaster := AffineMatrixInverse(m)*TAffineBox.AffineBox(rectRenderF);
+    abRaster := mInv*TAffineBox.AffineBox(rectRenderF);
     rectRasterF := abRaster.RectBoundsF;
     rectRasterF := abRaster.RectBoundsF;
     rectRaster := rect(floor(rectRasterF.Left),floor(rectRasterF.Top),ceil(rectRasterF.Right),ceil(rectRasterF.Bottom));
     rectRaster := rect(floor(rectRasterF.Left),floor(rectRasterF.Top),ceil(rectRasterF.Right),ceil(rectRasterF.Bottom));
 
 
@@ -1727,7 +1729,7 @@ begin
       shader.AmbientFactor := 0.5;
       shader.AmbientFactor := 0.5;
       shader.NegativeDiffusionFactor := 0.15;
       shader.NegativeDiffusionFactor := 0.15;
       lightPosF := AffineMatrixTranslation(-rectRaster.Left,-rectRaster.Top)
       lightPosF := AffineMatrixTranslation(-rectRaster.Left,-rectRaster.Top)
-                    *AffineMatrixInverse(m)*AMatrix*FLightPosition;
+                    *mInv*AMatrix*FLightPosition;
       lightPosZ := 100*Power(approxFactor,1.1);
       lightPosZ := 100*Power(approxFactor,1.1);
       if h*3/2 > lightPosZ then lightposZ := h*3/2;
       if h*3/2 > lightPosZ then lightposZ := h*3/2;
       shader.LightPosition3D := Point3D(lightPosF.x,lightPosF.y,lightPosZ);
       shader.LightPosition3D := Point3D(lightPosF.x,lightPosF.y,lightPosZ);
@@ -1737,7 +1739,7 @@ begin
         shader.Draw(raster,map,h,-rectRaster.Left,-rectRaster.Top,BackFill.SolidColor)
         shader.Draw(raster,map,h,-rectRaster.Left,-rectRaster.Top,BackFill.SolidColor)
       else
       else
       begin
       begin
-        scan := BackFill.CreateScanner(AffineMatrixTranslation(-rectRaster.left,-rectRaster.top)*AffineMatrixInverse(m)*AMatrix,ADraft);
+        scan := BackFill.CreateScanner(AffineMatrixTranslation(-rectRaster.left,-rectRaster.top)*mInv*AMatrix,ADraft);
         shader.DrawScan(raster,map,h,-rectRaster.Left,-rectRaster.Top,scan);
         shader.DrawScan(raster,map,h,-rectRaster.Left,-rectRaster.Top,scan);
         scan.Free;
         scan.Free;
       end;
       end;

+ 8 - 2
lazpaintcontrols/lcvectortextshapes.pas

@@ -931,10 +931,13 @@ var
   newPos: Integer;
   newPos: Integer;
   tl: TBidiTextLayout;
   tl: TBidiTextLayout;
   zoom: Single;
   zoom: Single;
+  untransformed: TAffineMatrix;
 begin
 begin
   tl := GetTextLayout;
   tl := GetTextLayout;
   zoom := GetTextRenderZoom;
   zoom := GetTextRenderZoom;
-  newPos := tl.GetCharIndexAt(AffineMatrixScale(zoom,zoom)*AffineMatrixInverse(GetUntransformedMatrix)*PointF(X,Y));
+  untransformed := GetUntransformedMatrix;
+  if not IsAffineMatrixInversible(untransformed) then exit;
+  newPos := tl.GetCharIndexAt(AffineMatrixScale(zoom,zoom)*AffineMatrixInverse(untransformed)*PointF(X,Y));
   if newPos<>-1 then
   if newPos<>-1 then
   begin
   begin
     if (newPos <> FSelEnd) or (not AExtend and (FSelStart <> FSelEnd)) or (UserMode <> vsuEditText) then
     if (newPos <> FSelEnd) or (not AExtend and (FSelStart <> FSelEnd)) or (UserMode <> vsuEditText) then
@@ -1497,12 +1500,15 @@ var
   tl: TBidiTextLayout;
   tl: TBidiTextLayout;
   pt: TPointF;
   pt: TPointF;
   i: Integer;
   i: Integer;
+  untransformed: TAffineMatrix;
 begin
 begin
   if not GetAffineBox(AffineMatrixIdentity,true).Contains(APoint) then
   if not GetAffineBox(AffineMatrixIdentity,true).Contains(APoint) then
     exit(false);
     exit(false);
   SetGlobalMatrix(AffineMatrixIdentity);
   SetGlobalMatrix(AffineMatrixIdentity);
   tl := GetTextLayout;
   tl := GetTextLayout;
-  pt := AffineMatrixInverse(GetUntransformedMatrix)*APoint;
+  untransformed := GetUntransformedMatrix;
+  if not IsAffineMatrixInversible(untransformed) then exit;
+  pt := AffineMatrixInverse(untransformed)*APoint;
   for i := 0 to tl.PartCount-1 do
   for i := 0 to tl.PartCount-1 do
     if tl.PartAffineBox[i].Contains(pt) then exit(true);
     if tl.PartAffineBox[i].Contains(pt) then exit(true);
   result := false;
   result := false;