mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 17:49:09 +02:00
* fixes to bidi algo and vinsert
This commit is contained in:
parent
64e2663c5c
commit
d9ce3626e5
@ -48,9 +48,13 @@ function VPos(UTF8Char:PChar; Len:integer; BytePos:integer):Cardinal;
|
|||||||
function VCharOf(UTF8Str:TUTF8String; vp:Integer; dir:TDirection):TUTF8Char;
|
function VCharOf(UTF8Str:TUTF8String; vp:Integer; dir:TDirection):TUTF8Char;
|
||||||
{Inserts a string into an other paying attention of RTL/LTR direction}
|
{Inserts a string into an other paying attention of RTL/LTR direction}
|
||||||
procedure VInsert(const Src:TUTF8String; var Dest:TUTF8String; vp:Integer; pDir:TDirection);
|
procedure VInsert(const Src:TUTF8String; var Dest:TUTF8String; vp:Integer; pDir:TDirection);
|
||||||
|
{Deletes a string into an other paying attention of RTL/LTR direction}
|
||||||
|
procedure VDelete(var str:TUTF8String; vp, len:Integer; pDir:TDirection);
|
||||||
{****************************Helper routines***********************************}
|
{****************************Helper routines***********************************}
|
||||||
{Returns direction of a character}
|
{Returns direction of a character}
|
||||||
function DirectionOf(UTF8Char:TUTF8Char):TDirection;
|
function DirectionOf(UTF8Char:TUTF8Char):TDirection;
|
||||||
|
{Returns contextual direction of caracter in a string}
|
||||||
|
function DirectionOf(UTF8String:TUTF8String; lp:Integer; pDir:TDirection):TDirection;
|
||||||
{Inserts a char as if it was typed using keyboard in the most user friendly way.
|
{Inserts a char as if it was typed using keyboard in the most user friendly way.
|
||||||
Returns the new cursor position after insersion depending on the new visual text}
|
Returns the new cursor position after insersion depending on the new visual text}
|
||||||
function InsertChar(Src:TUTF8Char; var Dest:TUTF8String; vp:Integer; pDir:TDirection):Integer;
|
function InsertChar(Src:TUTF8Char; var Dest:TUTF8String; vp:Integer; pDir:TDirection):Integer;
|
||||||
@ -211,7 +215,6 @@ var
|
|||||||
i:integer;
|
i:integer;
|
||||||
begin
|
begin
|
||||||
v2l := VisualToLogical(UTF8Str, pDir);
|
v2l := VisualToLogical(UTF8Str, pDir);
|
||||||
for i:= 0 to v2l[0] do Write(v2l[i],' ');writeln('vp=',vp,' v2l[vp]=',v2l[vp]);
|
|
||||||
if vp <= v2l[0]
|
if vp <= v2l[0]
|
||||||
then
|
then
|
||||||
Result := v2l[vp]
|
Result := v2l[vp]
|
||||||
@ -224,8 +227,11 @@ begin
|
|||||||
if lp > Length(UTF8String)
|
if lp > Length(UTF8String)
|
||||||
then
|
then
|
||||||
Exit('');
|
Exit('');
|
||||||
while(lp > 0) and ((Ord(UTF8String[lp]) and $F0) = $80) do
|
while(lp > 0) and ((Ord(UTF8String[lp]) and $F0) in [$80..$B0]) do
|
||||||
|
begin
|
||||||
|
writeln(lp,' ',HexStr(Ord(UTF8String[lp]),2),'!',HexStr(Ord(UTF8String[lp]) and $F0,2));
|
||||||
Dec(lp);
|
Dec(lp);
|
||||||
|
end;
|
||||||
if lp = 0
|
if lp = 0
|
||||||
then
|
then
|
||||||
Exit('');
|
Exit('');
|
||||||
@ -291,6 +297,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function DirectionOf(UTF8String:TUTF8String; lp:Integer; pDir:TDirection):TDirection;
|
||||||
|
var
|
||||||
|
c:TUTF8Char;
|
||||||
|
begin
|
||||||
|
c := LCharOf(UTF8String, lp);
|
||||||
|
Result := DirectionOf(c);
|
||||||
|
while(lp > 1) and (Result = drNONE)do
|
||||||
|
begin
|
||||||
|
c := LCharOf(UTF8String, lp - 1);
|
||||||
|
Result := DirectionOf(c);
|
||||||
|
lp := lp - Length(c);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function VisualToLogical(const UTF8String:TUTF8String; pDir:TDirection):TVisualToLogical;
|
function VisualToLogical(const UTF8String:TUTF8String; pDir:TDirection):TVisualToLogical;
|
||||||
procedure Insert(value:Byte; var v2l:TVisualToLogical; InsPos:Byte);
|
procedure Insert(value:Byte; var v2l:TVisualToLogical; InsPos:Byte);
|
||||||
var
|
var
|
||||||
@ -318,9 +338,8 @@ begin
|
|||||||
while lp <= Length(UTF8String) do
|
while lp <= Length(UTF8String) do
|
||||||
begin
|
begin
|
||||||
Character := LCharOf(UTF8String, lp);
|
Character := LCharOf(UTF8String, lp);
|
||||||
cDir := DirectionOf(Character);
|
cDir := DirectionOf(UTF8String, lp, pDir);
|
||||||
Inc(Result[0]);
|
Inc(Result[0]);
|
||||||
WriteLn('lpos=',lp,' vpos=',vp,' cDir=',Byte(cDir));
|
|
||||||
case cDir of
|
case cDir of
|
||||||
drRTL:
|
drRTL:
|
||||||
begin
|
begin
|
||||||
@ -332,16 +351,9 @@ begin
|
|||||||
vp := Result[0];
|
vp := Result[0];
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
case pDir of
|
vp := Result[0];
|
||||||
drRTL:;
|
|
||||||
drLTR:
|
|
||||||
vp := Result[0];
|
|
||||||
else
|
|
||||||
vp := vp;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
Insert(lp, Result, vp);
|
Insert(lp, Result, vp);
|
||||||
for i := 1 to Result[0] do Write('v2l[',i,']=',Result[vp],'/',lp);
|
|
||||||
Inc(lp, Length(Character));
|
Inc(lp, Length(Character));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -349,47 +361,48 @@ end;
|
|||||||
function InsertChar(Src:TUTF8Char; var Dest:TUTF8String; vp:Integer; pDir:TDirection):Integer;
|
function InsertChar(Src:TUTF8Char; var Dest:TUTF8String; vp:Integer; pDir:TDirection):Integer;
|
||||||
var
|
var
|
||||||
v2l:TVisualToLogical;
|
v2l:TVisualToLogical;
|
||||||
lp:Integer;
|
lp,rvp:Integer;
|
||||||
|
c:TUTF8Char;
|
||||||
begin
|
begin
|
||||||
v2l := VisualToLogical(Dest, pDir);
|
v2l := VisualToLogical(Dest, pDir);
|
||||||
if vp > v2l[0]
|
rvp := v2l[0];
|
||||||
|
if vp > rvp
|
||||||
then
|
then
|
||||||
begin
|
begin
|
||||||
lp := Length(Dest) + 1
|
lp := Length(Dest) + 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
lp := v2l[vp];
|
lp := v2l[vp];
|
||||||
Write('vp=',vp,' lp=',lp,' len=', Length(Dest));
|
c := LCharOf(Dest, lp);
|
||||||
|
if DirectionOf(c) = drRTL
|
||||||
|
then
|
||||||
|
begin
|
||||||
|
lp := lp + Length(c);
|
||||||
|
rvp := rvp + 1;
|
||||||
|
end;
|
||||||
case DirectionOf(Src) of
|
case DirectionOf(Src) of
|
||||||
drRTL:
|
drRTL:
|
||||||
begin
|
begin
|
||||||
if lp > Length(Dest)
|
|
||||||
then
|
|
||||||
Insert(Src, Dest, v2l[v2l[0]])
|
|
||||||
else
|
|
||||||
if(vp > v2l[0]) or (DirectionOf(LCharOf(Dest,v2l[vp])) = drRTL)
|
|
||||||
then
|
|
||||||
Insert(Src, Dest, lp + Length(LCharOf(Dest, lp)))
|
|
||||||
else
|
|
||||||
Insert(Src, Dest, lp);
|
|
||||||
Result := vp;
|
Result := vp;
|
||||||
|
Write(Result);
|
||||||
|
while (Result > 0) and (DirectionOf(LCharOf(Dest, v2l[Result])) <> drLTR) do
|
||||||
|
Result := Result - 1;
|
||||||
|
Write('-->',Result);
|
||||||
|
while (Result < vp) and (DirectionOf(LCharOf(Dest, v2l[Result])) <> drRTL) do
|
||||||
|
Result := Result + 1;
|
||||||
|
WriteLn('-->',Result)
|
||||||
end;
|
end;
|
||||||
drLTR:
|
drLTR:
|
||||||
begin
|
begin
|
||||||
Insert(Src, Dest, lp);
|
Result := rvp + 1;
|
||||||
Result := vp + 1;
|
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Insert(Src, Dest, lp);
|
Result := rvp + 1;
|
||||||
if lp > Length(Dest)
|
|
||||||
then
|
|
||||||
Result := lp
|
|
||||||
else
|
|
||||||
Result := lp + 1;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
WriteLn(' Result=', Result);
|
Insert(Src, Dest, lp);
|
||||||
|
WriteLn('vp=',vp,' lp=',lp,' len=', Length(Dest),' Result=', Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure VInsert(const Src:TUTF8String;var Dest:TUTF8String; vp:Integer; pDir:TDirection);
|
procedure VInsert(const Src:TUTF8String;var Dest:TUTF8String; vp:Integer; pDir:TDirection);
|
||||||
@ -397,5 +410,17 @@ begin
|
|||||||
Insert(Src, Dest, LPos(Dest, vp, pDir));
|
Insert(Src, Dest, LPos(Dest, vp, pDir));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure VDelete(var str:TUTF8String; vp, len:Integer; pDir:TDirection);
|
||||||
|
var
|
||||||
|
v2l:TVisualToLogical;
|
||||||
|
i:Integer;
|
||||||
|
begin
|
||||||
|
v2l := VisualToLogical(str, pDir);
|
||||||
|
for i := 1 to v2l[0] do
|
||||||
|
if(v2l[i] < vp) and (v2l[i] > vp + len)
|
||||||
|
then
|
||||||
|
Delete(str, v2l[i], 1);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user