You've already forked lazarus-ccr
richmemo: gtk2 line spacing and image loading
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3766 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -26,16 +26,16 @@ interface
|
|||||||
uses
|
uses
|
||||||
// Bindings
|
// Bindings
|
||||||
gtk2, glib2, gdk2, pango,
|
gtk2, glib2, gdk2, pango,
|
||||||
// FCL
|
// RTL/FCL
|
||||||
Classes, SysUtils,
|
Types, Classes, SysUtils,
|
||||||
// LCL
|
// LCL
|
||||||
LCLType, Controls, Graphics,
|
LCLType, Controls, Graphics,
|
||||||
// Gtk2 widget
|
// Gtk2 widget
|
||||||
Gtk2Def,
|
Gtk2Def,
|
||||||
GTK2WinApiWindow, Gtk2Globals, Gtk2Proc, InterfaceBase,
|
GTK2WinApiWindow, Gtk2Globals, Gtk2Proc, InterfaceBase,
|
||||||
Gtk2WSControls,
|
Gtk2WSControls, gdk2pixbuf,
|
||||||
// RichMemo
|
// RichMemo
|
||||||
RichMemo, WSRichMemo;
|
RichMemo, WSRichMemo, RichMemoUtils;
|
||||||
|
|
||||||
{ TGtk2WSCustomRichMemo }
|
{ TGtk2WSCustomRichMemo }
|
||||||
type
|
type
|
||||||
@ -45,6 +45,7 @@ type
|
|||||||
class procedure GetWidgetBuffer(const AWinControl: TWinControl; var TextWidget: PGtkWidget; var Buffer: PGtkTextBuffer);
|
class procedure GetWidgetBuffer(const AWinControl: TWinControl; var TextWidget: PGtkWidget; var Buffer: PGtkTextBuffer);
|
||||||
class function GetAttrAtPos(const AWinControl: TWinControl; TextStart: Integer): PGtkTextAttributes;
|
class function GetAttrAtPos(const AWinControl: TWinControl; TextStart: Integer): PGtkTextAttributes;
|
||||||
class procedure ApplyTag(abuffer: PGtkTextBuffer; tag: PGtkTextTag; TextStart, TextLen: Integer; ToParagraphs: Boolean = False);
|
class procedure ApplyTag(abuffer: PGtkTextBuffer; tag: PGtkTextTag; TextStart, TextLen: Integer; ToParagraphs: Boolean = False);
|
||||||
|
|
||||||
published
|
published
|
||||||
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
||||||
|
|
||||||
@ -56,10 +57,17 @@ type
|
|||||||
class procedure SetParaAlignment(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
class procedure SetParaAlignment(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
const AAlign: TIntParaAlignment); override;
|
const AAlign: TIntParaAlignment); override;
|
||||||
|
|
||||||
|
class function GetParaMetric(const AWinControl: TWinControl; TextStart: Integer;
|
||||||
|
var AMetric: TIntParaMetric): Boolean; override;
|
||||||
class procedure SetParaMetric(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
class procedure SetParaMetric(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
const AMetric: TIntParaMetric); override;
|
const AMetric: TIntParaMetric); override;
|
||||||
|
|
||||||
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override;
|
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override;
|
||||||
|
|
||||||
|
class function ImageFromFile(const ARichMemo: TCustomRichMemo; APos: Integer;
|
||||||
|
const FileNameUTF8: string;
|
||||||
|
const AImgSize: TSize
|
||||||
|
): Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -305,6 +313,31 @@ begin
|
|||||||
ApplyTag(buffer, tag, TextStart, TextLen, true);
|
ApplyTag(buffer, tag, TextStart, TextLen, true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TGtk2WSCustomRichMemo.GetParaMetric(
|
||||||
|
const AWinControl: TWinControl; TextStart: Integer;
|
||||||
|
var AMetric: TIntParaMetric): Boolean;
|
||||||
|
var
|
||||||
|
attr : PGtkTextAttributes;
|
||||||
|
fp : TFontParams;
|
||||||
|
const
|
||||||
|
ScreenDPI = 96; // todo: might change, should be received dynamically
|
||||||
|
PageDPI = 72; // not expected to be changed
|
||||||
|
PixToPt = PageDPI / ScreenDPI;
|
||||||
|
begin
|
||||||
|
attr:=GetAttrAtPos(AWinControl, TextStart);
|
||||||
|
GtkTextAttrToFontParams(attr^, fp);
|
||||||
|
Result := Assigned(attr);
|
||||||
|
if Result then begin
|
||||||
|
AMetric.SpaceAfter:=attr^.pixels_above_lines*PixToPt;
|
||||||
|
AMetric.SpaceBefore:=attr^.pixels_below_lines*PixToPt;
|
||||||
|
AMetric.FirstLine:=attr^.indent*PixToPt;
|
||||||
|
AMetric.HeadIndent:=attr^.left_margin*PixToPt;
|
||||||
|
AMetric.TailIndent:=attr^.right_margin*PixToPt;
|
||||||
|
AMetric.LineSpacing:=(attr^.pixels_inside_wrap*PixToPt+fp.Size*1.2)/(fp.Size*1.2);
|
||||||
|
gtk_text_attributes_unref(attr);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
class procedure TGtk2WSCustomRichMemo.SetParaMetric(
|
class procedure TGtk2WSCustomRichMemo.SetParaMetric(
|
||||||
const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
||||||
const AMetric: TIntParaMetric);
|
const AMetric: TIntParaMetric);
|
||||||
@ -316,6 +349,8 @@ var
|
|||||||
fl : double;
|
fl : double;
|
||||||
t : double;
|
t : double;
|
||||||
v : Integer;
|
v : Integer;
|
||||||
|
attr : PGtkTextAttributes;
|
||||||
|
fp : TFontParams;
|
||||||
const
|
const
|
||||||
ScreenDPI = 96; // todo: might change, should be received dynamically
|
ScreenDPI = 96; // todo: might change, should be received dynamically
|
||||||
PageDPI = 72; // not expected to be changed
|
PageDPI = 72; // not expected to be changed
|
||||||
@ -333,6 +368,10 @@ begin
|
|||||||
end else
|
end else
|
||||||
fl:=fl-h;
|
fl:=fl-h;
|
||||||
|
|
||||||
|
attr:=GetAttrAtPos(AWinControl, TextStart);
|
||||||
|
GtkTextAttrToFontParams(attr^, fp);
|
||||||
|
gtk_text_attributes_unref(attr);
|
||||||
|
|
||||||
GetWidgetBuffer(AWinControl, w, buffer);
|
GetWidgetBuffer(AWinControl, w, buffer);
|
||||||
tag := gtk_text_buffer_create_tag (buffer, nil,
|
tag := gtk_text_buffer_create_tag (buffer, nil,
|
||||||
'pixels-above-lines', [ gint(round(AMetric.SpaceBefore*DPIFactor)),
|
'pixels-above-lines', [ gint(round(AMetric.SpaceBefore*DPIFactor)),
|
||||||
@ -345,9 +384,10 @@ begin
|
|||||||
'right-margin-set', gboolean(gTRUE),
|
'right-margin-set', gboolean(gTRUE),
|
||||||
'indent', gint(round(fl*DPIFactor)),
|
'indent', gint(round(fl*DPIFactor)),
|
||||||
'indent-set', gboolean(gTRUE),
|
'indent-set', gboolean(gTRUE),
|
||||||
|
'pixels-inside-wrap', gint(round(fp.Size*1.2*(AMetric.LineSpacing-1)*DPIFactor)),
|
||||||
|
'pixels-inside_wrap-set', gboolean(gTRUE),
|
||||||
nil]);
|
nil]);
|
||||||
ApplyTag(buffer, tag, TextStart, TextLen, true);
|
ApplyTag(buffer, tag, TextStart, TextLen, true);
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class procedure TGtk2WSCustomRichMemo.InDelText(const AWinControl: TWinControl;
|
class procedure TGtk2WSCustomRichMemo.InDelText(const AWinControl: TWinControl;
|
||||||
@ -367,6 +407,40 @@ begin
|
|||||||
gtk_text_buffer_insert(b, @istart, @textUTF8[1], length(TextUTF8));
|
gtk_text_buffer_insert(b, @istart, @textUTF8[1], length(TextUTF8));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class function TGtk2WSCustomRichMemo.ImageFromFile(
|
||||||
|
const ARichMemo: TCustomRichMemo; APos: Integer; const FileNameUTF8: string;
|
||||||
|
const AImgSize: TSize): Boolean;
|
||||||
|
var
|
||||||
|
t: PGtkWidget;
|
||||||
|
b: PGtkTextBuffer;
|
||||||
|
istart: TGtkTextIter;
|
||||||
|
pix: PGdkPixbuf;
|
||||||
|
err: PGError;
|
||||||
|
const
|
||||||
|
ScreenDPI = 96; // todo: might change, should be received dynamically
|
||||||
|
PageDPI = 72; // not expected to be changed
|
||||||
|
DPIFactor = ScreenDPI / PageDPI;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
GetWidgetBuffer(ARichMemo, t, b);
|
||||||
|
if not Assigned(b) then Exit;
|
||||||
|
|
||||||
|
err:=nil;
|
||||||
|
|
||||||
|
if (AImgSize.cx=0) and (AImgSize.cy=0) then
|
||||||
|
pix := gdk_pixbuf_new_from_file(PChar(FileNameUTF8), @err)
|
||||||
|
else
|
||||||
|
pix := gdk_pixbuf_new_from_file_at_size(PChar(FileNameUTF8),
|
||||||
|
round(AImgSize.cx * DPIFactor), round(AImgSize.cy * DPIFactor), @err);
|
||||||
|
|
||||||
|
Result:=Assigned(pix);
|
||||||
|
if Result then begin
|
||||||
|
gtk_text_buffer_get_iter_at_offset(b, @istart, APos);
|
||||||
|
gtk_text_buffer_insert_pixbuf(b, @istart, pix);
|
||||||
|
end else
|
||||||
|
writeln(err^.message);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
class function TGtk2WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl; TextStart: Integer; var Params: TIntFontParams): Boolean;
|
class function TGtk2WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl; TextStart: Integer; var Params: TIntFontParams): Boolean;
|
||||||
var
|
var
|
||||||
@ -380,5 +454,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function GtkInsertImageFromFile(const ARichMemo: TCustomRichMemo; APos: Integer;
|
||||||
|
const FileNameUTF8: string;
|
||||||
|
const AImgSize: TSize
|
||||||
|
): Boolean;
|
||||||
|
begin
|
||||||
|
Result:=TGtk2WSCustomRichMemo.ImageFromFile(ARichMemo, APos, FileNameUTF8, AImgSize);
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
InsertImageFromFile := @GtkInsertImageFromFile;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user