summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/gui/widgettest/widgettest.pas1
-rw-r--r--gfx/fputf8utils.pas126
-rw-r--r--gfx/gdi/fpgfxpackage.lpk6
-rw-r--r--gfx/gdi/fpgfxpackage.pas2
-rw-r--r--gfx/x11/fpgfxpackage.lpk6
-rw-r--r--gfx/x11/fpgfxpackage.pas2
-rw-r--r--gfx/x11/gfx_x11.pas5
-rw-r--r--gui/fpgui.pas1
-rw-r--r--gui/fpguiedit.inc45
9 files changed, 176 insertions, 18 deletions
diff --git a/examples/gui/widgettest/widgettest.pas b/examples/gui/widgettest/widgettest.pas
index fcfe3b99..704e1619 100644
--- a/examples/gui/widgettest/widgettest.pas
+++ b/examples/gui/widgettest/widgettest.pas
@@ -694,6 +694,7 @@ constructor TEditForm.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
LoadForm(self);
+ Edit1.Text := 'Gráficas Magnificacion! Teste';
Edit2.PasswordChar := '*';
end;
diff --git a/gfx/fputf8utils.pas b/gfx/fputf8utils.pas
new file mode 100644
index 00000000..0bad5380
--- /dev/null
+++ b/gfx/fputf8utils.pas
@@ -0,0 +1,126 @@
+{
+ Some handly UTF8 function copied from the Lazarus LCL. Surely we can move
+ this into FPC?
+}
+unit fpUTF8Utils;
+
+{$ifdef FPC}
+ {$mode objfpc}{$H+}
+{$endif}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+
+function UTF8Pos(const SearchForText, SearchInText: string): integer;
+function UTF8Copy(const s: string; StartCharIndex, CharCount: integer): string;
+function UTF8Length(p: PChar; ByteCount: integer): integer;
+function UTF8CharStart(UTF8Str: PChar; Len, Index: integer): PChar;
+function UTF8CharacterLength(p: PChar): integer;
+
+
+implementation
+
+function UTF8Pos(const SearchForText, SearchInText: string): integer;
+// returns the character index, where the SearchForText starts in SearchInText
+var
+ p: LongInt;
+begin
+ p:=System.Pos(SearchForText,SearchInText);
+ if p>0 then
+ Result:=UTF8Length(PChar(SearchInText),p-1)+1
+ else
+ Result:=0;
+end;
+
+function UTF8Copy(const s: string; StartCharIndex, CharCount: integer): string;
+// returns substring
+var
+ StartBytePos: PChar;
+ EndBytePos: PChar;
+ MaxBytes: PtrInt;
+begin
+ StartBytePos:=UTF8CharStart(PChar(s),length(s),StartCharIndex-1);
+ if StartBytePos=nil then
+ Result:=''
+ else begin
+ MaxBytes:=PtrInt(PChar(s)+length(s)-StartBytePos);
+ EndBytePos:=UTF8CharStart(StartBytePos,MaxBytes,CharCount);
+ if EndBytePos=nil then
+ Result:=copy(s,StartBytePos-PChar(s)+1,MaxBytes)
+ else
+ Result:=copy(s,StartBytePos-PChar(s)+1,EndBytePos-StartBytePos);
+ end;
+end;
+
+function UTF8Length(p: PChar; ByteCount: integer): integer;
+var
+ CharLen: LongInt;
+begin
+ Result:=0;
+ while (ByteCount>0) do begin
+ inc(Result);
+ CharLen:=UTF8CharacterLength(p);
+ inc(p,CharLen);
+ dec(ByteCount,CharLen);
+ end;
+end;
+
+function UTF8CharStart(UTF8Str: PChar; Len, Index: integer): PChar;
+var
+ CharLen: LongInt;
+begin
+ Result:=UTF8Str;
+ if Result<>nil then begin
+ while (Index>0) and (Len>0) do begin
+ CharLen:=UTF8CharacterLength(Result);
+ dec(Len,CharLen);
+ dec(Index);
+ inc(Result,CharLen);
+ end;
+ if (Index>0) or (Len<0) then
+ Result:=nil;
+ end;
+end;
+
+function UTF8CharacterLength(p: PChar): integer;
+begin
+ if p<>nil then begin
+ if ord(p^)<%11000000 then begin
+ // regular single byte character (#0 is a character, this is pascal ;)
+ Result:=1;
+ end
+ else if ((ord(p^) and %11100000) = %11000000) then begin
+ // could be 2 byte character
+ if (ord(p[1]) and %11000000) = %10000000 then
+ Result:=2
+ else
+ Result:=1;
+ end
+ else if ((ord(p^) and %11110000) = %11100000) then begin
+ // could be 3 byte character
+ if ((ord(p[1]) and %11000000) = %10000000)
+ and ((ord(p[2]) and %11000000) = %10000000) then
+ Result:=3
+ else
+ Result:=1;
+ end
+ else if ((ord(p^) and %11111000) = %11110000) then begin
+ // could be 4 byte character
+ if ((ord(p[1]) and %11000000) = %10000000)
+ and ((ord(p[2]) and %11000000) = %10000000)
+ and ((ord(p[3]) and %11000000) = %10000000) then
+ Result:=4
+ else
+ Result:=1;
+ end
+ else
+ Result:=1
+ end else
+ Result:=0;
+end;
+
+end.
+
diff --git a/gfx/gdi/fpgfxpackage.lpk b/gfx/gdi/fpgfxpackage.lpk
index 84d2ab5b..06dbd483 100644
--- a/gfx/gdi/fpgfxpackage.lpk
+++ b/gfx/gdi/fpgfxpackage.lpk
@@ -24,7 +24,7 @@
<License Value="Modified LGPL
"/>
<Version Minor="4"/>
- <Files Count="6">
+ <Files Count="7">
<Item1>
<Filename Value="..\gfxbase.pas"/>
<UnitName Value="GfxBase"/>
@@ -49,6 +49,10 @@
<Filename Value="..\gelimage.pas"/>
<UnitName Value="GELImage"/>
</Item6>
+ <Item7>
+ <Filename Value="..\fputf8utils.pas"/>
+ <UnitName Value="fpUTF8Utils"/>
+ </Item7>
</Files>
<RequiredPkgs Count="1">
<Item1>
diff --git a/gfx/gdi/fpgfxpackage.pas b/gfx/gdi/fpgfxpackage.pas
index 61ffe20c..0669f181 100644
--- a/gfx/gdi/fpgfxpackage.pas
+++ b/gfx/gdi/fpgfxpackage.pas
@@ -7,7 +7,7 @@ unit fpGFXPackage;
interface
uses
- GfxBase, GFXInterface, GFX_GDI, fpgfx, GELDirty, GELImage;
+ GfxBase, GFXInterface, GFX_GDI, fpgfx, GELDirty, GELImage, fpUTF8Utils;
implementation
diff --git a/gfx/x11/fpgfxpackage.lpk b/gfx/x11/fpgfxpackage.lpk
index c58916a3..5c02e39b 100644
--- a/gfx/x11/fpgfxpackage.lpk
+++ b/gfx/x11/fpgfxpackage.lpk
@@ -21,7 +21,7 @@
<License Value="Modified LGPL
"/>
<Version Minor="4"/>
- <Files Count="9">
+ <Files Count="10">
<Item1>
<Filename Value="../gfxbase.pas"/>
<UnitName Value="GfxBase"/>
@@ -58,6 +58,10 @@
<Filename Value="../commandlineparams.pas"/>
<UnitName Value="CommandLineParams"/>
</Item9>
+ <Item10>
+ <Filename Value="../fputf8utils.pas"/>
+ <UnitName Value="fpUTF8Utils"/>
+ </Item10>
</Files>
<LazDoc Paths="../../docs/xml/gfx/"/>
<RequiredPkgs Count="1">
diff --git a/gfx/x11/fpgfxpackage.pas b/gfx/x11/fpgfxpackage.pas
index 84c4bda2..f6e51e3b 100644
--- a/gfx/x11/fpgfxpackage.pas
+++ b/gfx/x11/fpgfxpackage.pas
@@ -8,7 +8,7 @@ interface
uses
GfxBase, GFX_X11, gfxinterface, schar16, unitkeys, fpgfx, GELDirty, GELImage,
- CommandLineParams;
+ CommandLineParams, fpUTF8Utils;
implementation
diff --git a/gfx/x11/gfx_x11.pas b/gfx/x11/gfx_x11.pas
index 7128c4bf..1deba25a 100644
--- a/gfx/x11/gfx_x11.pas
+++ b/gfx/x11/gfx_x11.pas
@@ -621,6 +621,7 @@ function TX11Canvas.TextExtent(const AText: String): TSize;
var
{$IFDEF XftSupport}
extents : TXGlyphInfo;
+ WideText: WideString;
{$ELSE}
Direction, FontAscent, FontDescent: LongInt;
CharStruct: TXCharStruct;
@@ -634,7 +635,9 @@ begin
else
begin
{$IFDEF XftSupport}
- XftTextExtents8(GFApplication.Handle, FFontStruct.FontData, PChar(AText), Length(AText), extents);
+ WideText := Utf8Decode(AText);
+// XftTextExtents8(GFApplication.Handle, FFontStruct.FontData, PChar(AText), Length(AText), extents);
+ XftTextExtents16(GFApplication.Handle, FFontStruct.FontData, PChar(WideText), Length(WideText), extents);
Result.cx := extents.xOff;
Result.cy := extents.yOff;
{$ELSE}
diff --git a/gui/fpgui.pas b/gui/fpgui.pas
index 285c4c3b..ac69f788 100644
--- a/gui/fpgui.pas
+++ b/gui/fpgui.pas
@@ -159,6 +159,7 @@ implementation
uses
Math
,StyleManager
+ ,fpUTF8Utils
;
diff --git a/gui/fpguiedit.inc b/gui/fpguiedit.inc
index 8cd3268c..6ad17cb7 100644
--- a/gui/fpguiedit.inc
+++ b/gui/fpguiedit.inc
@@ -142,11 +142,13 @@ begin
BoundsSize.cx - Borders.Right - 1, BoundsSize.cy - Borders.Bottom - 1)) then
exit;
+ // setup the correct font color
if wsEnabled in WidgetState then
Canvas.SetColor(Style.GetUIColor(FFontColor))
else
Canvas.SetColor(Style.GetUIColor(clGrayText));
+ // paint the text
s := GetDrawText;
Canvas.TextOut(Point(-FDrawOffset + Borders.Left+2, 3), s);
@@ -176,7 +178,7 @@ begin
// drawing cursor
Canvas.SetColor(Style.GetUIColor(clWindowText));
// Style.SetUIColor(Canvas, clWindowText);
- tw := Canvas.TextWidth(Copy(s, 1, FCursorPos));
+ tw := Canvas.TextWidth(UTF8Copy(s, 1, FCursorPos));
// 2 pixel cursor line
// ItemRect.Top := Borders.Top;
@@ -202,21 +204,24 @@ begin
end;
procedure TFCustomEdit.EvKeyPressed(Key: Word; Shift: TShiftState);
+var
+ WideText: WideString;
begin
if Shift * [ssShift, ssAlt, ssCtrl, ssMeta, ssSuper, ssHyper, ssAltGr] = [] then
begin
+ WideText := UTF8Decode(Text);
// Normal typing - no selections
case Key of
keyLeft, keyUp:
if CursorPos > 0 then
CursorPos := CursorPos - 1;
keyRight, keyDown:
- if CursorPos < Length(Text) then
+ if CursorPos < Length(WideText) then
CursorPos := CursorPos + 1;
keyHome:
CursorPos := 0;
keyEnd:
- CursorPos := Length(Text);
+ CursorPos := Length(WideText);
else
inherited EvKeyPressed(Key, Shift);
end;
@@ -250,23 +255,27 @@ end;
procedure TFCustomEdit.EvKeyChar(KeyChar: Char);
+var
+ WideText: WideString;
begin
+ WideText := UTF8Decode(FText);
+
case KeyChar of
#8: { Backspace }
if FCursorPos > 0 then
begin
- FText := Copy(FText, 1, FCursorPos - 1) + Copy(FText, FCursorPos + 1, Length(FText));
+ FText := UTF8Copy(FText, 1, FCursorPos - 1) + UTF8Copy(FText, FCursorPos + 1, Length(WideText));
FCursorPos := FCursorPos - 1;
end;
#127: { Del }
- if FCursorPos < Length(FText) then
+ if FCursorPos < Length(WideText) then
begin
- FText := Copy(FText, 1, FCursorPos) + Copy(FText, FCursorPos + 2, Length(FText));
+ FText := UTF8Copy(FText, 1, FCursorPos) + UTF8Copy(FText, FCursorPos + 2, Length(WideText));
Redraw;
end;
#32..#126, #128..#255:
begin
- FText := Copy(FText, 1, FCursorPos) + KeyChar + Copy(FText, CursorPos + 1, Length(FText));
+ FText := UTF8Copy(FText, 1, FCursorPos) + KeyChar + UTF8Copy(FText, CursorPos + 1, Length(WideText));
FCursorPos := FCursorPos + 1;
end;
else
@@ -292,10 +301,13 @@ begin
end;
procedure TFCustomEdit.SetText(const AText: String);
+var
+ WideText: WideString;
begin
inherited SetText(AText);
+ WideText := Utf8Decode(FText);
FSelOffset := 0;
- FCursorPos := Length(FText);
+ FCursorPos := Length(WideText);
FSelStart := FCursorPos;
FDrawOffset := 0;
AdjustCursor;
@@ -334,6 +346,7 @@ var
n: integer;
cx: integer;
lText: string;
+ WideText: WideString;
begin
if (pEvent.Button = mbLeft) then
begin
@@ -343,13 +356,14 @@ begin
// Make sure we work with the correct displayed text
lText := GetDrawText;
+ WideText := UTF8Decode(lText);
cp := FCursorPos;
- cpx := FindForm.Wnd.Canvas.TextWidth(Copy(lText, 1, FCursorPos)) - FDrawOffset + lSideMargin;
+ cpx := FindForm.Wnd.Canvas.TextWidth(UTF8Copy(lText, 1, FCursorPos)) - FDrawOffset + lSideMargin;
- for n := 0 to Length(lText) do
+ for n := 0 to Length(WideText) do
begin
- cx := FindForm.Wnd.Canvas.TextWidth(Copy(lText, 1, n)) - FDrawOffset + lSideMargin;
+ cx := FindForm.Wnd.Canvas.TextWidth(UTF8Copy(lText, 1, n)) - FDrawOffset + lSideMargin;
if abs(cx - pEvent.Position.x) < abs(cpx - pEvent.Position.x) then
begin
cpx := cx;
@@ -396,7 +410,7 @@ begin
Exit; //==>
Canvas := FindForm.Wnd.Canvas;
- tw := Canvas.TextWidth(Copy(GetDrawText, 1, FCursorPos));
+ tw := Canvas.TextWidth(UTF8Copy(GetDrawText, 1, FCursorPos));
lBorders := Style.GetEditBoxBorders;
lSideMargins := lBorders.Left + lBorders.Right;
@@ -416,11 +430,16 @@ end;
// Return the correct text to be displayed
function TFCustomEdit.GetDrawText: string;
+var
+ WideText: WideString;
begin
if FPasswordChar = #0 then
Result := FText
else
- Result := StringOfChar(FPasswordChar, Length(FText));
+ begin
+ WideText := Utf8Decode(FText);
+ Result := StringOfChar(FPasswordChar, Length(WideText));
+ end;
end;
{$ENDIF read_implementation}