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

« back to all changes in this revision

Viewing changes to components/synedit/synedittextbuffer.pp

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Paul Gevers
  • Date: 2014-02-22 10:25:57 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20140222102557-ors9d31r84nz31jq
Tags: 1.2~rc2+dfsg-1
[ Abou Al Montacir ]
* New upstream pre-release.
  + Moved ideintf to components directory.
  + Added new package cairocanvas.
* Remove usage of depreciated parameters form of find. (Closes: Bug#724776)
* Bumped standard version to 3.9.5.
* Clean the way handling make files generation and removal.

[ Paul Gevers ]
* Remove nearly obsolete bzip compression for binary packages
  (See https://lists.debian.org/debian-devel/2014/01/msg00542.html)
* Update d/copyright for newly added dir in examples and components
* Update Vcs-* fields with new packaging location
* Update d/watch file to properly (Debian way) change upstreams versions
* Prevent 46MB of package size by sym linking duplicate files
* Patches
  - refresh to remove fuzz
  - add more Lintian found spelling errors
  - new patch to add shbang to two scripts in lazarus-src
* Drop lcl-# from Provides list of lcl-units-#
* Make lazarus-ide-qt4-# an arch all until it really contains stuff
* Make all metapackages arch all as the usecase for arch any doesn't
  seem to warrant the addition archive hit
* Fix permissions of non-scripts in lazarus-src-#

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
If you do not delete the provisions above, a recipient may use your version
28
28
of this file under either the MPL or the GPL.
29
29
 
30
 
$Id: synedittextbuffer.pp 36227 2012-03-22 18:28:03Z martin $
 
30
$Id: synedittextbuffer.pp 39835 2013-01-12 10:47:23Z martin $
31
31
 
32
32
You may retrieve the latest version of this file at the SynEdit home page,
33
33
located at http://SynEdit.SourceForge.net
181
181
    function GetRange(Index: Pointer): TSynManagedStorageMem; override;
182
182
    procedure PutRange(Index: Pointer; const ARange: TSynManagedStorageMem); override;
183
183
    function Get(Index: integer): string; override;
184
 
    function GetCapacity: integer;
185
 
      {$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF}                             //mh 2000-10-18
 
184
    function GetCapacity: integer; override;
186
185
    function GetCount: integer; override;
187
186
    procedure SetCount(const AValue: Integer);
188
187
    function GetObject(Index: integer): TObject; override;
189
188
    procedure Put(Index: integer; const S: string); override;
190
189
    procedure PutObject(Index: integer; AObject: TObject); override;
191
 
    procedure SetCapacity(NewCapacity: integer);
192
 
      {$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF}                             //mh 2000-10-18
 
190
    procedure SetCapacity(NewCapacity: integer); override;
193
191
    procedure SetUpdateState(Updating: Boolean; Sender: TObject); override;
194
192
 
195
193
    procedure UndoEditLinesDelete(LogY, ACount: Integer);
196
194
    procedure IncreaseTextChangeStamp;
197
195
    procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
 
196
    function  LogicPosIsCombining(const AChar: PChar): Boolean; inline;
198
197
 
199
198
    function GetDisplayView: TLazSynDisplayView; override;
200
199
  public
235
234
      write SetFlags;
236
235
    property Modified: Boolean read FModified write SetModified;
237
236
  public
 
237
    // Char bounds // 1 based (1 is the 1st char in the line)
 
238
    function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer;
 
239
                              AFlags: LPosFlags = []): Integer; override;
 
240
    function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
 
241
                              AFlags: LPosFlags = []): Boolean; override;
 
242
    function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
 
243
                                  AFlags: LPosFlags = []): Integer; override;
238
244
    property UndoList: TSynEditUndoList read GetUndoList write fUndoList;
239
245
    property RedoList: TSynEditUndoList read GetRedoList write fRedoList;
240
246
    procedure EditInsert(LogX, LogY: Integer; AText: String); override;
241
247
    function  EditDelete(LogX, LogY, ByteLen: Integer): String; override;
 
248
    function  EditReplace(LogX, LogY, ByteLen: Integer; AText: String): String; override;
242
249
    procedure EditLineBreak(LogX, LogY: Integer); override;
243
250
    procedure EditLineJoin(LogY: Integer; FillText: String = ''); override;
244
251
    procedure EditLinesInsert(LogY, ACount: Integer; AText: String = ''); override;
254
261
 
255
262
implementation
256
263
 
257
 
{$IFNDEF FPC}
258
 
  {$IFDEF SYN_COMPILER_3_UP}
259
 
resourcestring
260
 
  {$ELSE}
261
 
const
262
 
  {$ENDIF}
263
 
{$ELSE}
264
 
const
265
 
{$ENDIF}
 
264
const
266
265
  SListIndexOutOfBounds = 'Invalid stringlist index %d';
267
266
 
268
267
type
550
549
 
551
550
  FAttachedSynEditList := TFPList.Create;
552
551
  FUndoList := TSynEditUndoList.Create;
553
 
  fUndoList.OnAddedUndo := {$IFDEF FPC}@{$ENDIF}UndoRedoAdded;
 
552
  fUndoList.OnAddedUndo := @UndoRedoAdded;
554
553
  FRedoList := TSynEditUndoList.Create;
555
 
  fRedoList.OnAddedUndo := {$IFDEF FPC}@{$ENDIF}UndoRedoAdded;
 
554
  fRedoList.OnAddedUndo := @UndoRedoAdded;
556
555
  FIsUndoing := False;
557
556
  FIsRedoing := False;
558
557
  FModified := False;
822
821
procedure TSynEditStringList.DoGetPhysicalCharWidths(Line: PChar;
823
822
  LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
824
823
var
825
 
  i, j: Integer;
 
824
  i: Integer;
826
825
begin
827
826
  if not IsUtf8 then begin
828
827
    for i := 0 to LineLen-1 do
830
829
    exit;
831
830
  end;
832
831
 
833
 
  j := 0;
834
832
  for i := 0 to LineLen-1 do begin
835
 
    if j = 0 then begin
836
 
      PWidths^ := 1;
837
 
      j := UTF8CharacterLength(Line);
838
 
      inc(Line, j);
839
 
    end else begin
840
 
      PWidths^ := 0;
 
833
    case Line^ of
 
834
      #$00..#$7F:
 
835
        PWidths^ := 1;
 
836
      #$80..#$BF:
 
837
        PWidths^ := 0;
 
838
      else
 
839
        if LogicPosIsCombining(Line) then
 
840
          PWidths^ := 0
 
841
        else
 
842
          PWidths^ := 1;
 
843
      //#$CC:
 
844
      //  if ((Line+1)^ in [#$80..#$FF]) and (i>0)
 
845
      //  then PWidths^ := 0  // Combining Diacritical Marks (belongs to previos char) 0300-036F
 
846
      //  else PWidths^ := 1;
 
847
      //#$CD:
 
848
      //  if ((Line+1)^ in [#$00..#$AF]) and (i>0)
 
849
      //  then PWidths^ := 0  // Combining Diacritical Marks
 
850
      //  else PWidths^ := 1;
 
851
      //#$E1:
 
852
      //  if (((Line+1)^ = #$B7) and ((Line+2)^ in [#$80..#$BF])) and (i>0)
 
853
      //  then PWidths^ := 0  // Combining Diacritical Marks Supplement 1DC0-1DFF
 
854
      //  else PWidths^ := 1;
 
855
      //#$E2:
 
856
      //  if (((Line+1)^ = #$83) and ((Line+2)^ in [#$90..#$FF])) and (i>0)
 
857
      //  then PWidths^ := 0  // Combining Diacritical Marks for Symbols 20D0-20FF
 
858
      //  else PWidths^ := 1;
 
859
      //#$EF:
 
860
      //  if (((Line+1)^ = #$B8) and ((Line+2)^ in [#$A0..#$AF])) and (i>0)
 
861
      //  then PWidths^ := 0  // Combining half Marks FE20-FE2F
 
862
      //  else PWidths^ := 1;
 
863
      //else
 
864
      //  PWidths^ := 1;
841
865
    end;
842
 
    dec(j);
843
866
    inc(PWidths);
 
867
    inc(Line);
844
868
  end;
845
869
 
846
 
  //j := 0;
847
 
  //for i := 0 to LineLen-1 do begin
848
 
  //  if j = 0 then begin
849
 
  //    j := UTF8CharacterLength(Line);
850
 
  //    if (j=2) and
851
 
  //       ( ( (Line^ = #$CC) and ((Line+1)^ in [#$80..#$FF]) ) or
852
 
  //         ( (Line^ = #$CD) and ((Line+1)^ in [#$00..#$AF]) ) )
853
 
  //    then
854
 
  //      PWidths^ := 0 // Combining Diacritical Marks
855
 
  //    else
856
 
  //      PWidths^ := 1;
857
 
  //    inc(Line, j);
858
 
  //  end else begin
859
 
  //    PWidths^ := 0;
860
 
  //  end;
861
 
  //  dec(j);
862
 
  //  inc(PWidths);
863
 
  //end;
 
870
end;
 
871
 
 
872
function TSynEditStringList.LogicPosIsCombining(const AChar: PChar): Boolean;
 
873
begin
 
874
  Result := (
 
875
   ( (AChar[0] = #$CC) ) or                                                       // Combining Diacritical Marks (belongs to previos char) 0300-036F
 
876
   ( (AChar[0] = #$CD) and (AChar[1] in [#$80..#$AF]) ) or                        // Combining Diacritical Marks
 
877
   ( (AChar[0] = #$D8) and (AChar[1] in [#$90..#$9A]) ) or                        // Arabic 0610 (d890)..061A (d89a)
 
878
   ( (AChar[0] = #$D9) and (AChar[1] in [#$8b..#$9f, #$B0]) ) or                  // Arabic 064B (d98b)..065F (d99f) // 0670 (d9b0)
 
879
   ( (AChar[0] = #$DB) and (AChar[1] in [#$96..#$9C, #$9F..#$A4, #$A7..#$A8, #$AA..#$AD]) ) or // Arabic 06D6 (db96)..  .. ..06EA (dbaa)
 
880
   ( (AChar[0] = #$E0) and (AChar[1] = #$A3) and (AChar[2] in [#$A4..#$BE]) ) or  // Arabic 08E4 (e0a3a4) ..08FE (e0a3be)
 
881
   ( (AChar[0] = #$E1) and (AChar[1] = #$B7) ) or                                 // Combining Diacritical Marks Supplement 1DC0-1DFF
 
882
   ( (AChar[0] = #$E2) and (AChar[1] = #$83) and (AChar[2] in [#$90..#$FF]) ) or  // Combining Diacritical Marks for Symbols 20D0-20FF
 
883
   ( (AChar[0] = #$EF) and (AChar[1] = #$B8) and (AChar[2] in [#$A0..#$AF]) )     // Combining half Marks FE20-FE2F
 
884
  );
864
885
end;
865
886
 
866
887
function TSynEditStringList.GetDisplayView: TLazSynDisplayView;
1044
1065
  end;
1045
1066
end;
1046
1067
 
 
1068
function TSynEditStringList.LogicPosAddChars(const ALine: String; ALogicalPos,
 
1069
  ACount: integer; AFlags: LPosFlags): Integer;
 
1070
var
 
1071
  l: Integer;
 
1072
begin
 
1073
  // UTF8 handing of chars
 
1074
  Result := ALogicalPos;
 
1075
  l := length(ALine);
 
1076
  if ACount > 0 then begin;
 
1077
    while (Result < l) and (ACount > 0) do begin
 
1078
      inc(Result);
 
1079
      if (ALine[Result] in [#0..#127, #192..#255]) and
 
1080
         ( (lpStopAtCodePoint in AFlags) or (not LogicPosIsCombining(@ALine[Result])) )
 
1081
      then
 
1082
        dec(ACount);
 
1083
    end;
 
1084
    if lpAllowPastEOL in AFlags then
 
1085
      Result := Result + ACount;
 
1086
 
 
1087
    if (Result <= l) then
 
1088
      while (Result > 1) and
 
1089
            ( (not(ALine[Result] in [#0..#127, #192..#255])) or
 
1090
              ( (not(lpStopAtCodePoint in AFlags)) and LogicPosIsCombining(@ALine[Result]) )
 
1091
            )
 
1092
      do
 
1093
        dec(Result);
 
1094
  end else begin
 
1095
    while (Result > 1) and (ACount < 0) do begin
 
1096
      dec(Result);
 
1097
      if (Result > l) or (Result = 1) or
 
1098
         ( (ALine[Result] in [#0..#127, #192..#255]) and
 
1099
           ( (lpStopAtCodePoint in AFlags) or (not LogicPosIsCombining(@ALine[Result])) )
 
1100
         )
 
1101
      then
 
1102
        inc(ACount);
 
1103
    end;
 
1104
  end;
 
1105
end;
 
1106
 
 
1107
function TSynEditStringList.LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
 
1108
  AFlags: LPosFlags): Boolean;
 
1109
begin
 
1110
  // UTF8 handing of chars
 
1111
  Result := (lpAllowPastEol in AFlags) and (ALogicalPos >= 1);
 
1112
  if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit;
 
1113
  Result := ALine[ALogicalPos] in [#0..#127, #192..#255];
 
1114
 
 
1115
  if Result then
 
1116
    Result := (ALogicalPos = 1) or
 
1117
              (lpStopAtCodePoint in AFlags) or
 
1118
              (not LogicPosIsCombining(@ALine[ALogicalPos]));
 
1119
end;
 
1120
 
 
1121
function TSynEditStringList.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
 
1122
  AFlags: LPosFlags): Integer;
 
1123
begin
 
1124
  // UTF8 handing of chars
 
1125
  Result := ALogicalPos;
 
1126
  if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit;
 
1127
 
 
1128
  if lpAdjustToNext in AFlags then begin
 
1129
    while (Result <= length(ALine)) and
 
1130
      ( (not(ALine[Result] in [#0..#127, #192..#255])) or
 
1131
        ((Result <> 1) and
 
1132
         (not(lpStopAtCodePoint in AFlags)) and LogicPosIsCombining(@ALine[Result])
 
1133
        )
 
1134
      )
 
1135
    do
 
1136
      inc(Result);
 
1137
  end;
 
1138
 
 
1139
  if (not (lpAllowPastEol in AFlags)) and (Result > length(ALine)) then
 
1140
    Result := length(ALine); // + 1
 
1141
  if (Result > length(ALine)) then exit;
 
1142
 
 
1143
  while (Result > 1) and
 
1144
    ( (not(ALine[Result] in [#0..#127, #192..#255])) or
 
1145
      ( (not(lpStopAtCodePoint in AFlags)) and LogicPosIsCombining(@ALine[Result]) )
 
1146
    )
 
1147
  do
 
1148
    dec(Result);
 
1149
end;
 
1150
 
1047
1151
procedure TSynEditStringList.MarkModified(AFirst, ALast: Integer);
1048
1152
var
1049
1153
  Index: Integer;
1050
1154
begin
1051
1155
  for Index := AFirst - 1 to ALast - 1 do
1052
 
    if (Index >= 0) and (Index < Count) then
 
1156
    if (Index >= 0) or (Index < Count) then
1053
1157
      Flags[Index] := Flags[Index] + [sfModified] - [sfSaved];
1054
1158
end;
1055
1159
 
1127
1231
    LogX := Length(s) + 1;
1128
1232
  end;
1129
1233
  Strings[LogY - 1] := copy(s,1, LogX - 1) + AText + copy(s, LogX, length(s));
1130
 
  CurUndoList.AddChange(TSynEditUndoTxtInsert.Create(LogX, LogY, Length(AText)));
 
1234
  if AText <> '' then
 
1235
    CurUndoList.AddChange(TSynEditUndoTxtInsert.Create(LogX, LogY, Length(AText)));
1131
1236
  MarkModified(LogY, LogY);
1132
1237
  SendNotification(senrEditAction, self, LogY, 0, LogX, length(AText), AText);
1133
1238
  DecIsInEditAction;
1137
1242
var
1138
1243
  s: string;
1139
1244
begin
 
1245
  if ByteLen <= 0 then
 
1246
    exit;
1140
1247
  IncIsInEditAction;
1141
1248
  s := Strings[LogY - 1];
1142
1249
  if LogX - 1 > Length(s) then
1143
1250
    exit;
1144
1251
  Result := copy(s, LogX, ByteLen);
1145
1252
  Strings[LogY - 1] := copy(s,1, LogX - 1) + copy(s, LogX +  ByteLen, length(s));
1146
 
  CurUndoList.AddChange(TSynEditUndoTxtDelete.Create(LogX, LogY, Result));
1147
 
  MarkModified(LogY, LogY);
1148
 
  SendNotification(senrEditAction, self, LogY, 0, LogX, -ByteLen, '');
 
1253
  if Result <> '' then
 
1254
    CurUndoList.AddChange(TSynEditUndoTxtDelete.Create(LogX, LogY, Result));
 
1255
  MarkModified(LogY, LogY);
 
1256
  SendNotification(senrEditAction, self, LogY, 0, LogX, -ByteLen, '');
 
1257
  DecIsInEditAction;
 
1258
end;
 
1259
 
 
1260
function TSynEditStringList.EditReplace(LogX, LogY, ByteLen: Integer; AText: String): String;
 
1261
var
 
1262
  s, s2: string;
 
1263
begin
 
1264
  IncIsInEditAction;
 
1265
 
 
1266
  if ByteLen <= 0 then
 
1267
    ByteLen := 0;
 
1268
  s := Strings[LogY - 1];
 
1269
  if LogX - 1 > Length(s) then begin
 
1270
    AText := StringOfChar(' ', LogX - 1 - Length(s)) + AText;
 
1271
    LogX := Length(s) + 1;
 
1272
  end;
 
1273
 
 
1274
  if LogX - 1 + ByteLen > Length(s) then
 
1275
    ByteLen := Length(s) - (LogX-1);
 
1276
  Result := copy(s, LogX, ByteLen);
 
1277
 
 
1278
  SetLength(s2, Length(s) - ByteLen + Length(AText));
 
1279
  if LogX > 1 then
 
1280
    system.Move(s[1], s2[1], LogX-1);
 
1281
  if AText <> '' then
 
1282
    system.Move(AText[1], s2[LogX], Length(AText));
 
1283
  if Length(s)-(LogX-1)-ByteLen > 0 then
 
1284
    system.Move(s[LogX+ByteLen], s2[LogX+Length(AText)], Length(s)-(LogX-1)-ByteLen);
 
1285
  Strings[LogY - 1] := s2;
 
1286
  //Strings[LogY - 1] := copy(s,1, LogX - 1) + AText + copy(s, LogX +  ByteLen, length(s));
 
1287
 
 
1288
  if Result <> '' then
 
1289
    CurUndoList.AddChange(TSynEditUndoTxtDelete.Create(LogX, LogY, Result));
 
1290
  if AText <> '' then
 
1291
    CurUndoList.AddChange(TSynEditUndoTxtInsert.Create(LogX, LogY, Length(AText)));
 
1292
 
 
1293
  MarkModified(LogY, LogY);
 
1294
  SendNotification(senrEditAction, self, LogY, 0, LogX, -ByteLen, '');
 
1295
  SendNotification(senrEditAction, self, LogY, 0, LogX, length(AText), AText);
1149
1296
  DecIsInEditAction;
1150
1297
end;
1151
1298