Forráskód Böngészése

selection frames in high DPI

Juliette ELSASS 1 éve
szülő
commit
f56301c85f

+ 1 - 0
lazpaint/lazpaint.lpr

@@ -208,6 +208,7 @@ begin
   Application.Initialize;
   UGraph.NicePointMaxRadius:= DoScaleX(UGraph.NicePointMaxRadius, OriginalDPI);
   UGraph.FrameDashLength:= DoScaleX(UGraph.FrameDashLength, OriginalDPI);
+  UGraph.FramePenWidth:= DoScaleX(UGraph.FramePenWidth, OriginalDPI);
 
   LazpaintApplication := TMyLazPaintInstance.Create;
   LazpaintApplication.UseConfig(ActualConfig);

+ 9 - 22
lazpaint/tools/utoollayer.pas

@@ -429,7 +429,6 @@ var
   m: TAffineMatrix;
   ab: TAffineBox;
   ptsF: ArrayOfTPointF;
-  pts: array of TPoint;
 begin
   NeedLayerBounds;
 
@@ -446,17 +445,12 @@ begin
             BitmapToVirtualScreen(m*PointF(FLayerBounds.Right-0.001,FLayerBounds.Top+0.001)),
             BitmapToVirtualScreen(m*PointF(FLayerBounds.Left+0.001,FLayerBounds.Bottom-0.001)));
   ptsF := ab.AsPolygon;
-  pts := nil;
-  setlength(pts, length(ptsF));
-  for i := 0 to high(pts) do
-    pts[i] := ptsF[i].Round;
-
-  result := TRect.Union(pts);
-  result.Inflate(1,1);
+  for i := 0 to high(ptsF) do ptsF[i] := ptsF[i] + PointF(0.5, 0.5);
 
   if Assigned(VirtualScreen) then
-    virtualScreen.DrawpolygonAntialias(pts,BGRA(230,255,230,255),BGRA(0,0,0,255),
-      FrameDashLength*Manager.CanvasScale);
+    result := NiceFrame(virtualScreen, Manager.CanvasScale, ptsF,
+      BGRA(230,255,230,255), BGRA(0,0,0,255)) else
+    result := NiceFrameBounds(Manager.CanvasScale, ptsF);
 end;
 
 { TToolTransformLayer }
@@ -740,8 +734,6 @@ var
   m: TAffineMatrix;
   ab: TAffineBox;
   ptsF: ArrayOfTPointF;
-  pts: array of TPoint;
-  ptsRect: TRect;
 begin
   idx := Manager.Image.CurrentLayerIndex;
   if not FOriginalBoundsDefined then
@@ -776,18 +768,13 @@ begin
             BitmapToVirtualScreen(m*PointF(FOriginalBounds.Right-0.001,FOriginalBounds.Top+0.001)),
             BitmapToVirtualScreen(m*PointF(FOriginalBounds.Left+0.001,FOriginalBounds.Bottom-0.001)));
   ptsF := ab.AsPolygon;
-  pts := nil;
-  setlength(pts, length(ptsF));
-  for i := 0 to high(pts) do
-    pts[i] := ptsF[i].Round;
-
-  ptsRect := TRect.Union(pts);
-  ptsRect.Inflate(1,1);
-  Result.Union(ptsRect);
+  for i := 0 to high(ptsF) do ptsF[i] := ptsF[i] + PointF(0.5, 0.5);
 
   if Assigned(VirtualScreen) then
-    virtualScreen.DrawpolygonAntialias(pts,BGRA(230,255,230,255),BGRA(0,0,0,255),
-      FrameDashLength*Manager.CanvasScale);
+    result := NiceFrame(virtualScreen, Manager.CanvasScale, ptsF,
+      BGRA(230,255,230,255), BGRA(0,0,0,255))
+  else
+    result := NiceFrameBounds(Manager.CanvasScale, ptsF)
 end;
 
 function TToolTransformLayer.GetIsSelectingTool: boolean;

+ 7 - 26
lazpaint/tools/utoolselect.pas

@@ -279,9 +279,7 @@ function TToolSelectRect.Render(VirtualScreen: TBGRABitmap; VirtualScreenWidth,
 var
   ab: TAffineBox;
   ptsF: ArrayOfTPointF;
-  pts: array of TPoint;
   i: Integer;
-  abBounds: TRect;
 begin
   Result:= inherited Render(VirtualScreen, VirtualScreenWidth,
       VirtualScreenHeight, BitmapToVirtualScreen);
@@ -290,19 +288,12 @@ begin
   begin
     ab := TCustomRectShape(FShape).GetAffineBox(
       AffineMatrixTranslation(0.5,0.5)*FEditor.Matrix*AffineMatrixTranslation(-0.5,-0.5), false);
-    abBounds := ab.RectBounds;
-    abBounds.Inflate(1,1);
-    result := RectUnion(result, abBounds);
     if Assigned(VirtualScreen) then
     begin
       ptsF := ab.AsPolygon;
-      pts := nil;
-      setlength(pts, length(ptsF));
-      for i := 0 to high(ptsF) do
-        pts[i] := (ptsF[i]+PointF(0.5,0.5)).Round;
-      VirtualScreen.DrawPolygonAntialias(pts,BGRAWhite,BGRABlack,
-        FrameDashLength*Manager.CanvasScale);
-    end;
+      result := RectUnion(result, NiceFrame(VirtualScreen, Manager.CanvasScale, ptsF, BGRAWhite,BGRABlack));
+    end else
+      result := RectUnion(result, NiceFrameBounds(Manager.CanvasScale, ptsF));
   end;
 end;
 
@@ -327,34 +318,24 @@ function TToolSelectEllipse.Render(VirtualScreen: TBGRABitmap;
   VirtualScreenWidth, VirtualScreenHeight: integer;
   BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect;
 var
-  ab: TAffineBox;
   ptsF: ArrayOfTPointF;
-  pts: array of TPoint;
   i: Integer;
-  abBounds: TRect;
 begin
   Result:= inherited Render(VirtualScreen, VirtualScreenWidth,
       VirtualScreenHeight, BitmapToVirtualScreen);
 
   if BigImage and FQuickDefine then
   begin
-    ab := TCustomRectShape(FShape).GetAffineBox(
-      AffineMatrixTranslation(0.5,0.5)*FEditor.Matrix*AffineMatrixTranslation(-0.5,-0.5), false);
-    abBounds := ab.RectBounds;
-    abBounds.Inflate(1,1);
-    result := RectUnion(result, abBounds);
     if Assigned(VirtualScreen) then
     begin
       with TCustomRectShape(FShape) do
         ptsF := BGRAPath.ComputeEllipse(FEditor.Matrix*Origin,
                     FEditor.Matrix*XAxis,FEditor.Matrix*YAxis);
-      pts := nil;
-      setlength(pts, length(ptsF));
       for i := 0 to high(ptsF) do
-        pts[i] := ptsF[i].Round;
-      VirtualScreen.DrawPolygonAntialias(pts,BGRAWhite,BGRABlack,
-        FrameDashLength*Manager.CanvasScale);
-    end;
+        ptsF[i] := ptsF[i] + PointF(0.5, 0.5);
+      result := RectUnion(result, NiceFrame(VirtualScreen, Manager.CanvasScale, ptsF, BGRAWhite,BGRABlack));
+    end else
+      result := RectUnion(result, NiceFrameBounds(Manager.CanvasScale, ptsF));
   end;
 end;
 

+ 46 - 1
lazpaint/ugraph.pas

@@ -12,6 +12,7 @@ uses
 var
   NicePointMaxRadius: integer = 6;
   FrameDashLength: integer = 4;
+  FramePenWidth: integer = 10;
   CanvasScale: integer = 1;
 
 function ComputeRatio(ARatio: string): single;
@@ -29,6 +30,9 @@ function ComputeAngle(dx,dy: single): single;
 function GetSelectionCenter(bmp: TBGRABitmap): TPointF;
 procedure ComputeSelectionMask(image: TBGRABitmap; destMask: TBGRABitmap; ARect: TRect);
 procedure SubstractMask(image: TBGRABitmap; DestX,DestY: Integer; mask: TBGRABitmap; SourceMaskRect: TRect);
+function NiceFrameBounds(ACanvasScale: integer; APoints: array of TPointF): TRect;
+function NiceFrame(ABitmap: TBGRABitmap; ACanvasScale: integer; APoints: array of TPointF;
+  AColor1, AColor2: TBGRAPixel): TRect;
 function NicePointBounds(x,y: single): TRect;
 function NicePoint(bmp: TBGRABitmap; x,y: single; alpha: byte = 192):TRect; overload;
 function NicePoint(bmp: TBGRABitmap; ptF: TPointF; alpha: byte = 192):TRect; overload;
@@ -70,7 +74,7 @@ implementation
 
 uses GraphType, math, Types, FileUtil, dialogs, BGRAAnimatedGif,
   BGRAGradients, BGRATextFX, uresourcestrings, LCScaleDPI,
-  BGRAThumbnail, LCVectorPolyShapes, BGRAPolygon;
+  BGRAThumbnail, LCVectorPolyShapes, BGRAPolygon, BGRAPen;
 
 function ComputeRatio(ARatio: string): single;
 var
@@ -1193,6 +1197,47 @@ begin
     end;
 end;
 
+function NiceFrameBounds(ACanvasScale: integer; APoints: array of TPointF): TRect;
+var
+  rF: TRectF;
+  w: Extended;
+  pt: TPointF;
+begin
+  w := FramePenWidth*ACanvasScale/10 / 2 + 1;
+  rF := EmptyRectF;
+  for pt in APoints do
+    rF := rF.Union(RectF(pt + PointF(0.5, 0.5) - PointF(w, w),
+      pt + PointF(0.5, 0.5) + PointF(w, w)));
+  result := rect(floor(rF.Left), floor(rF.Top),
+    ceil(rF.Right), ceil(rF.Bottom));
+end;
+
+function NiceFrame(ABitmap: TBGRABitmap; ACanvasScale: integer;
+  APoints: array of TPointF; AColor1, AColor2: TBGRAPixel): TRect;
+var
+  w, d: single;
+  filler: TBGRAMultishapeFiller;
+  stroker: TBGRAPenStroker;
+begin
+  result := NiceFrameBounds(ACanvasScale, APoints);
+  w := FramePenWidth*ACanvasScale/10;
+  d := FrameDashLength*ACanvasScale;
+  filler := TBGRAMultishapeFiller.Create;
+  stroker := nil;
+  try
+    stroker := TBGRAPenStroker.Create;
+    stroker.JoinStyle:= pjsRound;
+    filler.AddPolygonStroke(APoints, AColor2, w, stroker);
+    stroker.CustomPenStyle := BGRAPenStyle(d/w, d/w);
+    filler.AddPolygonStroke(APoints, AColor1, w, stroker);
+    filler.PolygonOrder:= poLastOnTop;
+    filler.Draw(ABitmap);
+  finally
+    stroker.Free;
+    filler.Free;
+  end;
+end;
+
 function NicePointBounds(x,y: single): TRect;
 var
   penWidth, penWidthStroke: Single;