📄 gr32.pas
字号:
{$IFDEF CLX}
FHDC := QPainter_create;
if FHDC = nil then
begin
QImage_destroy(FHandle);
FBits := nil;
raise Exception.Create('Can''t create compatible DC');
end;
FPixmap := QPixmap_create;
{$ELSE}
FHDC := CreateCompatibleDC(0);
if FHDC = 0 then
begin
DeleteObject(FHandle);
FHandle := 0;
FBits := nil;
raise Exception.Create('Can''t create compatible DC');
end;
if SelectObject(FHDC, FHandle) = 0 then
begin
DeleteDC(FHDC);
DeleteObject(FHandle);
FHDC := 0;
FHandle := 0;
FBits := nil;
raise Exception.Create('Can''t select an object into DC');
end;
{$ENDIF}
end;
Width := NewWidth;
Height := NewHeight;
ResetClipRect;
finally
HandleChanged;
end;
end;
function TBitmap32.Empty: Boolean;
begin
{$IFDEF CLX}
Result := not(Assigned(FHandle) or Assigned(FPixmap)) or inherited Empty;
{$ELSE}
Result := (FHandle = 0) or inherited Empty;
{$ENDIF}
end;
procedure TBitmap32.Clear;
begin
Clear(clBlack32);
end;
procedure TBitmap32.Clear(FillColor: TColor32);
begin
if Empty then Exit;
if not MeasuringMode then
if Clipping then
FillRect(FClipRect.Left, FClipRect.Top, FClipRect.Right, FClipRect.Bottom, FillColor)
else
FillLongword(Bits[0], Width * Height, FillColor);
Changed;
end;
procedure TBitmap32.Delete;
begin
SetSize(0, 0);
end;
procedure TBitmap32.Assign(Source: TPersistent);
var
Canvas: TCanvas;
Picture: TPicture;
TempBitmap: TBitmap32;
I: integer;
DstP, SrcP: PColor32;
DstColor: TColor32;
procedure AssignFromBitmap(SrcBmp: TBitmap);
var
TransparentColor: TColor32;
I: integer;
begin
SetSize(SrcBmp.Width, SrcBmp.Height);
if Empty then Exit;
{$IFDEF CLX}
if not QPainter_isActive(Handle) then
if not QPainter_begin(Handle, Pixmap) then
raise EInvalidGraphicOperation.CreateRes(@SInvalidCanvasState);
QPainter_drawPixmap(Handle, 0, 0, SrcBmp.Handle, 0, 0, Width, Height);
QPainter_end(Handle);
PixmapChanged := True;
{$ELSE}
SrcBmp.Canvas.Lock; // lock to avoid GDI memory leaks, eg. when calling from threads
try
BitBlt(Handle, 0, 0, Width, Height, SrcBmp.Canvas.Handle, 0, 0, SRCCOPY);
finally
SrcBmp.Canvas.UnLock;
end;
{$ENDIF}
if SrcBmp.PixelFormat <> pf32bit then ResetAlpha;
if SrcBmp.Transparent then
begin
TransparentColor := Color32(SrcBmp.TransparentColor) and $00FFFFFF;
DstP := @Bits[0];
for I := 0 to Width * Height - 1 do
begin
DstColor := DstP^ and $00FFFFFF;
if DstColor = TransparentColor then
DstP^ := DstColor;
inc(DstP);
end;
end;
Font.Assign(SrcBmp.Canvas.Font);
end;
begin
BeginUpdate;
try
if Source = nil then
begin
SetSize(0, 0);
Exit;
end
else if Source is TBitmap32 then
with Source as TBitmap32 do
begin
CopyMapTo(Self);
CopyPropertiesTo(Self);
Exit;
end
else if Source is TBitmap then
begin
AssignFromBitmap(TBitmap(Source));
Exit;
end
else if Source is TGraphic then
begin
SetSize(TGraphic(Source).Width, TGraphic(Source).Height);
if Empty then Exit;
Canvas := TCanvas.Create;
try
Canvas.Handle := Self.Handle;
TGraphicAccess(Source).Draw(Canvas, MakeRect(0, 0, Width, Height));
ResetAlpha;
finally
Canvas.Free;
end;
end
else if Source is TPicture then
begin
with TPicture(Source) do
begin
if TPicture(Source).Graphic is TBitmap then
AssignFromBitmap(TBitmap(TPicture(Source).Graphic))
else if (TPicture(Source).Graphic is TIcon) {$IFNDEF CLX}or
(TPicture(Source).Graphic is TMetaFile) {$ENDIF} then
begin
// icons, metafiles etc...
SetSize(TPicture(Source).Graphic.Width, TPicture(Source).Graphic.Height);
if Empty then Exit;
TempBitmap := TBitmap32.Create;
Canvas := TCanvas.Create;
try
Self.Clear(clWhite32); // mask on white;
Canvas.Handle := Self.Handle;
TGraphicAccess(Graphic).Draw(Canvas, MakeRect(0, 0, Width, Height));
TempBitmap.SetSize(TPicture(Source).Graphic.Width, TPicture(Source).Graphic.Height);
TempBitmap.Clear(clRed32); // mask on red;
Canvas.Handle := TempBitmap.Handle;
TGraphicAccess(Graphic).Draw(Canvas, MakeRect(0, 0, Width, Height));
DstP := @Bits[0];
SrcP := @TempBitmap.Bits[0];
for I := 0 to Width * Height - 1 do
begin
DstColor := DstP^ and $00FFFFFF;
// this checks for transparency by comparing the pixel-color of the
// temporary bitmap (red masked) with the pixel of our
// bitmap (white masked). If they match, make that pixel opaque
if DstColor = (SrcP^ and $00FFFFFF) then
DstP^ := DstColor or $FF000000
else
// if the colors don't match (that is the case if there is a
// match "is clRed32 = clBlue32 ?"), just make that pixel
// transparent:
DstP^ := DstColor;
inc(SrcP); inc(DstP);
end;
finally
TempBitmap.Free;
Canvas.Free;
end;
end
else
begin
// anything else...
SetSize(TPicture(Source).Graphic.Width, TPicture(Source).Graphic.Height);
if Empty then Exit;
Canvas := TCanvas.Create;
try
Canvas.Handle := Self.Handle;
TGraphicAccess(Graphic).Draw(Canvas, MakeRect(0, 0, Width, Height));
ResetAlpha;
finally
Canvas.Free;
end;
end;
end;
Exit;
end
else if Source is TClipboard then
begin
Picture := TPicture.Create;
try
Picture.Assign(TClipboard(Source));
SetSize(Picture.Width, Picture.Height);
if Empty then Exit;
Canvas := TCanvas.Create;
try
Canvas.Handle := Self.Handle;
TGraphicAccess(Picture.Graphic).Draw(Canvas, MakeRect(0, 0, Width, Height));
ResetAlpha;
finally
Canvas.Free;
end;
finally
Picture.Free;
end;
Exit;
end
else
inherited; // default handler
finally;
EndUpdate;
Changed;
end;
end;
procedure TBitmap32.CopyMapTo(Dst: TBitmap32);
begin
Dst.SetSize(Width, Height);
if not Empty then
MoveLongword(Bits[0], Dst.Bits[0], Width * Height);
end;
procedure TBitmap32.CopyPropertiesTo(Dst: TBitmap32);
begin
with Dst do
begin
DrawMode := Self.DrawMode;
CombineMode := Self.CombineMode;
WrapMode := Self.WrapMode;
MasterAlpha := Self.MasterAlpha;
OuterColor := Self.OuterColor;
{$IFDEF DEPRECATEDMODE}
StretchFilter := Self.StretchFilter;
{$ENDIF}
ResamplerClassName := Self.ResamplerClassName;
if Assigned(Resampler) and Assigned(Self.Resampler) then
Resampler.Assign(Self.Resampler);
Font.Assign(Self.Font);
end;
end;
procedure TBitmap32.AssignTo(Dst: TPersistent);
var
Bmp: TBitmap;
procedure CopyToBitmap(Bmp: TBitmap);
begin
{$IFNDEF CLX}
Bmp.HandleType := bmDIB;
{$ENDIF}
Bmp.PixelFormat := pf32Bit;
Bmp.Canvas.Font.Assign(Font);
Bmp.Width := Width;
Bmp.Height := Height;
DrawTo(Bmp.Canvas.Handle, 0, 0);
end;
begin
if Dst is TPicture then CopyToBitmap(TPicture(Dst).Bitmap)
else if Dst is TBitmap then CopyToBitmap(TBitmap(Dst))
else if Dst is TClipboard then
begin
Bmp := TBitmap.Create;
try
CopyToBitmap(Bmp);
TClipboard(Dst).Assign(Bmp);
finally
Bmp.Free;
end;
end
else inherited;
end;
function TBitmap32.GetCanvas: TCanvas;
begin
if FCanvas = nil then
begin
{$IFDEF CLX}
FCanvas := TBitmap32Canvas.Create(Self);
{$ELSE}
FCanvas := TCanvas.Create;
{$ENDIF}
FCanvas.Handle := Handle;
FCanvas.OnChange := CanvasChanged;
end;
Result := FCanvas;
end;
procedure TBitmap32.CanvasChanged(Sender: TObject);
begin
Changed;
end;
function TBitmap32.CanvasAllocated: Boolean;
begin
Result := FCanvas <> nil;
end;
procedure TBitmap32.DeleteCanvas;
begin
if FCanvas <> nil then
begin
{$IFDEF CLX}
FCanvas.Handle := nil;
{$ELSE}
FCanvas.Handle := 0;
{$ENDIF}
FCanvas.Free;
FCanvas := nil;
end;
end;
procedure TBitmap32.SetPixel(X, Y: Integer; Value: TColor32);
begin
Bits[X + Y * Width] := Value;
end;
procedure TBitmap32.SetPixelS(X, Y: Integer; Value: TColor32);
begin
if {$IFDEF CHANGED_IN_PIXELS}not FMeasuringMode and{$ENDIF}
(X >= FClipRect.Left) and (X < FClipRect.Right) and
(Y >= FClipRect.Top) and (Y < FClipRect.Bottom) then
Bits[X + Y * Width] := Value;
{$IFDEF CHANGED_IN_PIXELS}
Changed(MakeRect(X, Y, X + 1, Y + 1));
{$ENDIF}
end;
function TBitmap32.GetScanLine(Y: Integer): PColor32Array;
begin
Result := @Bits[Y * FWidth];
end;
function TBitmap32.GetPixel(X, Y: Integer): TColor32;
begin
Result := Bits[X + Y * Width];
end;
function TBitmap32.GetPixelS(X, Y: Integer): TColor32;
begin
if (X >= FClipRect.Left) and (X < FClipRect.Right) and
(Y >= FClipRect.Top) and (Y < FClipRect.Bottom) then
Result := Bits[X + Y * Width]
else
Result := OuterColor;
end;
function TBitmap32.GetPixelPtr(X, Y: Integer): PColor32;
begin
Result := @Bits[X + Y * Width];
end;
procedure TBitmap32.Draw(DstX, DstY: Integer; Src: TBitmap32);
begin
if Assigned(Src) then Src.DrawTo(Self, DstX, DstY);
end;
procedure TBitmap32.Draw(DstX, DstY: Integer; const SrcRect: TRect; Src: TBitmap32);
begin
if Assigned(Src) then Src.DrawTo(Self, DstX, DstY, SrcRect);
end;
procedure TBitmap32.Draw(const DstRect, SrcRect: TRect; Src: TBitmap32);
begin
if Assigned(Src) then Src.DrawTo(Self, DstRect, SrcRect);
end;
{$IFDEF CLX}
procedure TBitmap32.Draw(const DstRect, SrcRect: TRect; SrcPixmap: QPixmapH);
var
NewMatrix: QWMatrixH;
SrcHeight, SrcWidth: Integer;
begin
if Empty then Exit;
if not FMeasuringMode then
begin
StartPainter;
QPainter_saveWorldMatrix(Handle);
try
SrcWidth := SrcRect.Right - SrcRect.Left;
SrcHeight := SrcRect.Bottom - SrcRect.Top;
// use world transformation to translate and scale.
NewMatrix:= QWMatrix_create((DstRect.Right - DstRect.Left) / SrcWidth ,
0, 0, (DstRect.Bottom - DstRect.Top) / SrcHeight, DstRect.Left, DstRect.Top);
try
QPainter_setWorldMatrix(Handle, NewMatrix, True);
QPainter_drawPixmap(Handle, 0, 0, SrcPixmap,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -