~ubuntu-branches/ubuntu/vivid/lazarus/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/spell_errors.diff/components/synedit/synedittexttabexpander.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Paul Gevers
  • Date: 2014-04-25 12:57:26 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20140425125726-6zkdcnnbbleuuvwj
Tags: 1.2+dfsg-1
[ Abou Al Montacir ]
* Packaged QT4 based IDE and LCL units.

[ Paul Gevers ]
* New upstream release
* Drop obsolete patches + refresh spell_errors.diff
* Update dependencies and description for QT4 changes
* Improve deduplication in d/rules (adds lcl-qt4 -> lcl-gtk2 -> lcl-nogui)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
{-------------------------------------------------------------------------------
2
 
The contents of this file are subject to the Mozilla Public License
3
 
Version 1.1 (the "License"); you may not use this file except in compliance
4
 
with the License. You may obtain a copy of the License at
5
 
http://www.mozilla.org/MPL/
6
 
 
7
 
Software distributed under the License is distributed on an "AS IS" basis,
8
 
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9
 
the specific language governing rights and limitations under the License.
10
 
 
11
 
Alternatively, the contents of this file may be used under the terms of the
12
 
GNU General Public License Version 2 or later (the "GPL"), in which case
13
 
the provisions of the GPL are applicable instead of those above.
14
 
If you wish to allow use of your version of this file only under the terms
15
 
of the GPL and not to allow others to use your version of this file
16
 
under the MPL, indicate your decision by deleting the provisions above and
17
 
replace them with the notice and other provisions required by the GPL.
18
 
If you do not delete the provisions above, a recipient may use your version
19
 
of this file under either the MPL or the GPL.
20
 
 
21
 
-------------------------------------------------------------------------------}
22
 
unit SynEditTextTabExpander;
23
 
 
24
 
{$I synedit.inc}
25
 
 
26
 
interface
27
 
 
28
 
uses
29
 
  LCLProc, Classes, SysUtils, LazSynEditText, SynEditTextBase;
30
 
 
31
 
type
32
 
 
33
 
  // lines longer than 16383 chars, will be stored as unknown
34
 
  TLineLen = Word;
35
 
  PLineLen = ^TLineLen;
36
 
 
37
 
  { TSynEditStringTabData }
38
 
 
39
 
  TSynEditStringTabData = class(TSynManagedStorageMem)
40
 
  private
41
 
    FRefCount: Integer;
42
 
    function GetLineLen(Index: Integer): TLineLen;
43
 
    procedure SetLineLen(Index: Integer; const AValue: TLineLen);
44
 
  public
45
 
    constructor Create;
46
 
    procedure IncRefCount;
47
 
    procedure DecRefCount;
48
 
    property RefCount: Integer read FRefCount;
49
 
    property LineLen[Index: Integer]: TLineLen read GetLineLen write SetLineLen; default;
50
 
  end;
51
 
 
52
 
{ TSynEditStringTabExpander }
53
 
 
54
 
  TSynEditStringTabExpander = class(TSynEditStringsLinked)
55
 
  private
56
 
    FTabWidth: integer;
57
 
    FIndexOfLongestLine: Integer;
58
 
    FTabData: TSynEditStringTabData;
59
 
    FLastLineHasTab: Boolean; // Last line, parsed by GetPhysicalCharWidths
60
 
    FLastLinePhysLen: Integer;
61
 
    FViewChangeStamp: int64;
62
 
    procedure TextBufferChanged(Sender: TObject);
63
 
    procedure LineCountChanged(Sender: TSynEditStrings; AIndex, ACount : Integer);
64
 
    function ExpandedString(Index: integer): string;
65
 
    function ExpandedStringLength(Index: integer): Integer;
66
 
  protected
67
 
    function GetViewChangeStamp: int64; override;
68
 
    function  GetTabWidth : integer;
69
 
    procedure SetTabWidth(const AValue : integer);
70
 
    function  GetExpandedString(Index: integer): string; override;
71
 
    function  GetLengthOfLongestLine: integer; override;
72
 
    procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
73
 
  public
74
 
    constructor Create(ASynStringSource: TSynEditStrings);
75
 
    destructor Destroy; override;
76
 
 
77
 
    property LengthOfLongestLine: integer read GetLengthOfLongestLine;
78
 
  public
79
 
    property TabWidth: integer read GetTabWidth write SetTabWidth;
80
 
  end;
81
 
 
82
 
 
83
 
implementation
84
 
 
85
 
const
86
 
  // Offset to add to LengthOfLine, if Line has no tabs.
87
 
  // (Length will still be valid if tab-width changes)
88
 
  NO_TAB_IN_LINE_OFFSET = high(TLineLen) div 2;
89
 
  LINE_LEN_UNKNOWN = high(TLineLen);
90
 
  MAX_LINE_LEN_STORED = NO_TAB_IN_LINE_OFFSET - 1;
91
 
 
92
 
function GetHasTabs(pLine: PChar): boolean;
93
 
begin
94
 
  if Assigned(pLine) then begin
95
 
    while (pLine^ <> #0) do begin
96
 
      if (pLine^ = #9) then break;
97
 
      Inc(pLine);
98
 
    end;
99
 
    Result := (pLine^ = #9);
100
 
  end else
101
 
    Result := FALSE;
102
 
end;
103
 
 
104
 
{ TSynEditStringTabData }
105
 
 
106
 
function TSynEditStringTabData.GetLineLen(Index: Integer): TLineLen;
107
 
begin
108
 
  Result := PLineLen(ItemPointer[Index])^;
109
 
end;
110
 
 
111
 
procedure TSynEditStringTabData.SetLineLen(Index: Integer; const AValue: TLineLen);
112
 
begin
113
 
  PLineLen(ItemPointer[Index])^ := AValue;
114
 
end;
115
 
 
116
 
constructor TSynEditStringTabData.Create;
117
 
begin
118
 
  inherited;
119
 
  ItemSize := SizeOf(TLineLen);
120
 
  FRefCount := 1;
121
 
end;
122
 
 
123
 
procedure TSynEditStringTabData.IncRefCount;
124
 
begin
125
 
  inc(FRefCount);
126
 
end;
127
 
 
128
 
procedure TSynEditStringTabData.DecRefCount;
129
 
begin
130
 
  dec(FRefCount);
131
 
end;
132
 
 
133
 
{ TSynEditStringTabExpander }
134
 
 
135
 
constructor TSynEditStringTabExpander.Create(ASynStringSource: TSynEditStrings);
136
 
begin
137
 
  FIndexOfLongestLine := -1;
138
 
  inherited Create(ASynStringSource);
139
 
  TextBufferChanged(nil);
140
 
  TabWidth := 8;
141
 
  fSynStrings.AddChangeHandler(senrLineCount, @LineCountChanged);
142
 
  fSynStrings.AddChangeHandler(senrLineChange, @LineCountChanged);
143
 
  fSynStrings.AddNotifyHandler(senrTextBufferChanged, @TextBufferChanged);
144
 
end;
145
 
 
146
 
destructor TSynEditStringTabExpander.Destroy;
147
 
var
148
 
  Data: TSynEditStringTabData;
149
 
begin
150
 
  Data := TSynEditStringTabData(fSynStrings.Ranges[Self]);
151
 
  if Assigned(Data) then begin
152
 
    Data.DecRefCount;
153
 
    if Data.RefCount = 0 then begin
154
 
      fSynStrings.Ranges[Self] := nil;
155
 
      Data.Free;
156
 
    end;
157
 
  end;
158
 
  fSynStrings.RemoveChangeHandler(senrLineChange, @LineCountChanged);
159
 
  fSynStrings.RemoveChangeHandler(senrLineCount, @LineCountChanged);
160
 
  fSynStrings.RemoveNotifyHandler(senrTextBufferChanged, @TextBufferChanged);
161
 
  inherited Destroy;
162
 
end;
163
 
 
164
 
function TSynEditStringTabExpander.GetTabWidth: integer;
165
 
begin
166
 
  Result := FTabWidth;
167
 
end;
168
 
 
169
 
procedure TSynEditStringTabExpander.SetTabWidth(const AValue: integer);
170
 
var
171
 
  i: integer;
172
 
begin
173
 
  if FTabWidth = AValue then exit;
174
 
 
175
 
  {$PUSH}{$Q-}{$R-}
176
 
  FViewChangeStamp := FViewChangeStamp + 1;
177
 
  {$POP}
178
 
 
179
 
  FTabWidth := AValue;
180
 
  FIndexOfLongestLine := -1;
181
 
  for i := 0 to Count - 1 do
182
 
    if not(FTabData[i] >= NO_TAB_IN_LINE_OFFSET) then
183
 
      FTabData[i] := LINE_LEN_UNKNOWN;
184
 
end;
185
 
 
186
 
function TSynEditStringTabExpander.GetViewChangeStamp: int64;
187
 
begin
188
 
  Result := inherited GetViewChangeStamp;
189
 
  {$PUSH}{$Q-}{$R-}
190
 
  Result := Result + FViewChangeStamp;
191
 
  {$POP}
192
 
end;
193
 
 
194
 
procedure TSynEditStringTabExpander.TextBufferChanged(Sender: TObject);
195
 
var
196
 
  Data: TSynEditStringTabData;
197
 
begin
198
 
  // Using self, instead as class, to register tab-width-data
199
 
  // other shared edits can have different tab-width
200
 
  if (Sender <> nil) and
201
 
     (FTabData = TSynEditStringTabData(NextLines.Ranges[Self]))
202
 
  then
203
 
    exit;
204
 
 
205
 
  if Sender <> nil then begin
206
 
    Data := TSynEditStringTabData(TSynEditStrings(Sender).Ranges[Self]);
207
 
    if Assigned(Data) then begin
208
 
      Data.DecRefCount;
209
 
      if Data.RefCount = 0 then begin
210
 
        TSynEditStrings(Sender).Ranges[Self] := nil;
211
 
        Data.Free;
212
 
      end;
213
 
    end;
214
 
  end;
215
 
  FTabData := TSynEditStringTabData(NextLines.Ranges[Self]);
216
 
  if FTabData = nil then begin
217
 
    FTabData := TSynEditStringTabData.Create;
218
 
    NextLines.Ranges[Self] := FTabData;
219
 
  end
220
 
  else
221
 
    FTabData.IncRefCount;
222
 
  LineCountChanged(TSynEditStrings(Sender), 0, Count);
223
 
end;
224
 
 
225
 
procedure TSynEditStringTabExpander.LineCountChanged(Sender: TSynEditStrings; AIndex, ACount: Integer);
226
 
var
227
 
  i: integer;
228
 
begin
229
 
  FIndexOfLongestLine := -1;
230
 
  for i := AIndex to AIndex + ACount - 1 do
231
 
    FTabData[i] := LINE_LEN_UNKNOWN;
232
 
end;
233
 
 
234
 
function TSynEditStringTabExpander.ExpandedString(Index: integer): string;
235
 
var
236
 
  Line: String;
237
 
  CharWidths: TPhysicalCharWidths;
238
 
  i, j, l: Integer;
239
 
begin
240
 
// this is only used by trimmer.lengthOfLongestLine / which is not called, if a tab module is present
241
 
  Line := fSynStrings[Index];
242
 
  if (Line = '') or (not GetHasTabs(PChar(Line))) then begin
243
 
    Result := Line;
244
 
    // xxx wrong double width // none latin ...
245
 
    //FTabData[Index] := length(Result) + NO_TAB_IN_LINE_OFFSET;
246
 
  end else begin
247
 
    CharWidths := GetPhysicalCharWidths(Pchar(Line), length(Line), Index);
248
 
    l := 0;
249
 
    for i := 0 to length(CharWidths)-1 do
250
 
      l := l + (CharWidths[i] and PCWMask);
251
 
    SetLength(Result, l);
252
 
 
253
 
    l := 1;
254
 
    for i := 1 to length(CharWidths) do begin
255
 
      if Line[i] <> #9 then begin
256
 
        Result[l] := Line[i];
257
 
        inc(l);
258
 
      end else begin
259
 
        for j := 1 to (CharWidths[i-1] and PCWMask) do begin
260
 
          Result[l] := ' ';
261
 
          inc(l);
262
 
        end;
263
 
      end;
264
 
    end;
265
 
    FTabData[Index] := length(Result);
266
 
  end;
267
 
end;
268
 
 
269
 
function TSynEditStringTabExpander.ExpandedStringLength(Index: integer): Integer;
270
 
var
271
 
  Line: String;
272
 
  CharWidths: TPhysicalCharWidths;
273
 
  i: Integer;
274
 
begin
275
 
  Line := fSynStrings[Index];
276
 
  if (Line = '') then begin
277
 
    Result := 0;
278
 
    FTabData[Index] := Result + NO_TAB_IN_LINE_OFFSET;
279
 
  end else begin
280
 
    i := length(Line);
281
 
    SetLength(CharWidths, i);
282
 
    DoGetPhysicalCharWidths(Pchar(Line), i, Index, @CharWidths[0]);
283
 
    Result := 0;
284
 
    for i := 0 to length(CharWidths)-1 do
285
 
      Result := Result + (CharWidths[i] and PCWMask);
286
 
 
287
 
    if FLastLineHasTab then // FLastLineHasTab is set by GetPhysicalCharWidths
288
 
      FTabData[Index] := Result
289
 
    else
290
 
      FTabData[Index] := Result + NO_TAB_IN_LINE_OFFSET;
291
 
  end;
292
 
end;
293
 
 
294
 
function TSynEditStringTabExpander.GetExpandedString(Index: integer): string;
295
 
begin
296
 
  if (Index >= 0) and (Index < Count) then begin
297
 
    if FTabData[Index] >= NO_TAB_IN_LINE_OFFSET then
298
 
      Result := fSynStrings[Index]
299
 
    else
300
 
      Result := ExpandedString(Index);
301
 
  end else
302
 
    Result := '';
303
 
end;
304
 
 
305
 
procedure TSynEditStringTabExpander.DoGetPhysicalCharWidths(Line: PChar;
306
 
  LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
307
 
var
308
 
  HasTab: Boolean;
309
 
  i, j: Integer;
310
 
begin
311
 
  inherited DoGetPhysicalCharWidths(Line, LineLen, Index, PWidths);
312
 
  HasTab := False;
313
 
  j := 0;
314
 
  for i := 0 to LineLen - 1 do begin
315
 
    if (PWidths^ and PCWMask) <> 0 then begin
316
 
      if Line^ = #9 then begin
317
 
        PWidths^ := (FTabWidth - (j mod FTabWidth) and PCWMask) or (PWidths^  and (not PCWMask));
318
 
        HasTab := True;
319
 
      end;
320
 
      j := j + (PWidths^ and PCWMask);
321
 
    end;
322
 
    inc(Line);
323
 
    inc(PWidths);
324
 
  end;
325
 
  FLastLineHasTab := HasTab;
326
 
  FLastLinePhysLen := j;
327
 
end;
328
 
 
329
 
function TSynEditStringTabExpander.GetLengthOfLongestLine: integer;
330
 
var
331
 
  Line: PChar;
332
 
  LineLen: Integer;
333
 
  CharWidths: PPhysicalCharWidth;
334
 
  i, j, m: Integer;
335
 
  Line1, Line2: Integer;
336
 
begin
337
 
  Line1 := 0;
338
 
  Line2 := Count - 1;
339
 
  if (fIndexOfLongestLine >= 0) and (fIndexOfLongestLine < Count) then begin
340
 
    Result := FTabData[fIndexOfLongestLine];
341
 
    if Result <> LINE_LEN_UNKNOWN then begin
342
 
      if Result >= NO_TAB_IN_LINE_OFFSET then Result := Result -  NO_TAB_IN_LINE_OFFSET;
343
 
      exit;
344
 
    end;
345
 
    Line1 := fIndexOfLongestLine;
346
 
    Line2 := fIndexOfLongestLine;
347
 
  end;
348
 
 
349
 
  try
350
 
    Result := 0;
351
 
    m := 0;
352
 
    CharWidths := nil;
353
 
    for i := Line1 to Line2 do begin
354
 
      j := FTabData[i];
355
 
      if j = LINE_LEN_UNKNOWN then begin
356
 
        // embedd a copy of ExpandedStringLength
357
 
        // allows to re-use CharWidths
358
 
        Line := NextLines.GetPChar(i,LineLen); // fSynStrings[i];
359
 
        j := 0;
360
 
        if (LineLen = 0) then begin
361
 
          FTabData[i] := j + NO_TAB_IN_LINE_OFFSET;
362
 
        end else begin
363
 
          if LineLen > m then begin
364
 
            ReAllocMem(CharWidths, LineLen * SizeOf(TPhysicalCharWidth));
365
 
            m := LineLen;
366
 
          end;
367
 
          DoGetPhysicalCharWidths(Line, LineLen, i, CharWidths);
368
 
          j := FLastLinePhysLen;
369
 
 
370
 
          if j > MAX_LINE_LEN_STORED then
371
 
            FTabData[i] := LINE_LEN_UNKNOWN
372
 
          else if FLastLineHasTab then // FLastLineHasTab is set by GetPhysicalCharWidths
373
 
            FTabData[i] := j
374
 
          else
375
 
            FTabData[i] := j + NO_TAB_IN_LINE_OFFSET;
376
 
        end;
377
 
      end
378
 
      else
379
 
      if j >= NO_TAB_IN_LINE_OFFSET then
380
 
        j := j -  NO_TAB_IN_LINE_OFFSET;
381
 
      if j > Result then begin
382
 
        Result := j;
383
 
        fIndexOfLongestLine := i;
384
 
      end;
385
 
    end;
386
 
  finally
387
 
    ReAllocMem(CharWidths, 0);
388
 
  end;
389
 
end;
390
 
 
391
 
end.
392