⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sborders.pas

📁 Alpha Controls 5.40,delphi上的alpha开发源码控件包。没有密码。5.40版的最新版。
💻 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 + -