Ignore:
Timestamp:
Mar 1, 2019, 8:09:20 PM (6 years ago)
Author:
ataylor
Message:

DBCS character boundary detection for cursor positioning logic.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Components/RichTextDocumentUnit.pas

    r420 r421  
    142142function IsDBCSSecondByte( const CharByte: Byte;
    143143                           const Codepage: LongInt ): boolean;
    144 
    145 // Adjusts the character position to the beginning or end of any multi-byte
    146 // character.
    147 procedure MoveToCharacterBoundary(     TextPointer: PChar;
    148                                    var Index:       LongInt;
    149                                    var Offset:      LongInt;
    150                                        RowStart:    LongInt;
    151                                        Codepage:    LongInt;
    152                                        Advance:     Boolean; );
    153144//
    154145// ALT ends
     
    850841    P := NextP;
    851842  end;
     843
     844  Q[ 0 ] := #0;         // ALT test
     845
    852846  result := PCharDiff( Q, Buffer );
    853847end;
     
    960954    end;
    961955end;
    962 
    963 // Given a string position, check to see if it's in the middle of a double-byte
    964 // character; if so, move back by one position so that we're sitting immediately
    965 // 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 var
    974   P:         PChar;
    975   NextP:     PChar;
    976   Element:   TTextElement;
    977   InsideDBC: boolean;
    978 begin
    979   if ( Offset > 0 ) and
    980      ( Codepage in [ 932, 936, 942, 943, 949, 950, 1381, 1386 ]) then
    981   begin
    982     P := TextPointer + RowStart;
    983     InsideDBC := false;
    984 
    985     // Because parsing of byte types is state based, we must verify every
    986     // byte's type from the beginning of the line until we reach the target.
    987     while RowStart < Index do
    988     begin
    989       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 should
    996     // 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 then
    1000     begin
    1001       // If this the first byte of a double byte character, move position by one.
    1002       if Advance Then
    1003       Begin
    1004         inc( Index );
    1005         inc( Offset );
    1006       End
    1007       Else
    1008       Begin
    1009         dec( Index );
    1010         dec( Offset );
    1011       End
    1012     end;
    1013   end;
    1014 
    1015 end;
    1016956//
    1017957// ALT ends
Note: See TracChangeset for help on using the changeset viewer.