Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Name von Unicode-Zeichen (https://www.delphipraxis.net/193150-name-von-unicode-zeichen.html)

Codehunter 27. Jun 2017 11:16

Name von Unicode-Zeichen
 
Hallo!

Gibt es eigentlich eine API wo man die Namen der Unicode-Zeichen abfragen kann? Gemeint ist das so:

Einfach mal charmap.exe aufrufen. Wenn man eines der Zeichen auswählt oder drüber maust, dann erscheint der Name des Zeichens in der Sprache, die das System verwendet. Hat Microsoft dafür irgendwo eine API eingebaut mit der man die Namen abfragen kann?

Grüße
Cody

bra 27. Jun 2017 11:34

AW: Name von Unicode-Zeichen
 
Sowas?
http://unicode.org/charts/charindex.html

Achso, eine API :pale:

Codehunter 27. Jun 2017 11:49

AW: Name von Unicode-Zeichen
 
Ich sage mal, die Betonung liegt auf Systemsprache ;-)

Ydobon 27. Jun 2017 12:30

AW: Name von Unicode-Zeichen
 
Die Zeichentabelle hat ihre eigene DLL: http://www.pinvoke.net/default.aspx/getuname.GetUName

Vielleicht sicherer ist aber sich bei Unicode.org die entsprechende Tabelle zu laden und selbst nachschauen.

Codehunter 27. Jun 2017 12:59

AW: Name von Unicode-Zeichen
 
Danke das war der Einstieg! Und wie ich gesehen habe, wenn man erstmal das richtige Stichwort weiß findet man auch frühere Fragen zum Thema :-D

Codehunter 27. Jun 2017 13:50

AW: Name von Unicode-Zeichen
 
Wo ich schon mal dabei bin: Kann man eigentlich auch feststellen, ob eine Schriftart ein Symbol für ein bestimmtes Zeichen enthält oder nicht? Ich schau schon alles bei den Font-Functions durch, aber ich sehe da nichts das unterscheiden ließe ob das Symbol in der Schriftart existiert oder nicht. Denn wenn nicht, wird einfach vom System her das Standard-Symbol (meistens ein rechteckiger Rahmen) verwendet.

Rollo62 27. Jun 2017 16:18

AW: Name von Unicode-Zeichen
 
Nicht das es dir jetzt weiterhilft. Aber
diese Seiten finde ich auch ganz interessant
http://http://www.fileformat.info/info/unicode/char/03a9/index.htm

himitsu 27. Jun 2017 17:32

AW: Name von Unicode-Zeichen
 
Es gibt die Unit Characters, aber da kann man sich nur die Typen/Gruppen/Eigenschaften der Chars holen,
aber leider nirgendwo die Namen.

Ich hatte auch in der GDI+ noch keine Funktion gefunden, welche den Namen liefert oder ob es das Zeichen überhaupt im Font gibt.
Du könntest zwar die Font-Datei selber auslesen/parsen und nachgucken, welche Zeichen darin definiert sind, aber das hilft nur bedingt, da in Windows auch ein Ersatzfont definiert sein könnte, welchen Windows zum Zeichnen des fehlenden Chars verwendet.
PS: Die großen Unicodefonts von Windows (z.B. Arial und MingLiU) bestehen auch nicht nur aus einer Datei. (die Chars wurden da auf mehrere Dateien verteilt)

Außerdem gibt die GDI "absichtlich" keinerlei Fehlerinformationen aus, wenn man ein nicht-vorhandenes Zeichen oder gar mit einem nicht-vorhandenen Font etwas schreiben will.



Das Einzige, was mir damals auf die schnelle eingefallen war, ist ein Bildvergleich.
* erst ein nie vorhandenes Char auf ein Bitmap zeichnen (da kommt dann das Ersatzzeichen des Fonts raus, was meistens ein Rechteck ist)
* dann das gewünschte Char zeichnen
* und die Bilder dann vergleichen :freak:

Und die Fontnamen, da hatte ich auch von unicode.org (das ist ja die Vergabestelle für die Unicodedefinition) die CSV's besorgt und die benötigten Daten als Resource an meine Anwendung gehängt.

Fritzew 27. Jun 2017 17:57

AW: Name von Unicode-Zeichen
 
Zugegeben ich habe es nicht getestet aber vieleicht hilft das:
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Ydobon 28. Jun 2017 00:42

AW: Name von Unicode-Zeichen
 
Ist schon über 10 Jahre her, als ich das Thema CJK und solche Probleme mal hatte. Um die alten Programme zu testen müsste ich allerdings erst mal die Tnt-Controls umbauen.
Aber laut Quelltexten z.B. GetGlyphIndices.
Falls noch weitere Fragen auftauchen lohnt sich vermutlich ein Blick in die Uniscribe-Abteilung. So weit ich mich erinnere kann die automatische Ersetzung aber bei solchen Test auch falsche Ergebnisse liefern.

PS: BabelMap ist da eine nette Sache.

Codehunter 28. Jun 2017 07:52

AW: Name von Unicode-Zeichen
 
Zitat:

Zitat von Ydobon (Beitrag 1375488)
Aber laut Quelltexten z.B. GetGlyphIndices.

Ich habe das jetzt mal so umgesetzt, wo GetGlyphIndices aber immer GDI_ERROR liefert. Mach ich da jetzt einen gedanklichen Fehler?
Delphi-Quellcode:
function TfrmMain.GetCharExists(const Chr: Char): Boolean;
var
  Buf: Word;
begin
  Result:= FALSE;
  if GetGlyphIndices(tvChars.Canvas.Handle, PChar(Chr), 1, @Buf,
                     GGI_MARK_NONEXISTING_GLYPHS) <> GDI_ERROR then
  begin
    Result:= (Buf <> $FFFF);
  end;
end;

Ydobon 28. Jun 2017 08:37

AW: Name von Unicode-Zeichen
 
Mal schnell was rauskopiert. Funktioniert mit japanischen Text und Tahoma vs. Arial Unicode MS.

Delphi-Quellcode:
var pwOutGlyphs: PWord;
    i, cwstr: Integer;
    wstr: String;
    erg: Cardinal;
begin
  wstr:=Edit1.Text;
  cwstr:=Length(wstr);
  if wstr='' then exit;
  GetMem(pwOutGlyphs, cwstr*2);
  ZeroMemory(pwOutGlyphs, cwstr*2);
  erg:=GetGlyphIndices(Canvas.Handle, @wstr[1], cwstr, pwOutGlyphs, GGI_MARK_NONEXISTING_GLYPHS);
  if erg=GDI_ERROR then RaiseLastOSError;
  ExtTextOut(Canvas.Handle, 10, 6, ETO_GLYPH_INDEX, Nil, PChar(pwOutGlyphs), cwstr, Nil);
  Memo1.Clear;
  for i:=0 to cwstr-1 do Memo1.Lines.Add(IntToHex(PWordArray(pwOutGlyphs)[i], 4));
end;
Edit: War noch von D2005.

himitsu 28. Jun 2017 08:44

AW: Name von Unicode-Zeichen
 
Zitat:

Delphi-Quellcode:
PChar(Chr)

:?:

Delphi-Quellcode:
PChar(@Chr)
// bzw.
@Chr
Und dann noch die fehlende #0-Terminierung

Und C=1 ?
Was ist, wenn pgi größer sein muß?

Ydobon 28. Jun 2017 08:58

AW: Name von Unicode-Zeichen
 
Ähm, OK.

Dann halt noch die Uniscribe-Version. Der Rest stimmt überein.
Delphi-Quellcode:
var sc: TScriptCache;
    hr: HRESULT;

  sc:=Nil;
  hr:=ScriptGetCMap(Canvas.Handle, @sc, @wstr[1], cwstr, SGCM_RTL, pwOutGlyphs);
  if (hr<>S_OK) and (hr<>S_FALSE) then RaiseLastOSError;
  ScriptFreeCache(@sc);

TiGü 28. Jun 2017 09:09

AW: Name von Unicode-Zeichen
 
Du kannst dich auch mal mit DirectWrite beschäftigen!
Da steckt sehr viel drin, was du sicherlich gebrauchen kannst.

Bspw. hat das IDWriteFont Interface eine HasCharacter-Methode.
Daneben gibt es noch eine Vielzahl weiterer Sachen, die sicherlich weiterhelfen:
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Direct2D, Winapi.D2D1;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    function GetCharExists(const Chr: Char): Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Caption := GetCharExists('&#8224;').ToString(TUseBoolStrs.True);
end;

function TForm1.GetCharExists(const Chr: Char): Boolean;
var
  hr: HRESULT;
  FontHandle: HFont;
  LogFont: TLogFont;
  GdiInterop: IDWriteGdiInterop;
  WriteFont: IDWriteFont;
  CharacterExists: BOOL;
begin
  Result := False;
  hr := DWriteFactory.GetGdiInterop(GdiInterop);
  if SUCCEEDED(hr) and Assigned(GdiInterop) then
  begin
    FontHandle := Self.Font.Handle;
    if GetObject(FontHandle, SizeOf(LogFont), @LogFont) <> 0 then
    begin
      hr := GdiInterop.CreateFontFromLOGFONT(LogFont, WriteFont);
      if SUCCEEDED(hr) and Assigned(WriteFont) then
      begin
        hr := WriteFont.HasCharacter(Ord(Chr), CharacterExists);
        Result := SUCCEEDED(hr) and CharacterExists;
      end;
    end;
  end;
end;

end.

TiGü 28. Jun 2017 09:23

AW: Name von Unicode-Zeichen
 
Vielleicht als Einstieg, wenn man von der alten GDI/WinApi-Welt kommt: https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Codehunter 30. Jun 2017 14:41

AW: Name von Unicode-Zeichen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also bei der ganzen Experimentiererei ist quasi nebenbei noch etwas Nützliches entstanden: Eine Art Zeichentabelle wie die von Windows, nur ein bisschen komfortabler, nicht so klein und fuddelig.

Ydobon 30. Jun 2017 21:09

AW: Name von Unicode-Zeichen
 
Mir fehlen da ein paar Komponenten, aber ist der Font Fallback Absicht? Die angezeigten Glyphen sind nicht unbedingt in den Schriftarten enthalten.

Codehunter 1. Jul 2017 08:45

AW: Name von Unicode-Zeichen
 
Zitat:

Zitat von Ydobon (Beitrag 1375752)
Mir fehlen da ein paar Komponenten, aber ist der Font Fallback Absicht? Die angezeigten Glyphen sind nicht unbedingt in den Schriftarten enthalten.

Genau darum dreht sich das Thema ja, dass Windows von sich aus einen Fallback macht und das zu vermeiden gar nicht so einfach ist.

Nebenbei zeigt sich, dass manche VCL-Komponenten bis heute Probleme mit Unicode haben. So funktioniert z.B. die Selektion von bestimmten Unicode-Zeichen in TLabeledEdit nicht.

Die Anwendung ist eigentlich nur als Testanwendung entstanden. Die Quellen sind ja dabei, Vorschläge gerne willkommen.

p80286 1. Jul 2017 09:20

AW: Name von Unicode-Zeichen
 
Zitat:

Zitat von Codehunter (Beitrag 1375758)
Die Anwendung ist eigentlich nur als Testanwendung entstanden. Die Quellen sind ja dabei, Vorschläge gerne willkommen.

Könntest Du die farbliche Hervorhebung etwas kräftigen? und für die, die noch mit Hex-Ziffern alt geworden sind, eine Umschaltmöglichkeit einbauen?

Und ein echtes Add on, einen Font (temporär) laden?
(die notwendigen Sourcen kann ich Dir heraus suchen)

Muß ich noch erwähnen, daß mir Dein Programm gefällt?

Gruß
K-H

Ydobon 1. Jul 2017 09:36

AW: Name von Unicode-Zeichen
 
An den Spaß kann ich mich noch gut erinnern. Habe mich dann sogar bei Microsoft's Typography registriert um die Infos und Tools zu benutzen (Registrierung ist heute wohl nicht mehr nötig). Richtig erschreckend wie viele Fehler in den ganz normalen Schriftarten stecken.

Bei GetGlyphIndices zeigt ein Index von $FFFF an, dass die Glyphe nicht enthalten ist (bei ScriptGetCMap ist es selbstverständlich die 0). Dann braucht man noch die jeweilige default Glyphe.

Letztlich habe ich dann die ganz harte Methode benutzt, das direkte Auslesen der CMAP-Tabellen. Für cmap4 wäre das ein Beispiel.

Und ich erwähne noch einmal: http://www.babelstone.co.uk/Software/BabelMap.html

TiGü 3. Jul 2017 09:32

AW: Name von Unicode-Zeichen
 
Da ich leider nicht im Besitz der Komponenten bin (TB2..., SpTBX...), kann ich dein Programm nicht kompilieren.
Zwei Sachen fallen mir jedoch beim durchschauen auf:

Es ist etwas suboptimal, bei jedem Aufruf von GetCharName die DLL getuname.dll zu laden und entzuladen.
Hier wäre es besser, einmal statisch die Funktion GetUName in Quelltext zu definieren und zu verwenden.

Du hast meine GetCharExists-Funktion im Prinzip einfach nur kopiert, ohne zu verstehen das dort passiert.
Mein Code diente zu Testzwecken und muss natürlich angepasst werden.
So wird nämlich hier immer die Schrift des Hauptformulars verwendet, ohne auf Änderungen in cbbFontListChange einzugehen.
Hier weist du ja explizit die Schrift von cbbFontList.SelectedFont den TreeView und dem Vorschaufenster zu.
Es wäre auch Ressourcen schonender, wenn du dir die Instanzen von IDWriteGdiInterop einmalig beim Programmstart holst und als Membervariable des Formulars führst.
Eine Neuerzeugung von IDWriteFont ist dann nur noch notwendig, wenn cbbFontListChange aufgerufen wird.

Somit würde sich die GetCharExists-Funktion verkürzen auf:

Delphi-Quellcode:
function TfrmMain.GetCharExists(const Chr: Char): Boolean;
var
  HR: HRESULT;
  CharacterExists: BOOL;
begin
  Result := btnShowAllChars.Checked;
  if Result then
    Exit;

  if Assigned(FWriteFont) then
  begin
    HR := FWriteFont.HasCharacter(Ord(Chr), CharacterExists);
    Result := SUCCEEDED(HR) and CharacterExists;
  end;
end;
Die einmalige Erzeugung von IDWriteGdiInterop und die Neuerzeugung von IDWriteFont beim Schriftartwechsel überlasse ich dir mal als Fingerübung. :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz