mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-24 09:19:33 +02:00
249 lines
7.1 KiB
ObjectPascal
249 lines
7.1 KiB
ObjectPascal
{ $Id$ }
|
|
{
|
|
----------------------------------
|
|
gtkdebug.pp - graphic dump utils
|
|
----------------------------------
|
|
|
|
@created(Wed May 10th WET 2007)
|
|
@lastmod($Date$)
|
|
@author(Marc Weustink <marc@@lazarus.dommelstein.net>)
|
|
|
|
This unit contains utility functions to show the contents of graphics
|
|
|
|
*****************************************************************************
|
|
This file is part of the Lazarus Component Library (LCL)
|
|
|
|
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
|
for details about the license.
|
|
*****************************************************************************
|
|
}
|
|
|
|
unit GtkDebug;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF gtk2}
|
|
glib2, gdk2pixbuf, gdk2, gtk2,
|
|
{$ELSE}
|
|
glib, gdk, gtk, gdkpixbuf,
|
|
{$ENDIF}
|
|
sysutils;
|
|
|
|
procedure DbgDumpBitmap(ABitmap: PGdkBitmap; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
procedure DbgDumpPixmap(APixmap: PGdkPixmap; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
procedure DbgDumpPixbuf(APixbuf: PGdkPixbuf; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
{$ifndef gtk1}
|
|
// do not debug images on gtk1, we cannot ref, unref them and thus we cannot rely that they will not be destroyed
|
|
procedure DbgDumpImage(AImage: PGdkImage; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
{$endif}
|
|
|
|
implementation
|
|
|
|
type
|
|
TDbgDumpType = (ddtBitmap, ddtPixmap, ddtPixbuf, ddtImage);
|
|
|
|
PDbgDumpInfo = ^TDbgDumpInfo;
|
|
TDbgDumpInfo = record
|
|
Width, Height: Integer;
|
|
case DumpType: TDbgDumpType of
|
|
ddtBitmap: (Bitmap: PGdkBitmap);
|
|
ddtPixmap: (Pixmap: PGdkPixmap);
|
|
ddtPixbuf: (Pixbuf: PGdkPixbuf);
|
|
ddtImage: (Image: PGdkImage);
|
|
end;
|
|
|
|
procedure OnDbgWindowDestroy(widget: PGtkWidget; Data: Pointer); cdecl;
|
|
var
|
|
Info: PDbgDumpInfo absolute Data;
|
|
begin
|
|
case Info^.DumpType of
|
|
ddtBitmap: if Info^.Bitmap <> nil then gdk_pixmap_unref(Info^.Bitmap);
|
|
ddtPixmap: if Info^.Pixmap <> nil then gdk_pixmap_unref(Info^.Pixmap);
|
|
ddtPixbuf: if Info^.Pixbuf <> nil then gdk_pixbuf_unref(Info^.Pixbuf);
|
|
ddtImage: if Info^.Image <> nil then {$ifndef gtk1}gdk_image_unref(Info^.Image){$endif};
|
|
end;
|
|
Dispose(Info);
|
|
end;
|
|
|
|
procedure OnDbgDrawAreaExpose(widget: PGtkWidget; event: PGdkEventExpose; Data: Pointer); cdecl;
|
|
var
|
|
Info: PDbgDumpInfo absolute Data;
|
|
gc: Pointer;
|
|
color: TGdkColor;
|
|
begin
|
|
gc := gdk_gc_new(widget^.window);
|
|
|
|
case Info^.DumpType of
|
|
ddtBitmap: begin
|
|
if Info^.Bitmap = nil
|
|
then color.pixel := $808080
|
|
else color.pixel := 0;
|
|
gdk_gc_set_foreground(gc, @color);
|
|
gdk_draw_rectangle(widget^.window, gc, 1, 0, 0, Info^.Width, Info^.Height);
|
|
|
|
if Info^.Bitmap <> nil
|
|
then begin
|
|
gdk_gc_set_clip_mask(gc, Info^.Bitmap);
|
|
color.pixel := $FFFFFF;
|
|
gdk_gc_set_foreground(gc, @color);
|
|
gdk_draw_rectangle(widget^.window, gc, 1, 0, 0, Info^.Width, Info^.Height);
|
|
end;
|
|
end;
|
|
ddtPixmap: begin
|
|
if Info^.Pixmap <> nil
|
|
then gdk_draw_pixmap(widget^.window, gc, Info^.Pixmap, 0, 0, 0, 0, Info^.Width, Info^.Height);
|
|
end;
|
|
ddtPixbuf: begin
|
|
if Info^.Pixbuf <> nil
|
|
then gdk_pixbuf_render_to_drawable_alpha(Info^.Pixbuf, widget^.window, 0, 0, 0, 0, Info^.Width, Info^.Height, GDK_PIXBUF_ALPHA_BILEVEL, $80, GDK_RGB_DITHER_NORMAL, 0, 0);
|
|
end;
|
|
ddtImage: begin
|
|
if Info^.Image <> nil
|
|
then gdk_draw_image(widget^.window, gc, Info^.Image, 0, 0, 0, 0, Info^.Width, Info^.Height);
|
|
end;
|
|
end;
|
|
|
|
gdk_gc_destroy(gc);
|
|
end;
|
|
|
|
procedure DbgCreateWindow(AInfo: PDbgDumpInfo; const ATitle: String);
|
|
var
|
|
window, darea: Pointer;
|
|
begin
|
|
window := gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
gtk_window_set_title(window, PChar(ATitle));
|
|
gtk_window_set_default_size(window, AInfo^.Width, AInfo^.Height);
|
|
|
|
darea := gtk_drawing_area_new;
|
|
gtk_drawing_area_size (darea, AInfo^.Width, AInfo^.Height);
|
|
gtk_container_add(window, darea);
|
|
|
|
gtk_signal_connect(darea, 'expose-event', TGTKSignalFunc(@OnDbgDrawAreaExpose), AInfo);
|
|
gtk_signal_connect(window, 'destroy', TGTKSignalFunc(@OnDbgWindowDestroy), AInfo);
|
|
|
|
gtk_widget_show_all(window);
|
|
end;
|
|
|
|
procedure DbgDumpBitmap(ABitmap: PGdkBitmap; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
var
|
|
Info: PDbgDumpInfo;
|
|
h,w,d: Integer;
|
|
begin
|
|
New(Info);
|
|
if ABitmap = nil
|
|
then begin
|
|
w := 0; h:= 0; d := 0;
|
|
end
|
|
else
|
|
{$ifdef gtk1}
|
|
gdk_window_get_geometry(ABitmap, nil,nil,@w,@h,@d);
|
|
{$else}
|
|
gdk_drawable_get_size(ABitmap, @w, @h);
|
|
d := gdk_drawable_get_depth(ABitmap);
|
|
{$endif}
|
|
|
|
if AWidth = -1 then AWidth := W;
|
|
if AHeight = -1 then AHeight := H;
|
|
Info^.Width := AWidth;
|
|
Info^.Height := AHeight;
|
|
if d = 1
|
|
then begin
|
|
Info^.DumpType := ddtBitmap;
|
|
Info^.Bitmap := ABitmap;
|
|
end
|
|
else begin
|
|
// got a pixmap as bitmap
|
|
Info^.DumpType := ddtPixmap;
|
|
Info^.Pixmap := ABitmap;
|
|
end;
|
|
gdk_pixmap_ref(ABitmap);
|
|
|
|
ATitle := ATitle + Format(' (Bitmap:$%p W:%d H:%d D:%d)', [ABitmap, w, h, d]);
|
|
DbgCreateWindow(Info, ATitle);
|
|
end;
|
|
|
|
procedure DbgDumpPixmap(APixmap: PGdkPixmap; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
var
|
|
Info: PDbgDumpInfo;
|
|
h,w,d: Integer;
|
|
begin
|
|
New(Info);
|
|
if APixmap = nil
|
|
then begin
|
|
w := 0; h:= 0; d := 0;
|
|
end
|
|
else
|
|
{$ifdef gtk1}
|
|
gdk_window_get_geometry(APixmap, nil,nil,@w,@h,@d);
|
|
{$else}
|
|
gdk_drawable_get_size(APixmap, @w, @h);
|
|
d := gdk_drawable_get_depth(APixmap);
|
|
{$endif}
|
|
if AWidth = -1 then AWidth := W;
|
|
if AHeight = -1 then AHeight := H;
|
|
Info^.Width := AWidth;
|
|
Info^.Height := AHeight;
|
|
if d = 1
|
|
then begin
|
|
// got a bitmap as pixmap
|
|
Info^.DumpType := ddtBitmap;
|
|
Info^.Bitmap := APixmap;
|
|
end
|
|
else begin
|
|
Info^.DumpType := ddtPixmap;
|
|
Info^.Pixmap := APixmap;
|
|
end;
|
|
gdk_pixmap_ref(APixmap);
|
|
|
|
ATitle := ATitle + Format(' (Pixmap:$%p W:%d H:%d D:%d)', [APixmap, w, h, d]);
|
|
DbgCreateWindow(Info, ATitle);
|
|
end;
|
|
|
|
procedure DbgDumpPixbuf(APixbuf: PGdkPixbuf; ATitle: String = ''; AWidth: Integer = -1; AHeight: Integer = -1);
|
|
var
|
|
Info: PDbgDumpInfo;
|
|
h,w,c: Integer;
|
|
begin
|
|
New(Info);
|
|
c := gdk_pixbuf_get_n_channels(APixbuf);
|
|
w := gdk_pixbuf_get_width(APixbuf);
|
|
h := gdk_pixbuf_get_height(APixbuf);
|
|
|
|
if AWidth = -1 then AWidth := W;
|
|
if AHeight = -1 then AHeight := H;
|
|
Info^.Width := AWidth;
|
|
Info^.Height := AHeight;
|
|
Info^.DumpType := ddtPixbuf;
|
|
Info^.Pixbuf := APixbuf;
|
|
gdk_pixbuf_ref(APixbuf);
|
|
|
|
ATitle := ATitle + Format(' (Pixbuf:$%p W:%d H:%d C:%d)', [APixbuf, w, h, c]);
|
|
DbgCreateWindow(Info, ATitle);
|
|
end;
|
|
|
|
procedure DbgDumpImage(AImage: PGdkImage; ATitle: String; AWidth: Integer;
|
|
AHeight: Integer);
|
|
var
|
|
Info: PDbgDumpInfo;
|
|
begin
|
|
New(Info);
|
|
|
|
if AWidth = -1 then AWidth := AImage^.width;
|
|
if AHeight = -1 then AHeight := AImage^.height;
|
|
|
|
Info^.Width := AWidth;
|
|
Info^.Height := AHeight;
|
|
Info^.DumpType := ddtImage;
|
|
Info^.Image := AImage;
|
|
{$ifndef gtk1}
|
|
gdk_image_ref(AImage);
|
|
{$endif}
|
|
|
|
DbgCreateWindow(Info, ATitle);
|
|
end;
|
|
|
|
end.
|