Prüfen ob ein Zeichen in einer Font existiert
Prüfen ob ein Zeichen in einer Font existiert
Tachchen,
ich habe da mal eine Frage:
Wie kann ich von einer Font (die zB. mit LoadFont geladen wurde, oder einer API) herausfinden, welche Zeichen wirklich enthalten sind.
Normalerweise ist es ja bei Fonts so, dass bei Zeichen die nicht wirklich existieren so n Recheck kommt.
Genau diese Zeichen will ich nun filtern, sodass, ähnlich wie bei der MS-Zeichentabelle, nur Zeichen dargestellt werden, die auch wirklich enthalten sind.
ich habe da mal eine Frage:
Wie kann ich von einer Font (die zB. mit LoadFont geladen wurde, oder einer API) herausfinden, welche Zeichen wirklich enthalten sind.
Normalerweise ist es ja bei Fonts so, dass bei Zeichen die nicht wirklich existieren so n Recheck kommt.
Genau diese Zeichen will ich nun filtern, sodass, ähnlich wie bei der MS-Zeichentabelle, nur Zeichen dargestellt werden, die auch wirklich enthalten sind.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Prüfen ob ein Zeichen in einer Font existiert
Schau Dir mal folgende 2 Themen an:
welche Chars wirklich enthalten sind.
undThe GetFontUnicodeRanges function returns information about which Unicode characters are supported by a font.
GetFontUnicodeRanges klingt interessant. So solltest Du an eine Map kommen,GetTextMetrics
Die TEXTMETRIC Struktur enthält 'TCHAR tmDefaultChar': The value of the character to be substituted for characters not in the font.
welche Chars wirklich enthalten sind.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Prüfen ob ein Zeichen in einer Font existiert
Danke Danilo, aber leider helfen mir beide Sachen nicht weiter.
GetTextMetrics enthält ja nur den Hinweis auf das zu verwendende Zeichen, wenn ein anderes Zeichen nicht existiert.
Ob es nicht existiert, kann ich daraus aber nicht ablesen.
GetFontUnicodeRanges wird (zumindest bei mir) garnicht unterstützt, fällt somit eh weg.
Ich habe auch schon Probiert, die Zeichenbreiten zu vergleichen, sodass Zeichen die gleich dem Default-Zeichen sind, rausfliegen, nur leider gibt es dabei zu viele Fehler ...
GetTextMetrics enthält ja nur den Hinweis auf das zu verwendende Zeichen, wenn ein anderes Zeichen nicht existiert.
Ob es nicht existiert, kann ich daraus aber nicht ablesen.
GetFontUnicodeRanges wird (zumindest bei mir) garnicht unterstützt, fällt somit eh weg.
Ich habe auch schon Probiert, die Zeichenbreiten zu vergleichen, sodass Zeichen die gleich dem Default-Zeichen sind, rausfliegen, nur leider gibt es dabei zu viele Fehler ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Prüfen ob ein Zeichen in einer Font existiert
@STARGÅTE
Ja leider bietet PB nicht die volle WinAPI-Unterstützung.
GetFontUnicodeRanges_() musst du vorher aus der Gdi32.dll importieren, so dass dieser Befehl verwendet werden kann.
Ja leider bietet PB nicht die volle WinAPI-Unterstützung.
GetFontUnicodeRanges_() musst du vorher aus der Gdi32.dll importieren, so dass dieser Befehl verwendet werden kann.
Re: Prüfen ob ein Zeichen in einer Font existiert
Nicht so schnell aufgeben!STARGÅTE hat geschrieben:GetFontUnicodeRanges wird (zumindest bei mir) garnicht unterstützt, fällt somit eh weg.
Da es mit Imports auch nicht ging (PB hat keine aktuellen WinAPI-Import-Libs),
muß man es halt wieder über OpenLibrary() machen. Kein Problem.
Ich habe jetzt für Dich ein komplettes Beispiel geschrieben, welches für einen
ausgewählten Font alle Unicode-Ranges und alle dazugehörigen Unicode-Chars
anzeigt. Ich hoffe es hilft Dir als Einstieg.
Code: Alles auswählen
;
; by Danilo, April 2011, PB 4.51 (x86)
;
; GetFontUnicodeRanges_() demo
;
; - displays unicode character ranges for a given font
; - displays the unicode characters
;
; requires Windows 2000+
;
; http://forums.purebasic.com/german/viewtopic.php?f=16&t=24209
;
EnableExplicit
CompilerIf #PB_Compiler_Unicode = 0
MessageRequester("ERROR","Compile with Unicode support!")
End
CompilerEndIf
;---------------------------------------------------------------
; WinAPI Imports and Declarations
;---------------------------------------------------------------
Structure WCRANGE
wcLow.u
cGlyphs.u
EndStructure
Structure GLYPHSET
cbThis.l
flAccel.l
cGlyphsSupported.l
cRanges.l
ranges.WCRANGE[$FFFF]
EndStructure
Prototype.l GetFontUnicodeRanges(hdc.l, *gs.GLYPHSET)
Procedure.l GetFontUnicodeRanges_(hdc.l, *gs.GLYPHSET)
;
; [in] hdc A handle to the device context.
; [out] *gs.GLYPHSET A pointer to a GLYPHSET structure that receives
; the glyph set information.
; If this parameter is #Null, the function returns
; the size of the GLYPHSET Structure required
; To store the information.
;
; ReturnValue: If the function succeeds, it returns number of bytes
; written To the GLYPHSET Structure Or, If the *gs parameter
; is #Null, it returns the size of the GLYPHSET Structure
; required To store the information.
; If the function fails, it returns zero.
;
; Requirements: Windows 2000 Professional
;
Define gdi32.l, returnValue.l
Define gfur.GetFontUnicodeRanges
If OSVersion() >= #PB_OS_Windows_2000
gdi32 = OpenLibrary(#PB_Any,"gdi32.dll")
If gdi32
gfur = GetFunction(gdi32,"GetFontUnicodeRanges")
If gfur
returnValue = gfur(hdc,*gs)
EndIf
CloseLibrary(gdi32)
EndIf
EndIf
ProcedureReturn returnValue
EndProcedure
;---------------------------------------------------------------
Procedure getFontRanges( _font, List _ranges.WCRANGE())
;
; getFontRanges() fills the LinkedList _ranges()
; with the wide char ranges supported by _font
;
Define hdc, size, i, oldFont
Define *gs.GLYPHSET
ClearList( _ranges() )
hdc = GetDC_( 0 )
oldFont = SelectObject_(hdc,FontID(_font))
size = GetFontUnicodeRanges_(hdc,#Null)
If size
*gs = AllocateMemory(size)
If *gs
If GetFontUnicodeRanges_(hdc,*gs)
For i = 0 To *gs\cRanges-1
If AddElement( _ranges() )
_ranges()\wcLow = *gs\ranges[i]\wcLow
_ranges()\cGlyphs = *gs\ranges[i]\cGlyphs
EndIf
Next i
EndIf
FreeMemory(*gs)
EndIf
EndIf
SelectObject_(hdc,oldFont)
ReleaseDC_(0,hdc)
EndProcedure
Procedure UpdateListBoxes(lbRanges, lbOut, font)
;
; get the WCRANGES for font
; and update the listboxes
;
NewList ranges.WCRANGE()
getFontRanges( font, ranges() )
SendMessage_(GadgetID(lbRanges),#WM_SETREDRAW,0,0)
SendMessage_(GadgetID(lbOut),#WM_SETREDRAW,0,0)
ClearGadgetItems(lbRanges)
ClearGadgetItems(lbOut)
AddGadgetItem(lbRanges,-1," All")
ForEach ranges()
Define range$ = RSet(StrU(ranges()\wcLow,#PB_Unicode),5) + " - " + RSet(StrU(ranges()\wcLow+ranges()\cGlyphs-1,#PB_Unicode),5)
AddGadgetItem(lbRanges,-1,range$)
Next
SetGadgetState(lbRanges,0)
ForEach ranges()
Define j
For j = 0 To ranges()\cGlyphs-1
AddGadgetItem(lbOut,-1, Chr(ranges()\wcLow+j) )
Next
;AddGadgetItem(lbOut,-1,"-------------------")
Next
SendMessage_ (GadgetID(lbRanges),#WM_SETREDRAW,1,0)
SendMessage_ (GadgetID(lbOut) ,#WM_SETREDRAW,1,0)
RedrawWindow_(GadgetID(lbRanges),0,0,#RDW_ERASE|#RDW_FRAME|#RDW_INVALIDATE|#RDW_ALLCHILDREN)
RedrawWindow_(GadgetID(lbOut) ,0,0,#RDW_ERASE|#RDW_FRAME|#RDW_INVALIDATE|#RDW_ALLCHILDREN)
EndProcedure
Define mainWindow
Define fontButton, fontInfo, listBoxRanges, listBoxOutput
Define listBoxRangesFont, listBoxOutputFont, fontInfoFont, tempFont
Define currentFontName$, currentFontSize, currentFontStyle
Define eventGadget
Define listBoxRangesSelection$
Define listBoxRangesSelectionStart.q, listBoxRangesSelectionEnd.q
Define i
mainWindow = OpenWindow(#PB_Any,0,0,800,500,"GetFontUnicodeRanges_",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If mainWindow
currentFontName$ = "Arial"
currentFontSize = 24
currentFontStyle = 0
listBoxOutputFont = LoadFont(#PB_Any, currentFontName$, currentFontSize, currentFontStyle)
listBoxRangesFont = LoadFont(#PB_Any, "Lucida Console", 12)
fontInfoFont = LoadFont(#PB_Any, "Lucida Console", 18, #PB_Font_Bold)
fontButton = ButtonGadget(#PB_Any,10,5,150,25,"Set Font")
fontInfo = TextGadget(#PB_Any,170,5,620,25,currentFontName$+", "+Str(currentFontSize))
SetGadgetFont(fontInfo,FontID(fontInfoFont))
TextGadget(#PB_Any,10,35,155,20,"Unicode Ranges:")
listBoxRanges = ListViewGadget(#PB_Any,10,55,155,440)
SetGadgetFont(listBoxRanges,FontID(listBoxRangesFont))
SetGadgetColor(listBoxRanges,#PB_Gadget_FrontColor,RGB($00,$FF,$80))
SetGadgetColor(listBoxRanges,#PB_Gadget_BackColor ,RGB($00,$00,$00))
TextGadget(#PB_Any,170,35,150,20,"Valid Characters:")
listBoxOutput = ListViewGadget(#PB_Any,170,55,620,440)
SetGadgetFont(listBoxOutput,FontID(listBoxOutputFont))
SetGadgetColor(listBoxOutput,#PB_Gadget_FrontColor,RGB($00,$FF,$80))
SetGadgetColor(listBoxOutput,#PB_Gadget_BackColor ,RGB($00,$00,$00))
UpdateListBoxes(listBoxRanges,listBoxOutput,listBoxOutputFont)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
eventGadget = EventGadget()
If EventGadget = fontButton
If FontRequester(currentFontName$, currentFontSize,0,0,currentFontStyle)
currentFontName$ = SelectedFontName()
currentFontSize = SelectedFontSize()
currentFontStyle = SelectedFontStyle()
tempFont = listBoxOutputFont
listBoxOutputFont = LoadFont(#PB_Any, currentFontName$, currentFontSize, currentFontStyle)
SetGadgetFont(listBoxOutput,FontID(listBoxOutputFont))
SetGadgetText(fontInfo, currentFontName$+", "+Str(currentFontSize))
UpdateListBoxes(listBoxRanges,listBoxOutput,listBoxOutputFont)
FreeFont(tempFont)
EndIf
ElseIf EventGadget = listBoxRanges
listBoxRangesSelection$ = GetGadgetItemText(listBoxRanges,GetGadgetState(listBoxRanges))
If listBoxRangesSelection$ = " All"
UpdateListBoxes(listBoxRanges,listBoxOutput,listBoxOutputFont)
Else
listBoxRangesSelectionStart = Val(StringField(listBoxRangesSelection$,1,"-"))
listBoxRangesSelectionEnd = Val(StringField(listBoxRangesSelection$,2,"-"))
SendMessage_ (GadgetID(listBoxOutput),#WM_SETREDRAW,0,0)
ClearGadgetItems(listBoxOutput)
For i = listBoxRangesSelectionStart To listBoxRangesSelectionEnd
AddGadgetItem(listBoxOutput,-1, Chr(i) )
Next i
SendMessage_ (GadgetID(listBoxOutput),#WM_SETREDRAW,1,0)
RedrawWindow_(GadgetID(listBoxOutput),0,0,#RDW_ERASE|#RDW_FRAME|#RDW_INVALIDATE|#RDW_ALLCHILDREN)
EndIf
EndIf
EndSelect
ForEver
EndIf
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Prüfen ob ein Zeichen in einer Font existiert
Danke Danilo,
dieser Code ist schon mal ein Schritt in die richtige Richtung.
Ganz zufriden bin ich jedoch trotzdem nicht mit dem Ergebnis, da bei manchen Fonts immer noch diese Rechtecke dabei sind.
Aber ich vermute dort, dass die Font einfach "zu billig" ist, und diese Intervalle garnicht unterstützt, oder irgendwie so.
Auf jedenfall hilft mir dein Code weiter, also danke ...
dieser Code ist schon mal ein Schritt in die richtige Richtung.
Ganz zufriden bin ich jedoch trotzdem nicht mit dem Ergebnis, da bei manchen Fonts immer noch diese Rechtecke dabei sind.
Aber ich vermute dort, dass die Font einfach "zu billig" ist, und diese Intervalle garnicht unterstützt, oder irgendwie so.
Auf jedenfall hilft mir dein Code weiter, also danke ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Prüfen ob ein Zeichen in einer Font existiert
Das ist mir auch aufgefallen, bei einigen Fonts. Ich meine auch, daß dasSTARGÅTE hat geschrieben:Ganz zufrieden bin ich jedoch trotzdem nicht mit dem Ergebnis, da bei manchen Fonts immer noch diese Rechtecke dabei sind.
Aber ich vermute dort, dass die Font einfach "zu billig" ist, und diese Intervalle garnicht unterstützt, oder irgendwie so.
ein Fehler in den Fonts ist (manche Zeichen nicht implementiert, aber
trotzdem in der Unicode-Range angegeben), denn was wir hier nutzen ist
der offiziell dokumentierte Weg über GetFontUnicodeRanges_().
Microsofts Fonts scheinen aber sauber entwickelt worden zu sein.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Re: Prüfen ob ein Zeichen in einer Font existiert
Also ich habe eben mal eine Test-Font mit FontStruct erstellt:
Mit nur 8 Zeichen : abcd.ttf
Nach dem installieren, arbeitet der Code mit dieser Font richtig:
Auf jedenfall werden wirklich nur a-d und A-D angezeigt
Also Danke nochmal
Mit nur 8 Zeichen : abcd.ttf
Nach dem installieren, arbeitet der Code mit dieser Font richtig:
Klar 32 gibs immer (Leerzeichen), und 0 und 13 sind vermutlich FontStuct spezifisch ^^All
0 - 0
13 - 13
32 - 32
65 - 68
97 - 100
Auf jedenfall werden wirklich nur a-d und A-D angezeigt
Also Danke nochmal
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- juergenkulow
- Beiträge: 188
- Registriert: 22.12.2016 12:49
- Wohnort: :D_üsseldorf-Wersten
Re: Prüfen ob ein Zeichen in einer Font existiert U+1D400-7F
Hallo,
ich versuche zu prüfen ob ein Unicode-Zeichen größer $10000 in einem Font existiert.
Leider wird mir bei Unicode-Ranges als letztes dezimal 65024-65024 (hex $FE00) angezeigt.
Oder gibt es einen anderen Weg Windows nach der Existenz eines hohen Unicode-Zeichens in einem Font zu befragen?
Beispiel zu hohen Unicode Zeichen:
https://en.wikibooks.org/wiki/Unicode/C ... D000-1DFFF
ich versuche zu prüfen ob ein Unicode-Zeichen größer $10000 in einem Font existiert.
Code: Alles auswählen
currentFontName$ = "Cambria Math"
Liegt da ein Fehler bei der Größe des Typs vor, cGlyphs WCHAR: A 16-bit Unicode character kann $1D400 nicht darstellen?EDIT: WCRANGE\cGlyphs.w zu WCRANGE\cGlyphs.u geändert
Oder gibt es einen anderen Weg Windows nach der Existenz eines hohen Unicode-Zeichens in einem Font zu befragen?
Beispiel zu hohen Unicode Zeichen:
Code: Alles auswählen
Procedure.s UnicodeChr(Number.i)
Protected Buffer.q
If Number <= $FFFF
Buffer = Number
ProcedureReturn PeekS(@Buffer, -1, #PB_Unicode)
Else
Buffer = (Number-$10000)>>10 | ((Number-$10000)&$3FF)<<16 + $DC00D800
ProcedureReturn PeekS(@Buffer, -1, #PB_Unicode)
EndIf
EndProcedure
For i=$1D400 To $1D7FF : Text$+UnicodeChr(i) : Next i
If OpenWindow(0, 0, 0, 1900, 1000, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 1900, 1000)
LoadFont(0, "Cambria Math", 20)
If StartVectorDrawing(CanvasVectorOutput(0))
VectorFont(FontID(0), 20)
j=0
For i=1 To Len(Text$) Step 26*4
MovePathCursor(0,j)
j+20
DrawVectorText(Mid(Text$,i,26*4))
Next i
StopVectorDrawing()
EndIf
MessageRequester("$1D400-$1D7FF",Text$)
; Repeat
; Event = WaitWindowEvent()
; Until Event = #PB_Event_CloseWindow
EndIf
Bitte stelle Deine Fragen, denn den Erkenntnisapparat einschalten entscheidet über das einzig bekannte Leben im Universum.
Jürgen Kulow Wersten :D_üsseldorf NRW D Europa Erde Sonnensystem Lokale_Flocke Lokale_Blase Orion-Arm
Milchstraße Lokale_Gruppe Virgo-Superhaufen Laniakea Sichtbares_Universum
Jürgen Kulow Wersten :D_üsseldorf NRW D Europa Erde Sonnensystem Lokale_Flocke Lokale_Blase Orion-Arm
Milchstraße Lokale_Gruppe Virgo-Superhaufen Laniakea Sichtbares_Universum
Re: Prüfen ob ein Zeichen in einer Font existiert
Gute Frage juergenkulow,
auch ich habe nach dieser Möglichkeit schon gesucht, da ich auch einige Zeichen über $FFFF brauche, aber wissen will ob sie überhaupt existieren.
Nachdem ja nun DrawText usw. diese Zeichen mit den Surrogates richtig anzeigen, kann ich aber leider nicht die WIN API nutzen, da die Struktur dies wie du selbst erkannt hast nicht ausreicht (sie ist aber richtig definiert und kann nur bis $FFFF)
Ich habe leider bislang nichts gefunden.
auch ich habe nach dieser Möglichkeit schon gesucht, da ich auch einige Zeichen über $FFFF brauche, aber wissen will ob sie überhaupt existieren.
Nachdem ja nun DrawText usw. diese Zeichen mit den Surrogates richtig anzeigen, kann ich aber leider nicht die WIN API nutzen, da die Struktur dies wie du selbst erkannt hast nicht ausreicht (sie ist aber richtig definiert und kann nur bis $FFFF)
Ich habe leider bislang nichts gefunden.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr