cxgraphics.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,593 行 · 第 1/5 页

PAS
1,593
字号
      SoftwareAlphaBlend(AClientRect.Right, AClientRect.Bottom);
  end;

  procedure ComplexAlphaBlend;
  var
    ADirectDestBitmap, ADirectSrcBitmap, AStretchedSrcBitmap: TBitmap;
  begin
    ADirectSrcBitmap := CreateDirectBitmap(ASrcDC, ASrcRect);
    ADirectDestBitmap := CreateDirectBitmap(ADestDC, ADestRect);
    AStretchedSrcBitmap := cxCreateBitmap(ADestRect, pf32bit);
    try
      if ASmoothImage then
        cxSmoothResizeBitmap(ADirectSrcBitmap, AStretchedSrcBitmap, True)
      else
        ResizeBitmap(AStretchedSrcBitmap, ADirectSrcBitmap);
      InternalAlphaBlend(ADirectDestBitmap, AStretchedSrcBitmap);
      cxBitBlt(ADestDC, ADirectDestBitmap.Canvas.Handle, ADestRect, cxNullPoint, SRCCOPY);
    finally
      AStretchedSrcBitmap.Free;
      ADirectDestBitmap.Free;
      ADirectSrcBitmap.Free;
    end;
  end;

begin
  ASmoothImage := ASmoothImage and not cxRectIdentical(ADestRect, ASrcRect);
  if IsWin95X or not Assigned(VCLAlphaBlend) or ASmoothImage then
    ComplexAlphaBlend
  else
    SystemAlphaBlend(ADestDC, ASrcDC, ADestRect, ASrcRect, AConstantAlpha);
end;

procedure cxAlphaBlend(ADestBitmap, ASrcBitmap: TBitmap; const ADestRect, ASrcRect: TRect; ASmoothImage: Boolean = False; AConstantAlpha: Byte = $FF); overload;
begin
  CommonAlphaBlend(ADestBitmap.Canvas.Handle, ASrcBitmap.Canvas.Handle, ADestRect, ASrcRect, ASmoothImage, AConstantAlpha);
end;

procedure cxAlphaBlend(ADestDC: HDC; ASrcBitmap: TBitmap; const ADestRect, ASrcRect: TRect; ASmoothImage: Boolean = False; AConstantAlpha: Byte = $FF); overload;
begin
  CommonAlphaBlend(ADestDC, ASrcBitmap.Canvas.Handle, ADestRect, ASrcRect, ASmoothImage, AConstantAlpha);
end;

procedure cxAlphaBlend(ADestDC, ASrcDC: HDC; const ADestRect, ASrcRect: TRect; ASmoothImage: Boolean = False; AConstantAlpha: Byte = $FF); overload;
begin
  CommonAlphaBlend(ADestDC, ASrcDC, ADestRect, ASrcRect, ASmoothImage, AConstantAlpha);
end;

procedure cxBitBlt(ADestDC, ASrcDC: HDC; const ADestRect: TRect; const ASrcTopLeft: TPoint; ROP: DWORD);
begin
  BitBlt(ADestDC, ADestRect.Left, ADestRect.Top, cxRectWidth(ADestRect), cxRectHeight(ADestRect),
    ASrcDC, ASrcTopLeft.X, ASrcTopLeft.Y, ROP);
end;

procedure cxBlendFunction(const ASource: TRGBQuad; var ADest: TRGBQuad; ASourceConstantAlpha: Byte);

  function GetValue(AValue: Single): Byte;
  begin
    Result := GetChannelValue(Round(AValue));
  end;

var
  ASCA, ASrcAlpha: Single;
begin
  ASCA := ASourceConstantAlpha / 255;
  ASrcAlpha := 1 - ASource.rgbReserved * ASCA / 255;

  ADest.rgbRed := GetValue(ASource.rgbRed * ASCA + ASrcAlpha * ADest.rgbRed);
  ADest.rgbGreen := GetValue(ASource.rgbGreen * ASCA + ASrcAlpha * ADest.rgbGreen);
  ADest.rgbBlue := GetValue(ASource.rgbBlue * ASCA + ASrcAlpha * ADest.rgbBlue);
  ADest.rgbReserved := GetValue(ASource.rgbReserved * ASCA + ASrcAlpha * ADest.rgbReserved);
end;

procedure cxSetBitmapParams(ABitmap: TBitmap; AWidth, AHeight: Integer; AFormat: TPixelFormat);
begin
{$IFDEF DELPHI6}
  ABitmap.PixelFormat := AFormat;
{$ENDIF}
  ABitmap.Width := AWidth;
  ABitmap.Height := AHeight;
{$IFNDEF DELPHI6}
  ABitmap.PixelFormat := AFormat;
{$ENDIF}
end;

function cxCreateBitmap(const ASize: TSize; AFormat: TPixelFormat = pf24bit): TBitmap;
begin
  Result := cxCreateBitmap(ASize.cx, ASize.cy, AFormat);
end;

function cxCreateBitmap(const ARect: TRect; AFormat: TPixelFormat = pf24bit): TBitmap;
begin
  Result := cxCreateBitmap(cxRectWidth(ARect), cxRectHeight(ARect), AFormat);
end;

function cxCreateBitmap(AWidth, AHeight: Integer; AFormat: TPixelFormat = pf24bit): TBitmap;
begin
  Result := TBitmap.Create;
  cxSetBitmapParams(Result, AWidth, AHeight, AFormat);
end;

function cxCreateTrueColorBitmap(const ASize: TSize): TBitmap;
begin
  Result := cxCreateTrueColorBitmap(ASize.cx, ASize.cy);
end;

function cxCreateTrueColorBitmap(AWidth, AHeight: Integer): TBitmap;
begin
  Result := TBitmap.Create;
  Result.Handle := cxCreateTrueColorBitmapHandle(AWidth, AHeight);
end;

function cxCreateTrueColorBitmapHandle(AWidth, AHeight: Integer; ABPP: Integer = 32): HBitmap;
begin
  Result := CreateBitmap(AWidth, AHeight, 1, ABPP, nil);
end;

procedure cxDrawDesignRect(ACanvas: TcxCanvas; const ARect: TRect; ASelected: Boolean);
const
  Colors: array[Boolean] of TColor = ($A0FFA0, $9090FF);
var
  AColor: TColor;
  I: Integer;
  AShadowRect: TRect;
begin
  if not IsRectEmpty(ARect) then
  begin
    ACanvas.SaveState;
    try
      ACanvas.SetClipRegion(TcxRegion.Create(ARect), roSet);
      AColor := Colors[ASelected];
      ACanvas.FillRect(ARect, AColor);
      ACanvas.Pen.Color := Dark(AColor, 75);
      for I := 1 to MulDiv(ARect.Right, 3, 2) do
        ACanvas.Polyline([Point(ARect.Right - I * 3, ARect.Top), Point(ARect.Right, ARect.Top + I * 3)]);
      ACanvas.FrameRect(ARect, Dark(AColor, 50));
    finally
      ACanvas.RestoreState;
    end;
    ACanvas.ExcludeClipRect(ARect);
    AShadowRect := cxRectOffset(ARect, 1, 1);
    ACanvas.FillRect(AShadowRect, clBtnShadow);
    ACanvas.ExcludeClipRect(AShadowRect);
  end;
end;

function cxGetBitmapPixelFormat(ABitmap: TBitmap): Integer;
const
  ABitCounts: array [pf1Bit..pf32Bit] of Byte = (1,4,8,16,16,24,32);
begin
  case ABitmap.PixelFormat of
    pf1bit..pf32Bit: Result := ABitCounts[ABitmap.PixelFormat]
  else
    Result := GetDeviceCaps(ABitmap.Canvas.Handle, BITSPIXEL);
  end;
end;

procedure cxDrawBitmap(ADestDC: THandle; ASrcBitmap: TBitmap;
  const ADestRect: TRect; const ASrcPoint: TPoint; AMode: Integer); overload;

  procedure InternalDrawBitmap;

    procedure SoftwareBitBlt;
    var
      ABitmap: TcxBitmap;
    begin
      ABitmap := TcxBitmap.CreateSize(ADestRect);
      try
        cxBitBlt(ABitmap.Canvas.Handle, ASrcBitmap.Canvas.Handle, ABitmap.ClientRect, ASrcPoint, SRCCOPY);
        ABitmap.TransformBitmap(btmResetAlpha);
        cxBitBlt(ADestDC, ABitmap.Canvas.Handle, ADestRect, cxNullPoint, AMode);
      finally
        ABitmap.Free;
      end;
    end;

   begin
    if IsWin95X and (GetDeviceCaps(ADestDC, BITSPIXEL) = 32) and (cxGetBitmapPixelFormat(ASrcBitmap) < 32) then
      SoftwareBitBlt
    else
      cxBitBlt(ADestDC, ASrcBitmap.Canvas.Handle, ADestRect, ASrcPoint, AMode);
  end;

var
  APrevPalette: HPALETTE;
begin
  if (ASrcBitmap.Palette <> 0) and (GetDeviceCaps(ADestDC, BITSPIXEL) <= 8) then
  begin
    APrevPalette := SelectPalette(ADestDC, ASrcBitmap.Palette, True);
    RealizePalette(ADestDC);
    InternalDrawBitmap;
    SelectPalette(ADestDC, APrevPalette, True);
  end
  else
    InternalDrawBitmap;
end;

procedure cxDrawImage(ADC: THandle; AGlyphRect, ABackgroundRect: TRect; AGlyph: TBitmap;
  AImages: TCustomImageList; AImageIndex: Integer; ADrawMode: TcxImageDrawMode;
  ASmoothImage: Boolean = False; ABrush: THandle = 0;
  ATransparentColor: TColor = clNone; AUseLeftBottomPixelAsTransparent: Boolean = True);

  procedure DrawBackGround(ABitmap: TcxBitmap);
  begin
    if ABrush = 0 then
      cxBitBlt(ABitmap.Canvas.Handle, ADC, ABitmap.ClientRect, ABackgroundRect.TopLeft, SRCCOPY)
    else
      FillRect(ABitmap.Canvas.Handle, ABitmap.ClientRect, ABrush);
  end;

  procedure DrawImage(ABitmap: TcxBitmap; ADrawMode: TcxImageDrawMode);

    procedure MakeImage(AImageBitmap: TcxBitmap; out AIsAlphaUsed: Boolean);
    begin
      if not IsGlyphAssigned(AGlyph) then
      begin
        if AImages is TcxImageList then
          TcxImageList(AImages).GetImageInfo(AImageIndex, AImageBitmap, nil)
        else
          TcxImageList.GetImageInfo(AImages.Handle, AImageIndex, AImageBitmap, nil);

//        cxDrawImageList(AImages.Handle, AImageIndex, AImageBitmap.Canvas.Handle,
//          cxNullPoint, AImages.DrawingStyle, AImages.ImageType)
//#DG can break destination        AImages.Draw(AImageBitmap.Canvas, 0, 0, AImageIndex)
        AIsAlphaUsed := TcxImageList.GetPixelFormat(AImages.Handle) >= 32;
      end
      else
      begin
        AImageBitmap.CopyBitmap(AGlyph);
        AIsAlphaUsed := cxGetBitmapPixelFormat(AGlyph) >= 32;
      end;
      AIsAlphaUsed := AIsAlphaUsed and AImageBitmap.IsAlphaUsed;
      if not AIsAlphaUsed then
        AImageBitmap.TransformBitmap(btmSetOpaque);
    end;

    procedure MakeMask(AImageBitmap, AMaskBitmap: TcxBitmap; AIsAlphaUsed: Boolean);
    var
      AImageListMask: TcxBitmap;
    begin
      AMaskBitmap.CopyBitmap(AImageBitmap);
      if not AIsAlphaUsed then
      begin
        if not IsGlyphAssigned(AGlyph) then
        begin
          AImageListMask := TcxBitmap.CreateSize(AMaskBitmap.ClientRect);
          try
            TcxImageList.GetImageInfo(AImages.Handle, AImageIndex, nil, AImageListMask);
            AImageListMask.TransformBitmap(btmCorrectBlend);
            AMaskBitmap.Filter(AImageListMask);
          finally
            AImageListMask.Free;
          end;
        end;
        if ATransparentColor <> clNone then
          AMaskBitmap.TransparentPixels.Add(ATransparentColor);
        if AUseLeftBottomPixelAsTransparent and IsGlyphAssigned(AGlyph) then
          AMaskBitmap.TransparentPixels.Add(AMaskBitmap.TransparentColor);
      end;
      AMaskBitmap.TransformBitmap(btmMakeMask);
    end;

  const
    AImageShadowSize = 2;
  var
    BW, BH: Integer;
    AImageBitmap, AMaskBitmap: TcxBitmap;
    AConstantAlpha: Byte;
    AIsAlphaUsed: Boolean;
  begin
    OffsetRect(AGlyphRect, -ABackgroundRect.Left, -ABackgroundRect.Top);
    if not Assigned(CustomDrawImageProc) or not CustomDrawImageProc(ABitmap.Canvas, AImages, AImageIndex, AGlyph, AGlyphRect, ADrawMode) then
    begin
      if not IsGlyphAssigned(AGlyph) then
      begin
        BW := AImages.Width;
        BH := AImages.Height;
      end
      else
      begin
        BW := AGlyph.Width;
        BH := AGlyph.Height;
      end;

      AImageBitmap := GetImageBitmap(BW, BH);
      MakeImage(AImageBitmap, AIsAlphaUsed);

      AMaskBitmap := GetMaskBitmap(BW, BH);
      MakeMask(AImageBitmap, AMaskBitmap, AIsAlphaUsed);
      AImageBitmap.Filter(AMaskBitmap);
      AConstantAlpha := $FF;
      case ADrawMode of
        idmFaded:
          begin
            AImageBitmap.TransformBitmap(btmFade);
            AConstantAlpha := FadeMap.SrcConstantAlpha;
          end;
        idmGrayScale:
          AImageBitmap.TransformBitmap(btmGrayScale);
        idmDingy:
          AImageBitmap.TransformBitmap(btmDingy);
        idmShadowed:
          begin
            AImageBitmap.DrawShadow(AMaskBitmap, AImageShadowSize, clBtnShadow, True);
            AGlyphRect := cxRectInflate(AGlyphRect, 0, 0, AImageShadowSize, AImageShadowSize);
            OffsetRect(AGlyphRect, -AImageShadowSize div 2, -AImageShadowSize div 2);
          end;
        idmDisabled:
          begin
            if AIsAlphaUsed then
            begin
              AImageBitmap.TransformBitmap(btmDisable);
              AConstantAlpha := DisableMap.SrcConstantAlpha;
            end
            else
            begin
              AImageBitmap.TransformBitmap(btmDirty);
              AImageBitmap.Dr

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?