mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-03 00:00:39 +02:00
SynEdit: Prepare displaying ligatures (experimental, window only)
git-svn-id: trunk@39532 -
This commit is contained in:
parent
936fd56eea
commit
9e7bee0700
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2775,6 +2775,7 @@ components/synedit/synedittextbase.pas svneol=native#text/plain
|
||||
components/synedit/synedittextbidichars.pas svneol=native#text/pascal
|
||||
components/synedit/synedittextbuffer.pp svneol=native#text/pascal
|
||||
components/synedit/synedittextdoublewidthchars.pas svneol=native#text/plain
|
||||
components/synedit/synedittextsystemcharwidth.pas svneol=native#text/pascal
|
||||
components/synedit/synedittexttabexpander.pas svneol=native#text/plain
|
||||
components/synedit/synedittexttrimmer.pas svneol=native#text/plain
|
||||
components/synedit/synedittypes.pp svneol=native#text/pascal
|
||||
|
@ -25,7 +25,8 @@ uses
|
||||
SynHighlighterVB, SynHighlighterXML, SynMacroRecorder, SynMemo, SynPluginSyncroEdit,
|
||||
SynPluginSyncronizedEditBase, SynPluginTemplateEdit, LazSynEditText, LazSynTextArea,
|
||||
SynRegExpr, SynTextDrawer, SynEditMarkupGutterMark, SynHighlighterBat, SynHighlighterIni,
|
||||
SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars, LazarusPackageIntf;
|
||||
SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars, SynEditTextSystemCharWidth,
|
||||
LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -79,6 +79,9 @@ uses
|
||||
{$IFDEF USE_UTF8BIDI_LCL}
|
||||
FreeBIDI, utf8bidi,
|
||||
{$ENDIF}
|
||||
{$IFDEF WithSynExperimentalCharWidth}
|
||||
SynEditTextSystemCharWidth,
|
||||
{$ENDIF}
|
||||
Types, LCLIntf, LCLType, LMessages, LazUTF8, LCLProc, LazMethodList, LazLoggerBase,
|
||||
SysUtils, Classes, Messages, Controls, Graphics, Forms, StdCtrls, ExtCtrls, Menus,
|
||||
SynEditTypes, SynEditSearch, SynEditKeyCmds, SynEditMouseCmds, SynEditMiscProcs,
|
||||
@ -472,6 +475,9 @@ type
|
||||
FTrimmedLinesView: TSynEditStringTrimmingList;
|
||||
FDoubleWidthChrLinesView: SynEditStringDoubleWidthChars;
|
||||
FBidiChrLinesView: TSynEditStringBidiChars;
|
||||
{$IFDEF WithSynExperimentalCharWidth}
|
||||
FSysCharWidthLinesView: TSynEditStringSystemWidthChars;
|
||||
{$ENDIF}
|
||||
FTabbedLinesView: TSynEditStringTabExpander;
|
||||
FTheLinesView: TSynEditStrings;
|
||||
FLines: TSynEditStrings; // The real (un-mapped) line-buffer
|
||||
@ -1871,6 +1877,13 @@ begin
|
||||
FDoubleWidthChrLinesView := SynEditStringDoubleWidthChars.Create
|
||||
(FTrimmedLinesView);
|
||||
|
||||
{$IFDEF WithSynExperimentalCharWidth}
|
||||
FSysCharWidthLinesView := TSynEditStringSystemWidthChars.Create(FDoubleWidthChrLinesView, Self.Canvas);
|
||||
|
||||
FBidiChrLinesView := TSynEditStringBidiChars.Create(FSysCharWidthLinesView);
|
||||
FTabbedLinesView := TSynEditStringTabExpander.Create(FBidiChrLinesView);
|
||||
{$ELSE}
|
||||
|
||||
{$IFnDEF WithOutSynBiDi}
|
||||
FBidiChrLinesView := TSynEditStringBidiChars.Create(FDoubleWidthChrLinesView);
|
||||
{$ENDIF}
|
||||
@ -1882,6 +1895,8 @@ begin
|
||||
FTabbedLinesView := TSynEditStringTabExpander.Create(FDoubleWidthChrLinesView);
|
||||
{$ENDIF}
|
||||
|
||||
{$ENDIF} // WithSynExperimentalCharWidth
|
||||
|
||||
// Pointer to the First/Lowest View
|
||||
// TODO: this should be Folded...
|
||||
FTheLinesView := FTabbedLinesView;
|
||||
@ -2346,6 +2361,9 @@ begin
|
||||
{$IFnDEF WithOutSynBiDi}
|
||||
FreeAndNil(FBidiChrLinesView);
|
||||
{$ENDIF}
|
||||
{$IFDEF WithSynExperimentalCharWidth}
|
||||
FreeAndNil(FSysCharWidthLinesView);
|
||||
{$ENDIF}
|
||||
FreeAndNil(FDoubleWidthChrLinesView);
|
||||
TSynEditStringList(FLines).DetachSynEdit(Self);
|
||||
if TSynEditStringList(FLines).AttachedSynEditCount = 0 then
|
||||
|
126
components/synedit/synedittextsystemcharwidth.pas
Normal file
126
components/synedit/synedittextsystemcharwidth.pas
Normal file
@ -0,0 +1,126 @@
|
||||
unit SynEditTextSystemCharWidth;
|
||||
|
||||
(*
|
||||
WARNING:
|
||||
This unit is highly experimental
|
||||
*)
|
||||
|
||||
{-------------------------------------------------------------------------------
|
||||
The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing rights and limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of the
|
||||
GNU General Public License Version 2 or later (the "GPL"), in which case
|
||||
the provisions of the GPL are applicable instead of those above.
|
||||
If you wish to allow use of your version of this file only under the terms
|
||||
of the GPL and not to allow others to use your version of this file
|
||||
under the MPL, indicate your decision by deleting the provisions above and
|
||||
replace them with the notice and other provisions required by the GPL.
|
||||
If you do not delete the provisions above, a recipient may use your version
|
||||
of this file under either the MPL or the GPL.
|
||||
|
||||
-------------------------------------------------------------------------------}
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$IFDEF Windows} windows, {$endif}
|
||||
Classes, SysUtils, LazSynEditText, LazUTF8, Controls, Graphics, LazLoggerBase;
|
||||
|
||||
type
|
||||
|
||||
{ TSynEditStringBidiChars }
|
||||
|
||||
{ TSynEditStringSystemWidthChars }
|
||||
|
||||
TSynEditStringSystemWidthChars = class(TSynEditStringsLinked)
|
||||
private
|
||||
FHandleOwner: TCanvas;
|
||||
protected
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
|
||||
public
|
||||
constructor Create(ASynStringSource: TSynEditStrings; AHandleOwner: TCanvas);
|
||||
property HandleOwner: TCanvas read FHandleOwner;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TSynEditStringSystemWidthChars }
|
||||
|
||||
constructor TSynEditStringSystemWidthChars.Create(ASynStringSource: TSynEditStrings;
|
||||
AHandleOwner: TCanvas);
|
||||
begin
|
||||
inherited Create(ASynStringSource);
|
||||
FHandleOwner := AHandleOwner;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringSystemWidthChars.DoGetPhysicalCharWidths(Line: PChar; LineLen,
|
||||
Index: Integer; PWidths: PPhysicalCharWidth);
|
||||
var
|
||||
//s: UnicodeString;// wideString;
|
||||
{$IFDEF Windows}
|
||||
i: DWORD;
|
||||
cpRes: TGCPRESULTS;
|
||||
outs: array of widechar;
|
||||
order, dx, caret: array of integer;
|
||||
cclass, glyph: array of word;
|
||||
|
||||
s: WideString;
|
||||
j, k: Integer;
|
||||
l: SizeUInt;
|
||||
{$endif}
|
||||
begin
|
||||
inherited DoGetPhysicalCharWidths(Line, LineLen, Index, PWidths);
|
||||
if not IsUtf8 then
|
||||
exit;
|
||||
|
||||
{$IFDEF Windows}
|
||||
SetLength(s, LineLen+1); // wide chars of UTF-16 <= bytes of UTF-8 string
|
||||
if ConvertUTF8ToUTF16(PWideChar(S), LineLen+1, Line, LineLen, [toInvalidCharToSymbol], l) <> trNoError then
|
||||
exit;
|
||||
SetLength(s, l - 1);
|
||||
|
||||
cpRes.lStructSize := sizeof(cpRes);
|
||||
SetLength(outs, Length(s)+1); cpRes.lpOutString := @outs[0];
|
||||
SetLength(order, Length(s)+1); cpRes.lpOrder := @order[0];
|
||||
SetLength(dx, Length(s)+1); cpRes.lpDx := @dx[0];
|
||||
SetLength(caret, Length(s)+1); cpRes.lpCaretPos := @caret[0];
|
||||
SetLength(cclass, Length(s)+1); cpRes.lpClass := @cclass[0];
|
||||
SetLength(glyph, Length(s)+1); cpRes.lpGlyphs := @glyph[0];
|
||||
cpRes.nGlyphs := length(s);
|
||||
|
||||
i := GetCharacterPlacementW(FHandleOwner.Handle, pwidechar(s), length(s), 0,
|
||||
@cpRes, GCP_DIACRITIC + GCP_KASHIDA + GCP_LIGATE);
|
||||
if i = 0 then
|
||||
exit;
|
||||
|
||||
k := 0; // index for order
|
||||
|
||||
for j := 0 to LineLen-1 do begin
|
||||
if Line^ in [#$00..#$7F, #$C0..#$FF] then begin
|
||||
if PWidths^ <> 0 then begin
|
||||
if (k > 0) and (order[k] = order[k-1]) then begin
|
||||
debugln(['TSynEditStringSystemWidthChars for line ', Index, ' set char at ', j, '(', k, ') to be drawn with previous']);
|
||||
PWidths^ := 0;
|
||||
end;
|
||||
end;
|
||||
inc(k);
|
||||
end;
|
||||
|
||||
inc(PWidths);
|
||||
inc(Line);
|
||||
end;
|
||||
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user