mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-30 15:31:09 +02:00
LCL-GTK3: Improve bitmap drawing etc. Issue #38567, patch from Anton Kavalenka.
git-svn-id: trunk@64802 -
This commit is contained in:
parent
2b0050a648
commit
1d097a9a7d
@ -180,6 +180,8 @@ begin
|
||||
Result:=inherited GetAcceleratorString(AVKey,AShiftState);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Function: RawImage_CreateBitmap
|
||||
Params: ARawImage:
|
||||
@ -196,6 +198,9 @@ var
|
||||
NewData: PByte;
|
||||
ImageFormat: cairo_format_t;
|
||||
ARowStride: PtrUInt;
|
||||
x,y:integer;
|
||||
src,dst,pdst,psrc,SrcRowPtr,DstRowPtr:pbyte;
|
||||
ridx,gidx,bidx,aidx:byte;
|
||||
begin
|
||||
Result := False;
|
||||
ABitmap := 0;
|
||||
@ -203,8 +208,57 @@ begin
|
||||
|
||||
if ARawImage.DataSize > 0 then
|
||||
begin
|
||||
NewData := GetMem(ARawImage.DataSize);
|
||||
Move(ARawImage.Data^, NewData^, ARawImage.DataSize);
|
||||
case Desc.LineEnd of
|
||||
rileQWordBoundary:
|
||||
begin
|
||||
ARowStride := Desc.Width;
|
||||
if Desc.Width and 1 <> 0 then Inc(ARowStride);
|
||||
ARowStride := ARowStride shl 2;
|
||||
end;
|
||||
rileDQWordBoundary:
|
||||
begin
|
||||
ARowStride := Desc.Width shr 1;
|
||||
if Desc.Width and 3 <> 0 then Inc(ARowStride);
|
||||
ARowStride := ARowStride shl 3;
|
||||
end;
|
||||
else
|
||||
ARowStride := Desc.Width shl 2;
|
||||
end;
|
||||
|
||||
// check if the pixels are in order, pixbuf expects them in R-G-B-A
|
||||
Desc.GetRGBIndices(Ridx, Gidx, Bidx, AIdx);
|
||||
|
||||
GetMem(NewData, ArawImage.DataSize);
|
||||
|
||||
//if (Ridx <> 0) or (Gidx <> 1) or (Bidx <> 2) or (AIdx <> 3) then
|
||||
begin
|
||||
// put components in right order
|
||||
|
||||
DstRowPtr := NewData;
|
||||
SrcRowPtr := ArawImage.Data;
|
||||
y := Desc.Height;
|
||||
while y > 0 do
|
||||
begin
|
||||
Src := SrcRowPtr;
|
||||
Dst := DstRowPtr;
|
||||
x := Desc.Width;
|
||||
while x > 0 do
|
||||
begin
|
||||
Dst[0] := Src[Ridx];
|
||||
Dst[1] := Src[Gidx];
|
||||
Dst[2] := Src[Bidx];
|
||||
Dst[3] := $ff;//Src[Aidx] ;
|
||||
|
||||
Inc(Src, 4);
|
||||
Inc(Dst, 4);
|
||||
Dec(x);
|
||||
end;
|
||||
Inc(SrcRowPtr, ARowstride);
|
||||
Inc(DstRowPtr, ARowstride);
|
||||
Dec(y);
|
||||
end;
|
||||
end;
|
||||
|
||||
end
|
||||
else
|
||||
NewData := nil;
|
||||
@ -218,21 +272,26 @@ begin
|
||||
end;
|
||||
ARowStride := GetBytesPerLine(Desc.Width, Desc.BitsPerPixel, rileDWordBoundary);
|
||||
ABitmap := HBitmap(TGtk3Image.Create(NewData, Desc.Width, Desc.Height, ARowStride, ImageFormat,
|
||||
not ASkipMask)); // Using ASkipMask for DataOwner param prevents a crash later.
|
||||
{not ASkipMask}true)); // Using ASkipMask for DataOwner param prevents a crash later.
|
||||
Result := ABitmap <> 0;
|
||||
|
||||
{ if ASkipMask then
|
||||
FreeMem(NewData); }
|
||||
|
||||
if ASkipMask then Exit;
|
||||
|
||||
if (ARawImage.Mask <> nil) and (ARawImage.MaskSize > 0) then
|
||||
begin
|
||||
NewData := GetMem(ARawImage.MaskSize);
|
||||
//FillChar(NewData^, ARawImage.MaskSize,$ff);
|
||||
Move(ARawImage.Mask^, NewData^, ARawImage.MaskSize);
|
||||
end
|
||||
else
|
||||
NewData := nil;
|
||||
|
||||
ARowStride := GetBytesPerLine(Desc.Width, Desc.BitsPerPixel, rileDWordBoundary);
|
||||
AMask := HBitmap(TGtk3Image.Create(NewData, Desc.Width, Desc.Height, ARowStride, CAIRO_FORMAT_A1, True));
|
||||
|
||||
ARowStride := GetBytesPerLine(Desc.Width, {Desc.BitsPerPixel}8, rileDWordBoundary);
|
||||
AMask := HBitmap(TGtk3Image.Create(NewData, Desc.Width, Desc.Height, ARowStride, CAIRO_FORMAT_A8, True));
|
||||
|
||||
end;
|
||||
|
||||
@ -747,7 +806,7 @@ begin
|
||||
if InvertPixels then
|
||||
WorkMask.invertPixels(QImageInvertRGB);
|
||||
*)
|
||||
if WorkMask.bits<>nil then
|
||||
if (WorkMask.bits<>nil) and (ARawImage.Mask<>nil) then
|
||||
Move(WorkMask.bits^, ARawImage.Mask^, ARawImage.MaskSize);
|
||||
// if InvertPixels then
|
||||
// WorkMask.invertPixels(QImageInvertRGB);
|
||||
|
@ -264,6 +264,7 @@ type
|
||||
procedure fillRect(x, y, w, h: Integer; ABrush: HBRUSH); overload;
|
||||
procedure fillRect(x, y, w, h: Integer); overload;
|
||||
function RoundRect(X1, Y1, X2, Y2: Integer; RX, RY: Integer): Boolean;
|
||||
function drawFrameControl(arect:TRect;uType,uState:cardinal):boolean;
|
||||
function drawFocusRect(const aRect: TRect): boolean;
|
||||
function getBpp: integer;
|
||||
function getDepth: integer;
|
||||
@ -714,11 +715,12 @@ begin
|
||||
sz:=fHandle^.get_size;
|
||||
if fHandle^.get_size_is_absolute then
|
||||
begin
|
||||
sz:=12;// sz div PANGO_SCALE;
|
||||
sz:= sz div PANGO_SCALE;
|
||||
end else
|
||||
begin
|
||||
{ in points }
|
||||
sz:=round(96*sz/PANGO_SCALE/72);//round(2.03*sz/PANGO_SCALE);
|
||||
//sz:=round(96*sz/PANGO_SCALE/72);//round(2.03*sz/PANGO_SCALE);
|
||||
sz := MulDiv(sz, 96{Screen.PixelsPerInch}, 72 * PANGO_SCALE)
|
||||
end;
|
||||
|
||||
fLogFont.lfHeight:=sz;//round(sz/PANGO_SCALE);
|
||||
@ -2103,6 +2105,79 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TGtk3DeviceContext.drawFrameControl(arect:TRect;uType,uState:cardinal):boolean;
|
||||
var
|
||||
Context: PGtkStyleContext;
|
||||
AValue: TGValue;
|
||||
pw:PGtkWidget;
|
||||
path:PGtkwIdgetPath;
|
||||
pc:pgchar;
|
||||
w:PgtkWidget;
|
||||
begin
|
||||
|
||||
Result:=false;
|
||||
|
||||
{ if Parent <> nil then
|
||||
Context := Parent^.get_style_context
|
||||
else
|
||||
begin
|
||||
Context:=TGtkStyleContext.new();
|
||||
Context^.add_class('button');
|
||||
end;
|
||||
if Context = nil then
|
||||
begin
|
||||
DebugLn('WARNING: TGtk3WidgetSet.DrawFrameControl on non widget context isn''t implemented.');
|
||||
exit;
|
||||
end; }
|
||||
|
||||
w:=nil;
|
||||
|
||||
if uType=DFC_BUTTON then
|
||||
begin
|
||||
w:=GetStyleWidget(lgsButton);
|
||||
end else
|
||||
if uType=DFC_MENU then
|
||||
begin
|
||||
w:=GetStyleWidget(lgsMenu);
|
||||
end;
|
||||
|
||||
if not Assigned(w) then exit;
|
||||
|
||||
Context:=w^.get_style_context;
|
||||
path:=w^.get_path;
|
||||
gtk_style_context_set_path (context, path);
|
||||
gtk_style_context_set_state (context,(* gtk_widget_path_iter_get_state (path, -1)*) -1);
|
||||
|
||||
{GTK_STATE_FLAG_NORMAL: TGtkStateFlags = 0;
|
||||
GTK_STATE_FLAG_ACTIVE: TGtkStateFlags = 1;
|
||||
GTK_STATE_FLAG_PRELIGHT: TGtkStateFlags = 2;
|
||||
GTK_STATE_FLAG_SELECTED: TGtkStateFlags = 4;
|
||||
GTK_STATE_FLAG_INSENSITIVE: TGtkStateFlags = 8;
|
||||
GTK_STATE_FLAG_INCONSISTENT: TGtkStateFlags = 16;
|
||||
GTK_STATE_FLAG_FOCUSED: TGtkStateFlags = 32;
|
||||
GTK_STATE_FLAG_BACKDROP: TGtkStateFlags = 64;
|
||||
GTK_STATE_FLAG_DIR_LTR: TGtkStateFlags = 128;
|
||||
GTK_STATE_FLAG_DIR_RTL: TGtkStateFlags = 256;
|
||||
}
|
||||
gtk_style_context_set_state (context, GTK_STATE_FLAG_FOCUSED or GTK_STATE_FLAG_PRELIGHT);
|
||||
|
||||
pw:=w;
|
||||
while Assigned(pw) do
|
||||
begin
|
||||
|
||||
Context:=pw^.get_style_context;
|
||||
path:=pw^.get_path;
|
||||
with aRect do
|
||||
begin
|
||||
gtk_render_background(Context,pcr, Left, Top, Right - Left, Bottom - Top);
|
||||
gtk_render_frame(Context,pcr, Left, Top, Right - Left, Bottom - Top);
|
||||
end;
|
||||
pw:=pw^.parent;
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TGtk3DeviceContext.drawFocusRect(const aRect: TRect): boolean;
|
||||
var
|
||||
Context: PGtkStyleContext;
|
||||
|
@ -2370,7 +2370,7 @@ begin
|
||||
*)
|
||||
end else
|
||||
begin
|
||||
ARgba := TColortoTGdkRGBA(AValue);
|
||||
ARgba := TColortoTGdkRGBA(ColorToRGB(AValue));
|
||||
{$info GTK3: set GdkRGBA.alpah to 1.0?}
|
||||
|
||||
{ColorToCairoRGB(ColorToRGB(AValue), R, G, B);
|
||||
@ -6734,10 +6734,15 @@ begin
|
||||
Result := PGtkWidget(check);
|
||||
check^.set_use_underline(True);
|
||||
{fWidgetRGBA[0].G:=0.8;
|
||||
fWidgetRGBA[0].Alpha:=0.7;
|
||||
check^.override_color(GTK_STATE_NORMAL,@Self.FWidgetRGBA[0]);}
|
||||
fWidgetRGBA[0].Alpha:=1;
|
||||
check^.override_color(GTK_STATE_FLAG_NORMAL,@Self.FWidgetRGBA[0]);}
|
||||
(*fWidgetRGBA[0].G:=0.8;
|
||||
fWidgetRGBA[0].B:=0.9;
|
||||
fWidgetRGBA[0].Alpha:=0.9;
|
||||
check^.override_color(GTK_STATE_FLAG_ACTIVE,@Self.FWidgetRGBA[0]); *)
|
||||
// nil resets color to gtk default
|
||||
FWidget^.override_background_color(GTK_STATE_FLAG_NORMAL, nil);
|
||||
{ FWidget^.override_color(GTK_STATE_FLAG_NORMAL, nil);
|
||||
FWidget^.override_background_color(GTK_STATE_FLAG_NORMAL, nil);}
|
||||
end;
|
||||
|
||||
{ TGtk3RadioButton }
|
||||
|
@ -600,11 +600,9 @@ end;
|
||||
function TGtk3WidgetSet.DrawFrameControl(DC: HDC; const aRect: TRect; uType,
|
||||
uState: Cardinal): Boolean;
|
||||
begin
|
||||
{$IFDEF GTK3DEBUGNOTIMPLEMENTED}
|
||||
DebugLn('WARNING: TGtk3WidgetSet.DrawFrameControl not implemented ...');
|
||||
{$ENDIF}
|
||||
Result := False;
|
||||
// inherited DrawFrameControl(DC, aRect, uType, uState);
|
||||
Result:=false;
|
||||
if IsValidDC(DC) then
|
||||
Result:=TGtk3DeviceContext(DC).drawFrameControl(aRect,uType,uState);
|
||||
end;
|
||||
|
||||
function TGtk3WidgetSet.DrawFocusRect(DC: HDC; const aRect: TRect): boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user