Seite 2 von 2
Re: Font, DrawText, "wahre" Beite ermitteln
Verfasst: 29.09.2010 16:18
von bobobo
STARGÅTE hat geschrieben:Das hat mit Monospace nix zu tun bobobo!
Denn selbst wenn die Breite eines Zeichens immer gleich wäre, gibt mir auch dort TextWidth() die Breite im Text-Fluss zurück.
Damit werden auch bei diesen Fonts Serifen und Tropfen abgeschnitten, falls dieser außerhalb der Text-Fluss-Breite liegen.
aha .. dann bin ich ja gottseidank nur blind
Code: Alles auswählen
Enumeration
#Window : #Gadget : #Image
EndEnumeration
Global Font_vv = FontID(LoadFont(#PB_Any, "Times New Roman", 32,#PB_Font_Italic))
Global Font_ms = FontID(LoadFont(#PB_Any, "Courier", 32, #PB_Font_Italic))
CreateImage(#Image, 256, 256)
StartDrawing(ImageOutput(#Image))
DrawingFont(Font_vv)
DrawingMode(#PB_2DDrawing_Transparent)
t.s="f"
Box(10, 10, TextWidth(t), TextHeight(t), $808080)
DrawText(10, 10, t, $FFFFFF)
DrawingFont(Font_ms)
t.s="f"
Box(10, 110, TextWidth(t), TextHeight(t), $808080)
DrawText(10, 110, t, $FFFFFF)
StopDrawing()
SetClipboardImage(#Image)
OpenWindow(#Window, 0, 0, ImageWidth(#Image), ImageHeight(#Image), "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ImageGadget(#Gadget, 0, 0, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: Font, DrawText, "wahre" Beite ermitteln
Verfasst: 29.09.2010 17:24
von STARGÅTE
Dein Beispiel funktioniert nur, weil dort eh immer jeweils 8px an jede Seite addiert werden wenn diese Schift Kursiv ist ...
Code: Alles auswählen
Enumeration
#Image
EndEnumeration
Font_ms = FontID(LoadFont(#PB_Any, "Courier", 32))
Font_ms2 = FontID(LoadFont(#PB_Any, "Courier", 32, #PB_Font_Italic))
CreateImage(#Image, 256, 256)
StartDrawing(ImageOutput(#Image))
DrawingFont(Font_ms)
Debug TextWidth(" ")
Debug TextWidth(" ")
Debug TextWidth(" ")
Debug "---"
DrawingFont(Font_ms2)
Debug TextWidth(" ")
Debug TextWidth(" ")
Debug TextWidth(" ")
StopDrawing()
24
48
72
---
40
64
88
und normal hat Courier ja keine Serifen die außerhalb der Text-Fluss-Breite liegen
Wie gesagt, das Problem wird dadurch nicht behoben, sonden nur umgangen.
Re: Font, DrawText, "wahre" Beite ermitteln
Verfasst: 29.09.2010 18:59
von bobobo
also ein walkaround statt workaround .. und das ist besser als besser als nix

Re: Font, DrawText, "wahre" Beite ermitteln
Verfasst: 29.09.2010 19:19
von c4s
Stargate, mir ist gerade aufgefallen, dass du den Titel für die Forensuche anpassen solltest, denn nach
Beite sucht bestimmt keiner.

Re: Font, DrawText, "wahre" Breite ermitteln
Verfasst: 29.09.2010 19:29
von bobobo
ohne r hat die deutsche spache kaum saft und kaft
Re: Font, DrawText, "wahre" Breite ermitteln
Verfasst: 30.09.2010 16:41
von Kukulkan
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