📄 dxgdiplusclasses.pas
字号:
end;
function TdxGPHatchBrush.GetHatchStyle: TdxGPHatchStyle;
begin
SetStatus(GdipGetHatchStyle(GpHatch(FNativeBrush), Result));
end;
{ TdxGPPen }
constructor TdxGPPen.Create(brush: TdxGPBrush; width: Single);
var
unit_: TdxGPUnit;
begin
unit_ := UnitWorld;
FNativePen := nil;
FLastResult := GdipCreatePen2(brush.FNativeBrush, width, unit_, FNativePen);
end;
constructor TdxGPPen.Create(color: DWORD; width: Single);
var
unit_: TdxGPUnit;
begin
unit_ := UnitWorld;
FNativePen := nil;
FLastResult := GdipCreatePen1(color, width, unit_, FNativePen);
end;
destructor TdxGPPen.Destroy;
begin
GdipDeletePen(FNativePen);
inherited;
end;
function TdxGPPen.GetAlignment: TdxGPPenAlignment;
begin
SetStatus(GdipGetPenMode(FNativePen, Result));
end;
function TdxGPPen.GetBrush: TdxGPBrush;
var
type_: TdxGPPenType;
ABrush: TdxGPBrush;
ANativeBrush: GpBrush;
begin
type_ := GetPenType;
ABrush := nil;
case type_ of
PenTypeSolidColor : ABrush := TdxGPSolidBrush.Create;
PenTypeHatchFill : ABrush := TdxGPHatchBrush.Create;
PenTypeTextureFill : ABrush := TdxGPTextureBrush.Create;
PenTypePathGradient : ABrush := TdxGPBrush.Create;
PenTypeLinearGradient : ABrush := TdxGPLinearGradientBrush.Create;
end;
if ABrush <> nil then
begin
SetStatus(GdipGetPenBrushFill(FNativePen, ANativeBrush));
brush.SetNativeBrush(ANativeBrush);
end;
Result := ABrush;
end;
function TdxGPPen.GetColor: DWORD;
var
type_: TdxGPPenType;
argb: DWORD;
begin
type_ := GetPenType;
Result := 0;
if (type_ = PenTypeSolidColor) then
begin
SetStatus(GdipGetPenColor(FNativePen, argb));
if FLastResult = Ok then Result := argb;
end;
end;
function TdxGPPen.GetLastStatus: TdxGPStatus;
begin
Result := FLastResult;
FLastResult := Ok;
end;
function TdxGPPen.GetPenType: TdxGPPenType;
begin
SetStatus(GdipGetPenFillType(FNativePen, Result));
end;
function TdxGPPen.GetWidth: Single;
begin
SetStatus(GdipGetPenWidth(FNativePen, Result));
end;
procedure TdxGPPen.SetAlignment(const Value: TdxGPPenAlignment);
begin
SetStatus(GdipSetPenMode(FNativePen, Value));
end;
procedure TdxGPPen.SetBrush(const Value: TdxGPBrush);
begin
SetStatus(GdipSetPenBrushFill(FNativePen, Value.FNativeBrush));
end;
procedure TdxGPPen.SetColor(const Value: DWORD);
begin
SetStatus(GdipSetPenColor(FNativePen, Value));
end;
procedure TdxGPPen.SetNativePen(ANativePen: GpPen);
begin
FNativePen := ANativePen;
end;
function TdxGPPen.SetStatus(status: TdxGPStatus): TdxGPStatus;
begin
if (status <> Ok) then FLastResult := status;
Result := status;
end;
procedure TdxGPPen.SetWidth(const Value: Single);
begin
SetStatus(GdipSetPenWidth(FNativePen, Value));
end;
{ TdxGPGraphics }
constructor TdxGPGraphics.Create(hdc: HDC);
var
AGraphics :GpGraphics;
begin
inherited Create;
AGraphics := nil;
FLastResult := GdipCreateFromHDC(hdc, AGraphics);
SetNativeGraphics(AGraphics);
end;
destructor TdxGPGraphics.Destroy;
begin
GdipDeleteGraphics(FNativeGraphics);
inherited;
end;
procedure TdxGPGraphics.FillRectangle(brush: TdxGPBrush; const rect: TdxGPRect);
begin
SetStatus(GdipFillRectangleI(FNativeGraphics, brush.FNativeBrush, rect.X, rect.Y, rect.Width, rect.Height));
end;
procedure TdxGPGraphics.SetNativeGraphics(AGraphics: GpGraphics);
begin
FNativeGraphics := AGraphics
end;
function TdxGPGraphics.Clear(color: TColor): TdxGPStatus;
begin
Result := SetStatus(GdipGraphicsClear(FNativeGraphics, color));
end;
function TdxGPGraphics.DrawArc(pen: TdxGPPen; const rect: TdxGPRect;
startAngle, sweepAngle: Single): TdxGPStatus;
begin
Result := SetStatus(GdipDrawArcI(FNativeGraphics, pen.FNativePen,
rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle));
end;
function TdxGPGraphics.DrawBezier(pen: TdxGPPen; const pt1, pt2, pt3,
pt4: TdxGPPoint): TdxGPStatus;
begin
Result := SetStatus(GdipDrawBezierI(FNativeGraphics, pen.FNativePen,
pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt1.Y));
end;
function TdxGPGraphics.DrawBezier(pen: TdxGPPen; x1, y1, x2, y2, x3, y3,
x4, y4: Integer): TdxGPStatus;
begin
Result := SetStatus(GdipDrawBezierI(FNativeGraphics, pen.FNativePen,
x1, y1, x2, y2, x3, y3, x4, y4));
end;
function TdxGPGraphics.DrawClosedCurve(pen: TdxGPPen; points: PdxGPPoint;
count: Integer; tension: Single): TdxGPStatus;
begin
Result := SetStatus(GdipDrawClosedCurve2I(FNativeGraphics, pen.FNativePen,
points, count, tension));
end;
function TdxGPGraphics.DrawCurve(pen: TdxGPPen; points: PdxGPPoint;
count: Integer; tension: Single): TdxGPStatus;
begin
Result := SetStatus(GdipDrawCurve2I(FNativeGraphics, pen.FNativePen,
points, count, tension));
end;
function TdxGPGraphics.DrawEllipse(pen: TdxGPPen;
const rect: TdxGPRect): TdxGPStatus;
begin
Result := SetStatus(GdipDrawEllipseI(FNativeGraphics, pen.FNativePen,
rect.X, rect.Y, rect.Width, rect.Height));
end;
function TdxGPGraphics.DrawLine(pen: TdxGPPen; x1, y1, x2, y2: Integer): TdxGPStatus;
begin
Result := SetStatus(GdipDrawLineI(FNativeGraphics, pen.FNativePen, x1, y1, x2, y2));
end;
function TdxGPGraphics.DrawLine(pen: TdxGPPen; const pt1, pt2: TdxGPPoint): TdxGPStatus;
begin
Result := SetStatus(GdipDrawLineI(FNativeGraphics, pen.FNativePen, pt1.X, pt1.Y, pt2.X, pt2.Y));
end;
function TdxGPGraphics.DrawPie(pen: TdxGPPen; const rect: TdxGPRect;
startAngle, sweepAngle: Single): TdxGPStatus;
begin
Result := SetStatus(GdipDrawPieI(FNativeGraphics, pen.FNativePen,
rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle));
end;
function TdxGPGraphics.DrawPolygon(pen: TdxGPPen; points: PdxGPPoint;
count: Integer): TdxGPStatus;
begin
Result := SetStatus(GdipDrawPolygonI(FNativeGraphics, pen.FNativePen, points, count));
end;
function TdxGPGraphics.DrawRectangle(pen: TdxGPPen;
const rect: TdxGPRect): TdxGPStatus;
begin
Result := SetStatus(GdipDrawRectangleI(FNativeGraphics, pen.FNativePen,
rect.X, rect.Y, rect.Width, rect.Height));
end;
function TdxGPGraphics.FillClosedCurve(brush: TdxGPBrush; points: PdxGPPoint;
count: Integer): TdxGPStatus;
begin
Result := SetStatus(GdipFillClosedCurveI(FNativeGraphics, brush.FNativeBrush,
points, count));
end;
function TdxGPGraphics.FillEllipse(brush: TdxGPBrush;
const rect: TdxGPRect): TdxGPStatus;
begin
Result := SetStatus(GdipFillEllipseI(FNativeGraphics, brush.FNativeBrush,
rect.X, rect.Y, rect.Width, rect.Height));
end;
function TdxGPGraphics.FillPie(brush: TdxGPBrush; const rect: TdxGPRect;
startAngle, sweepAngle: Single): TdxGPStatus;
begin
Result := SetStatus(GdipFillPieI(FNativeGraphics, brush.FNativeBrush,
rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle));
end;
function TdxGPGraphics.FillPolygon(brush: TdxGPBrush; points: PdxGPPoint;
count: Integer): TdxGPStatus;
begin
Result := SetStatus(GdipFillPolygonI(FNativeGraphics, brush.FNativeBrush,
points, count, FillModeAlternate));
end;
function TdxGPGraphics.GetHDC: HDC;
begin
SetStatus(GdipGetDC(FNativeGraphics, Result));
end;
function TdxGPGraphics.GetLastStatus: TdxGPStatus;
begin
Result := FLastResult;
FLastResult := Ok;
end;
function TdxGPGraphics.GetNativeGraphics: GpGraphics;
begin
Result := FNativeGraphics;
end;
function TdxGPGraphics.GetNativePen(pen: TdxGPPen): GpPen;
begin
Result := pen.FNativePen;
end;
procedure TdxGPGraphics.ReleaseHDC(hdc: HDC);
begin
SetStatus(GdipReleaseDC(FNativeGraphics, hdc));
end;
function TdxGPGraphics.SetStatus(status: TdxGPStatus): TdxGPStatus;
begin
if (status <> Ok) then FLastResult := status;
Result := status;
end;
{ TdxGPImage }
constructor TdxGPImage.CreateFromBitmap(ABitmap: TBitmap);
begin
CheckPngCodec;
CreateFromPattern(ABitmap.Width, ABitmap.Height,
GetBitmapBits(ABitmap), ABitmap.PixelFormat = pf32Bit);
end;
constructor TdxGPImage.CreateFromPattern(const AWidth, AHeight: Integer;
const ABits: TdxRGBColors; AHasAlphaChannel: Boolean);
var
I: Integer;
begin
FBits := ABits;
if not AHasAlphaChannel then
for I := 0 to Length(FBits) - 1 do
FBits[I].rgbReserved := 255;
GdipCheck(GdipCreateBitmapFromScan0(AWidth, AHeight,
AWidth * 4, PixelFormat32bppPARGB, @FBits[0], FHandle));
end;
constructor TdxGPImage.CreateFromStream(AStream: TStream);
var
Bitmap: TBitmap;
Header: TBitmapFileHeader;
begin
if not CheckGdiPlus or (AStream.Size < SizeOf(Header)) then Exit;
AStream.ReadBuffer(Header, SizeOf(Header));
AStream.Seek(-SizeOf(Header), soFromCurrent);
if Header.bfType = $4D42 then
begin
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromStream(AStream);
CreateFromBitmap(Bitmap);
finally
Bitmap.Free;
end;
end
else
LoadFromDataStream(AStream);
end;
destructor TdxGPImage.Destroy;
begin
if Handle <> nil then
GdipCheck(GdipDisposeImage(Handle));
FBits := nil;
inherited Destroy;
end;
function TdxGPImage.Clone: TdxGPImage;
var
W, H: Single;
begin
if Length(FBits) > 0 then
begin
GdipCheck(GdipGetImageDimension(Handle, W, H));
Result := dxGpImageClass.CreateFromPattern(Trunc(W), Trunc(H), FBits, True);
end
else
begin
Result := dxGpImageClass.Create;
GdipCheck(GdipCloneImage(Handle, Result.FHandle));
end;
end;
procedure TdxGPImage.SaveToStream(AStream: TStream);
begin
GdipCheck(GdipSaveImageToStream(Handle,
TStreamAdapter.Create(AStream, soReference), @PngCodec, nil));
end;
function TdxGPImage.MakeComposition(AOverlay: TdxGPImage; AAlpha: Byte): TdxGPImage;
var
A: Single;
ABits: TdxRGBColors;
ADest: TRGBQuad;
AImageHeight: Single;
AImageWidth: Single;
ASource: TRGBQuad;
I, ACount: Integer;
begin
Result := nil;
if Length(FBits) > 0 then
begin
GdipCheck(GdipGetImageDimension(Handle, AImageWidth, AImageHeight));
ACount := Trunc(AImageWidth) * Trunc(AImageHeight);
A := AAlpha / 255;
SetLength(ABits, ACount);
for I := 0 to ACount - 1 do
begin
ADest := FBits[I];
ASource := AOverlay.FBits[I];
ADest.rgbBlue := Round(ADest.rgbBlue * (1 - A) + ASource.rgbBlue * A);
ADest.rgbGreen := Round(ADest.rgbGreen * (1 - A) + ASource.rgbGreen * A);
ADest.rgbRed := Round(ADest.rgbRed * (1 - A) + ASource.rgbRed * A);
ADest.rgbReserved := Round(ADest.rgbReserved * (1 - A) + ASource.rgbReserved * A);
ABits[I] := ADest;
end;
Result := dxGpImageClass.CreateFromPattern(Trunc(AImageWidth),
Trunc(AImageHeight), ABits, True);
end;
end;
procedure TdxGPImage.Draw(DC: HDC; const R: TRect);
var
AGraphics: GpGraphics;
AImageWidth, AImageHeight: Single;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -