Hallo,
ich habe eine Lösung gefunden, die ganz ohne API auskommt:
Code: Alles auswählen
; Returns the width (pixel) of a char respecting it's surrounding chars...
; IMPORTANT: This needs a current StartDrawing() context and a defined font!
Procedure.l GetCharWidth(Text.s, CharPos.l)
If CharPos.l < 2
; first char
Char1.s = Left(Text.s, 2) ; the first two
Char2.s = Mid(Text.s, 2, 1); without the needed
ProcedureReturn TextWidth(Char1.s) - TextWidth(Char2.s)
EndIf
If CharPos.l > Len(Text.s) - 1
; last char
Char1.s = Right(Text.s, 2) ; the last two
Char2.s = Right(Text.s, 1); without the needed
ProcedureReturn TextWidth(Char1.s) - TextWidth(Char2.s)
EndIf
If CharPos.l > 1 And CharPos.l < Len(Text.s)
; all other chars
Char1.s = Mid(Text.s, CharPos.l - 1, 3) ; all three
Char2.s = Left(Char1.s, 1) + Right(Char1.s, 1); without the needed
ProcedureReturn TextWidth(Char1.s) - TextWidth(Char2.s)
EndIf
EndProcedure
; ---------------- test routine ------------------
If OpenWindow(0, 100, 200, 595, 160, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
TestText.s = "Für diese Waffel braucht es Zucker!"
LoadFont(0, "Times New Roman", 22, #PB_Font_Italic)
StartDrawing(WindowOutput(0))
DrawingMode(#PB_2DDrawing_Transparent)
FrontColor(#Black)
BackColor(#White)
; set font
DrawingFont(FontID(0))
For x.l = 1 To Len(TestText.s)
; standard method
Char.s = Mid(TestText.s, x.l, 1)
Wi.l = TextWidth(Char.s)
DrawText(TextWidth1.l, 10, Char.s)
TextWidth1.l = TextWidth1.l + Wi.l
Debug "Originalbreite für " + Char.s + ": " + Str(Wi.l)
; new method
Wi.l = GetCharWidth(TestText.s, x.l)
DrawText(TextWidth2.l, 40, Char.s)
TextWidth2.l = TextWidth2.l + Wi.l
Debug "Neu für " + Char.s + ": " + Str(Wi.l)
Debug "------------------------------------------"
Next
StopDrawing()
FreeFont(0)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow ; If the user has pressed on the close button
Quit = 1
EndIf
Until Quit = 1
EndIf
End
Der Test zeigt zweimal die Zeichenkette. Die erste Zeile wird Zeichen für Zeichen mit der TextWidth() Methode berechnet. In der zweiten Zeile wird meine Routine verwendet.
Es funktioniert so, dass ich ja die Breite eines Zeichens aus einer Zeichenkette suche. Ich berechne zuerst die Breite incl. der beiden umgebenden Zeichen und entferne dann das gesuchte Zeichen. Die Differenz ist die gesuchte Breite. Klappt hier ganz gut (Verschiedene Schriften und Stile). Ich weiss, dass das nicht 100% klappt (hängt vom Zusammenpassen der umgebenden Zeichen ab), aber es ist eine gute Näherung.
Volker