📄 sborders.pas
字号:
unit sBorders;
{$I sDefs.inc}
interface
uses Windows, Graphics, Classes, SysUtils, sMaskData;
procedure PaintRgnBorder(Bmp : TBitmap; Region : hrgn; Filling : boolean; MaskData : TsMaskData; State : integer); //v5 Ready
procedure CopyMask(DstX1, DstY1, DstX2, DstY2, SrcX1, SrcY1, SrcX2, SrcY2 : integer; Bmp : TBitmap; Region : hrgn; MaskData : TsMaskData; FillRgn : boolean = False);
implementation
uses acntUtils, Math, sSkinManager, sConst;
procedure CopyMask(DstX1, DstY1, DstX2, DstY2, SrcX1, SrcY1, SrcX2, SrcY2 : integer; Bmp : TBitmap; Region : hrgn; MaskData : TsMaskData; FillRgn : boolean = False);
var
S1, S2, M : PRGBArray;
X, Y, h, w, MaskH, MaskHd2, MaskBmpHeight: Integer;
c : TsColor;
RegRect : TRect;
fr : hrgn;
BmpSrc : TBitmap;
src, dst, msk : TsRGB;
begin
if (DstX1 < 0) or (DstX2 < 0) or (DstY1 < 0) or (DstY2 < 0) or (Bmp.Height < 2) or (Bmp.Width < 2) then Exit;
if MaskData.Manager = nil then Exit;
if MaskData.Bmp = nil then BmpSrc := TsSkinManager(MaskData.Manager).MasterBitmap else BmpSrc := MaskData.Bmp;
if MaskData.MaskType = 1 then begin
MaskH := HeightOf(MaskData.R);
MaskBmpHeight := BmpSrc.Height - 1;
MaskHd2 := MaskH div 2;
h := Min(DstY2 - DstY1, Bmp.Height - DstY1);
h := Min(h, MaskBmpHeight - SrcY1);
h := Min(SrcY2 - SrcY1, h);
w := Min(DstX2 - DstX1, SrcX2 - SrcX1);
RegRect := Rect(-1, 0, 0, 0);
c.A := 0;
try
if FillRgn then for Y := 0 to h do begin
S1 := Bmp.ScanLine[DstY1 + Y];
S2 := BmpSrc.ScanLine[SrcY1 + Y];
M := BmpSrc.ScanLine[SrcY1 + MaskHd2 + Y];
for X := 0 to w do begin
src := S2[SrcX1 + X];
c.R := src.R;
c.G := src.G;
c.B := src.B;
if c.C = sFuchsia.C then begin // If transparent pixel..
if RegRect.Left <> -1 then inc(RegRect.Right) else begin
RegRect.Left := DstX1 + X;
RegRect.Right := RegRect.Left + 1;
RegRect.Top := DstY1 + Y;
RegRect.Bottom := RegRect.Top + 1;
end;
end
else begin
if RegRect.Left <> -1 then begin
fr := CreateRectRgn(RegRect.Left, RegRect.Top, RegRect.Right, RegRect.Bottom);
CombineRgn(Region, Region, fr, RGN_XOR);
DeleteObject(fr);
RegRect.Left := -1;
end;
dst := S1[DstX1 + X];
msk := M[SrcX1 + X];
dst.R := IntToByte(((dst.R - src.R) * msk.R + src.R shl 8) shr 8);
dst.G := IntToByte(((dst.G - src.G) * msk.G + src.G shl 8) shr 8);
dst.B := IntToByte(((dst.B - src.B) * msk.B + src.B shl 8) shr 8);
S1[DstX1 + X] := dst;
end;
end;
if RegRect.Left <> -1 then begin
fr := CreateRectRgn(RegRect.Left, RegRect.Top, RegRect.Right, RegRect.Bottom);
CombineRgn(Region, Region, fr, RGN_DIFF);
DeleteObject(fr);
RegRect.Left := -1;
end;
end
else for Y := 0 to h do begin
S1 := Bmp.ScanLine[DstY1 + Y];
S2 := BmpSrc.ScanLine[SrcY1 + Y];
M := BmpSrc.ScanLine[SrcY1 + MaskHd2 + Y];
for X := 0 to w do begin
dst := S1[DstX1 + X];
src := S2[SrcX1 + X];
msk := M[SrcX1 + X];
dst.R := IntToByte(((dst.R - src.R) * msk.R + src.R shl 8) shr 8);
dst.G := IntToByte(((dst.G - src.G) * msk.G + src.G shl 8) shr 8);
dst.B := IntToByte(((dst.B - src.B) * msk.B + src.B shl 8) shr 8);
S1[DstX1 + X] := dst;
end;
end;
except
end;
end
else begin
h := Min(DstY2 - DstY1, Bmp.Height - DstY1);
h := Min(SrcY2 - SrcY1, h);
w := Min(DstX2 - DstX1, SrcX2 - SrcX1);
RegRect := Rect(-1, 0, 0, 0);
c.A := 0;
try
if FillRgn then for Y := 0 to h do begin
S1 := Bmp.ScanLine[DstY1 + Y];
S2 := BmpSrc.ScanLine[SrcY1 + Y];
for X := 0 to w do begin
src := S2[SrcX1 + X];
c.R := src.R;
c.G := src.G;
c.B := src.B;
if c.C = sFuchsia.C then begin // If transparent pixel..
if RegRect.Left <> -1 then inc(RegRect.Right) else begin
RegRect.Left := DstX1 + X;
RegRect.Right := RegRect.Left + 1;
RegRect.Top := DstY1 + Y;
RegRect.Bottom := RegRect.Top + 1;
end;
end
else begin
if RegRect.Left <> -1 then begin
fr := CreateRectRgn(RegRect.Left, RegRect.Top, RegRect.Right, RegRect.Bottom);
CombineRgn(Region, Region, fr, RGN_XOR);
DeleteObject(fr);
RegRect.Left := -1;
end;
S1[DstX1 + X] := src;
end;
end;
if RegRect.Left <> -1 then begin
fr := CreateRectRgn(RegRect.Left, RegRect.Top, RegRect.Right, RegRect.Bottom);
CombineRgn(Region, Region, fr, RGN_DIFF);
DeleteObject(fr);
RegRect.Left := -1;
end;
end
else for Y := 0 to h do begin
S1 := Bmp.ScanLine[DstY1 + Y];
S2 := BmpSrc.ScanLine[SrcY1 + Y];
for X := 0 to w do S1[DstX1 + X] := S2[SrcX1 + X];
end;
except
end;
// BitBlt(Bmp.Canvas.Handle, DstX1, DstY1, SrcX2 - SrcX1, SrcY2 - SrcY1, BmpSrc.Canvas.Handle, SrcX1, SrcY1, SRCCOPY);
end;
end;
procedure PaintRgnBorder(Bmp : TBitmap; Region : hrgn; Filling : boolean; MaskData : TsMaskData; State : integer);
var
x, y : integer;
w, h : integer;
dw, dh, pw : integer;
wl, wt, wr, wb : integer;
begin
if (Bmp.Width < 2) or (Bmp.Height < 2) or (MaskData.Manager = nil) then Exit;
wl := MaskData.WL; wt := MaskData.WT; wr := MaskData.WR; wb := MaskData.WB;
if wl + wr > Bmp.Width then begin
x := ((wl + wr) - Bmp.Width) div 2;
dec(wl, x); dec(wr, x); if Bmp.Width mod 2 > 0 then dec(wr);
if wl < 0 then wl := 0;
if wr < 0 then wr := 0;
end;
if wt + wb > Bmp.Height then begin
x := ((wt + wb) - Bmp.Height) div 2;
dec(wt, x); dec(wb, x); if Bmp.Height mod 2 > 0 then dec(wb);
if wt < 0 then wt := 0;
if wb < 0 then wb := 0;
end;
if MaskData.ImageCount < 1 then begin
MaskData.ImageCount := 1;
MaskData.R := Rect(0, 0, MaskData.Bmp.Width, MaskData.Bmp.Height);
end;
if State >= MaskData.ImageCount then State := MaskData.ImageCount - 1;
pw := WidthOf(MaskData.R) div MaskData.ImageCount; // Width of mask
dh := HeightOf(MaskData.R) div (1 + MaskData.MaskType); // Height of mask
w := pw - MaskData.WL - MaskData.WR; if w < 0 then w := 0; // Width of middle piece
h := dh - MaskData.WT - MaskData.WB; if h < 0 then h := 0; // Height of middle piece
dw := MaskData.R.Left + pw * State; // Offset of mask
// left - top
CopyMask(0, 0, wl - 1, wt - 1, dw, MaskData.R.Top, dw + wl - 1, MaskData.R.Top + wt - 1, Bmp, Region, MaskData, True);
// left - bottom
CopyMask(0, Bmp.Height - wb, wl - 1, Bmp.Height - 1, dw, MaskData.R.Top + dh - wb{MaskData.WT + h}, dw + MaskData.WL - 1, MaskData.R.Top + dh{MaskData.WT + h + MaskData.WB} - 1, Bmp, Region, MaskData, True);
// left - middle
y := wt;
while y < Bmp.Height - h - wb do begin
CopyMask(0, y, wl - 1, y + h - 1, dw, MaskData.R.Top + wt, MaskData.R.Left + dw + wl - 1, MaskData.R.Top + wt + h - 1, Bmp, Region, MaskData, False);
inc(y, h);
end;
if y < Bmp.Height - wb then CopyMask(0, y, wl - 1, Bmp.Height - wb - 1, dw, MaskData.R.Top + wt, dw + wl - 1, MaskData.R.Top + wt + h - 1, Bmp, Region, MaskData, False);
// top - middle
x := wl;
while x < Bmp.Width - w - wr do begin
CopyMask(x, 0, x + w - 1, wt - 1, dw + wl, MaskData.R.Top, dw + w + wl - 1, MaskData.R.Top + wt - 1, Bmp, Region, MaskData, False);
inc(x, w);
end;
if x < Bmp.Width - wr then CopyMask(x, 0, Bmp.Width - wr - 1, wt - 1, dw + wl, MaskData.R.Top, dw + w + wl - 1, MaskData.R.Top + wt - 1, Bmp, Region, MaskData, False);
// bottom - middle
x := wl;
while x < Bmp.Width - w - wr do begin
CopyMask(x, Bmp.Height - wb, x + w - 1, Bmp.Height - 1, dw + wl, MaskData.R.Top + dh - wb, dw + w + wl - 1, MaskData.R.Top + dh - 1, Bmp, Region, MaskData, False);
inc(x, w);
end;
if x < Bmp.Width - wr then CopyMask(x, Bmp.Height - wb, Bmp.Width - wr - 1, Bmp.Height - 1, dw + wl, MaskData.R.Top + dh - wb, dw + w + wl - 1, MaskData.R.Top + dh - 1, Bmp, Region, MaskData, False);
// right - middle
y := wt;
while y < Bmp.Height - h - wb do begin
CopyMask(Bmp.Width - wr, y, Bmp.Width - 1, y + h - 1, dw + w + wl, MaskData.R.Top + wt, dw + pw - 1, MaskData.R.Top + h + wt - 1, Bmp, Region, MaskData, False);
inc(y, h);
end;
if y < Bmp.Height - wb then CopyMask(Bmp.Width - wr, y, Bmp.Width - 1, Bmp.Height - wb - 1, dw + w + wl, MaskData.R.Top + wt, dw + pw - 1, MaskData.R.Top + h + wt - 1, Bmp, Region, MaskData, False);
// right - bottom
CopyMask(Bmp.Width - wr, Bmp.Height - wb, Bmp.Width - 1, Bmp.Height - 1, dw + pw - wr, MaskData.R.Top + dh - wb, dw + pw - 1, MaskData.R.Top + dh - 1, Bmp, Region, MaskData, True);
// right - top
CopyMask(Bmp.Width - wr, 0, Bmp.Width - 1, wt - 1, dw + pw - wr, MaskData.R.Top, dw + pw - 1, MaskData.R.Top + wt - 1, Bmp, Region, MaskData, True);
// Fill
if Filling and (MaskData.DrawMode and BDM_FILL = BDM_FILL) then begin //???
y := wt;
while y < Bmp.Height - h - wb do begin
x := wl;
while x < Bmp.Width - w - wr do begin
CopyMask(x, y, x + w - 1, y + h - 1, dw + wl, MaskData.R.Top + wt, dw + w + wl - 1, MaskData.R.Top + h + wl - 1, Bmp, Region, MaskData, False);
inc(x, w);
end;
if x < Bmp.Width - wr then CopyMask(x, y, Bmp.Width - wr - 1, y + h, dw + wl, MaskData.R.Top + wt, dw + w + wl - 1, MaskData.R.Top + h + wt - 1, Bmp, Region, MaskData, False);
inc(y, h);
end;
x := wl;
if y < Bmp.Height - wb then begin
while x < Bmp.Width - w - wr do begin
CopyMask(x, y, x + w - 1, Bmp.Height - wb - 1, dw + wl, MaskData.R.Top + wt, dw + w + wl - 1, MaskData.R.Top + h + wt - 1, Bmp, Region, MaskData, False);
inc(x, w);
end;
if x < Bmp.Width - wr then CopyMask(x, y, Bmp.Width - wr - 1, Bmp.Height - wb - 1, dw + wl, MaskData.R.Top + wt, dw + w + wl - 1, MaskData.R.Top + h + wt - 1, Bmp, Region, MaskData, False);
end;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -