📄 salphagraph.pas
字号:
unit sAlphaGraph;
{$I sDefs.inc}
interface
// universal formula for blending // Peter Result := ((Src1 - Src2) * PercentOfSrc1 + Src2 / 256) shr 8;
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, sConst, ExtCtrls, Jpeg, math{$IFNDEF ACHINTS}, sMaskData, sCommonData{$ENDIF};
{$IFNDEF NOTFORHELP}
type
TsCorner = (scLeftTop, scLeftBottom, scRightTop, scRightBottom);
TsCorners = set of TsCorner;
TacFast24 = class
private
FBitmap: TBitmap;
FWidth, FHeight: Integer;
FDelta: Integer;
function GetPixel(X, Y: Integer): TsColor;
procedure SetPixel(X, Y: Integer; const Value: TsColor);
public
FStart, FLength, DstStart : longint;
function Attach(Bmp: TBitmap) : boolean;
property Width: Integer read FWidth;
property Height: Integer read FHeight;
property Pixels[X, Y: Integer]: TsColor read GetPixel write SetPixel; default;
end;
TacFast32 = class
private
FBitmap: TBitmap;
FWidth, FHeight: Integer;
FDelta: Integer;
function GetPixel(X, Y: Integer): TsColor;
procedure SetPixel(X, Y: Integer; const Value: TsColor);
public
FStart, FLength, DstStart : longint;
function Attach(Bmp: TBitmap) : boolean;
property Width: Integer read FWidth;
property Height: Integer read FHeight;
property Pixels[X, Y: Integer]: TsColor read GetPixel write SetPixel; default;
end;
TacFastSum24 = class
private
FBmpSrc, FBmpDst: TBitmap;
FWidthDst, FHeightDst: Integer;
FStartSrc, FStartDst : longint;
FDeltaSrc, FDeltaDst: Integer;
public
Alpha : byte;
DstX1, DstY1, DstX2, DstY2, SrcX1, SrcY1, SrcX2, SrcY2 : longint;
procedure BlendBitmaps; pascal;
procedure BlendBitmapsRect; pascal;
function Attach(BmpSrc, BmpDst: TBitmap) : boolean;
end;
var
Fast24Src, Fast24Dst : TacFast24;
FastSum24 : TacFastSum24;
Fast32Src : TacFast32;
{$ENDIF} // NOTFORHELP
procedure BlendColorRect(Bmp: TBitmap; R: TRect; Transparency: TPercent; Color: TColor);
{$IFNDEF ACHINTS}
// Copy with AlphaMask from MasterBmp (get transp. pixels from parent)
procedure CopyMasterRect(R1, R2 : TRect; Bmp : TBitmap; CI : TCacheInfo; MaskData : TsMaskData);
procedure DrawSmallSkinRect(Bmp : TBitmap; R : TRect; Filling : boolean; ci : TCacheInfo; MaskData : TsMaskData; State : integer);
// Skinned rectangle with transparent corners
procedure DrawSkinRect(Bmp : TBitmap; R : TRect; Filling : boolean; ci : TCacheInfo; MaskData : TsMaskData; State : integer; UpdateCorners : boolean; SkinManager : TObject = nil);
// Skip transparent part of corners
procedure DrawSkinGlyph(Bmp : TBitmap; P : TPoint; State, AddedTransparency : integer; MaskData : TsMaskData);
// Transparency - percent of the bmp visibility
procedure BmpDisabledKind(Bmp : TBitmap; DisabledKind : TsDisabledKind; Parent : TControl; CI : TCacheInfo; Offset : TPoint);
{$IFNDEF NOTFORHELP}
// Skip transparent pixels
procedure CopyMasterRectA(R1, R2 : TRect; Bmp : TBitmap; CI : TCacheInfo; MaskData : TsMaskData);
procedure BlendGlyphByMask(R1, R2 : TRect; Bmp1, Bmp2 : TBitmap; TransColor : TColor; AddedTransparency : integer; MaskData : TsMaskData);
procedure UpdateCorners(SkinData : TsCommonData; State : integer); overload;
procedure UpdateCorners(SkinData : TsCommonData; State : integer; Corners : TsCorners); overload;
{$ENDIF} // NOTFORHELP
{$ENDIF}
implementation
Uses acntUtils, sGraphUtils{$IFNDEF ACHINTS}, sDefaults, sVclUtils, sSkinManager{$ENDIF};
procedure BlendColorRect(Bmp: TBitmap; R: TRect; Transparency: TPercent; Color: TColor);
var
BmpLine : PRGBArray;
BlendColor : TsColor;
x, y : integer;
rT, tR : real;
begin
if R.Left < 0 then R.Left := 0;
if R.Top < 0 then R.Top := 0;
if R.Right > Bmp.Width - 1 then R.Right := Bmp.Width - 1;
if R.Bottom > Bmp.Height - 1 then R.Bottom := Bmp.Height - 1;
BlendColor.C := ColorToRGB(Color);
rT := Transparency / 100;
tR := 1 - rT;
for y := R.Top to R.Bottom do begin
BmpLine := Bmp.ScanLine[y];
for x := R.Left to R.Right do begin
BmpLine[X].R := Round(BmpLine[X].R * rT + BlendColor.R * tR);
BmpLine[X].G := Round(BmpLine[X].G * rT + BlendColor.G * tR);
BmpLine[X].B := Round(BmpLine[X].B * rT + BlendColor.B * tR);
end;
end;
end;
{$IFNDEF ACHINTS}
procedure BmpDisabledKind(Bmp : TBitmap; DisabledKind : TsDisabledKind; Parent : TControl; CI : TCacheInfo; Offset : TPoint);
var
C : TsColor;
R : TRect;
begin
if (dkGrayed in DisabledKind) then begin
GrayScale(Bmp);
end;
if (dkBlended in DisabledKind) then begin
R := Rect(0, 0, Bmp.Width, Bmp.Height);
if CI.Ready then begin
C.A := 255;
OffsetRect(R, CI.X + Offset.X, CI.Y + Offset.Y);
BlendTransRectangle(Bmp, 0, 0, CI.Bmp, R, DefDisabledBlend, C);
end
else begin
if ParentCenterColor <> clFuchsia
then C.C := ParentCenterColor
else C.C := ColorToRGB(TsHackedControl(Parent).Color);
BlendColorRect(Bmp, R, 50, C.C);
end;
end;
end;
procedure DrawSmallSkinRect(Bmp : TBitmap; R : TRect; Filling : boolean; ci : TCacheInfo; MaskData : TsMaskData; State : integer);
var
x, y : integer;
w, h : integer;
dw, dh : integer;
mw, mh, minhp, minwp, minh, minw : integer;
begin
if MaskData.Bmp = nil then with TsSkinManager(MaskData.Manager) do begin
if MaskData.Manager = nil then Exit;
if (WidthOf(R) < 2) or (HeightOf(R) < 2) then Exit;
if MaskData.ImageCount = 0 then exit;
if State >= MaskData.ImageCount then State := MaskData.ImageCount - 1;
dw := State * WidthOf(MaskData.R) div (MaskData.ImageCount); // Width of mask
dh := HeightOf(MaskData.R) div (1 + MaskData.MaskType); // Height of mask
w := WidthOf(MaskData.R) div (3 * MaskData.ImageCount);
h := HeightOf(MaskData.R) div (3 * (1 + MaskData.MaskType));
if WidthOf(R) < w * 2 then mw := WidthOf(R) div 2 else mw := 0;
if HeightOf(R) < h * 2 then mh := HeightOf(R) div 2 else mh := 0;
if mh > 0 then begin
minh := mh;
if HeightOf(R) mod 2 <> 0 then minhp := minh + 1 else minhp := minh;
end else begin
minh := h;
minhp := h;
end;
if mw > 0 then begin
minw := mw;
if WidthOf(R) mod 2 <> 0 then minwp := minw + 1 else minwp := minw;
end else begin
minw := w;
minwp := w;
end;
if MaskData.MaskType = 0 then begin
// left - top
CopyTransRect(Bmp, MasterBitmap, R.Left, R.Top,
Rect(MaskData.R.Left + dw,
MaskData.R.Top,
MaskData.R.Left + dw + minw,
MaskData.R.Top + minh),
clFuchsia, CI, True);
// left - middle
y := R.Top + h;
if MaskData.DrawMode and BDM_STRETCH = 0 then begin
while y < R.Bottom - h do begin
BitBlt(Bmp.Canvas.Handle, R.Left, y, minw, h, MasterBitmap.Canvas.Handle, MaskData.R.Left + dw, MaskData.R.Top + h, SRCCOPY);
inc(y, h);
end;
if y < R.Bottom - h then BitBlt(Bmp.Canvas.Handle, R.Left, y, minw, h,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw, MaskData.R.Top + h, SRCCOPY);
end
else StretchBlt(Bmp.Canvas.Handle,
R.Left, y, R.Left + minw, R.Bottom - minh - y,
MasterBitmap.Canvas.Handle,
MaskData.R.Left + dw, MaskData.R.Top + h, minw, h,
SRCCOPY);
// top - middle
x := R.Left + minw;
if MaskData.DrawMode and BDM_STRETCH = 0 then begin
while x < R.Right - w - minw do begin
BitBlt(Bmp.Canvas.Handle, x, R.Top, w, minh, MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Top, SRCCOPY);
inc(x, w);
end;
if x < R.Right - minw then BitBlt(Bmp.Canvas.Handle, x, R.Top, R.Right - minw - x, minh, MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Top, SRCCOPY);
end
else StretchBlt(Bmp.Canvas.Handle,
x, R.Top, R.Right - minw - x, minh,
MasterBitmap.Canvas.Handle,
MaskData.R.Left + dw + w, MaskData.R.Top, w, minh,
SRCCOPY); // v4.52
// left - bottom
CopyTransRect(Bmp, MasterBitmap, R.Left, R.Bottom - minhp,
Rect(MaskData.R.Left + dw,
MaskData.R.Bottom - minhp,
MaskData.R.Left + dw + minw - 1,
MaskData.R.Bottom - 1),
clFuchsia, CI, True);
// bottom - middle
x := R.Left + minw;
if MaskData.DrawMode and BDM_STRETCH = 0 then begin
while x < R.Right - w - minw do begin
BitBlt(Bmp.Canvas.Handle, x, R.Bottom - minh, w, minh,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Bottom - minh, SRCCOPY);
inc(x, w);
end;
if x < R.Right - minw then BitBlt(Bmp.Canvas.Handle, x, R.Bottom - minh, R.Right - minw - x, minh,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Bottom - minh, SRCCOPY);
end
else StretchBlt(Bmp.Canvas.Handle,
x, R.Bottom - minh, R.Right - minw - x, minh,
MasterBitmap.Canvas.Handle,
MaskData.R.Left + dw + w, MaskData.R.Bottom - minh, w, minh,
SRCCOPY); // v4.52
// right - bottom
CopyTransRect(Bmp, MasterBitmap, R.Right - minwp, R.Bottom - minhp,
Rect(MaskData.R.Left + dw + 3 * w - minwp,
MaskData.R.Bottom - minhp,
MaskData.R.Left + dw + 3 * w - 1,
MaskData.R.Bottom - 1),
clFuchsia, CI, True);
// right - top
CopyTransRect(Bmp, MasterBitmap, R.Right - minwp, R.Top,
Rect(MaskData.R.Left + dw + 3 * w - minwp,
MaskData.R.Top,
MaskData.R.Left + dw + 3 * w - 1,
MaskData.R.Top + minh - 1),
clFuchsia, CI, True);
// right - middle
y := R.Top + h;
while y < R.Bottom - h do begin
BitBlt(Bmp.Canvas.Handle, R.Right - minwp, y, minwp, h,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + 3 * w - minwp, MaskData.R.Top + h, SRCCOPY);
inc(y, h);
end;
if y < R.Bottom - h then begin
BitBlt(Bmp.Canvas.Handle, R.Right - minwp, y, minwp, R.Bottom - h - y,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + 3 * w - minwp, MaskData.R.Top + h, SRCCOPY);
end;
// Fill
if Filling and (MaskData.DrawMode and BDM_FILL = BDM_FILL) then begin
y := R.Top + h;
while y < R.Bottom - 2 * h do begin
x := R.Left + w;
while x < R.Right - 2 * w do begin
BitBlt(Bmp.Canvas.Handle, x, y, w, h,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Top + h, SRCCOPY);
inc(x, w);
end;
if x < R.Right - w then begin
BitBlt(Bmp.Canvas.Handle, x, y, R.Right - w - x, R.Bottom - h - y,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Top + h, SRCCOPY);
end;
inc(y, h);
end;
x := R.Left + w;
if y < R.Bottom - h then begin
while x < R.Right - 2 * w do begin
BitBlt(Bmp.Canvas.Handle, x, y, w, R.Bottom - h - y,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Top + h, SRCCOPY);
inc(x, w);
end;
if x < R.Right - w then begin
BitBlt(Bmp.Canvas.Handle, x, y, R.Right - w - x, R.Bottom - h - y,
MasterBitmap.Canvas.Handle, MaskData.R.Left + dw + w, MaskData.R.Top + h, SRCCOPY);
end
end;
end;
end
else begin
CopyMasterRect(Rect(R.Left, R.Top, R.Left + minw + 1, R.Top + minh + 1),
Rect(MaskData.R.Left + dw, MaskData.R.Top, MaskData.R.Left + dw + minw, MaskData.R.Top + minh),
Bmp, ci, MaskData);
// left - middle
y := R.Top + h;
while y < R.Bottom - h do begin
CopyMasterRect(Rect(R.Left, y, R.Left + minw + 1, y + h + 1),
Rect(MaskData.R.Left + dw, MaskData.R.Top + h, MaskData.R.Left + dw + minw, MaskData.R.Top + 2 * h),
Bmp, CI, MaskData);
inc(y, h);
end;
if y < R.Bottom - h then begin
CopyMasterRect(Rect(R.Left, y, R.Left + minw, R.Bottom - h), Rect(MaskData.R.Left + dw, MaskData.R.Top + h, MaskData.R.Left + dw + minw, MaskData.R.Top + dh - h), Bmp, CI, MaskData);
end;
// top - middle
x := R.Left + w;
while x < R.Right - 2 * w do begin
CopyMasterRect(Rect(x, R.Top, x + w, R.Top + minh), Rect(MaskData.R.Left + dw + w, MaskData.R.Top, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + minh), Bmp, CI, MaskData);
inc(x, w);
end;
if x < R.Right - w then begin
CopyMasterRect(Rect(x, R.Top, R.Right - w, R.Top + minh), Rect(MaskData.R.Left + dw + w, MaskData.R.Top, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + minh), Bmp, CI, MaskData);
end;
// left - bottom
CopyMasterRect(Rect(R.Left, R.Bottom - minhp, R.Left + minw, R.Bottom), Rect(MaskData.R.Left + dw, MaskData.R.Top + dh - minhp, MaskData.R.Left + dw + minw, MaskData.R.Top + dh), Bmp, CI, MaskData);
// bottom - middle
x := R.Left + w;
while x < R.Right - 2 * w do begin
CopyMasterRect(Rect(x, R.Bottom - minhp, x + w, R.Bottom), Rect(MaskData.R.Left + dw + w, MaskData.R.Top + dh - minhp, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + dh), Bmp, CI, MaskData);
inc(x, w);
end;
if x < R.Right - w then begin
CopyMasterRect(Rect(x, R.Bottom - minhp, R.Right - w, R.Bottom), Rect(MaskData.R.Left + dw + w, MaskData.R.Top + dh - minhp, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + dh), Bmp, CI, MaskData);
end;
// right - bottom
CopyMasterRect(Rect(R.Right - minwp, R.Bottom - minhp, R.Right, R.Bottom), Rect(MaskData.R.Left + dw + 3 * w - minwp, MaskData.R.Top + dh - minhp, MaskData.R.Left + dw + 3 * w, MaskData.R.Top + dh), Bmp, CI, MaskData);
// right - top
CopyMasterRect(Rect(R.Right - minwp, R.Top, R.Right, R.Top + minh), Rect(MaskData.R.Left + dw + 3 * w - minwp, MaskData.R.Top, MaskData.R.Left + dw + 3 * w, MaskData.R.Top + minh), Bmp, CI, MaskData);
// right - middle
y := R.Top + h;
while y < R.Bottom - h do begin
CopyMasterRect(Rect(R.Right - minwp, y, R.Right, y + h), Rect(MaskData.R.Left + dw + 3 * w - minwp, MaskData.R.Top + h, MaskData.R.Left + dw + 3 * w, MaskData.R.Top + 2 * h), Bmp, CI, MaskData);
inc(y, h);
end;
if y < R.Bottom - h then begin
CopyMasterRect(Rect(R.Right - minwp, y, R.Right, R.Bottom - h), Rect(MaskData.R.Left + dw + 3 * w - minwp, MaskData.R.Top + h, MaskData.R.Left + dw + 3 * w, MaskData.R.Top + 2 * h), Bmp, CI, MaskData);
end;
// Fill
if Filling and (MaskData.DrawMode and BDM_FILL = BDM_FILL) then begin
y := R.Top + h;
while y < R.Bottom - h do begin
x := R.Left + w;
while x < R.Right - 2 * w do begin
CopyMasterRect(Rect(x, y, x + w, y + h), Rect(MaskData.R.Left + dw + w, MaskData.R.Top + h, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + 2 * h), Bmp, EmptyCI, MaskData);
inc(x, w);
end;
if x < R.Right - w then begin
CopyMasterRect(Rect(x, y, R.Right - w, y + h), Rect(MaskData.R.Left + dw + w, MaskData.R.Top + h, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + 2 * h), Bmp, EmptyCI, MaskData);
end;
inc(y, h);
end;
x := R.Left + w;
if y < R.Bottom - h then begin
while x < R.Right - 2 * w do begin
CopyMasterRect(Rect(x, y, x + w, R.Bottom - h), Rect(MaskData.R.Left + dw + w, MaskData.R.Top + h, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + 2 * h), Bmp, EmptyCI, MaskData);
inc(x, w);
end;
if x < R.Right - w then begin
CopyMasterRect(Rect(x, y, R.Right - w, R.Bottom - h), Rect(MaskData.R.Left + dw + w, MaskData.R.Top + h, MaskData.R.Left + dw + 2 * w, MaskData.R.Top + 2 * h), Bmp, EmptyCI, MaskData);
end
end;
end;
end;
end;
end;
procedure DrawSkinRect(Bmp : TBitmap; R : TRect; Filling : boolean; ci : TCacheInfo; MaskData : TsMaskData; State : integer; UpdateCorners : boolean; SkinManager : TObject = nil);
var
x, y : integer;
w, h : integer;
dw, dh : integer;
wl, wt, wr, wb : integer;
BmpSrc : TBitmap;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -