Discussion:
Unicode-Zeichen die nicht in der BMP sind
(zu alt für eine Antwort)
Matthias Frey
2015-03-31 14:41:21 UTC
Permalink
Hallo,
wie verarbeite ich Unicode-Zeichen, die nicht in der base plane liegen?
(Z.B. http://unicode.org/cldr/utility/character.jsp?a=1D510)

Mit Unicodestring sollte das kein Problem sein. Aber wie verarbeite ich
die dann?
Die Delphi-Doku: "In Delphi sind Char- und PChar-Typen jetzt
WideChar- bzw. PWideChar-Typen."
Ein WideChat sind nur 16-Bit. Wie kann ich dann so ein
Zeichen speichern?

Die Doku gibt leider dazu nicht viel her:
http://docwiki.embarcadero.com/RADStudio/XE7/de/Unicode_in_RAD_Studio
Unter dem Abschnitt "Indizierung" ist ein Codebeispiel. Auch hier ist
ein Zeichen ein Char, also 16-Bit.


Matthias
Peter Below (TeamB)
2015-03-31 17:39:09 UTC
Permalink
Post by Matthias Frey
Hallo,
wie verarbeite ich Unicode-Zeichen, die nicht in der base plane
liegen? (Z.B. http://unicode.org/cldr/utility/character.jsp?a=1D510)
Mit Unicodestring sollte das kein Problem sein. Aber wie verarbeite
ich die dann?
solche Zeichen sind in einem Unicodestring als surrogate pair
gespeichert, d.h. als zwei "zeichen".

Wenn Du viel mit sowas arbeiten mußt solltest Du den Unicodestring
zuerst in einen UCS4-String umwandeln, in dem jeder Codepoint dann vier
bytes belegt. Siehe UnicodeStringToUCS4String. Falls Du surrogate
pairs in Unicodestring direct verarbeiten willst, siehe IsSurrogate,
IsSurrogatePair in der online help.
--
Peter Below (TeamB)
Matthias Frey
2015-04-18 19:57:39 UTC
Permalink
Post by Peter Below (TeamB)
Post by Matthias Frey
Hallo,
wie verarbeite ich Unicode-Zeichen, die nicht in der base plane
liegen? (Z.B. http://unicode.org/cldr/utility/character.jsp?a=1D510)
Mit Unicodestring sollte das kein Problem sein. Aber wie verarbeite
ich die dann?
solche Zeichen sind in einem Unicodestring als surrogate pair
gespeichert, d.h. als zwei "zeichen".
Wenn Du viel mit sowas arbeiten mußt solltest Du den Unicodestring
zuerst in einen UCS4-String umwandeln, in dem jeder Codepoint dann vier
bytes belegt. Siehe UnicodeStringToUCS4String. Falls Du surrogate
pairs in Unicodestring direct verarbeiten willst, siehe IsSurrogate,
IsSurrogatePair in der online help.
Danke. Die letzen beiden Funktionen verwende ich jetzt für manche Fälle.
Akutes Problem ist, das die Zeichen nicht wie gewünscht am Bildschirm
ankommen. Die Form stimmt schon, aber das Zeichen liegt viel zu hoch und
zwar in der vorigen Zeile.

Beim Debuggen komme ich vor bei an

procedure TCanvas.TextOut(X, Y: Integer; const Text: String);
begin
Changing;
RequiredState([csHandleValid, csFontValid, csBrushValid]);
if CanvasOrientation = coRightToLeft then Inc(X, TextWidth(Text) + 1);
Winapi.Windows.ExtTextOut(FHandle, X, Y, FTextFlags, nil, Text,
Length(Text), nil);
MoveTo(X + TextWidth(Text), Y);
Changed;
end;

Bei Winapi.Windows.ExtTextOut ist
X=30, Y=79, FTextFlags=0
Text ist 'M𝔐ΚΑΤΑ ΜΑΘΘΑΙΟΝ'. (Mein Mailprogramm zeigt da sogar richtig an.)
Text als Speicherauszug:
$4D $00 $35 $D8 $10 $DD $9A $03 $91 $03 $A4 $03 $91 $03 $20 $00 ...
Die ersten zwei Bytes sind ein "M". Das nächste Zeichen und die
nächsten vier Bytes sind das Zeichen um das es geht.
Length(Text)=16 (stimmt das?)

Was kann da falsch gehen? Hilfe ist willkommen.

Leider können nur wenige Programme überhaupt richtig damit umgehen und ich
weiß nicht so genau auf was ich mich verlassen kann. Ultraedit zeigt die
Zeichen zwar richtig an, hat aber Probleme beim markieren. Der Delphi
Debugger zeigts wohl auch an so wie ich das erwarte.

Matthias
Hans-Peter Diettrich
2015-04-18 23:21:27 UTC
Permalink
Post by Matthias Frey
Akutes Problem ist, das die Zeichen nicht wie gewünscht am Bildschirm
ankommen. Die Form stimmt schon, aber das Zeichen liegt viel zu hoch und
zwar in der vorigen Zeile.
Das könnte an einem kaputten Font liegen. Wie sieht die Darstellung mit
einem anderen Font aus?

DoDi
Peter Below (TeamB)
2015-04-20 17:03:39 UTC
Permalink
Matthias Frey wrote:


Das ist eventuell ein Windows-Problem, oder ein Problem des verwendeten
Fonts. Kann ich leider nichts zu sagen, mit sowas habe ich mich nie
'rumschlagen müssen.

Hast Du dich schon mal mit Uniscribe beschäftigt? Siehe
https://msdn.microsoft.com/en-us/library/windows/desktop/dd374127%28v=vs.85%29.aspx
Post by Matthias Frey
Leider können nur wenige Programme überhaupt richtig damit umgehen
und ich weiß nicht so genau auf was ich mich verlassen kann.
Ultraedit zeigt die Zeichen zwar richtig an, hat aber Probleme beim
markieren. Der Delphi Debugger zeigts wohl auch an so wie ich das
erwarte.
Matthias
--
Peter Below (TeamB)
Achim Kalwa
2015-04-23 11:36:25 UTC
Permalink
Hallo,
Post by Matthias Frey
Bei Winapi.Windows.ExtTextOut ist
X=30, Y=79, FTextFlags=0
Text ist 'M𝔐ΚΑΤΑ ΜΑΘΘΑΙΟΝ'. (Mein Mailprogramm zeigt da sogar richtig an.)
$4D $00 $35 $D8 $10 $DD $9A $03 $91 $03 $A4 $03 $91 $03 $20 $00 ...
Die ersten zwei Bytes sind ein "M". Das nächste Zeichen und die
nächsten vier Bytes sind das Zeichen um das es geht.
Length(Text)=16 (stimmt das?)
Siegt ganz OK aus (UTF-16 codiert). Hier gibts mehr Informationen über
dieses Zeichen:

http://www.fileformat.info/info/unicode/char/1d510/index.htm

Und dort gibt es auch eine Liste der Fonts, in denen dieses Zeichen
unterstützt wird:

http://www.fileformat.info/info/unicode/char/1d510/fontsupport.htm

HTH
Achim
Matthias Frey
2015-04-25 16:55:54 UTC
Permalink
Post by Matthias Frey
Hallo,
Hallo
Post by Matthias Frey
Post by Matthias Frey
Bei Winapi.Windows.ExtTextOut ist
X=30, Y=79, FTextFlags=0
Text ist 'M𝔐ΚΑΤΑ ΜΑΘΘΑΙΟΝ'. (Mein Mailprogramm zeigt da sogar richtig an.)
$4D $00 $35 $D8 $10 $DD $9A $03 $91 $03 $A4 $03 $91 $03 $20 $00 ...
Die ersten zwei Bytes sind ein "M". Das nächste Zeichen und die
nächsten vier Bytes sind das Zeichen um das es geht.
Length(Text)=16 (stimmt das?)
Siegt ganz OK aus (UTF-16 codiert).
Danke. Immerhin scheint das zu stimmen.
Post by Matthias Frey
http://www.fileformat.info/info/unicode/char/1d510/index.htm
Und dort gibt es auch eine Liste der Fonts, in denen dieses Zeichen
http://www.fileformat.info/info/unicode/char/1d510/fontsupport.htm
Ich muss SBL Greek verwenden.

Habe nun als erstes ein neues Testprogramm erstellt nur mit einer
TPaintBox und einer Testausgabe. Da ist (mit 'SBL Greek') alles
richtig - und auch mit 'MS Sans Serif' und 'Arial'.
Ich gehe davon aus, dass es am Font selber nicht liegen wird.

Dann habe ich die Testausgabe an anderee Stellen in mein Programm
integriert - auch da ist es gut.
Nun habe ich geschaut, was denn an der fraglichen Stelle alles ist,
oder in dem Control oder dem Canvas. Letztendlich gefunden habe
ich das: "SetTextAlign(Canvas.Handle, TA_UPDATECP or TA_Baseline);"

Wenn ich die TA_Baseline rausnehme dann funktioniert es so dass
das Zeichen dann richtig kommt. (Genaugenommen dann genauso falsch
wie die anderen Zeichen, die dann alle zu tief sind.)

Allerdings habe ich keine Ahnung warum die Baseline von dem Zeichen
so tief ist. Der Effekt zeigt sich bei allen drei oben erwähnten
Fonts.

Ich mache jetzt einen WorkAround.
Wenn jemand mir noch Informationen oder Ideen hätte bin ich dankbar.

(TA_Baseline kann ich nicht generell entfernen. Das ist eine
grundsätzliche Festlegung vom Konzept der Anzeige.)
Post by Matthias Frey
HTH
JA!
Post by Matthias Frey
Achim
Matthias
Matthias Frey
2015-04-25 17:00:15 UTC
Permalink
Post by Peter Below (TeamB)
Post by Matthias Frey
Hallo,
wie verarbeite ich Unicode-Zeichen, die nicht in der base plane
liegen? (Z.B. http://unicode.org/cldr/utility/character.jsp?a=1D510)
Mit Unicodestring sollte das kein Problem sein. Aber wie verarbeite
ich die dann?
solche Zeichen sind in einem Unicodestring als surrogate pair
gespeichert, d.h. als zwei "zeichen".
Wenn Du viel mit sowas arbeiten mußt solltest Du den Unicodestring
zuerst in einen UCS4-String umwandeln, in dem jeder Codepoint dann vier
bytes belegt. Siehe UnicodeStringToUCS4String. Falls Du surrogate
pairs in Unicodestring direct verarbeiten willst, siehe IsSurrogate,
IsSurrogatePair in der online help.
Danke.
Letztere beiden verwende ich inzwischen.

Das mit UnicodeStringToUCS4String sieht mir sehr exotisch aus.
D.h. man muss dann wieder alles selber machen.

Kann ich dann z.B. bei der Windows API function GetCharWidth32
diese UCS4-Zeichen abfüllen?

Matthias

Lesen Sie weiter auf narkive:
Suchergebnisse für 'Unicode-Zeichen die nicht in der BMP sind' (Fragen und Antworten)
9
Antworten
wie ist soetwas das möglich?
gestartet 2010-07-05 23:23:58 UTC
computer & internet
Loading...