1{-------------------------------------------------------------------------------
2The contents of this file are subject to the Mozilla Public License
3Version 1.1 (the "License"); you may not use this file except in compliance
4with the License. You may obtain a copy of the License at
5http://www.mozilla.org/MPL/
6Software distributed under the License is distributed on an "AS IS" basis,
7WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
8the specific language governing rights and limitations under the License.
9
10The Original Code is: SynEditHighlighter.pas, released 2000-04-07.
11
12The Original Code is based on mwHighlighter.pas by Martin Waldenburg, part of
13the mwEdit component suite.
14Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg.
15All Rights Reserved.
16
17Contributors to the SynEdit and mwEdit projects are listed in the
18Contributors.txt file.
19
20$Id$
21
22You may retrieve the latest version of this file at the SynEdit home page,
23located at http://SynEdit.SourceForge.net
24
25Known Issues:
26-------------------------------------------------------------------------------}
27
28unit SynEditHighlighter;
29
30{$I synedit.inc}
31
32interface
33
34uses
35  SysUtils, Classes, Registry, IniFiles,
36  // LCL
37  LCLProc, LCLIntf, LCLType, Graphics,
38  // LazUtils
39  LazUTF8, LazMethodList,
40  // SynEdit
41  SynEditTypes, SynEditTextBase;
42
43type
44  { TSynHighlighterRangeList }
45
46  TSynHighlighterRangeList = class(TSynManagedStorageMem)
47  private
48    FRefCount: Integer;
49    FNeedsReScanStartIndex: Integer;
50    FNeedsReScanEndIndex: Integer;
51    FNeedsReScanRealStartIndex: Integer;
52    function GetNeedsReScanRealStartIndex: Integer;
53    function GetRange(Index: Integer): Pointer;
54    procedure SetRange(Index: Integer; const AValue: Pointer);
55  protected
56    procedure LineTextChanged(AIndex: Integer; ACount: Integer = 1); override;
57    procedure InsertedLines(AIndex, ACount: Integer); override;
58    procedure DeletedLines(AIndex, ACount: Integer); override;
59  public
60    constructor Create;
61    procedure ClearReScanNeeded;
62    procedure AdjustReScanStart(ANewStart: Integer);
63    procedure InvalidateAll;
64    procedure IncRefCount;
65    procedure DecRefCount;
66    property Range[Index: Integer]: Pointer read GetRange write SetRange; default;
67    property RefCount: Integer read FRefCount;
68    property NeedsReScanStartIndex: Integer read FNeedsReScanStartIndex;
69    property NeedsReScanEndIndex: Integer read FNeedsReScanEndIndex;
70    property NeedsReScanRealStartIndex: Integer read GetNeedsReScanRealStartIndex;
71  end;
72
73  { TLazSynCustomTextAttributes }
74
75  TLazSynCustomTextAttributes = class(TPersistent)
76  {strict} private
77    FUpdateCount: Integer;
78    FWasChanged: Boolean;
79
80    FBackground: TColor;
81    FForeground: TColor;
82    FFrameColor: TColor;
83    FFrameEdges: TSynFrameEdges;
84    FFrameStyle: TSynLineStyle;
85    fStyle: TFontStyles;
86    fStyleMask: TFontStyles;
87
88    FBackPriority: integer;
89    FForePriority: integer;
90    FFramePriority: integer;
91    FStylePriority: Array [TFontStyle] of integer;
92
93    function GetStylePriority(AIndex: TFontStyle): integer;
94    procedure SetBackground(AValue: TColor);
95    procedure SetBackPriority(AValue: integer);
96    procedure SetForeground(AValue: TColor);
97    procedure SetForePriority(AValue: integer);
98    procedure SetFrameColor(AValue: TColor);
99    procedure SetFrameEdges(AValue: TSynFrameEdges);
100    procedure SetFramePriority(AValue: integer);
101    procedure SetFrameStyle(AValue: TSynLineStyle);
102    procedure SetStyle(AValue: TFontStyles);
103    procedure SetStyleMask(AValue: TFontStyles);
104    procedure SetStylePriority(AIndex: TFontStyle; AValue: integer);
105  protected
106    procedure AssignFrom(Src: TLazSynCustomTextAttributes); virtual;
107    procedure DoClear; virtual;
108    procedure Changed;
109    procedure DoChange; virtual;
110    procedure Init; virtual;
111  public
112    constructor Create;
113    procedure Clear;
114    procedure Assign(aSource: TPersistent); override;
115    procedure SetAllPriorities(APriority: integer);
116    procedure BeginUpdate;
117    procedure EndUpdate;
118  public
119    property Background: TColor read FBackground write SetBackground;
120    property Foreground: TColor read FForeground write SetForeground;
121    property FrameColor: TColor read FFrameColor write SetFrameColor;
122    property FrameStyle: TSynLineStyle  read FFrameStyle write SetFrameStyle;
123    property FrameEdges: TSynFrameEdges read FFrameEdges write SetFrameEdges;
124    property Style: TFontStyles     read fStyle write SetStyle;
125    property StyleMask: TFontStyles read fStyleMask write SetStyleMask;
126
127    property StylePriority[Index: TFontStyle]: integer read GetStylePriority write SetStylePriority;
128
129    property BackPriority: integer read FBackPriority write SetBackPriority;
130    property ForePriority: integer read FForePriority write SetForePriority;
131    property FramePriority: integer read FFramePriority write SetFramePriority;
132    property BoldPriority: integer index fsBold read GetStylePriority write SetStylePriority;
133    property ItalicPriority: integer index fsItalic read GetStylePriority write SetStylePriority;
134    property UnderlinePriority: integer index fsUnderline read GetStylePriority write SetStylePriority;
135    property StrikeOutPriority: integer index fsStrikeOut read GetStylePriority write SetStylePriority;
136  end;
137
138  { TSynHighlighterAttributes }
139
140  TSynHighlighterAttributes = class(TLazSynCustomTextAttributes)
141  private
142    FBackgroundDefault: TColor;
143    FForegroundDefault: TColor;
144    FFrameColorDefault: TColor;
145    FFrameEdgesDefault: TSynFrameEdges;
146    FFrameStyleDefault: TSynLineStyle;
147    FStyleDefault: TFontStyles;
148    FStyleMaskDefault: TFontStyles;
149    FStoredName: string;
150    FConstName: string;
151    FCaption: PString;
152    FOnChange: TNotifyEvent;
153    function GetBackgroundColorStored: boolean;
154    function GetFontStyleMaskStored : boolean;
155    function GetForegroundColorStored: boolean;
156    function GetFrameColorStored: boolean;
157    function GetFrameEdgesStored: boolean;
158    function GetFrameStyleStored: boolean;
159    function GetStyleFromInt: integer;
160    procedure SetStyleFromInt(const Value: integer);
161    function GetFontStyleStored: boolean;
162    function GetStyleMaskFromInt : integer;
163    procedure SetStyleMaskFromInt(const Value : integer);
164  protected
165    function GetBackPriorityStored: Boolean; virtual;
166    function GetForePriorityStored: Boolean; virtual;
167    function GetFramePriorityStored: Boolean; virtual;
168    function GetStylePriorityStored(AIndex: TFontStyle): Boolean; virtual;
169
170    procedure AssignFrom(Src: TLazSynCustomTextAttributes); override;
171    procedure DoChange; override;
172  public
173    constructor Create;
174    constructor Create(aCaption: string; aStoredName: String = '');
175    constructor Create(aCaption: PString; aStoredName: String = '');
176    function  IsEnabled: boolean; virtual;
177    procedure InternalSaveDefaultValues; virtual;
178    function  LoadFromBorlandRegistry(rootKey: HKEY; attrKey, attrName: string;
179                                      oldStyle: boolean): boolean; virtual;
180    function  LoadFromRegistry(Reg: TRegistry): boolean;
181    function  SaveToRegistry(Reg: TRegistry): boolean;
182    function  LoadFromFile(Ini : TIniFile): boolean;
183    function  SaveToFile(Ini : TIniFile): boolean;
184  public
185    property IntegerStyle: integer read GetStyleFromInt write SetStyleFromInt;
186    property IntegerStyleMask: integer read GetStyleMaskFromInt write SetStyleMaskFromInt;
187    property Name: string read FConstName; // value of Caption at creation, use Caption instead, kept for compatibility
188    property Caption: PString read FCaption; // is never nil
189    property StoredName: string read FStoredName write FStoredName; // the identifier
190    property OnChange: TNotifyEvent read fOnChange write fOnChange;
191  published
192    property Background stored GetBackgroundColorStored;
193    property Foreground stored GetForegroundColorStored;
194    property FrameColor stored GetFrameColorStored;
195    property FrameStyle stored GetFrameStyleStored;
196    property FrameEdges stored GetFrameEdgesStored;
197    property Style stored GetFontStyleStored;
198    // TODO: StyleMask move to TSynHighlighterAttributesModifier
199    property StyleMask stored GetFontStyleMaskStored;
200    // FStyle = [],       FStyleMask = []        ==> no modification
201    // FStyle = [fsBold], FStyleMask = []        ==> invert fsBold
202    // FStyle = [],       FStyleMask = [fsBold]  ==> clear  fsBold
203    // FStyle = [fsBold], FStyleMask = [fsBold]  ==> set    fsBold
204
205    property BackPriority stored GetBackPriorityStored;
206    property ForePriority stored GetForePriorityStored;
207    property FramePriority stored GetFramePriorityStored;
208    property BoldPriority stored GetStylePriorityStored;
209    property ItalicPriority stored GetStylePriorityStored;
210    property UnderlinePriority stored GetStylePriorityStored;
211    property StrikeOutPriority stored GetStylePriorityStored;
212  end;
213
214  { TSynHighlighterAttributesModifier }
215
216  TSynHighlighterAttributesModifier = class(TSynHighlighterAttributes)
217  private
218    FBackAlpha: byte;
219    FForeAlpha: byte;
220    FFrameAlpha: byte;
221
222    FBackAlphaDefault: byte;
223    FForeAlphaDefault: byte;
224    FFrameAlphaDefault: byte;
225    FBackPriorityDefault: integer;
226    FForePriorityDefault: integer;
227    FFramePriorityDefault: integer;
228    FStylePriorityDefault: Array [TFontStyle] of integer;
229
230    function GetBackAlphaStored: Boolean;
231    function GetForeAlphaStored: Boolean;
232    function GetFrameAlphaStored: Boolean;
233
234    procedure SetBackAlpha(AValue: byte);
235    procedure SetForeAlpha(AValue: byte);
236    procedure SetFrameAlpha(AValue: byte);
237  protected
238    function GetBackPriorityStored: Boolean; override;
239    function GetForePriorityStored: Boolean; override;
240    function GetFramePriorityStored: Boolean; override;
241    function GetStylePriorityStored(Index: TFontStyle): Boolean; override;
242
243    procedure AssignFrom(Src: TLazSynCustomTextAttributes); override;
244    procedure DoClear; override;
245  public
246    procedure InternalSaveDefaultValues; override;
247  published
248    // Alpha = 0 means solid // 1..255 means n of 256
249    property BackAlpha: byte read FBackAlpha write SetBackAlpha stored GetBackAlphaStored;
250    property ForeAlpha: byte read FForeAlpha write SetForeAlpha stored GetForeAlphaStored;
251    property FrameAlpha: byte read FFrameAlpha write SetFrameAlpha stored GetFrameAlphaStored;
252  end;
253
254  TSynHighlighterCapability = (
255    hcUserSettings, // supports Enum/UseUserSettings
256    hcRegistry,     // supports LoadFrom/SaveToRegistry
257    hcCodeFolding
258  );
259
260  TSynHighlighterCapabilities = set of TSynHighlighterCapability;
261
262const
263  { EXPERIMENTAL: A list of some typical attributes.
264    This may be returned by a Highlighter via GetDefaultAttribute. Implementation
265    is optional for each HL. So a HL may return nil even if it has an attribute
266    of the requested type.
267    This list does *not* aim to be complete. It may be replaced in future.
268  }
269  SYN_ATTR_COMMENT           =   0;
270  SYN_ATTR_IDENTIFIER        =   1;
271  SYN_ATTR_KEYWORD           =   2;
272  SYN_ATTR_STRING            =   3;
273  SYN_ATTR_WHITESPACE        =   4;
274  SYN_ATTR_SYMBOL            =   5;
275  SYN_ATTR_NUMBER            =   6;
276  SYN_ATTR_DIRECTIVE         =   7;
277  SYN_ATTR_ASM               =   8;
278  SYN_ATTR_VARIABLE          =   9;
279
280type
281
282  TSynDividerDrawConfigSetting = Record
283    Color: TColor;
284  end;
285
286const
287  SynEmptyDividerDrawConfigSetting: TSynDividerDrawConfigSetting =
288    ( Color: clNone );
289
290type
291  { TSynDividerDrawConfig }
292
293  TSynDividerDrawConfig = class
294  private
295    FDepth: Integer;
296    FTopSetting, FNestSetting: TSynDividerDrawConfigSetting;
297    fOnChange: TNotifyEvent;
298    function GetNestColor: TColor; virtual;
299    function GetTopColor: TColor; virtual;
300    procedure SetNestColor(const AValue: TColor); virtual;
301    procedure SetTopColor(const AValue: TColor); virtual;
302  protected
303    function GetMaxDrawDepth: Integer; virtual;
304    procedure SetMaxDrawDepth(AValue: Integer); virtual;
305    procedure Changed;
306  public
307    // Do not use to set values, or you skip the change notification
308    property TopSetting: TSynDividerDrawConfigSetting read FTopSetting;
309    property NestSetting: TSynDividerDrawConfigSetting read FNestSetting;
310  public
311    constructor Create;
312    procedure Assign(Src: TSynDividerDrawConfig); virtual;
313    property MaxDrawDepth: Integer read GetMaxDrawDepth write SetMaxDrawDepth;
314    property TopColor: TColor read GetTopColor write SetTopColor;
315    property NestColor: TColor read GetNestColor write SetNestColor;
316    property OnChange: TNotifyEvent read fOnChange write fOnChange;
317  end;
318
319  { TSynEditLinesList }
320
321  TSynEditLinesList=class(TFPList)
322  private
323    function GetSynString(Index: Integer): TSynEditStringsBase;
324    procedure PutSynStrings(Index: Integer; const AValue: TSynEditStringsBase);
325  public
326    property Items[Index: Integer]: TSynEditStringsBase
327             read GetSynString write PutSynStrings; default;
328  end;
329
330  { TSynCustomHighlighter }
331
332  TSynCustomHighlighter = class(TComponent)
333  private
334    fAttributes: TStringListUTF8Fast;
335    fAttrChangeHooks: TMethodList;
336    FCapabilities: TSynHighlighterCapabilities;
337    FKnownLines: TSynEditLinesList;
338    FCurrentLines: TSynEditStringsBase;
339    FCurrentRanges: TSynHighlighterRangeList;
340    FDrawDividerLevel: Integer;
341    FLineIndex: Integer;
342    FLineText: String;
343    fUpdateCount: integer;                                                      //mh 2001-09-13
344    fEnabled: Boolean;
345    fWordBreakChars: TSynIdentChars;
346    FIsScanning: Boolean;
347    function GetKnownRanges(Index: Integer): TSynHighlighterRangeList;
348    procedure SetDrawDividerLevel(const AValue: Integer); deprecated;
349    procedure SetEnabled(const Value: boolean);                                 //DDH 2001-10-23
350  protected
351    FAttributeChangeNeedScan: Boolean;
352    fDefaultFilter: string;
353    fUpdateChange: boolean;                                                     //mh 2001-09-13
354    FIsInNextToEOL: Boolean;
355    procedure AddAttribute(AAttrib: TSynHighlighterAttributes);
356    procedure FreeHighlighterAttributes;                                        //mh 2001-09-13
357    function GetAttribCount: integer; virtual;
358    function GetAttribute(idx: integer): TSynHighlighterAttributes; virtual;
359    function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
360      virtual; abstract;
361    function GetDefaultFilter: string; virtual;
362    function GetIdentChars: TSynIdentChars; virtual;
363    procedure SetWordBreakChars(AChars: TSynIdentChars); virtual;
364    function GetSampleSource: string; virtual;
365    function IsFilterStored: boolean; virtual;
366    procedure SetAttributesOnChange(AEvent: TNotifyEvent);
367    procedure SetDefaultFilter(Value: string); virtual;
368    procedure SetSampleSource(Value: string); virtual;
369    function GetRangeIdentifier: Pointer; virtual;
370    function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; virtual;
371    procedure AfterAttachedToRangeList(ARangeList: TSynHighlighterRangeList); virtual;
372    procedure BeforeDetachedFromRangeList(ARangeList: TSynHighlighterRangeList); virtual;
373    function UpdateRangeInfoAtLine(Index: Integer): Boolean; virtual; // Returns true if range changed
374    // code fold - only valid if hcCodeFolding in Capabilities
375    procedure SetCurrentLines(const AValue: TSynEditStringsBase); virtual; // todo remove virtual
376    procedure DoCurrentLinesChanged; virtual;
377    property  LineIndex: Integer read FLineIndex;
378    property CurrentRanges: TSynHighlighterRangeList read FCurrentRanges;
379    function GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting; virtual;
380    function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; virtual;
381    function GetDividerDrawConfigCount: Integer; virtual;
382    function PerformScan(StartIndex, EndIndex: Integer; ForceEndIndex: Boolean = False): Integer; virtual;
383    property IsScanning: Boolean read FIsScanning;
384    property KnownRanges[Index: Integer]: TSynHighlighterRangeList read GetKnownRanges;
385    property KnownLines: TSynEditLinesList read FKnownLines;
386  public
387    procedure DefHighlightChange(Sender: TObject);
388    property  AttributeChangeNeedScan: Boolean read FAttributeChangeNeedScan;
389    class function GetCapabilities: TSynHighlighterCapabilities; virtual;
390    class function GetLanguageName: string; virtual;
391  public
392    constructor Create(AOwner: TComponent); override;
393    destructor Destroy; override;
394    function AddSpecialAttribute(const aCaption: string;
395                     const aStoredName: String = ''): TSynHighlighterAttributes;
396    function AddSpecialAttribute(const aCaption: PString;
397                     const aStoredName: String = ''): TSynHighlighterAttributes;
398    procedure Assign(Source: TPersistent); override;
399    procedure BeginUpdate;
400    procedure EndUpdate;
401    procedure AttachToLines(Lines: TSynEditStringsBase);
402    procedure DetachFromLines(Lines: TSynEditStringsBase);
403  public
404    function GetEol: Boolean; virtual; abstract;
405    function GetRange: Pointer; virtual;
406    function GetToken: String; virtual; abstract;
407    procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); virtual; abstract;
408    function GetEndOfLineAttribute: TSynHighlighterAttributes; virtual; // valid after line was scanned to EOL
409    function GetTokenAttribute: TSynHighlighterAttributes; virtual; abstract;
410    function GetTokenKind: integer; virtual; abstract;
411    function GetTokenPos: Integer; virtual; abstract; // 0-based
412    function IsKeyword(const AKeyword: string): boolean; virtual;               // DJLP 2000-08-09
413    procedure Next; virtual; abstract;
414    procedure NextToEol;
415
416    property DrawDivider[Index: integer]: TSynDividerDrawConfigSetting
417      read GetDrawDivider;
418    property DrawDividerLevel: Integer read FDrawDividerLevel write SetDrawDividerLevel; deprecated;
419  public
420    property CurrentLines: TSynEditStringsBase read FCurrentLines write SetCurrentLines;
421
422    procedure StartAtLineIndex(LineNumber:Integer); virtual; // 0 based
423    procedure ContinueNextLine; // To be called at EOL; does not read the range
424
425    procedure ScanRanges;
426    (* IdleScanRanges
427       Scan in small chunks during OnIdle; Return True, if more work avail
428       This method is still under development. It may be changed, removed, un-virtualized, or anything.
429       In future SynEdit & HL may have other IDLE tasks, and if and when that happens, there will be new ways to control this
430    *)
431    function  IdleScanRanges: Boolean; virtual; experimental;
432    function NeedScan: Boolean;
433    procedure ScanAllRanges;
434    procedure SetRange(Value: Pointer); virtual;
435    procedure ResetRange; virtual;
436    procedure SetLine(const NewValue: String;
437                      LineNumber:Integer // 0 based
438                      ); virtual;
439  public
440    function UseUserSettings(settingIndex: integer): boolean; virtual;
441    procedure EnumUserSettings(Settings: TStrings); virtual;
442    function LoadFromRegistry(RootKey: HKEY; Key: string): boolean; virtual;
443    function SaveToRegistry(RootKey: HKEY; Key: string): boolean; virtual;
444    function LoadFromFile(AFileName: String): boolean;                          //DDH 10/16/01
445    function SaveToFile(AFileName: String): boolean;                            //DDH 10/16/01
446    procedure HookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
447    procedure UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
448    property IdentChars: TSynIdentChars read GetIdentChars;
449    property WordBreakChars: TSynIdentChars read fWordBreakChars write SetWordBreakChars;
450    property LanguageName: string read GetLanguageName;
451  public
452    property AttrCount: integer read GetAttribCount;
453    property Attribute[idx: integer]: TSynHighlighterAttributes read GetAttribute;
454    property Capabilities: TSynHighlighterCapabilities read FCapabilities;
455    property SampleSource: string read GetSampleSource write SetSampleSource;
456    // The below should be depricated and moved to those HL that actually implement them.
457    property CommentAttribute: TSynHighlighterAttributes
458      index SYN_ATTR_COMMENT read GetDefaultAttribute;
459    property IdentifierAttribute: TSynHighlighterAttributes
460      index SYN_ATTR_IDENTIFIER read GetDefaultAttribute;
461    property KeywordAttribute: TSynHighlighterAttributes
462      index SYN_ATTR_KEYWORD read GetDefaultAttribute;
463    property StringAttribute: TSynHighlighterAttributes
464      index SYN_ATTR_STRING read GetDefaultAttribute;
465    property SymbolAttribute: TSynHighlighterAttributes                         //mh 2001-09-13
466      index SYN_ATTR_SYMBOL read GetDefaultAttribute;
467    property WhitespaceAttribute: TSynHighlighterAttributes
468      index SYN_ATTR_WHITESPACE read GetDefaultAttribute;
469
470    property DividerDrawConfig[Index: Integer]: TSynDividerDrawConfig
471      read GetDividerDrawConfig;
472    property DividerDrawConfigCount: Integer read GetDividerDrawConfigCount;
473  published
474    property DefaultFilter: string read GetDefaultFilter write SetDefaultFilter
475      stored IsFilterStored;
476    property Enabled: boolean read fEnabled write SetEnabled default TRUE;      //DDH 2001-10-23
477  end;
478
479  TSynCustomHighlighterClass = class of TSynCustomHighlighter;
480
481  TSynHighlighterList = class(TList)
482  private
483    hlList: TList;
484    function GetItem(idx: integer): TSynCustomHighlighterClass;
485  public
486    constructor Create;
487    destructor Destroy; override;
488    function Count: integer;
489    function FindByName(name: string): integer;
490    function FindByClass(comp: TComponent): integer;
491    property Items[idx: integer]: TSynCustomHighlighterClass
492      read GetItem; default;
493  end;
494
495  procedure RegisterPlaceableHighlighter(highlighter: TSynCustomHighlighterClass);
496  function GetPlaceableHighlighters: TSynHighlighterList;
497
498implementation
499
500const
501  IDLE_SCAN_CHUNK_SIZE = 2500;
502
503{ TSynHighlighterAttributesModifier }
504
505procedure TSynHighlighterAttributesModifier.SetBackAlpha(AValue: byte);
506begin
507  if FBackAlpha = AValue then Exit;
508  FBackAlpha := AValue;
509  Changed;
510end;
511
512function TSynHighlighterAttributesModifier.GetBackPriorityStored: Boolean;
513begin
514  Result := FBackPriority <> FBackPriorityDefault;
515end;
516
517function TSynHighlighterAttributesModifier.GetBackAlphaStored: Boolean;
518begin
519  Result := FBackAlpha <> FBackAlphaDefault;
520end;
521
522function TSynHighlighterAttributesModifier.GetForeAlphaStored: Boolean;
523begin
524  Result := FForeAlpha <> FForeAlphaDefault;
525end;
526
527function TSynHighlighterAttributesModifier.GetForePriorityStored: Boolean;
528begin
529  Result := FForePriority <> FForePriorityDefault;
530end;
531
532function TSynHighlighterAttributesModifier.GetFrameAlphaStored: Boolean;
533begin
534  Result := FFrameAlpha <> FForeAlphaDefault;
535end;
536
537function TSynHighlighterAttributesModifier.GetFramePriorityStored: Boolean;
538begin
539  Result := FFramePriority <> FFramePriorityDefault;
540end;
541
542function TSynHighlighterAttributesModifier.GetStylePriorityStored(Index: TFontStyle): Boolean;
543begin
544  Result := FStylePriority[Index] <> FStylePriorityDefault[Index];
545end;
546
547procedure TSynHighlighterAttributesModifier.SetForeAlpha(AValue: byte);
548begin
549  if FForeAlpha = AValue then Exit;
550  FForeAlpha := AValue;
551  Changed;
552end;
553
554procedure TSynHighlighterAttributesModifier.SetFrameAlpha(AValue: byte);
555begin
556  if FFrameAlpha = AValue then Exit;
557  FFrameAlpha := AValue;
558  Changed;
559end;
560
561procedure TSynHighlighterAttributesModifier.AssignFrom(Src: TLazSynCustomTextAttributes);
562var
563  Source: TSynHighlighterAttributesModifier;
564begin
565  inherited AssignFrom(Src);
566  if Src is TSynHighlighterAttributesModifier then begin
567    Source := TSynHighlighterAttributesModifier(Src);
568    FBackAlpha  := Source.BackAlpha;
569    FForeAlpha  := Source.ForeAlpha;
570    FFrameAlpha := Source.FrameAlpha;
571  end
572  else begin
573    FBackAlpha  := 0;
574    FForeAlpha  := 0;
575    FFrameAlpha := 0;
576  end;
577end;
578
579procedure TSynHighlighterAttributesModifier.DoClear;
580begin
581  inherited DoClear;
582  FBackAlpha  := 0;
583  FForeAlpha  := 0;
584  FFrameAlpha := 0;
585end;
586
587procedure TSynHighlighterAttributesModifier.InternalSaveDefaultValues;
588begin
589  inherited InternalSaveDefaultValues;
590  FBackPriorityDefault  := FBackPriority;
591  FForePriorityDefault  := FForePriority;
592  FFramePriorityDefault := FFramePriority;
593  FForeAlphaDefault     := FForeAlpha;
594  FBackAlphaDefault     := FBackAlpha;
595  FFrameAlphaDefault    := FFrameAlpha;
596  FStylePriorityDefault := FStylePriority;
597end;
598
599{$IFDEF _Gp_MustEnhanceRegistry}
600  function IsRelative(const Value: string): Boolean;
601  begin
602    Result := not ((Value <> '') and (Value[1] = '\'));
603  end;
604
605  function TBetterRegistry.OpenKeyReadOnly(const Key: string): Boolean;
606  var
607    TempKey: HKey;
608    S: string;
609    Relative: Boolean;
610  begin
611    S := Key;
612    Relative := IsRelative(S);
613
614    if not Relative then Delete(S, 1, 1);
615    TempKey := 0;
616    Result := RegOpenKeyEx(GetBaseKey(Relative), PChar(S), 0,
617        KEY_READ, TempKey) = ERROR_SUCCESS;
618    if Result then
619    begin
620      if (CurrentKey <> 0) and Relative then S := CurrentPath + '\' + S;
621      ChangeKey(TempKey, S);
622    end;
623  end; { TBetterRegistry.OpenKeyReadOnly }
624{$ENDIF _Gp_MustEnhanceRegistry}
625
626{ THighlighterList }
627
628function TSynHighlighterList.Count: integer;
629begin
630  Result := hlList.Count;
631end;
632
633constructor TSynHighlighterList.Create;
634begin
635  inherited Create;
636  hlList := TList.Create;
637end;
638
639destructor TSynHighlighterList.Destroy;
640begin
641  hlList.Free;
642  inherited;
643end;
644
645function TSynHighlighterList.FindByClass(comp: TComponent): integer;
646var
647  i: integer;
648begin
649  Result := -1;
650  for i := 0 to Count-1 do begin
651    if comp is Items[i] then begin
652      Result := i;
653      Exit;
654    end;
655  end; //for
656end;
657
658function TSynHighlighterList.FindByName(name: string): integer;
659var
660  i: integer;
661begin
662  Result := -1;
663  for i := 0 to Count-1 do begin
664    if Items[i].GetLanguageName = name then begin
665      Result := i;
666      Exit;
667    end;
668  end; //for
669end;
670
671function TSynHighlighterList.GetItem(idx: integer): TSynCustomHighlighterClass;
672begin
673  Result := TSynCustomHighlighterClass(hlList[idx]);
674end;
675
676var
677  G_PlaceableHighlighters: TSynHighlighterList;
678
679function GetPlaceableHighlighters: TSynHighlighterList;
680begin
681  Result := G_PlaceableHighlighters;
682end;
683
684procedure RegisterPlaceableHighlighter(highlighter: TSynCustomHighlighterClass);
685begin
686  if G_PlaceableHighlighters.hlList.IndexOf(highlighter) < 0 then
687    G_PlaceableHighlighters.hlList.Add(highlighter);
688end;
689
690{ TLazSynCustomTextAttributes }
691
692procedure TLazSynCustomTextAttributes.SetBackground(AValue: TColor);
693begin
694  if FBackground = AValue then Exit;
695  FBackground := AValue;
696  Changed;
697end;
698
699function TLazSynCustomTextAttributes.GetStylePriority(AIndex: TFontStyle
700  ): integer;
701begin
702  Result := FStylePriority[AIndex];
703end;
704
705procedure TLazSynCustomTextAttributes.SetBackPriority(AValue: integer);
706begin
707  if FBackPriority = AValue then Exit;
708  FBackPriority := AValue;
709  Changed;
710end;
711
712procedure TLazSynCustomTextAttributes.SetForeground(AValue: TColor);
713begin
714  if FForeground = AValue then Exit;
715  FForeground := AValue;
716  Changed;
717end;
718
719procedure TLazSynCustomTextAttributes.SetForePriority(AValue: integer);
720begin
721  if FForePriority = AValue then Exit;
722  FForePriority := AValue;
723  Changed;
724end;
725
726procedure TLazSynCustomTextAttributes.SetFrameColor(AValue: TColor);
727begin
728  if FFrameColor = AValue then Exit;
729  FFrameColor := AValue;
730  Changed;
731end;
732
733procedure TLazSynCustomTextAttributes.SetFrameEdges(AValue: TSynFrameEdges);
734begin
735  if FFrameEdges = AValue then Exit;
736  FFrameEdges := AValue;
737  Changed;
738end;
739
740procedure TLazSynCustomTextAttributes.SetFramePriority(AValue: integer);
741begin
742  if FFramePriority = AValue then Exit;
743  FFramePriority := AValue;
744  Changed;
745end;
746
747procedure TLazSynCustomTextAttributes.SetFrameStyle(AValue: TSynLineStyle);
748begin
749  if FFrameStyle = AValue then Exit;
750  FFrameStyle := AValue;
751  Changed;
752end;
753
754procedure TLazSynCustomTextAttributes.SetStyle(AValue: TFontStyles);
755begin
756  if fStyle = AValue then Exit;
757  fStyle := AValue;
758  Changed;
759end;
760
761procedure TLazSynCustomTextAttributes.SetStyleMask(AValue: TFontStyles);
762begin
763  if fStyleMask = AValue then Exit;
764  fStyleMask := AValue;
765  Changed;
766end;
767
768procedure TLazSynCustomTextAttributes.SetStylePriority(AIndex: TFontStyle;
769  AValue: integer);
770begin
771  if FStylePriority[AIndex] = AValue then Exit;
772  FStylePriority[AIndex] := AValue;
773  Changed;
774end;
775
776procedure TLazSynCustomTextAttributes.Changed;
777begin
778  FWasChanged := True;
779  if FUpdateCount > 0 then
780    exit;
781  FWasChanged := False;
782  DoChange;
783end;
784
785procedure TLazSynCustomTextAttributes.AssignFrom(Src: TLazSynCustomTextAttributes);
786begin
787  //
788end;
789
790procedure TLazSynCustomTextAttributes.DoClear;
791var
792  i: TFontStyle;
793begin
794  Background := clNone;
795  Foreground := clNone;
796  FrameColor := clNone;
797  FrameStyle := slsSolid;
798  FrameEdges := sfeAround;
799  Style := [];
800  StyleMask := [];
801  FForePriority := 0;
802  FBackPriority := 0;
803  FFramePriority := 0;
804  for i := Low(TFontStyle) to High(TFontStyle) do
805    FStylePriority[i] := 0;
806end;
807
808procedure TLazSynCustomTextAttributes.DoChange;
809begin
810  //
811end;
812
813procedure TLazSynCustomTextAttributes.Init;
814begin
815  // called by create
816  Clear;
817end;
818
819constructor TLazSynCustomTextAttributes.Create;
820begin
821  inherited;
822  FUpdateCount := 0;
823  FWasChanged := False;
824  Init;
825end;
826
827procedure TLazSynCustomTextAttributes.Clear;
828begin
829  BeginUpdate;
830  DoClear;
831  EndUpdate;
832end;
833
834procedure TLazSynCustomTextAttributes.Assign(aSource: TPersistent);
835var
836  Source : TLazSynCustomTextAttributes;
837begin
838  if aSource is TLazSynCustomTextAttributes then
839  begin
840    BeginUpdate;
841    Source := TLazSynCustomTextAttributes(aSource);
842    Foreground := Source.Foreground;
843    Background := Source.Background;
844    FrameColor := Source.FrameColor;
845    FrameStyle := Source.FrameStyle;
846    FrameEdges := Source.FrameEdges;
847    Style      := Source.FStyle;
848    StyleMask  := Source.FStyleMask;
849    ForePriority   := Source.ForePriority;
850    BackPriority   := Source.BackPriority;
851    FramePriority  := Source.FramePriority;
852    FStylePriority  := Source.FStylePriority;
853    AssignFrom(Source);
854    EndUpdate;
855  end
856  else
857    inherited;
858end;
859
860procedure TLazSynCustomTextAttributes.SetAllPriorities(APriority: integer);
861var
862  i: TFontStyle;
863begin
864  BeginUpdate;
865  ForePriority := APriority;
866  BackPriority := APriority;
867  FramePriority := APriority;
868  for i := Low(TFontStyle) to High(TFontStyle) do
869    StylePriority[i] := APriority;
870  EndUpdate;
871end;
872
873procedure TLazSynCustomTextAttributes.BeginUpdate;
874begin
875  inc(FUpdateCount);
876end;
877
878procedure TLazSynCustomTextAttributes.EndUpdate;
879begin
880  dec(FUpdateCount);
881  if (FUpdateCount = 0) and FWasChanged then
882    Changed;
883end;
884
885{ TSynHighlighterAttributes }
886
887constructor TSynHighlighterAttributes.Create(aCaption: string;
888  aStoredName: String = '');
889begin
890  Create;
891  FConstName := aCaption;
892  FCaption := @FConstName;
893  if aStoredName = '' then
894    aStoredName := FConstName;
895  FStoredName := aStoredName;;
896end;
897
898constructor TSynHighlighterAttributes.Create(aCaption: PString; aStoredName: String);
899begin
900  Create;
901  if aCaption<>nil then begin
902    FConstName := aCaption^;
903    FCaption := aCaption;
904  end
905  else begin
906    FConstName := '';
907    FCaption := @FConstName;
908  end;
909  if aStoredName = '' then
910    aStoredName := FConstName;
911  FStoredName := aStoredName;
912end;
913
914function TSynHighlighterAttributes.IsEnabled: boolean;
915begin
916  Result := (Background <> clNone) or (Foreground <> clNone) or
917            ( (FrameColor <> clNone) and (FrameEdges <> sfeNone) ) or
918            (Style <> []) or (StyleMask <> []);
919end;
920
921function TSynHighlighterAttributes.GetBackgroundColorStored: boolean;
922begin
923  Result := Background <> fBackgroundDefault;
924end;
925
926function TSynHighlighterAttributes.GetFontStyleMaskStored : boolean;
927begin
928  Result := StyleMask <> fStyleMaskDefault;
929end;
930
931function TSynHighlighterAttributes.GetForegroundColorStored: boolean;
932begin
933  Result := Foreground <> fForegroundDefault;
934end;
935
936function TSynHighlighterAttributes.GetFrameColorStored: boolean;
937begin
938  Result := FrameColor <> FFrameColorDefault;
939end;
940
941function TSynHighlighterAttributes.GetFrameEdgesStored: boolean;
942begin
943  Result := FrameEdges <> FFrameEdgesDefault;
944end;
945
946function TSynHighlighterAttributes.GetFrameStyleStored: boolean;
947begin
948  Result := FrameStyle <> FFrameStyleDefault;
949end;
950
951function TSynHighlighterAttributes.GetFontStyleStored: boolean;
952begin
953  Result := Style <> fStyleDefault;
954end;
955
956procedure TSynHighlighterAttributes.InternalSaveDefaultValues;
957(* Called once from TSynCustomHighlighter.Create (and only from there),
958   after all Attributes where created  *)
959begin
960  fForegroundDefault := Foreground;
961  fBackgroundDefault := Background;
962  FFrameColorDefault := FrameColor;
963  FFrameStyleDefault := FrameStyle;
964  FFrameEdgesDefault := FrameEdges;
965  fStyleDefault      := Style;
966  fStyleMaskDefault  := StyleMask;
967end;
968
969function TSynHighlighterAttributes.LoadFromBorlandRegistry(rootKey: HKEY;
970  attrKey, attrName: string; oldStyle: boolean): boolean;
971  // How the highlighting information is stored:
972  // Delphi 1.0:
973  //   I don't know and I don't care.
974  // Delphi 2.0 & 3.0:
975  //   In the registry branch HKCU\Software\Borland\Delphi\x.0\Highlight
976  //   where x=2 or x=3.
977  //   Each entry is one string value, encoded as
978  //     <foreground RGB>,<background RGB>,<font style>,<default fg>,<default Background>,<fg index>,<Background index>
979  //   Example:
980  //     0,16777215,BI,0,1,0,15
981  //     foreground color (RGB): 0
982  //     background color (RGB): 16777215 ($FFFFFF)
983  //     font style: BI (bold italic), possible flags: B(old), I(talic), U(nderline)
984  //     default foreground: no, specified color will be used (black (0) is used when this flag is 1)
985  //     default background: yes, white ($FFFFFF, 15) will be used for background
986  //     foreground index: 0 (foreground index (Pal16), corresponds to foreground RGB color)
987  //     background index: 15 (background index (Pal16), corresponds to background RGB color)
988  // Delphi 4.0 & 5.0:
989  //   In the registry branch HKCU\Software\Borland\Delphi\4.0\Editor\Highlight.
990  //   Each entry is subkey containing several values:
991  //     Foreground Color: foreground index (Pal16), 0..15 (dword)
992  //     Background Color: background index (Pal16), 0..15 (dword)
993  //     Bold: fsBold yes/no, 0/True (string)
994  //     Italic: fsItalic yes/no, 0/True (string)
995  //     Underline: fsUnderline yes/no, 0/True (string)
996  //     Default Foreground: use default foreground (clBlack) yes/no, False/-1 (string)
997  //     Default Background: use default backround (clWhite) yes/no, False/-1 (string)
998{$IFNDEF SYN_LAZARUS}
999const
1000  Pal16: array [0..15] of TColor = (clBlack, clMaroon, clGreen, clOlive,
1001          clNavy, clPurple, clTeal, clLtGray, clDkGray, clRed, clLime,
1002          clYellow, clBlue, clFuchsia, clAqua, clWhite);
1003{$ENDIF}
1004
1005  function LoadOldStyle(rootKey: HKEY; attrKey, attrName: string): boolean;
1006  var
1007    {$IFNDEF SYN_LAZARUS}
1008    descript : string;
1009    //fgColRGB : string;
1010    //bgColRGB : string;
1011    fontStyle: string;
1012    fgDefault: string;
1013    bgDefault: string;
1014    fgIndex16: string;
1015    bgIndex16: string;
1016    {$ENDIF}
1017    reg      : TRegistry;
1018
1019    function Get(var name: string): string;
1020    var
1021      p: integer;
1022    begin
1023      p := Pos(',',name);
1024      if p = 0 then p := Length(name)+1;
1025      Result := Copy(name,1,p-1);
1026      name := Copy(name,p+1,Length(name)-p);
1027    end; { Get }
1028
1029  begin { LoadOldStyle }
1030    Result := false;
1031    try
1032      reg := TRegistry.Create;
1033      reg.RootKey := rootKey;
1034      try
1035        with reg do begin
1036          {$IFNDEF SYN_LAZARUS}
1037          // ToDo Registry
1038          if OpenKeyReadOnly(attrKey) then begin
1039            try
1040              if ValueExists(attrName) then begin
1041                descript := ReadString(attrName);
1042                //fgColRGB  := Get(descript);
1043                //bgColRGB  := Get(descript);
1044                fontStyle := Get(descript);
1045                fgDefault := Get(descript);
1046                bgDefault := Get(descript);
1047                fgIndex16 := Get(descript);
1048                bgIndex16 := Get(descript);
1049                if bgDefault = '1'
1050                  then Background := clWindow
1051                  else Background := Pal16[StrToInt(bgIndex16)];
1052                if fgDefault = '1'
1053                  then Foreground := clWindowText
1054                  else Foreground := Pal16[StrToInt(fgIndex16)];
1055                Style := [];
1056                if Pos('B',fontStyle) > 0 then Style := Style + [fsBold];
1057                if Pos('I',fontStyle) > 0 then Style := Style + [fsItalic];
1058                if Pos('U',fontStyle) > 0 then Style := Style + [fsUnderline];
1059                Result := true;
1060              end;
1061            finally CloseKey; end;
1062          end; // if
1063          {$ENDIF}
1064        end; // with
1065      finally reg.Free; end;
1066    except end;
1067  end; { LoadOldStyle }
1068
1069  function LoadNewStyle(rootKey: HKEY; attrKey, attrName: string): boolean;
1070  var
1071    {$IFNDEF SYN_LAZARUS}
1072    fgIndex16    : DWORD;
1073    bgIndex16    : DWORD;
1074    fontBold     : string;
1075    fontItalic   : string;
1076    fontUnderline: string;
1077    fgDefault    : string;
1078    bgDefault    : string;
1079    {$ENDIF}
1080    reg          : TRegistry;
1081
1082    function IsTrue(value: string): boolean;
1083    begin
1084      Result := not ((CompareText(value,'FALSE') = 0) or (value = '0'));
1085    end; { IsTrue }
1086
1087  begin
1088    Result := false;
1089    try
1090      reg := TRegistry.Create;
1091      reg.RootKey := rootKey;
1092      try
1093        with reg do begin
1094          {$IFNDEF SYN_LAZARUS}
1095          // ToDo Registry
1096          if OpenKeyReadOnly(attrKey+'\'+attrName) then begin
1097            try
1098              if ValueExists('Foreground Color')
1099                then fgIndex16 := ReadInteger('Foreground Color')
1100                else Exit;
1101              if ValueExists('Background Color')
1102                then bgIndex16 := ReadInteger('Background Color')
1103                else Exit;
1104              if ValueExists('Bold')
1105                then fontBold := ReadString('Bold')
1106                else Exit;
1107              if ValueExists('Italic')
1108                then fontItalic := ReadString('Italic')
1109                else Exit;
1110              if ValueExists('Underline')
1111                then fontUnderline := ReadString('Underline')
1112                else Exit;
1113              if ValueExists('Default Foreground')
1114                then fgDefault := ReadString('Default Foreground')
1115                else Exit;
1116              if ValueExists('Default Background')
1117                then bgDefault := ReadString('Default Background')
1118                else Exit;
1119              if IsTrue(bgDefault)
1120                then Background := clWindow
1121                else Background := Pal16[bgIndex16];
1122              if IsTrue(fgDefault)
1123                then Foreground := clWindowText
1124                else Foreground := Pal16[fgIndex16];
1125              Style := [];
1126              if IsTrue(fontBold) then Style := Style + [fsBold];
1127              if IsTrue(fontItalic) then Style := Style + [fsItalic];
1128              if IsTrue(fontUnderline) then Style := Style + [fsUnderline];
1129              Result := true;
1130            finally CloseKey; end;
1131          end; // if
1132          {$ENDIF}
1133        end; // with
1134      finally reg.Free; end;
1135    except end;
1136  end; { LoadNewStyle }
1137
1138begin
1139  if oldStyle then Result := LoadOldStyle(rootKey, attrKey, attrName)
1140              else Result := LoadNewStyle(rootKey, attrKey, attrName);
1141end; { TSynHighlighterAttributes.LoadFromBorlandRegistry }
1142
1143function TSynHighlighterAttributes.LoadFromRegistry(Reg: TRegistry): boolean;
1144{$IFNDEF SYN_LAZARUS}
1145var
1146  key: string;
1147{$ENDIF}
1148begin
1149  {$IFNDEF SYN_LAZARUS}
1150  // ToDo  Registry
1151  key := Reg.CurrentPath;
1152  if Reg.OpenKeyReadOnly(StoredName) then begin
1153    if Reg.ValueExists('Background') then
1154      Background := Reg.ReadInteger('Background');
1155    if Reg.ValueExists('Foreground') then
1156      Foreground := Reg.ReadInteger('Foreground');
1157    if Reg.ValueExists('Style') then
1158      IntegerStyle := Reg.ReadInteger('Style');
1159    if Reg.ValueExists('StyleMask') then
1160      IntegerStyle := Reg.ReadInteger('StyleMask');
1161    reg.OpenKeyReadOnly('\' + key);
1162    Result := true;
1163  end else
1164    Result := false;
1165  {$ELSE}
1166  Result:=false;
1167  {$ENDIF}
1168end;
1169
1170function TSynHighlighterAttributes.SaveToRegistry(Reg: TRegistry): boolean;
1171var
1172  key: string;
1173begin
1174  key := Reg.CurrentPath;
1175  if Reg.OpenKey(StoredName,true) then begin
1176    Reg.WriteInteger('Background', Background);
1177    Reg.WriteInteger('Foreground', Foreground);
1178    Reg.WriteInteger('Style', IntegerStyle);
1179    Reg.WriteInteger('StyleMask', IntegerStyleMask);
1180    reg.OpenKey('\' + key, false);
1181    Result := true;
1182  end else
1183    Result := false;
1184end;
1185
1186function TSynHighlighterAttributes.LoadFromFile(Ini : TIniFile): boolean;       //DDH 10/16/01
1187var
1188  S: TStringListUTF8Fast;
1189begin
1190  S := TStringListUTF8Fast.Create;
1191  try
1192    Ini.ReadSection(StoredName, S);
1193    if S.Count > 0 then
1194    begin
1195      if S.IndexOf('Background') <> -1 then
1196        Background := Ini.ReadInteger(StoredName, 'Background', clWindow);
1197      if S.IndexOf('Foreground') <> -1 then
1198        Foreground := Ini.ReadInteger(StoredName, 'Foreground', clWindowText);
1199      if S.IndexOf('Style') <> -1 then
1200        IntegerStyle := Ini.ReadInteger(StoredName, 'Style', 0);
1201      if S.IndexOf('StyleMask') <> -1 then
1202        IntegerStyleMask := Ini.ReadInteger(StoredName, 'StyleMask', 0);
1203      Result := true;
1204    end else Result := false;
1205  finally
1206    S.Free;
1207  end;
1208end;
1209
1210function TSynHighlighterAttributes.SaveToFile(Ini : TIniFile): boolean;         //DDH 10/16/01
1211begin
1212  Ini.WriteInteger(StoredName, 'Background', Background);
1213  Ini.WriteInteger(StoredName, 'Foreground', Foreground);
1214  Ini.WriteInteger(StoredName, 'Style', IntegerStyle);
1215  Ini.WriteInteger(StoredName, 'StyleMask', IntegerStyleMask);
1216  Result := true;
1217end;
1218
1219function TSynHighlighterAttributes.GetStyleFromInt: integer;
1220begin
1221  if fsBold in Style then Result:= 1 else Result:= 0;
1222  if fsItalic in Style then Result:= Result + 2;
1223  if fsUnderline in Style then Result:= Result + 4;
1224  if fsStrikeout in Style then Result:= Result + 8;
1225end;
1226
1227procedure TSynHighlighterAttributes.SetStyleFromInt(const Value: integer);
1228begin
1229  if Value and $1 = 0 then  Style:= [] else Style:= [fsBold];
1230  if Value and $2 <> 0 then Style:= Style + [fsItalic];
1231  if Value and $4 <> 0 then Style:= Style + [fsUnderline];
1232  if Value and $8 <> 0 then Style:= Style + [fsStrikeout];
1233end;
1234
1235function TSynHighlighterAttributes.GetStyleMaskFromInt : integer;
1236begin
1237  if fsBold in StyleMask then Result:= 1 else Result:= 0;
1238  if fsItalic in StyleMask then Result:= Result + 2;
1239  if fsUnderline in StyleMask then Result:= Result + 4;
1240  if fsStrikeout in StyleMask then Result:= Result + 8;
1241end;
1242
1243procedure TSynHighlighterAttributes.SetStyleMaskFromInt(const Value : integer);
1244begin
1245  if Value and $1 = 0 then  StyleMask:= [] else StyleMask:= [fsBold];
1246  if Value and $2 <> 0 then StyleMask:= StyleMask + [fsItalic];
1247  if Value and $4 <> 0 then StyleMask:= StyleMask + [fsUnderline];
1248  if Value and $8 <> 0 then StyleMask:= StyleMask + [fsStrikeout];
1249end;
1250
1251function TSynHighlighterAttributes.GetBackPriorityStored: Boolean;
1252begin
1253  Result := FBackPriority <> 0;
1254end;
1255
1256function TSynHighlighterAttributes.GetForePriorityStored: Boolean;
1257begin
1258  Result := FForePriority <> 0;
1259end;
1260
1261function TSynHighlighterAttributes.GetFramePriorityStored: Boolean;
1262begin
1263  Result := FFramePriority <> 0;
1264end;
1265
1266function TSynHighlighterAttributes.GetStylePriorityStored(AIndex: TFontStyle
1267  ): Boolean;
1268begin
1269  Result := FStylePriority[AIndex] <> 0;
1270end;
1271
1272procedure TSynHighlighterAttributes.AssignFrom(Src: TLazSynCustomTextAttributes);
1273begin
1274  inherited AssignFrom(Src);
1275  if not (Src is TSynHighlighterAttributes) then exit;
1276  FConstName      := TSynHighlighterAttributes(Src).FConstName;
1277  FStoredName:= TSynHighlighterAttributes(Src).FStoredName;
1278  Changed; {TODO: only if really changed}
1279end;
1280
1281procedure TSynHighlighterAttributes.DoChange;
1282begin
1283  inherited DoChange;
1284  if Assigned(fOnChange) then
1285    fOnChange(Self);
1286end;
1287
1288constructor TSynHighlighterAttributes.Create;
1289begin
1290  inherited Create;
1291  InternalSaveDefaultValues;
1292end;
1293
1294{ TSynEditLinesList }
1295
1296function TSynEditLinesList.GetSynString(Index: Integer): TSynEditStringsBase;
1297begin
1298  Result := TSynEditStringsBase(inherited Items[Index]);
1299end;
1300
1301procedure TSynEditLinesList.PutSynStrings(Index: Integer; const AValue: TSynEditStringsBase);
1302begin
1303  inherited Items[Index] := AValue;
1304end;
1305
1306{ TSynCustomHighlighter }
1307
1308constructor TSynCustomHighlighter.Create(AOwner: TComponent);
1309begin
1310  FCapabilities:=GetCapabilities;
1311  FKnownLines := TSynEditLinesList.Create;
1312  inherited Create(AOwner);
1313  fWordBreakChars := TSynWordBreakChars;
1314  fAttributes := TStringListUTF8Fast.Create;
1315  fAttributes.Duplicates := dupError;
1316  fAttributes.Sorted := TRUE;
1317  fAttrChangeHooks := TMethodList.Create;
1318  fDefaultFilter := '';
1319end;
1320
1321destructor TSynCustomHighlighter.Destroy;
1322begin
1323  FreeHighlighterAttributes;
1324  fAttributes.Free;
1325  fAttrChangeHooks.Free;
1326  inherited Destroy;
1327  FreeAndNil(FKnownLines);
1328end;
1329
1330procedure TSynCustomHighlighter.BeginUpdate;
1331begin
1332  Inc(fUpdateCount);
1333end;
1334
1335procedure TSynCustomHighlighter.EndUpdate;
1336begin
1337  if fUpdateCount > 0 then begin
1338    Dec(fUpdateCount);
1339    if (fUpdateCount = 0) and fUpdateChange then begin
1340      fUpdateChange := FALSE;
1341      DefHighlightChange(Self);
1342    end;
1343  end;
1344end;
1345
1346procedure TSynCustomHighlighter.FreeHighlighterAttributes;
1347var
1348  i: integer;
1349begin
1350  if fAttributes <> nil then begin
1351    for i := fAttributes.Count - 1 downto 0 do
1352      TSynHighlighterAttributes(fAttributes.Objects[i]).Free;
1353    fAttributes.Clear;
1354  end;
1355end;
1356
1357procedure TSynCustomHighlighter.Assign(Source: TPersistent);
1358var
1359  Src: TSynCustomHighlighter;
1360  i, j: integer;
1361  SrcAttri: TSynHighlighterAttributes;
1362  StoredName: String;
1363begin
1364  if Source is TSynCustomHighlighter then begin
1365    Src := TSynCustomHighlighter(Source);
1366    for i := 0 to AttrCount - 1 do begin
1367      // assign first attribute with the same name
1368      StoredName := Attribute[i].StoredName;
1369      for j := 0 to Src.AttrCount - 1 do begin
1370        SrcAttri := Src.Attribute[j];
1371        if StoredName = SrcAttri.StoredName then begin
1372          Attribute[i].Assign(SrcAttri);
1373          continue;
1374        end;
1375      end;
1376    end;
1377    for i := 0 to DividerDrawConfigCount - 1 do
1378      DividerDrawConfig[i].Assign(Src.DividerDrawConfig[i]);
1379    // assign the sample source text only if same or descendant class
1380    if Src is ClassType then
1381      SampleSource := Src.SampleSource;
1382    fWordBreakChars := Src.WordBreakChars;
1383    DefaultFilter := Src.DefaultFilter;
1384    Enabled := Src.Enabled;
1385  end else
1386    inherited Assign(Source);
1387end;
1388
1389procedure TSynCustomHighlighter.EnumUserSettings(Settings: TStrings);
1390begin
1391  Settings.Clear;
1392end;
1393
1394function TSynCustomHighlighter.UseUserSettings(settingIndex: integer): boolean;
1395begin
1396  Result := false;
1397end;
1398
1399function TSynCustomHighlighter.LoadFromRegistry(RootKey: HKEY;
1400  Key: string): boolean;
1401var
1402  r: TRegistry;
1403{  i: integer; }
1404begin
1405  r := TRegistry.Create;
1406  try
1407    r.RootKey := RootKey;
1408    {TODO:
1409    if r.OpenKeyReadOnly(Key) then begin
1410      Result := true;
1411      for i := 0 to AttrCount-1 do
1412        Result := Result and Attribute[i].LoadFromRegistry(r);
1413    end
1414    else
1415    }
1416      Result := false;
1417
1418  finally r.Free; end;
1419end;
1420
1421function TSynCustomHighlighter.SaveToRegistry(RootKey: HKEY;
1422  Key: string): boolean;
1423var
1424  r: TRegistry;
1425  i: integer;
1426begin
1427  r := TRegistry.Create;
1428  try
1429    r.RootKey := RootKey;
1430    if r.OpenKey(Key,true) then begin
1431      Result := true;
1432      for i := 0 to AttrCount-1 do
1433        Result := Result and Attribute[i].SaveToRegistry(r);
1434    end
1435    else Result := false;
1436  finally r.Free; end;
1437end;
1438
1439function TSynCustomHighlighter.LoadFromFile(AFileName : String): boolean;       //DDH 10/16/01
1440VAR AIni : TIniFile;
1441    i : Integer;
1442begin
1443  AIni := TIniFile.Create(UTF8ToSys(AFileName));
1444  try
1445    with AIni do
1446    begin
1447      Result := true;
1448      for i := 0 to AttrCount-1 do
1449        Result := Result and Attribute[i].LoadFromFile(AIni);
1450    end;
1451  finally
1452    AIni.Free;
1453  end;
1454end;
1455
1456function TSynCustomHighlighter.SaveToFile(AFileName : String): boolean;         //DDH 10/16/01
1457var AIni : TIniFile;
1458    i: integer;
1459begin
1460  AIni := TIniFile.Create(UTF8ToSys(AFileName));
1461  try
1462    with AIni do
1463    begin
1464      Result := true;
1465      for i := 0 to AttrCount-1 do
1466        Result := Result and Attribute[i].SaveToFile(AIni);
1467    end;
1468  finally
1469    AIni.Free;
1470  end;
1471end;
1472
1473procedure TSynCustomHighlighter.AddAttribute(AAttrib: TSynHighlighterAttributes);
1474begin
1475  fAttributes.AddObject(AAttrib.StoredName, AAttrib);
1476end;
1477
1478function TSynCustomHighlighter.AddSpecialAttribute(const aCaption: string;
1479  const aStoredName: String): TSynHighlighterAttributes;
1480begin
1481  result := TSynHighlighterAttributes.Create(aCaption,aStoredName);
1482  AddAttribute(result);
1483end;
1484
1485function TSynCustomHighlighter.AddSpecialAttribute(const aCaption: PString;
1486  const aStoredName: String): TSynHighlighterAttributes;
1487begin
1488  Result := TSynHighlighterAttributes.Create(aCaption,aStoredName);
1489  AddAttribute(result);
1490end;
1491
1492procedure TSynCustomHighlighter.DefHighlightChange(Sender: TObject);
1493begin
1494  if fUpdateCount > 0 then
1495    fUpdateChange := TRUE
1496  else begin
1497    fAttrChangeHooks.CallNotifyEvents(self);
1498    FAttributeChangeNeedScan := False;
1499  end;
1500end;
1501
1502function TSynCustomHighlighter.GetAttribCount: integer;
1503begin
1504  Result := fAttributes.Count;
1505end;
1506
1507function TSynCustomHighlighter.GetAttribute(idx: integer): TSynHighlighterAttributes;
1508begin
1509  Result := nil;
1510  if (idx >= 0) and (idx < fAttributes.Count) then
1511    Result := TSynHighlighterAttributes(fAttributes.Objects[idx]);
1512end;
1513
1514class function TSynCustomHighlighter.GetCapabilities: TSynHighlighterCapabilities;
1515begin
1516  Result := [hcRegistry]; //registry save/load supported by default
1517end;
1518
1519function TSynCustomHighlighter.GetDefaultFilter: string;
1520begin
1521  Result := fDefaultFilter;
1522end;
1523
1524function TSynCustomHighlighter.GetIdentChars: TSynIdentChars;
1525begin
1526  Result := ['_', 'A'..'Z', 'a'..'z', '0'..'9'];
1527end;
1528
1529function TSynCustomHighlighter.GetEndOfLineAttribute: TSynHighlighterAttributes;
1530begin
1531  Result := nil;
1532end;
1533
1534procedure TSynCustomHighlighter.SetWordBreakChars(AChars: TSynIdentChars);
1535begin
1536  fWordBreakChars := AChars;
1537end;
1538
1539class function TSynCustomHighlighter.GetLanguageName: string;
1540begin
1541{$IFDEF SYN_DEVELOPMENT_CHECKS}
1542  raise Exception.CreateFmt('%s.GetLanguageName not implemented', [ClassName]);
1543{$ENDIF}
1544  Result := '<Unknown>';
1545end;
1546
1547function TSynCustomHighlighter.GetRange: Pointer;
1548begin
1549  Result := nil;
1550end;
1551
1552function TSynCustomHighlighter.GetSampleSource: string;
1553begin
1554  Result := '';
1555end;
1556
1557procedure TSynCustomHighlighter.HookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
1558begin
1559  fAttrChangeHooks.Add(TMethod(ANotifyEvent));
1560end;
1561
1562function TSynCustomHighlighter.IsFilterStored: boolean;
1563begin
1564  Result := TRUE;
1565end;
1566
1567{begin}                                                                         // DJLP 2000-08-09
1568function TSynCustomHighlighter.IsKeyword(const AKeyword: string): boolean;
1569begin
1570  Result := FALSE;
1571end;
1572{end}                                                                           // DJLP 2000-08-09
1573
1574procedure TSynCustomHighlighter.NextToEol;
1575begin
1576  FIsInNextToEOL := True;
1577  while not GetEol do Next;
1578  FIsInNextToEOL := False;
1579end;
1580
1581procedure TSynCustomHighlighter.ContinueNextLine;
1582begin
1583  inc(FLineIndex);
1584  SetLine(CurrentLines[FLineIndex], FLineIndex);
1585end;
1586
1587procedure TSynCustomHighlighter.StartAtLineIndex(LineNumber: Integer);
1588begin
1589  FLineIndex := LineNumber;
1590  if LineNumber = 0 then
1591    ResetRange
1592  else
1593    SetRange(FCurrentRanges[LineNumber - 1]);
1594  SetLine(CurrentLines[LineNumber], LineNumber);
1595end;
1596
1597procedure TSynCustomHighlighter.ResetRange;
1598begin
1599end;
1600
1601procedure TSynCustomHighlighter.SetLine(const NewValue: String; LineNumber: Integer);
1602begin
1603  // Keep a copy of the line text, since some highlighters just use a PChar pointer to it.
1604  FLineText := NewValue;
1605  FIsInNextToEOL := False;
1606  FLineIndex := LineNumber;
1607end;
1608
1609procedure TSynCustomHighlighter.SetAttributesOnChange(AEvent: TNotifyEvent);
1610(* Called once from TSynCustomHighlighter.Create (and only from there),
1611   after all Attributes where created  *)
1612var
1613  i: integer;
1614  Attri: TSynHighlighterAttributes;
1615begin
1616  for i := fAttributes.Count - 1 downto 0 do begin
1617    Attri := TSynHighlighterAttributes(fAttributes.Objects[i]);
1618    if Attri <> nil then begin
1619      Attri.OnChange := AEvent;
1620      Attri.InternalSaveDefaultValues;
1621    end;
1622  end;
1623end;
1624
1625procedure TSynCustomHighlighter.SetRange(Value: Pointer);
1626begin
1627end;
1628
1629procedure TSynCustomHighlighter.SetDefaultFilter(Value: string);
1630begin
1631  fDefaultFilter := Value;
1632end;
1633
1634procedure TSynCustomHighlighter.SetSampleSource(Value: string);
1635begin
1636end;
1637
1638function TSynCustomHighlighter.GetRangeIdentifier: Pointer;
1639begin
1640  Result := self;
1641end;
1642
1643function TSynCustomHighlighter.CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList;
1644begin
1645  Result := TSynHighlighterRangeList.Create;
1646end;
1647
1648procedure TSynCustomHighlighter.AfterAttachedToRangeList(ARangeList: TSynHighlighterRangeList);
1649begin  // empty base
1650end;
1651
1652procedure TSynCustomHighlighter.BeforeDetachedFromRangeList(ARangeList: TSynHighlighterRangeList);
1653begin  // empty base
1654end;
1655
1656procedure TSynCustomHighlighter.UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
1657begin
1658  fAttrChangeHooks.Remove(TMethod(ANotifyEvent));
1659end;
1660
1661function TSynCustomHighlighter.UpdateRangeInfoAtLine(Index: Integer): Boolean;
1662var
1663  r: Pointer;
1664begin
1665  r := GetRange;
1666  Result := r <> FCurrentRanges[Index];
1667  if Result then
1668    FCurrentRanges[Index] := r;
1669end;
1670
1671procedure TSynCustomHighlighter.ScanRanges;
1672var
1673  StartIndex, EndIndex: Integer;
1674begin
1675  StartIndex := CurrentRanges.NeedsReScanStartIndex;
1676  if (StartIndex < 0) or (StartIndex >= CurrentRanges.Count) then
1677    exit;
1678  EndIndex := CurrentRanges.NeedsReScanEndIndex + 1;
1679  //debugln(['=== scan ',StartIndex,' - ',EndIndex]);
1680  FIsScanning := True;
1681  try
1682    EndIndex :=  PerformScan(StartIndex, EndIndex);
1683  finally
1684    FIsScanning := False;
1685  end;
1686  StartIndex := CurrentRanges.NeedsReScanRealStartIndex; // include idle scanned
1687  CurrentRanges.ClearReScanNeeded;
1688  // Invalidate one line above, since folds can change depending on next line
1689  // TODO: only classes with end-fold-last-line
1690  if StartIndex > 0
1691  then CurrentLines.SendHighlightChanged(StartIndex - 1, EndIndex - StartIndex + 1)
1692  else CurrentLines.SendHighlightChanged(StartIndex,     EndIndex - StartIndex    );
1693end;
1694
1695function TSynCustomHighlighter.IdleScanRanges: Boolean;
1696var
1697  StartIndex, EndIndex, RealEndIndex: Integer;
1698begin
1699  Result := False;
1700  StartIndex := CurrentRanges.NeedsReScanStartIndex;
1701  if (StartIndex < 0) or (StartIndex >= CurrentRanges.Count) then
1702    exit;
1703  EndIndex := CurrentRanges.NeedsReScanEndIndex + 1;
1704
1705  RealEndIndex := EndIndex;
1706  if EndIndex > StartIndex + IDLE_SCAN_CHUNK_SIZE then
1707    EndIndex := StartIndex + IDLE_SCAN_CHUNK_SIZE;
1708  FIsScanning := True;
1709  try
1710    EndIndex :=  PerformScan(StartIndex, EndIndex, True);
1711  finally
1712    FIsScanning := False;
1713  end;
1714
1715  if EndIndex >= RealEndIndex then begin
1716    StartIndex := CurrentRanges.NeedsReScanRealStartIndex; // include idle scanned
1717//debugln(['=== IDLE SendHighlightChanged ',StartIndex,' - ',EndIndex]);
1718    CurrentRanges.ClearReScanNeeded;
1719  // Invalidate one line above, since folds can change depending on next line
1720    CurrentLines.SendHighlightChanged(StartIndex - 1, EndIndex - StartIndex + 1);
1721    exit;
1722  end
1723  else begin
1724    CurrentRanges.AdjustReScanStart(EndIndex);
1725    Result := True;
1726  end;
1727end;
1728
1729function TSynCustomHighlighter.NeedScan: Boolean;
1730begin
1731  Result := (CurrentRanges.NeedsReScanStartIndex >= 0);
1732end;
1733
1734function TSynCustomHighlighter.PerformScan(StartIndex, EndIndex: Integer;
1735  ForceEndIndex: Boolean = False): Integer;
1736var
1737  c: Integer;
1738begin
1739  Result := StartIndex;
1740  c := CurrentLines.Count;
1741  if (c = 0) or (Result >= c) then
1742    exit;
1743  StartAtLineIndex(Result);
1744  NextToEol;
1745  while UpdateRangeInfoAtLine(Result) or (Result <= EndIndex) do begin
1746    inc(Result);
1747    if (Result = c) or (ForceEndIndex and (Result > EndIndex)) then
1748      break;
1749    ContinueNextLine;
1750    NextToEol;
1751  end;
1752end;
1753
1754procedure TSynCustomHighlighter.ScanAllRanges;
1755begin
1756  CurrentRanges.InvalidateAll;
1757  ScanRanges;
1758end;
1759
1760procedure TSynCustomHighlighter.SetEnabled(const Value: boolean);
1761begin
1762  if fEnabled <> Value then
1763  begin
1764    fEnabled := Value;
1765    //we need to notify any editor that we are attached to to repaint,
1766    //but a highlighter doesn't know what editor it is attached to.
1767    //Until this is resolved, you will have to manually call repaint
1768    //on the editor in question.
1769  end;
1770end;
1771
1772procedure TSynCustomHighlighter.SetCurrentLines(const AValue: TSynEditStringsBase);
1773begin
1774  if AValue = FCurrentLines then
1775    exit;
1776  FCurrentLines := AValue;
1777  if FCurrentLines <> nil
1778  then FCurrentRanges := TSynHighlighterRangeList(AValue.Ranges[GetRangeIdentifier])
1779  else FCurrentRanges := nil;
1780  DoCurrentLinesChanged;
1781end;
1782
1783procedure TSynCustomHighlighter.DoCurrentLinesChanged;
1784begin
1785  //
1786end;
1787
1788procedure TSynCustomHighlighter.AttachToLines(Lines: TSynEditStringsBase);
1789var
1790  r: TSynHighlighterRangeList;
1791begin
1792  r := TSynHighlighterRangeList(Lines.Ranges[GetRangeIdentifier]);
1793  if assigned(r) then
1794    r.IncRefCount
1795  else begin
1796    FKnownLines.Add(Lines);
1797    r := CreateRangeList(Lines);
1798    Lines.Ranges[GetRangeIdentifier] := r;
1799    r.InvalidateAll;
1800  end;
1801  AfterAttachedToRangeList(r); // RefCount already increased
1802  FCurrentLines := nil;
1803end;
1804
1805procedure TSynCustomHighlighter.DetachFromLines(Lines: TSynEditStringsBase);
1806var
1807  r: TSynHighlighterRangeList;
1808begin
1809  r := TSynHighlighterRangeList(Lines.Ranges[GetRangeIdentifier]);
1810  if not assigned(r) then exit;
1811  r.DecRefCount;
1812  BeforeDetachedFromRangeList(r); // RefCount already decreased
1813  if r.RefCount = 0 then begin
1814    Lines.Ranges[GetRangeIdentifier] := nil;
1815    if FCurrentRanges = r then begin
1816      FCurrentRanges := nil;
1817      FCurrentLines := nil;
1818    end;
1819    r.Free;
1820  end;
1821  FKnownLines.Remove(Lines);
1822end;
1823
1824procedure TSynCustomHighlighter.SetDrawDividerLevel(const AValue: Integer);
1825begin
1826  if FDrawDividerLevel = AValue then exit;
1827  FDrawDividerLevel := AValue;
1828  //DefHighlightChange(Self);
1829end;
1830
1831function TSynCustomHighlighter.GetKnownRanges(Index: Integer): TSynHighlighterRangeList;
1832begin
1833  Result := TSynHighlighterRangeList(KnownLines[Index].Ranges[GetRangeIdentifier]);
1834end;
1835
1836function TSynCustomHighlighter.GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting;
1837begin
1838  result := SynEmptyDividerDrawConfigSetting;
1839end;
1840
1841function TSynCustomHighlighter.GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig;
1842begin
1843  Result := nil;
1844end;
1845
1846function TSynCustomHighlighter.GetDividerDrawConfigCount: Integer;
1847begin
1848  Result := 0;
1849end;
1850
1851{ TSynHighlighterRangeList }
1852
1853function TSynHighlighterRangeList.GetRange(Index: Integer): Pointer;
1854begin
1855  Result := Pointer(ItemPointer[Index]^);
1856end;
1857
1858function TSynHighlighterRangeList.GetNeedsReScanRealStartIndex: Integer;
1859begin
1860  Result := FNeedsReScanRealStartIndex;
1861  if Result < 0 then
1862    Result := FNeedsReScanStartIndex;
1863end;
1864
1865procedure TSynHighlighterRangeList.SetRange(Index: Integer; const AValue: Pointer);
1866begin
1867  Pointer(ItemPointer[Index]^) := AValue;
1868end;
1869
1870procedure TSynHighlighterRangeList.LineTextChanged(AIndex: Integer; ACount: Integer = 1);
1871begin
1872  if FNeedsReScanStartIndex < 0 then begin
1873    FNeedsReScanStartIndex := AIndex;
1874    FNeedsReScanEndIndex := AIndex + ACount - 1;
1875  end
1876  else if AIndex < FNeedsReScanStartIndex then
1877    FNeedsReScanStartIndex := AIndex
1878  else if AIndex + ACount - 1 > FNeedsReScanEndIndex then
1879    FNeedsReScanEndIndex := AIndex + ACount - 1;
1880end;
1881
1882procedure TSynHighlighterRangeList.InsertedLines(AIndex, ACount: Integer);
1883begin
1884  if (FNeedsReScanStartIndex < 0) or (AIndex < FNeedsReScanStartIndex) then
1885    FNeedsReScanStartIndex := AIndex;
1886
1887  if (FNeedsReScanEndIndex < 0) or (FNeedsReScanEndIndex < AIndex) then
1888    FNeedsReScanEndIndex := AIndex + ACount
1889  else
1890    FNeedsReScanEndIndex := FNeedsReScanEndIndex + ACount
1891end;
1892
1893procedure TSynHighlighterRangeList.DeletedLines(AIndex, ACount: Integer);
1894begin
1895  if AIndex >= Count then exit;
1896  if (FNeedsReScanStartIndex < 0) or (AIndex < FNeedsReScanStartIndex) then
1897    FNeedsReScanStartIndex := AIndex;
1898  if (FNeedsReScanEndIndex < 0) or (FNeedsReScanEndIndex < AIndex) then
1899    FNeedsReScanEndIndex := AIndex;
1900end;
1901
1902procedure TSynHighlighterRangeList.ClearReScanNeeded;
1903begin
1904  FNeedsReScanStartIndex := -1;
1905  FNeedsReScanEndIndex := -1;
1906  FNeedsReScanRealStartIndex := -1;
1907end;
1908
1909procedure TSynHighlighterRangeList.AdjustReScanStart(ANewStart: Integer);
1910begin
1911  if FNeedsReScanRealStartIndex < 0 then
1912    FNeedsReScanRealStartIndex := FNeedsReScanStartIndex;
1913  FNeedsReScanStartIndex := ANewStart;
1914end;
1915
1916procedure TSynHighlighterRangeList.InvalidateAll;
1917begin
1918  FNeedsReScanStartIndex := 0;
1919  FNeedsReScanEndIndex := Count - 1;
1920end;
1921
1922constructor TSynHighlighterRangeList.Create;
1923begin
1924  Inherited;
1925  ItemSize := SizeOf(Pointer);
1926  FRefCount := 1;
1927  ClearReScanNeeded;
1928end;
1929
1930procedure TSynHighlighterRangeList.IncRefCount;
1931begin
1932  inc(FRefCount);
1933end;
1934
1935procedure TSynHighlighterRangeList.DecRefCount;
1936begin
1937  dec(FRefCount);
1938end;
1939
1940{ TSynDividerDrawConfig }
1941
1942function TSynDividerDrawConfig.GetNestColor: TColor;
1943begin
1944  Result := FNestSetting.Color;
1945end;
1946
1947function TSynDividerDrawConfig.GetTopColor: TColor;
1948begin
1949  Result := FTopSetting.Color;
1950end;
1951
1952procedure TSynDividerDrawConfig.SetNestColor(const AValue: TColor);
1953begin
1954  if AValue = FNestSetting.Color then exit;
1955  FNestSetting.Color := AValue;
1956  Changed;
1957end;
1958
1959procedure TSynDividerDrawConfig.SetTopColor(const AValue: TColor);
1960begin
1961  if AValue = FTopSetting.Color then exit;
1962  FTopSetting.Color := AValue;
1963  Changed;
1964end;
1965
1966function TSynDividerDrawConfig.GetMaxDrawDepth: Integer;
1967begin
1968  Result := FDepth;
1969end;
1970
1971procedure TSynDividerDrawConfig.SetMaxDrawDepth(AValue: Integer);
1972begin
1973  if FDepth = AValue then exit;
1974  FDepth := AValue;
1975  Changed;
1976end;
1977
1978procedure TSynDividerDrawConfig.Changed;
1979begin
1980  if Assigned(fOnChange) then
1981    fOnChange(Self);
1982end;
1983
1984constructor TSynDividerDrawConfig.Create;
1985begin
1986  inherited;
1987  FDepth := 0;
1988  FTopSetting.Color := clDefault;
1989  FNestSetting.Color := clDefault;
1990end;
1991
1992procedure TSynDividerDrawConfig.Assign(Src: TSynDividerDrawConfig);
1993begin
1994  fOnChange := src.fOnChange;
1995  FDepth := Src.FDepth;
1996end;
1997
1998initialization
1999  G_PlaceableHighlighters := TSynHighlighterList.Create;
2000finalization
2001  G_PlaceableHighlighters.Free;
2002  G_PlaceableHighlighters := nil;
2003end.
2004
2005
2006