📄 gr32_polygons.pas
字号:
begin
Bitmap.BeginUpdate;
if Antialiased then
begin
PolyPolygonXS(Bitmap, Points, FillCallback, FillMode, AntialiasMode, Transformation);
if (OutlineColor and $FF000000) <> 0 then
PolyPolylineXS(Bitmap, Points, OutlineColor, Closed, Transformation);
end
else
begin
PolyPolygonTS(Bitmap, Points, FillCallback, FillMode, Transformation);
if (OutlineColor and $FF000000) <> 0 then
PolyPolylineTS(Bitmap, Points, OutlineColor, Closed, Transformation);
end;
Bitmap.EndUpdate;
//SAARIXX
Bitmap.Changed(MakeRect(GetBoundingRect));
end;
procedure TPolygon32.Draw(Bitmap: TBitmap32; OutlineColor: TColor32;
Filler: TCustomPolygonFiller; Transformation: TTransformation);
begin
Draw(Bitmap, OutlineColor, Filler.FillLine, Transformation);
end;
procedure TPolygon32.DrawEdge(Bitmap: TBitmap32; Color: TColor32; Transformation: TTransformation);
begin
Bitmap.BeginUpdate;
if Antialiased then
PolyPolylineXS(Bitmap, Points, Color, Closed, Transformation)
else
PolyPolylineTS(Bitmap, Points, Color, Closed, Transformation);
Bitmap.EndUpdate;
//SAARIXX
Bitmap.Changed(MakeRect(GetBoundingRect));
end;
procedure TPolygon32.DrawFill(Bitmap: TBitmap32; Color: TColor32; Transformation: TTransformation);
begin
Bitmap.BeginUpdate;
if Antialiased then
PolyPolygonXS(Bitmap, Points, Color, FillMode, AntialiasMode, Transformation)
else
PolyPolygonTS(Bitmap, Points, Color, FillMode, Transformation);
Bitmap.EndUpdate;
//SAARIXX
Bitmap.Changed(MakeRect(GetBoundingRect));
end;
procedure TPolygon32.DrawFill(Bitmap: TBitmap32; FillCallback: TFillLineEvent;
Transformation: TTransformation);
begin
Bitmap.BeginUpdate;
if Antialiased then
PolyPolygonXS(Bitmap, Points, FillCallback, FillMode, AntialiasMode, Transformation)
else
PolyPolygonTS(Bitmap, Points, FillCallback, FillMode, Transformation);
Bitmap.EndUpdate;
//SAARIXX
Bitmap.Changed(MakeRect(GetBoundingRect));
end;
procedure TPolygon32.DrawFill(Bitmap: TBitmap32; Filler: TCustomPolygonFiller;
Transformation: TTransformation);
begin
DrawFill(Bitmap, Filler.FillLine, Transformation);
end;
function TPolygon32.Grow(const Delta: TFixed; EdgeSharpness: Single = 0): TPolygon32;
var
J, I, PrevI: Integer;
PX, PY, AX, AY, BX, BY, CX, CY, R, D, E: Integer;
procedure AddPoint(LongDeltaX, LongDeltaY: Integer);
var
N, L: Integer;
begin
with Result do
begin
N := High(Points);
L := Length(Points[N]);
SetLength(Points[N], L + 1);
end;
with Result.Points[N][L] do
begin
X := PX + LongDeltaX;
Y := PY + LongDeltaY;
end;
end;
begin
BuildNormals;
if EdgeSharpness > 0.99 then
EdgeSharpness := 0.99
else if EdgeSharpness < 0 then
EdgeSharpness := 0;
D := Delta;
E := Round(D * (1 - EdgeSharpness));
Result := TPolygon32.Create;
CopyPropertiesTo(Result);
if Delta = 0 then
begin
// simply copy the data
SetLength(Result.FPoints, Length(Points));
for J := 0 to High(Points) do
Result.Points[J] := Copy(Points[J], 0, Length(Points[J]));
Exit;
end;
Result.Points := nil;
for J := 0 to High(Points) do
begin
if Length(Points[J]) < 2 then Continue;
Result.NewLine;
for I := 0 to High(Points[J]) do
begin
with Points[J][I] do
begin
PX := X;
PY := Y;
end;
with Normals[J][I] do
begin
BX := MulDiv(X, D, $10000);
BY := MulDiv(Y, D, $10000);
end;
if (I > 0) or Closed then
begin
PrevI := I - 1;
if PrevI < 0 then PrevI := High(Points[J]);
with Normals[J][PrevI] do
begin
AX := MulDiv(X, D, $10000);
AY := MulDiv(Y, D, $10000);
end;
if (I = High(Points[J])) and (not Closed) then AddPoint(AX, AY)
else
begin
CX := AX + BX;
CY := AY + BY;
R := MulDiv(AX, CX, D) + MulDiv(AY, CY, D);
if R > E then AddPoint(MulDiv(CX, D, R), MulDiv(CY, D, R))
else
begin
AddPoint(AX, AY);
AddPoint(BX, BY);
end;
end;
end
else AddPoint(BX, BY);
end;
end;
end;
procedure TPolygon32.NewLine;
begin
SetLength(FPoints, Length(Points) + 1);
Normals := nil;
end;
procedure TPolygon32.Offset(const Dx, Dy: TFixed);
var
J, I: Integer;
begin
for J := 0 to High(Points) do
for I := 0 to High(Points[J]) do
with Points[J][I] do
begin
Inc(X, Dx);
Inc(Y, Dy);
end;
end;
function TPolygon32.Outline: TPolygon32;
var
J, I: Integer;
begin
BuildNormals;
Result := TPolygon32.Create;
CopyPropertiesTo(Result);
Result.Points := nil;
for J := 0 to High(Points) do
begin
if Length(Points[J]) < 2 then Continue;
if Closed then
begin
Result.NewLine;
for I := 0 to High(Points[J]) do Result.Add(Points[J][I]);
Result.NewLine;
for I := High(Points[J]) downto 0 do Result.Add(Points[J][I]);
end
else // not closed
begin
Result.NewLine;
for I := 0 to High(Points[J]) do Result.Add(Points[J][I]);
for I := High(Points[J]) downto 0 do Result.Add(Points[J][I]);
end;
end;
end;
procedure TPolygon32.Transform(Transformation: TTransformation);
begin
Points := TransformPoints(Points, Transformation);
end;
{ TBitmapFiller }
procedure TBitmapPolygonFiller.FillLineOpaque(Dst: PColor32; DstX, DstY,
Length: Integer; AlphaValues: PColor32);
var
PatternX, PatternY, X: Integer;
OpaqueAlpha: TColor32;
Src: PColor32;
BlendMemEx: TBlendMemEx;
begin
PatternX := (DstX - OffsetX) mod FPattern.Width;
If PatternX < 0 then PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
PatternY := (DstY - OffsetY) mod FPattern.Height;
If PatternY < 0 then PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
If Assigned(AlphaValues) then
begin
OpaqueAlpha := TColor32($FF shl 24);
BlendMemEx := BLEND_MEM_EX[FPattern.CombineMode];
for X := DstX to DstX + Length - 1 do
begin
BlendMemEx(Src^ and $00FFFFFF or OpaqueAlpha, Dst^, AlphaValues^);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
Inc(AlphaValues);
end
end
else
for X := DstX to DstX + Length - 1 do
begin
Dst^ := Src^;
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
end;
end;
procedure TBitmapPolygonFiller.FillLineBlend(Dst: PColor32; DstX, DstY, Length: Integer; AlphaValues: PColor32);
var
PatternX, PatternY, X: Integer;
Src: PColor32;
BlendMemEx: TBlendMemEx;
BlendMem: TBlendMem;
begin
PatternX := (DstX - OffsetX) mod FPattern.Width;
If PatternX < 0 then PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
PatternY := (DstY - OffsetY) mod FPattern.Height;
If PatternY < 0 then PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
If Assigned(AlphaValues) then
begin
BlendMemEx := BLEND_MEM_EX[FPattern.CombineMode];
for X := DstX to DstX + Length - 1 do
begin
BlendMemEx(Src^, Dst^, AlphaValues^);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
Inc(AlphaValues);
end
end
else
begin
BlendMem := BLEND_MEM[FPattern.CombineMode];
for X := DstX to DstX + Length - 1 do
begin
BlendMem(Src^, Dst^);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
end;
end;
end;
procedure TBitmapPolygonFiller.FillLineBlendMasterAlpha(Dst: PColor32; DstX, DstY,
Length: Integer; AlphaValues: PColor32);
var
PatternX, PatternY, X: Integer;
Src: PColor32;
BlendMemEx: TBlendMemEx;
begin
PatternX := (DstX - OffsetX) mod FPattern.Width;
If PatternX < 0 then PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
PatternY := (DstY - OffsetY) mod FPattern.Height;
If PatternY < 0 then PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
BlendMemEx := BLEND_MEM_EX[FPattern.CombineMode];
If Assigned(AlphaValues) then
for X := DstX to DstX + Length - 1 do
begin
BlendMemEx(Src^, Dst^, (AlphaValues^ * FPattern.MasterAlpha) div 255);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
Inc(AlphaValues);
end
else
for X := DstX to DstX + Length - 1 do
begin
BlendMemEx(Src^, Dst^, FPattern.MasterAlpha);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
end;
end;
procedure TBitmapPolygonFiller.FillLineCustomCombine(Dst: PColor32; DstX, DstY,
Length: Integer; AlphaValues: PColor32);
var
PatternX, PatternY, X: Integer;
Src: PColor32;
begin
PatternX := (DstX - OffsetX) mod FPattern.Width;
If PatternX < 0 then PatternX := (FPattern.Width + PatternX) mod FPattern.Width;
PatternY := (DstY - OffsetY) mod FPattern.Height;
If PatternY < 0 then PatternY := (FPattern.Height + PatternY) mod FPattern.Height;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
If Assigned(AlphaValues) then
for X := DstX to DstX + Length - 1 do
begin
FPattern.OnPixelCombine(Src^, Dst^, (AlphaValues^ * FPattern.MasterAlpha) div 255);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
Inc(AlphaValues);
end
else
for X := DstX to DstX + Length - 1 do
begin
FPattern.OnPixelCombine(Src^, Dst^, FPattern.MasterAlpha);
Inc(Dst); Inc(Src); Inc(PatternX);
If PatternX >= FPattern.Width then
begin
PatternX := 0;
Src := @FPattern.Bits[PatternX + PatternY * FPattern.Width];
end;
end;
end;
function TBitmapPolygonFiller.GetFillLine: TFillLineEvent;
begin
if not Assigned(FPattern) then
begin
Result := nil;
end
else if FPattern.DrawMode = dmOpaque then
Result := FillLineOpaque
else if FPattern.DrawMode = dmBlend then
begin
If FPattern.MasterAlpha = 255 then
Result := FillLineBlend
else
Result := FillLineBlendMasterAlpha;
end
else if (FPattern.DrawMode = dmCustom) and Assigned(FPattern.OnPixelCombine) then
begin
Result := FillLineCustomCombine;
end
else
Result := nil;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -