diff --git a/components/richmemo/gtk2/gtk2richmemo.pas b/components/richmemo/gtk2/gtk2richmemo.pas index 32c21fda4..62153efce 100644 --- a/components/richmemo/gtk2/gtk2richmemo.pas +++ b/components/richmemo/gtk2/gtk2richmemo.pas @@ -39,6 +39,7 @@ uses const TagNameNumeric = 'numeric'; + TagNameSubOrSuper = 'suborsuper'; BulletChar = #$E2#$80#$A2; TabChar = #$09; @@ -48,15 +49,21 @@ type protected class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); class procedure GetWidgetBuffer(const AWinControl: TWinControl; var TextWidget: PGtkWidget; var Buffer: PGtkTextBuffer); + + class function GetAttrAtIter(view: PGtkTextView; const start: TGtkTextIter): PGtkTextAttributes; class function GetAttrAtPos(const AWinControl: TWinControl; TextStart: Integer; APara: Boolean = false): PGtkTextAttributes; + class procedure GetAttributesAt(const AWinControl: TWinControl; TextStart: Integer; APara: Boolean; + var attr: PGtkTextAttributes; var fp: TFontParams); + class procedure ApplyTag(abuffer: PGtkTextBuffer; tag: PGtkTextTag; TextStart, TextLen: Integer; ToParagraphs: Boolean = False); + class procedure FormatSubSuperScript(buffer: PGtkTextBuffer; vs: TVScriptPos; fontSizePts: Double; TextStart, TextLen: Integer); published class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override; class procedure DestroyHandle(const AWinControl: TWinControl); override; - class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override; - class function GetStrings(const ACustomMemo: TCustomMemo): TStrings; override; + class function GetSelLength(const ACustomEdit: TCustomEdit): integer; override; + class function GetStrings(const ACustomMemo: TCustomMemo): TStrings; override; class function GetStyleRange(const AWinControl: TWinControl; TextStart: Integer; var RangeStart, RangeLen: Integer): Boolean; override; @@ -140,8 +147,13 @@ type property Owner: TWinControl read FOwner; end; -implementation +const + SubSuperFontKoef = 0.583; // the koef for the font size of sub/super scripts matching Adover Illustrator and OpenOffice + SuperRiseKoef = 0.58; + SubRiseKoef = -0.08; + +implementation // todo: why "shr" on each of this flag test? function gtktextattr_underline(const a : TGtkTextAppearance) : Boolean; @@ -160,7 +172,7 @@ begin end; -function GtkTextAttrToFontParams(const textAttr: TGtkTextAttributes; var FontParams: TIntFontParams): Boolean; +function GtkTextAttrToFontParams(const textAttr: TGtkTextAttributes; var FontParams: TIntFontParams; const FontKoef : Double = 1.0): Boolean; var w : integer; st : TPangoStyle; @@ -182,7 +194,7 @@ begin sz:=FontParams.Size / PANGO_SCALE; if pango_font_description_get_size_is_absolute(pf) then sz:=sz/(ScreenDPI/PageDPI); - FontParams.Size:=round(sz); + FontParams.Size:=round(sz*FontKoef); w := pango_font_description_get_weight(pf); if w > PANGO_WEIGHT_NORMAL then Include(FontParams.Style, fsBold); @@ -339,7 +351,6 @@ function Gtk2_RichMemoKeyPress(view: PGtkTextView; Event: PGdkEventKey; var buf : PGtkTextBuffer; mark : PGtkTextMark; - iend : TGtkTextIter; istart : TGtkTextIter; tag : PGtkTextTag; begin @@ -565,24 +576,33 @@ begin buffer := gtk_text_view_get_buffer (PGtkTextView(TextWidget)); end; +class function TGtk2WSCustomRichMemo.GetAttrAtIter(view: PGtkTextView; const start: TGtkTextIter): PGtkTextAttributes; +var + attr : PGtkTextAttributes; +begin + Result:=nil; + attr := gtk_text_view_get_default_attributes(view); + if not Assigned(attr) then Exit; + + gtk_text_iter_get_attributes(@start, attr); + Result:=attr; +end; + class function TGtk2WSCustomRichMemo.GetAttrAtPos( const AWinControl: TWinControl; TextStart: Integer; APara: Boolean ): PGtkTextAttributes; var TextWidget : PGtkWidget; buffer : PGtkTextBuffer; iter : TGtkTextIter; - attr : PGtkTextAttributes; begin Result:=nil; GetWidgetBuffer(AWinControl, TextWidget, buffer); - - attr := gtk_text_view_get_default_attributes(PGtkTextView(TextWidget)); - if not Assigned(attr) then Exit; + if not Assigned(buffer) then Exit; gtk_text_buffer_get_iter_at_offset(buffer, @iter, TextStart); if APara then gtk_text_iter_set_line_offset(@iter, 0); - gtk_text_iter_get_attributes(@iter, attr); - Result:=attr; + + Result := GetAttrAtIter(PGtkTextView(TextWidget), iter); end; class procedure TGtk2WSCustomRichMemo.ApplyTag(abuffer: PGtkTextBuffer; @@ -651,6 +671,8 @@ begin 'editable-set', gboolean(gTRUE), nil]); + gtk_text_buffer_create_tag (buffer, TagNameSubOrSuper, nil); + Set_RC_Name(AWinControl, Widget); SetCallbacks(Widget, WidgetInfo); end; @@ -732,6 +754,84 @@ begin Result:=true; end; +class procedure TGtk2WSCustomRichMemo.FormatSubSuperScript(buffer: PGtkTextBuffer; vs: TVScriptPos; fontSizePts: Double; TextStart, TextLen: Integer); +var + sz : gint; + istart : TGtkTextIter; + iend : TGtkTextIter; + tag : PGtkTextTag; + scrtag : PGtkTextTag; + hasscript : Boolean; + k : Double; +begin + gtk_text_buffer_get_iter_at_offset (buffer, @istart, TextStart); + scrtag := gtk_text_tag_table_lookup( gtk_text_buffer_get_tag_table(buffer), TagNameSubOrSuper ); + hasscript := gtk_text_iter_has_tag( @istart, scrtag ); + + if not hasscript then begin + iend:=istart; + gtk_text_iter_forward_to_tag_toggle(@iend, scrtag); + hasscript:=gtk_text_iter_get_offset(@iend) 0 then fp.VScriptPos:=vpSuperScript; + end else + GtkTextAttrToFontParams(attr^, fp); + +end; + + class procedure TGtk2WSCustomRichMemo.SetTextAttributes(const AWinControl: TWinControl; TextStart, TextLen: Integer; const Params: TIntFontParams); var TextWidget: PGtkWidget; @@ -772,6 +872,7 @@ begin nil]); ApplyTag(buffer, tag, TextStart, TextLen); + FormatSubSuperScript(buffer, Params.VScriptPos, Params.Size, TextStart, TextLen); end; class function TGtk2WSCustomRichMemo.GetParaAlignment( @@ -830,8 +931,7 @@ const PageDPI = 72; // not expected to be changed PixToPt = PageDPI / ScreenDPI; begin - attr:=GetAttrAtPos(AWinControl, TextStart, true); - GtkTextAttrToFontParams(attr^, fp); + GetAttributesAt(AWinControl, TextStart, true, attr, fp); Result := Assigned(attr); if Result then begin if attr^.indent<0 then begin @@ -879,8 +979,7 @@ begin end else fl:=fl-h; - attr:=GetAttrAtPos(AWinControl, TextStart); - GtkTextAttrToFontParams(attr^, fp); + GetAttributesAt(AWinControl, TextStart, true, attr, fp); gtk_text_attributes_unref(attr); GetWidgetBuffer(AWinControl, w, buffer); @@ -1028,10 +1127,6 @@ const PageDPI = 72; // not expected to be changed PixToPt = PageDPI / ScreenDPI; var - w : PGtkWidget; - buffer : PGtkTextBuffer; - tag : PGtkTextTag; - parr : PPangoTabArray; i : Integer; attr : PGtkTextAttributes; loc : gint; @@ -1325,7 +1420,6 @@ var w : PGtkWidget; b : PGtkTextBuffer; istart : TGtkTextIter; - iend : TGtkTextIter; anch : PGtkTextChildAnchor; gi : TGtk2InlineObject; draw : PGtkWidget; @@ -1378,16 +1472,14 @@ begin 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 - attr : PGtkTextAttributes; + attr : PGtkTextAttributes; begin - attr:=GetAttrAtPos(AWinControl, TextStart); + GetAttributesAt(AWinControl, TextStart, false, attr, params); Result := Assigned(attr); - if Result then begin - GtkTextAttrToFontParams(attr^, Params); - gtk_text_attributes_unref(attr); - end; + if Result then gtk_text_attributes_unref(attr); end; function GtkInsertImageFromFile(const ARichMemo: TCustomRichMemo; APos: Integer;