Skip to content

Commit

Permalink
version 4.1.7 (VCL+FMX)
Browse files Browse the repository at this point in the history
- Updated packages for compilation with Skia4Delphi (defined by SVGIconImageList.inc)
- Fixed uses for skia unit
- Aligned to Image32 4.5 Version of 11 August 2024
  • Loading branch information
carloBarazzetta committed Aug 13, 2024
1 parent 9f7c15d commit 29f0d36
Show file tree
Hide file tree
Showing 68 changed files with 1,879 additions and 685 deletions.
499 changes: 317 additions & 182 deletions Demo/D12/SVGIconImageDemoFMX.dproj

Large diffs are not rendered by default.

20 changes: 9 additions & 11 deletions Image32/source/Img32.Draw.pas
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,6 @@ implementation
{$ENDIF CPUX86}

type
{$IF not declared(NativeInt)}
NativeInt = Integer;
{$IFEND}

{$IFDEF SUPPORTS_POINTERMATH}
// Works for Delphi 2009 and newer. For FPC it is a requirement,
// otherwise 32bit and 64bit code behave differently for negative
Expand Down Expand Up @@ -1690,7 +1686,7 @@ function TLinearGradientRenderer.Initialize(targetImage: TImage32): Boolean;
fColorsCnt := Ceil(dy + dxdy * (fEndPt.X - fStartPt.X));
MakeColorGradient(fGradientColors, fColorsCnt, fColors);
// get a list of perpendicular offsets for each
SetLength(fPerpendicOffsets, ImgWidth);
NewIntegerArray(fPerpendicOffsets, ImgWidth, True);
// from an imaginary line that's through fStartPt and perpendicular to
// the gradient line, get a list of Y offsets for each X in image width
for i := 0 to ImgWidth -1 do
Expand All @@ -1715,7 +1711,7 @@ function TLinearGradientRenderer.Initialize(targetImage: TImage32): Boolean;

fColorsCnt := Ceil(dx + dydx * (fEndPt.Y - fStartPt.Y));
MakeColorGradient(fGradientColors, fColorsCnt, fColors);
SetLength(fPerpendicOffsets, ImgHeight);
NewIntegerArray(fPerpendicOffsets, ImgHeight, True);
// from an imaginary line that's through fStartPt and perpendicular to
// the gradient line, get a list of X offsets for each Y in image height
for i := 0 to ImgHeight -1 do
Expand Down Expand Up @@ -1926,11 +1922,13 @@ procedure TSvgRadialGradientRenderer.RenderProc(x1, x2, y: integer; alpha: PByte
ellipsePt.X := (-qb -qs)/(2 * qa) else
ellipsePt.X := (-qb +qs)/(2 * qa);
ellipsePt.Y := m * ellipsePt.X + c;
dist := Hypot(pt.X - fFocusPt.X, pt.Y - fFocusPt.Y);
dist2 := Hypot(ellipsePt.X - fFocusPt.X, ellipsePt.Y - fFocusPt.Y);

// Use sqr'ed distances (Sqrt(a^2+b^2)/Sqrt(x^2+y^2) => Sqrt((a^2+b^2)/(x^2+y^2))
dist := Sqr(pt.X - fFocusPt.X) + Sqr(pt.Y - fFocusPt.Y);
dist2 := Sqr(ellipsePt.X - fFocusPt.X) + Sqr(ellipsePt.Y - fFocusPt.Y);
if dist2 = 0 then
q := 1 else
q := dist/ dist2;
q := Sqrt(dist/dist2);
end else
q := 1; //shouldn't happen :)
end;
Expand Down Expand Up @@ -2109,7 +2107,7 @@ procedure DrawLine(img: TImage32;
lines: TPathsD;
begin
setLength(lines, 1);
setLength(lines[0], 2);
NewPointDArray(lines[0], 2, True);
lines[0][0] := pt1;
lines[0][1] := pt2;
DrawLine(img, lines, lineWidth, color, esRound);
Expand Down Expand Up @@ -2473,7 +2471,7 @@ procedure DrawPolygon_ClearType(img: TImage32; const polygons: TPathsD;
cr.Free;
end;
ApplyClearType(tmpImg, color, backColor);
img.CopyBlend(tmpImg, tmpImg.Bounds, rec, BlendToAlpha);
img.CopyBlend(tmpImg, tmpImg.Bounds, rec, BlendToAlphaLine);
finally
tmpImg.Free;
end;
Expand Down
127 changes: 74 additions & 53 deletions Image32/source/Img32.Extra.pas
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
(*******************************************************************************
* Author : Angus Johnson *
* Version : 4.4 *
* Date : 3 July 2024 *
* Date : 26 July 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2019-2024 *
* Purpose : Miscellaneous routines that don't belong in other modules. *
Expand Down Expand Up @@ -538,7 +538,9 @@ procedure DrawShadow(img: TImage32; const polygons: TPathsD;
begin
rec := GetBounds(polygons);
if IsEmptyRect(rec) or (depth < 1) then Exit;
if not ClockwiseRotationIsAnglePositive then angleRads := -angleRads;
{$IFDEF CLOCKWISE_ROTATION_WITH_NEGATIVE_ANGLES}
angleRads := -angleRads;
{$ENDIF}
NormalizeAngle(angleRads);
GetSinCos(angleRads, y, x);
depth := depth * 0.5;
Expand All @@ -554,7 +556,7 @@ procedure DrawShadow(img: TImage32; const polygons: TPathsD;
DrawPolygon(shadowImg, shadowPolys, fillRule, color);
FastGaussianBlur(shadowImg, shadowImg.Bounds, blurSize, 1);
if cutoutInsideShadow then EraseInsidePaths(shadowImg, polys, fillRule);
img.CopyBlend(shadowImg, shadowImg.Bounds, rec, BlendToAlpha);
img.CopyBlend(shadowImg, shadowImg.Bounds, rec, BlendToAlphaLine);
finally
shadowImg.Free;
end;
Expand Down Expand Up @@ -590,7 +592,7 @@ procedure DrawGlow(img: TImage32; const polygons: TPathsD;
DrawPolygon(glowImg, glowPolys, fillRule, color);
FastGaussianBlur(glowImg, glowImg.Bounds, blurRadius, 2);
glowImg.ScaleAlpha(4);
img.CopyBlend(glowImg, glowImg.Bounds, rec, BlendToAlpha);
img.CopyBlend(glowImg, glowImg.Bounds, rec, BlendToAlphaLine);
finally
glowImg.Free;
end;
Expand Down Expand Up @@ -676,7 +678,7 @@ procedure GridBackground(img: TImage32; majorInterval, minorInterval: integer;
begin
img.Clear(fillColor);
w := img.Width; h := img.Height;
SetLength(path, 2);
NewPointDArray(path, 2, True);
if minorInterval > 0 then
begin
x := minorInterval;
Expand Down Expand Up @@ -895,7 +897,7 @@ procedure RedEyeRemove(img: TImage32; const rect: TRect);
path := Ellipse(cutoutRec);
radGrad.SetParameters(rect3, clBlack32, clNone32);
DrawPolygon(mask, path, frNonZero, radGrad);
cutout.CopyBlend(mask, mask.Bounds, cutout.Bounds, BlendMask);
cutout.CopyBlend(mask, mask.Bounds, cutout.Bounds, BlendMaskLine);
// now remove red from the cutout
RemoveColor(cutout, clRed32);
// finally replace the cutout ...
Expand Down Expand Up @@ -935,7 +937,7 @@ procedure EraseOutsidePath(img: TImage32; const path: TPathD;
try
p := TranslatePath(path, -outsideBounds.Left, -outsideBounds.top);
DrawPolygon(mask, p, fillRule, clBlack32);
img.CopyBlend(mask, mask.Bounds, outsideBounds, BlendMask);
img.CopyBlend(mask, mask.Bounds, outsideBounds, BlendMaskLine);
finally
mask.Free;
end;
Expand All @@ -955,7 +957,7 @@ procedure EraseOutsidePaths(img: TImage32; const paths: TPathsD;
try
pp := TranslatePath(paths, -outsideBounds.Left, -outsideBounds.top);
DrawPolygon(mask, pp, fillRule, clBlack32);
img.CopyBlend(mask, mask.Bounds, outsideBounds, BlendMask);
img.CopyBlend(mask, mask.Bounds, outsideBounds, BlendMaskLine);
finally
mask.Free;
end;
Expand Down Expand Up @@ -986,7 +988,9 @@ procedure Draw3D(img: TImage32; const polygons: TPathsD;
begin
rec := GetBounds(polygons);
if IsEmptyRect(rec) then Exit;
if not ClockwiseRotationIsAnglePositive then angleRads := -angleRads;
{$IFDEF CLOCKWISE_ROTATION_WITH_NEGATIVE_ANGLES}
angleRads := -angleRads;
{$ENDIF}
GetSinCos(angleRads, y, x);
paths := TranslatePath(polygons, -rec.Left, -rec.Top);
RectWidthHeight(rec, w, h);
Expand All @@ -999,7 +1003,7 @@ procedure Draw3D(img: TImage32; const polygons: TPathsD;
EraseInsidePaths(tmp, paths2, fillRule);
FastGaussianBlur(tmp, tmp.Bounds, Round(blurRadius), 0);
EraseOutsidePaths(tmp, paths, fillRule, tmp.Bounds);
img.CopyBlend(tmp, tmp.Bounds, rec, BlendToAlpha);
img.CopyBlend(tmp, tmp.Bounds, rec, BlendToAlphaLine);
end;
if GetAlpha(colorDk) > 0 then
begin
Expand All @@ -1008,7 +1012,7 @@ procedure Draw3D(img: TImage32; const polygons: TPathsD;
EraseInsidePaths(tmp, paths2, fillRule);
FastGaussianBlur(tmp, tmp.Bounds, Round(blurRadius), 0);
EraseOutsidePaths(tmp, paths, fillRule, tmp.Bounds);
img.CopyBlend(tmp, tmp.Bounds, rec, BlendToAlpha);
img.CopyBlend(tmp, tmp.Bounds, rec, BlendToAlphaLine);
end;
finally
tmp.Free;
Expand Down Expand Up @@ -1087,7 +1091,7 @@ function DrawButton(img: TImage32; const pt: TPointD;
case buttonShape of
bsDiamond:
begin
SetLength(Result, 4);
NewPointDArray(Result, 4, True);
for i := 0 to 3 do Result[i] := pt;
Result[0].X := Result[0].X -radius;
Result[1].Y := Result[1].Y -radius;
Expand Down Expand Up @@ -1198,8 +1202,8 @@ procedure TraceContours(img: TImage32; intensity: integer);
begin
w := img.Width; h := img.Height;
if w * h = 0 then Exit;
SetLength(tmp, w * h);
SetLength(tmp2, w * h);
NewColor32Array(tmp, w * h);
NewColor32Array(tmp2, w * h);
s := img.PixelRow[0]; d := @tmp[0];
for j := 0 to h-1 do
begin
Expand Down Expand Up @@ -1750,7 +1754,7 @@ function SimplifyPath(const path: TPathD;
end;
if highI +1 < minLen then Exit;
if not isClosedPath then first := @srArray[0];
SetLength(Result, highI +1);
NewPointDArray(Result, highI +1, True);
for i := 0 to HighI do
begin
Result[i] := first.pt;
Expand Down Expand Up @@ -1873,7 +1877,7 @@ function SimplifyPathEx(const path: TPathD; shapeTolerance: double): TPathD;
end;

if highI < 2 then Exit;
SetLength(Result, highI +1);
NewPointDArray(Result, highI +1, True);
for i := 0 to HighI do
begin
Result[i] := current.pt;
Expand Down Expand Up @@ -1921,7 +1925,7 @@ function SmoothToCubicBezier(const path: TPathD;
len := Length(path);
if len < 3 then Exit;

SetLength(Result, len *3 +1);
NewPointDArray(Result, len *3 +1, True);
prev := len-1;
SetLength(pl, len);
SetLength(unitVecs, len);
Expand Down Expand Up @@ -1994,7 +1998,7 @@ function SmoothToCubicBezier2(const path: TPathD;
len := Length(path);
if len < 3 then Exit;

SetLength(Result, len *3 +1);
NewPointDArray(Result, len *3 +1);
prev := len-1;
SetLength(pl, len);
SetLength(unitVecs, len);
Expand Down Expand Up @@ -2091,7 +2095,7 @@ procedure Append(var path: TPathD; const pt: TPointD);
len: integer;
begin
len := Length(path);
SetLength(path, len +1);
SetLengthUninit(path, len +1);
path[len] := pt;
end;
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -2239,7 +2243,7 @@ function BoxesForGauss(stdDev, boxCnt: integer): TArrayOfInteger;
i, wl, wu, m: integer;
wIdeal, mIdeal: double;
begin
SetLength(Result, boxCnt);
NewIntegerArray(Result, boxCnt, True);
wIdeal := Sqrt((12*stdDev*stdDev/boxCnt)+1); // Ideal averaging filter width
wl := Floor(wIdeal); if not Odd(wl) then dec(wl);
mIdeal :=
Expand All @@ -2265,7 +2269,7 @@ procedure BoxBlurH(var src, dst: TArrayOfColor32; w,h, stdDev: integer);
var
i,j, ti, li, ri, re, ovr: integer;
fv, val: TWeightedColor;
ce: TColor32;
lastColor: TColor32;
begin
ovr := Max(0, stdDev - w);
for i := 0 to h -1 do
Expand All @@ -2274,7 +2278,7 @@ procedure BoxBlurH(var src, dst: TArrayOfColor32; w,h, stdDev: integer);
li := ti;
ri := ti +stdDev;
re := ti +w -1; // idx of last pixel in row
ce := src[re]; // color of last pixel in row
lastColor := src[re]; // color of last pixel in row
fv.Reset(src[ti]);
val.Reset(src[ti], stdDev +1);
for j := 0 to stdDev -1 - ovr do
Expand All @@ -2283,30 +2287,38 @@ procedure BoxBlurH(var src, dst: TArrayOfColor32; w,h, stdDev: integer);
for j := 0 to stdDev do
begin
if ri > re then
val.Add(ce) else
val.Add(lastColor) else
val.Add(src[ri]);
inc(ri);
val.Subtract(fv);
if ti <= re then
dst[ti] := val.Color;
inc(ti);
end;
for j := stdDev +1 to w - stdDev -1 do

// Skip "val.Color" calculation if both for-loops are skipped anyway
if (ti <= re) or (w > stdDev*2 + 1) then
begin
if ri <= re then
lastColor := val.Color;
for j := stdDev +1 to w - stdDev -1 do
begin
val.Add(src[ri]); inc(ri);
val.Subtract(src[li]); inc(li);
if ri <= re then
begin
if val.AddSubtract(src[ri], src[li]) then
lastColor := val.Color;
inc(ri);
inc(li);
end;
dst[ti] := lastColor; inc(ti);
end;
while ti <= re do
begin
if val.AddNoneSubtract(src[li]) then
lastColor := val.Color;
inc(li);
dst[ti] := lastColor;
inc(ti);
end;
dst[ti] := val.Color; inc(ti);
end;
while ti <= re do
begin
if ti > re then Break;
val.Add(clNone32);
val.Subtract(src[li]); inc(li);
dst[ti] := val.Color;
inc(ti);
end;
end;
end;
Expand All @@ -2316,7 +2328,7 @@ procedure BoxBlurV(var src, dst: TArrayOfColor32; w, h, stdDev: integer);
var
i,j, ti, li, ri, re, ovr: integer;
fv, val: TWeightedColor;
ce: TColor32;
lastColor: TColor32;
begin
ovr := Max(0, stdDev - h);
for i := 0 to w -1 do
Expand All @@ -2325,7 +2337,7 @@ procedure BoxBlurV(var src, dst: TArrayOfColor32; w, h, stdDev: integer);
li := ti;
ri := ti + stdDev * w;
re := ti +w *(h-1); // idx of last pixel in column
ce := src[re]; // color of last pixel in column
lastColor := src[re]; // color of last pixel in column
fv.Reset(src[ti]);
val.Reset(src[ti], stdDev +1);
for j := 0 to stdDev -1 -ovr do
Expand All @@ -2334,29 +2346,38 @@ procedure BoxBlurV(var src, dst: TArrayOfColor32; w, h, stdDev: integer);
for j := 0 to stdDev do
begin
if ri > re then
val.Add(ce) else
val.Add(lastColor) else
val.Add(src[ri]);
inc(ri, w);
val.Subtract(fv);
if ti <= re then
dst[ti] := val.Color;
inc(ti, w);
end;
for j := stdDev +1 to h - stdDev -1 do

// Skip "val.Color" calculation if both for-loops are skipped anyway
if (ti <= re) or (h > stdDev*2 + 1) then
begin
if ri <= re then
lastColor := val.Color;
for j := stdDev +1 to h - stdDev -1 do
begin
val.Add(src[ri]); inc(ri, w);
val.Subtract(src[li]); inc(li, w);
if ri <= re then
begin
if val.AddSubtract(src[ri], src[li]) then
lastColor := val.Color;
inc(ri, w);
inc(li, w);
end;
dst[ti] := lastColor; inc(ti, w);
end;
while ti <= re do
begin
if val.AddNoneSubtract(src[li]) then
lastColor := val.Color;
inc(li, w);
dst[ti] := lastColor;
inc(ti, w);
end;
dst[ti] := val.Color; inc(ti, w);
end;
while ti <= re do
begin
val.Add(clNone32);
val.Subtract(src[li]); inc(li, w);
dst[ti] := val.Color;
inc(ti, w);
end;
end;
end;
Expand All @@ -2380,8 +2401,8 @@ procedure FastGaussianBlur(img: TImage32;
RectWidthHeight(rec2, w, h);
if (Min(w, h) < 2) or ((stdDevX < 1) and (stdDevY < 1)) then Exit;
len := w * h;
SetLength(src, len);
SetLength(dst, len);
NewColor32Array(src, len, True); // content is overwritten in BoxBlurH
NewColor32Array(dst, len, True);
if blurFullImage then
begin
// copy the entire image into 'dst'
Expand Down
Loading

0 comments on commit 29f0d36

Please sign in to comment.