- Timestamp:
- Mar 1, 2019, 8:09:20 PM (6 years ago)
- Location:
- trunk/Components
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Components/RichTextDocumentUnit.pas
r420 r421 142 142 function IsDBCSSecondByte( const CharByte: Byte; 143 143 const Codepage: LongInt ): boolean; 144 145 // Adjusts the character position to the beginning or end of any multi-byte146 // character.147 procedure MoveToCharacterBoundary( TextPointer: PChar;148 var Index: LongInt;149 var Offset: LongInt;150 RowStart: LongInt;151 Codepage: LongInt;152 Advance: Boolean; );153 144 // 154 145 // ALT ends … … 850 841 P := NextP; 851 842 end; 843 844 Q[ 0 ] := #0; // ALT test 845 852 846 result := PCharDiff( Q, Buffer ); 853 847 end; … … 960 954 end; 961 955 end; 962 963 // Given a string position, check to see if it's in the middle of a double-byte964 // character; if so, move back by one position so that we're sitting immediately965 // in front of the double-byte character instead.966 //967 procedure MoveToCharacterBoundary( TextPointer: PChar;968 var Index: LongInt;969 var Offset: LongInt;970 RowStart: LongInt;971 Codepage: LongInt;972 Advance: Boolean; );973 var974 P: PChar;975 NextP: PChar;976 Element: TTextElement;977 InsideDBC: boolean;978 begin979 if ( Offset > 0 ) and980 ( Codepage in [ 932, 936, 942, 943, 949, 950, 1381, 1386 ]) then981 begin982 P := TextPointer + RowStart;983 InsideDBC := false;984 985 // Because parsing of byte types is state based, we must verify every986 // byte's type from the beginning of the line until we reach the target.987 while RowStart < Index do988 begin989 Element := ExtractNextTextElement( P, NextP );990 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, Codepage );991 P := NextP;992 inc( RowStart );993 end;994 995 // We've reached the target position, and the current parsing state should996 // be correctly set. So now we can safely determine the target byte's type.997 Element := ExtractNextTextElement( P, NextP );998 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, Codepage );999 if InsideDBC then1000 begin1001 // If this the first byte of a double byte character, move position by one.1002 if Advance Then1003 Begin1004 inc( Index );1005 inc( Offset );1006 End1007 Else1008 Begin1009 dec( Index );1010 dec( Offset );1011 End1012 end;1013 end;1014 1015 end;1016 956 // 1017 957 // ALT ends -
trunk/Components/RichTextLayoutUnit.pas
r420 r421 75 75 76 76 Codepage: ULong; // ALT 77 78 // TEMP (ALT) 79 DebugLog: TextFile; 80 // TEMP (ALT) 81 77 82 78 83 // Drawing functions … … 121 126 Function GetTextEnd: longint; 122 127 128 // ALT 129 Function FindCharacterBoundary( TextPointer: PChar; 130 var Index: LongInt; 131 Advance: Boolean; ): LongInt; 132 123 133 Public 124 134 constructor Create( Text: PChar; … … 177 187 FRichTextSettings := RichTextSettings; 178 188 189 { 190 AssignFile( DebugLog, 'parse.txt'); 191 ReWrite( DebugLog ); 192 WriteLn( DebugLog, 'Opened log for writing.'); 193 } 194 179 195 FImages := Images; 180 196 … … 212 228 FreeMem( Flines, FAllocatedNumLines * sizeof( TLayoutLine ) ); 213 229 FLinks.Destroy; 230 231 { 232 // TEMP (ALT) 233 WriteLn( DebugLog, '============================='); 234 CloseFile( DebugLog ); 235 // TEMP (ALT) 236 } 214 237 215 238 Inherited Destroy; … … 932 955 Style: TTextDrawStyle; 933 956 NewMarginX: longint; 957 InsideDBC: Boolean; // ALT 934 958 begin 935 959 Line := FLines[ LineIndex ]; … … 941 965 942 966 StartedDrawing := false; 967 InsideDBC := false; // ALT 943 968 944 969 while P < EndP do 945 970 begin 946 971 Element := ExtractNextTextElement( P, NextP ); 972 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, Codepage ); // ALT 947 973 948 974 case Element.ElementType of 949 975 teWordBreak, 950 976 teText, 977 teWrapChar, // ALT 978 teLeadByte, // ALT 951 979 teImage: 952 980 begin … … 967 995 968 996 // Now find out how wide the thing is 969 inc( X, GetElementWidth( Element ) ); 970 971 end; 997 if (( Element.ElementType = teLeadByte ) And ( EndP > P )) then // ALT 998 inc( X, FFontManager.CJKTextWidth( 2, P )) 999 else 1000 inc( X, GetElementWidth( Element ) ); 1001 1002 end; 1003 1004 // teSecondByte: do nothing and continue to next byte (ALT) 972 1005 973 1006 teStyle: … … 1205 1238 end; 1206 1239 1240 // ALT begins 1241 // 1242 // Given a text position, check if it's in the middle of a double-byte 1243 // character; if so, shift the position one byte forwards or backwards. 1244 // 1245 function TRichTextLayout.FindCharacterBoundary( TextPointer: PChar; // pointer to text 1246 var Index: LongInt; // position (byte index) within text 1247 Advance: Boolean; // whether to adjust position forward 1248 ): LongInt; // returns new offset within line 1249 var 1250 P: PChar; // pointer to current character in string 1251 NextP: PChar; // pointer to the following character, if any 1252 Element: TTextElement; // element data about the current character 1253 CurrentPos: LongInt; // index of first character of line 1254 Line: LongInt; // current line number 1255 Offset: LongInt; // offset position within current line 1256 InsideDBC: boolean; 1257 begin 1258 if ( Offset > 0 ) and 1259 ( Codepage in [ 932, 936, 942, 943, 949, 950, 1381, 1386 ]) then 1260 begin 1261 // Because parsing of byte types is state based, we must verify every 1262 // byte's type from the beginning of the line until we reach the target. 1263 // 1264 Line := GetLineFromCharIndex( Index ); 1265 CurrentPos := GetCharIndex( FLines[ Line ].Text ); 1266 P := TextPointer + CurrentPos; 1267 Offset := 0; 1268 InsideDBC := false; 1269 1270 while CurrentPos < Index do 1271 begin 1272 Element := ExtractNextTextElement( P, NextP ); 1273 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, Codepage ); 1274 CurrentPos := CurrentPos + PCharPointerDiff( NextP, P ); 1275 Offset := Offset + PCharPointerDiff( NextP, P ); 1276 P := NextP; 1277 end; 1278 1279 // We've reached the target position, and the current parsing state should 1280 // be correctly set. So now we can safely determine the target byte's type. 1281 // 1282 Element := ExtractNextTextElement( P, NextP ); 1283 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, Codepage ); 1284 1285 if Element.ElementType = teSecondByte then 1286 begin 1287 // If we are inside a a double byte character, shift position by one. 1288 if Advance Then 1289 Begin 1290 inc( Index ); 1291 inc( Offset ); 1292 End 1293 Else 1294 Begin 1295 dec( Index ); 1296 dec( Offset ); 1297 End 1298 end; 1299 1300 end; 1301 1302 Result := Offset; 1303 end; 1304 // 1305 // ALT ends 1306 1207 1307 Initialization 1208 1308 End. -
trunk/Components/RichTextView.PAS
r420 r421 87 87 FCursorRow: longint; 88 88 FCursorOffset: longint; 89 90 FCursorMoveRight: boolean; // ALT - TRUE if cursor is moving to the right 89 91 90 92 FSelectionStart: longint; … … 460 462 Procedure TRichTextView.SetSelectionStartInternal( SelectionStart: longint ); 461 463 var 464 Line: longint; // ALT 462 465 Offset: longint; // ALT 463 466 begin … … 470 473 ClearSelection; 471 474 472 // ALT 473 Offset := FCursorOffset; 474 MoveToCharacterBoundary( FText, SelectionStart, FCursorOffset, Offset, FLayout.Codepage, false ); 475 // Should already be ensured by this point? 476 // FLayout.FindCharacterBoundary( FText, SelectionStart, false ); // ALT 475 477 476 478 FSelectionStart := SelectionStart; … … 485 487 StartRedrawLine: longint; 486 488 EndRedrawLine: longint; 487 Offset: longint; // ALT 489 Offset: longint; // ALT 490 Line: longint; // ALT 488 491 OldClip: TRect; 489 492 begin … … 491 494 exit; 492 495 493 // ALT 494 Offset := FCursorOffset; 495 MoveToCharacterBoundary( FText, SelectionEnd, FCursorOffset, Offset, FLayout.Codepage, false ); 496 // Should already be ensured by this point? 497 // FLayout.FindCharacterBoundary( FText, SelectionEnd, false ); // ALT 496 498 497 499 if FSelectionStart = -1 then … … 955 957 Offset, 956 958 Link ); 959 957 960 end; 958 961 … … 1257 1260 // ALT - move to nearest character boundary 1258 1261 Index := FLayout.GetCharIndex( Line.Text ) + FCursorOffset; 1259 RowStart := FLayout.GetCharIndex( Line.Text ); 1260 MoveToCharacterBoundary( FText, Index, FCursorOffset, RowStart, FLayout.Codepage, false ); 1262 1263 FLayout.FindCharacterBoundary( FText, Index, FCursorMoveRight ); 1264 FCursorOffset := FLayout.GetOffsetFromCharIndex( Index, CursorRow ); 1265 FCursorMoveRight := false; 1266 // ALT 1261 1267 1262 1268 FLayout.GetXFromOffset( FCursorOffset, CursorRow, X ); … … 1998 2004 Row: longint; 1999 2005 begin 2006 FCursorMoveRight := false; // ALT 2007 2000 2008 if SelectionSet then 2001 2009 begin … … 2037 2045 PreserveSelection: boolean ); 2038 2046 var 2039 // P: PChar; // ALT2040 // NextP: PChar; // ALT2041 // Element: TTextElement; // ALT2042 // InsideDBC: boolean; // ALT2043 2047 RowStart: longint; // ALT 2044 2048 MoveRight: boolean; // ALT … … 2048 2052 2049 2053 Index := FLayout.GetCharIndex( FLayout.FLines[ Row ].Text ) + Offset; 2050 2051 // ALT2052 {2053 if ( Offset > 0 ) and2054 ( FLayout.Codepage in [ 932, 936, 942, 943, 949, 950, 1381, 1386 ]) then2055 begin2056 RowStart := FLayout.GetCharIndex( FLayout.FLines[ Row ].Text );2057 P := FText + RowStart;2058 InsideDBC := false;2059 while RowStart < Index do2060 begin2061 Element := ExtractNextTextElement( P, NextP );2062 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, FLayout.Codepage );2063 P := NextP;2064 inc( RowStart );2065 end;2066 Element := ExtractNextTextElement( P, NextP );2067 CheckSpecialElementType( Element.Character, Element.ElementType, InsideDBC, FLayout.Codepage );2068 if InsideDBC then2069 begin2070 dec( Index );2071 dec( Offset );2072 end;2073 end;2074 }2075 2076 2054 RowStart := FLayout.GetCharIndex( FLayout.FLines[ Row ].Text ); 2077 2055 2078 // ALT 2079 if Offset = ( FCursorOffset + 1 ) then 2080 MoveRight := true 2081 else 2082 MoveRight := false; 2083 MoveToCharacterBoundary( FText, Index, Offset, RowStart, FLayout.Codepage, MoveRight ); 2084 2085 FCursorOffset := Offset; 2056 Offset := FLayout.FindCharacterBoundary( FText, Index, FCursorMoveRight ); // ALT 2057 FCursorOffset := FLayout.GetOffsetFromCharIndex( Index, Row ); 2086 2058 FCursorRow := Row; 2087 2059 … … 2106 2078 Line: TLayoutLine; 2107 2079 begin 2080 FCursorMoveRight := true; 2108 2081 P := FText + CursorIndex; 2109 2082 … … 2423 2396 begin 2424 2397 CursorVisible := FSelectionStart <> -1; 2398 FCursorMoveRight := false; 2425 2399 2426 2400 Case KeyCode of
Note:
See TracChangeset
for help on using the changeset viewer.