GDI+ Textrendering (BB-Code)

  • Moin,

    Ich suche eine Funktion, die einen BB-Code behafteten Text anständig auf ein GFX zeichnet.
    Habe dazu schon etwas entworfen, scheitere aber grundsätzlich an der Unkenntnis der exakten Buchstabengröße. Dabei ist unrelevant wie groß die Buchstaben tatsächlich sind (dafür hätte ich eine Funktion), sondern wie groß der "Kasten" ist den sie beanspruchen. Für allgemeine Ratschläge bin ich natürlich auch offen ;)

    Hier mal als kleines Beispiel ein Skript.

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; Codes:
    ; X Kursiv
    ; X Fett
    ; X Unterstrichen
    ; X [c=rot] Roter Text [/code] - Farbe als Wort
    ; X

    [/autoit] [autoit]
    C: 6
    Text mit Farbe 6

    [autoit]- Farbe der 16 Windows Farben
    ; X [c=(0x)FF0000] Roter Text [/code] - Farbe als 24Bit Wert
    ; X [c=(0x)80FF0000] Halbtransparent Rot [/code] - Farbe als 32Bit Wert
    ; X [s] Durchgestrichen [/s]
    ; X Größe in Pixeln
    ; X [x=5] - Zur korrektur kann x und y angepasst werden
    ; X [y=-1] - Zur korrektur kann x und y angepasst werden

    [/autoit] [autoit][/autoit] [autoit]

    ; [center] Zentriert [/center]
    ; Schriftart
    ;
    ; https://autoit.de/www.a.de/bild.jpg
    ; Klick Mich

    [/autoit] [autoit][/autoit] [autoit]

    Global $sText = 'Hallo' & @CRLF & 'Das sieht total seltsam aus...' & @CRLF & _
    'Sowas möchte ich nicht zum Frühstück essen !' & @CRLF & _
    'Dies is[s]t ein sehr krea[/s]tiver Text' & @CRLF & @CRLF & @CRLF & _
    '[size=50]Hallo[y=10]du[y=0] Spaßvogel[/size]' & @CRLF & @CRLF & @CRLF & @CRLF & _
    '[size=50]a[size=40]bcdefghijklmnopqrstuvwxyz[/size][/size]' & @CRLF & _
    '

    [/autoit] [autoit]
    C: 10
    Far[size=30]big

    [autoit]so [c=dunkelrot]mag[/code] i[/size]ch [c=80FF8040]das[/code] !' & _
    @CRLF & @CRLF & '[c=ff0000]Das ist [y=-5]ein[y=0] Test[/code]' & @CRLF & @CRLF & _
    '[x=100]Update auf Version 0.0.0.1[x=0]' & @CRLF & _
    '' & @CRLF & _
    'Neu:' & @CRLF & _
    ' - Account über Webseite registrieren' & @CRLF & _
    ' - Ingame Login' & @CRLF & _
    ' - Ingame Menu' & @CRLF & _
    ' - Ein Berg auf dem sich ein kleines Dorf mit allen' & @CRLF & _
    ' momentanen Models befindet.' & @CRLF & _
    ' - Leichte Vegetation' & @CRLF & _
    ' - Man kann sich die Landschaft ansehen' & @CRLF & _
    '' & @CRLF & _
    'Bugfixes:' & @CRLF & _
    ' - Noch keine, da dies das "First Release" ist !' & @CRLF & _
    '' & @CRLF & _
    '[x=100]euer Team ;)[x=0]' & @CRLF & _
    '' & @CRLF & _
    '[y=-80][x=80][size=9]ich stehe einfach mittendrin :P'

    [/autoit] [autoit][/autoit] [autoit]

    Global $bRenew

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()
    Global $hGUI = GUICreate('Test', 1000, 500)
    Global $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    Global $hBMP = _GDIPlus_BitmapCreateFromGraphics(500, 500, $hGFX)
    Global $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
    Global $hEdit = GUICtrlCreateEdit($sText, 500, 0, 500, 500, 0x1000)
    _GDIPlus_GraphicsClear($hBUF, 0xFFFFFFFF)
    DllCall($ghGDIPDll, 'uint', 'GdipSetTextRenderingHint', 'hwnd', $hBUF, 'int', 5)
    _BB_Draw($hBUF, 0, 0, $sText)
    WM_PAINT()

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg(0x0111, 'WM_COMMAND')
    GUIRegisterMsg(0xF, 'WM_PAINT')
    GUISetState(@SW_SHOW, $hGUI)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ MouseClick(

    [/autoit] [autoit][/autoit] [autoit]

    While GUIGetMsg() <> -3
    If $bRenew Then
    _GDIPlus_GraphicsClear($hBUF, 0xFFFFFFFF)
    _BB_Draw($hBUF, 0, 0, GUICtrlRead($hEdit))
    WM_PAINT()
    $bRenew = False
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iCode = _WinAPI_HiWord($wParam)
    If $iCode = 768 Then $bRenew = True
    EndFunc ;==>WM_COMMAND

    [/autoit] [autoit][/autoit] [autoit]

    Func _BB_Draw($hGFX, $iX, $iY, $sText)
    $sText = StringReplace($sText, @CR, '', 0, 1)
    Local $iStepSizeX = 9, $iStepSizeY = 14, $sChar, $iStepX, $iStepY, $aFormat, $iLen, _
    $sFormat_Kursiv, $sFormat_Fett, $sFormat_BB_Farbe = 'FF000000', $sFormat_Unterstrichen, $sFormat_Size = '10', $sFormat_Font, $sFormat_Durchgestrichen, _
    $xOff = 0, $yOff = 0

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To StringLen($sText) Step 1
    $sChar = StringMid($sText, $i, 1)
    Switch $sChar
    Case '['
    For $o = $i To StringLen($sText) Step 1
    If StringMid($sText, $o, 1) = ']' Then
    $iLen = $o - $i
    ExitLoop
    EndIf
    Next
    _BB_SetFormat(StringMid($sText, $i + 1, $iLen - 1), $sFormat_Fett, $sFormat_Kursiv, $sFormat_Unterstrichen, $sFormat_Durchgestrichen, $sFormat_Size, $sFormat_BB_Farbe, $xOff, $yOff)
    $i += $iLen
    Case @LF
    $iStepY += 1
    $iStepX = 0
    Case Else
    $aFormat = _BB_GetFormat($sFormat_Fett, $sFormat_Kursiv, $sFormat_Unterstrichen, $sFormat_Durchgestrichen, $sFormat_Size, $sFormat_BB_Farbe)
    _BB_Char($hGFX, $iX + $iStepX * $iStepSizeX + $xOff, $iY + $iStepY * $iStepSizeY + $yOff, $sChar, $aFormat)
    $iStepX += 1 * Int('0x' & $aFormat[4]) / 16
    EndSwitch
    Next
    EndFunc ;==>_BB_Draw

    [/autoit] [autoit][/autoit] [autoit]

    Func _BB_SetFormat($s, ByRef $sFormat_Fett, ByRef $sFormat_Kursiv, ByRef $sFormat_Unterstrichen, ByRef $sFormat_Durchgestrichen, ByRef $sFormat_Size, ByRef $sFormat_BB_Farbe, ByRef $xOff, ByRef $yOff)
    Local $sLeft = StringLeft($s, 1)
    If $sLeft = '/' Then
    $s = StringTrimLeft($s, 1)
    Switch StringLeft($s, 1)
    Case 'b'
    $sFormat_Fett = StringTrimRight($sFormat_Fett, 2)
    Case 'i'
    $sFormat_Kursiv = StringTrimRight($sFormat_Kursiv, 2)
    Case 'u'
    $sFormat_Unterstrichen = StringTrimRight($sFormat_Unterstrichen, 2)
    Case 's'
    Switch StringLeft($s, 4)
    Case 'size'
    $sFormat_Size = StringTrimRight($sFormat_Size, 3)
    Case Else
    $sFormat_Durchgestrichen = StringTrimRight($sFormat_Durchgestrichen, 2)
    EndSwitch
    Case 'c'
    $sFormat_BB_Farbe = StringTrimRight($sFormat_BB_Farbe, 9)
    EndSwitch
    Else
    Switch StringLeft($s, 1)
    Case 'b'
    If $sFormat_Fett Then
    $sFormat_Fett &= '|1'
    Else
    $sFormat_Fett = '1'
    EndIf
    Case 'i'
    If $sFormat_Kursiv Then
    $sFormat_Kursiv &= '|1'
    Else
    $sFormat_Kursiv = '1'
    EndIf
    Case 'u'
    If $sFormat_Unterstrichen Then
    $sFormat_Unterstrichen &= '|1'
    Else
    $sFormat_Unterstrichen = '1'
    EndIf
    Case 's'
    Switch StringLeft($s, 5)
    Case 'size='
    If $sFormat_Size Then
    $sFormat_Size &= '|' & Hex(Int(StringTrimLeft($s, 5)), 2)
    Else
    $sFormat_Size = Hex(Int(StringTrimLeft($s, 5)), 2)
    EndIf
    Case Else
    If $sFormat_Durchgestrichen Then
    $sFormat_Durchgestrichen &= '|1'
    Else
    $sFormat_Durchgestrichen = '1'
    EndIf
    EndSwitch
    Case 'c'
    If $sFormat_BB_Farbe Then
    $sFormat_BB_Farbe &= '|' & _BB_Farbe($s)
    Else
    $sFormat_BB_Farbe = _BB_Farbe($s)
    EndIf
    Case 'x'
    $xOff = Int(StringTrimLeft($s, 2))
    Case 'y'
    $yOff = Int(StringTrimLeft($s, 2))
    EndSwitch
    EndIf
    EndFunc ;==>_BB_SetFormat

    [/autoit] [autoit][/autoit] [autoit]

    Func _BB_Farbe($s)
    Local $x = StringSplit($s, '=')
    Local $c = $x[$x[0]]
    Local Static $aDosCol[16] = [0xFF000000, 0xFF800000, 0xFF008000, 0xFF808000, 0xFF000080, 0xFF800080, 0xFF008080, 0xFFC0C0C0, 0xFF808080, 0xFFFF0000, 0xFF00FF00, 0xFFFFFF00, 0xFF0000FF, 0xFFFF00FF, 0xFF00FFFF, 0xFFFFFFFF]
    Local Static $aNamenEn[16] = ['black', 'maroon', 'green', 'olive', 'navy', 'purple', 'teal', 'silver', 'gray', 'red', 'lime', 'yellow', 'blue', 'fuchsia', 'aqua', 'white']
    Local Static $aNamenDe[16] = ['schwarz', 'dunkelrot', 'dunkelgrün', 'oliv', 'dunkelblau', 'lila', 'türkis', 'hellgrau', 'grau', 'rot', 'grün', 'gelb', 'blau', 'pink', 'hellblau', 'weiß']
    If StringIsXDigit($c) Then
    Switch StringLen($c)
    Case 1, 2
    $c = Int($c)
    $c -= Int($c / 16) * 16
    Return Hex($aDosCol[$c], 8)
    Case 6
    Return 'FF' & $c
    Case 8
    Return $c
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    Else
    For $i = 0 To 15 Step 1
    If ($c = $aNamenEn[$i]) Or ($c = $aNamenDe[$i]) Then
    ConsoleWrite($i & @CRLF)
    Return Hex($aDosCol[Int($i)], 8)
    EndIf
    Next
    EndIf
    Return 'FF000000'
    EndFunc ;==>_BB_Farbe

    [/autoit] [autoit][/autoit] [autoit]

    Func _BB_Char($hGFX, $iX, $iY, $sChar, $aFormat)
    Local $hBRU = _GDIPlus_BrushCreateSolid('0x' & $aFormat[5])
    Local $hFOR = _GDIPlus_StringFormatCreate()
    Local $hFAM = _GDIPlus_FontFamilyCreate('Courier New')
    Local $hFON = _GDIPlus_FontCreate($hFAM, Int('0x' & $aFormat[4]), $aFormat[0] * 1 + $aFormat[1] * 2 + $aFormat[2] * 4 + $aFormat[3] * 8, 2)
    Local $tRect = _GDIPlus_RectFCreate($iX - Int('0x' & $aFormat[4]) * 0.25 + 2, $iY - Int('0x' & $aFormat[4]) ^ 1.34 * 0.19 + 6)
    _GDIPlus_GraphicsDrawStringEx($hGFX, $sChar, $hFON, $tRect, $hFOR, $hBRU)
    _GDIPlus_FontDispose($hFON)
    _GDIPlus_FontFamilyDispose($hFAM)
    _GDIPlus_StringFormatDispose($hFOR)
    _GDIPlus_BrushDispose($hBRU)
    EndFunc ;==>_BB_Char

    [/autoit] [autoit][/autoit] [autoit]

    Func _BB_GetFormat($sFormat_Fett, $sFormat_Kursiv, $sFormat_Unterstrichen, $sFormat_Durchgestrichen, $sFormat_Size, $sFormat_BB_Farbe)
    Local $a[6], $b
    $b = StringSplit($sFormat_Fett, '|')
    $a[0] = $b[$b[0]]
    $b = StringSplit($sFormat_Kursiv, '|')
    $a[1] = $b[$b[0]]
    $b = StringSplit($sFormat_Unterstrichen, '|')
    $a[2] = $b[$b[0]]
    $b = StringSplit($sFormat_Durchgestrichen, '|')
    $a[3] = $b[$b[0]]
    $b = StringSplit($sFormat_Size, '|')
    $a[4] = $b[$b[0]]
    $b = StringSplit($sFormat_BB_Farbe, '|')
    $a[5] = $b[$b[0]]
    Return $a
    EndFunc ;==>_BB_GetFormat

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT()
    _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    EndFunc ;==>WM_PAINT

    [/autoit][/autoit][/autoit]


    Edit: Hab den Tag mal auf "gelöst" gesetzt, da ich glaube die Lösung gefunden zu haben.
    Sollte dem nicht so sein mache ich wieder auf und spezifiziere meine Frage neu.

    Edit2: Nun ist alles geklärt. :)
    lg
    Mars

  • Wenn du eine Funktion hast, um zu ermitteln wie groß die Buchstaben sind, wieso addierst du dann nicht Buchstabe für Buchstabe und kommst dann auf die Größe?

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Das ist ganz einfach. Meine Funktion checkt nur die Ränder. Es wird also der Buchstabe auf einem Transparenten Hintergrund gedacht und von allen 4 Seiten gesucht ob ein Pixel nicht transparent ist. Wird ein Pixel gefunden wird die Schranke nicht weiter verschoben. Zum Schluss hat man die Breite und Höhe des Buchstabens in Pixeln. Das Problem dabei ist, dass diese Größe nicht der Anzahl Pixel entspricht die der Buchstabe im Text beansprucht. Er ist vllt 15px breit, der Nächste kommt aber schon nach 13 Pixeln. (bsp.)
    Hab schonmal davon gehört, dass MeasureString ziemlich ungenau arbeitet. Irgendwo gab es ein Beispiel von Eukalyptus (glaube ich) indem über GDI+Path die Buchstabengröße sehr gut bestimmt wird. Dieses Verfahren kenne ich aber leider nicht und bräuchte ein Beispielskript um es zu verstehen.

  • Gibt es nicht Fonts bei denen alle Buchstaben gleich groß sind? Aber ich vermute du möchtest das Multifontkompatibel (schönes Wort, nicht? :P) machen...
    Dann probier doch mal Eukalyptus MeasureString... ich glaube yxyx hat hier so ziemlich die Lösung: [ offen ] GDIPlus MeasureString
    €: Wenn nicht gibts ja hier ein Beispiel der Hilfe.
    Oder hier noch ne andere Funktion von BugFix (Idee: Das ganze erst als Label unvisible zeichnen, mit gleichen Properties, dann messen und dann per GDI+ ausgeben nachdem gemessen wurde).

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Ich werde das Skript mal neu schreiben und MeasureString verwenden.
    Ich bin mir aber sicher mal gelesen zu haben, dass diese Funktion unzureichend ist, wenn man einzelne Buchstaben damit vermisst.
    Der Umschrieb wird ne Weile dauern, da ich jetzt grade nicht viel Zeit habe.

    Edit: Hab grade glaube ich die Path Version gefunden Klick Mich

  • Ich hab ein Beispiel erstellt, das verschiende Möglichkeiten der Stringabmessung zeigen soll:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <StructureConstants.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)
    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $iWidth = 1200
    Global $iHeight = 700

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui = GUICreate("Test", $iWidth, $iHeight)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Global $hGfxBuffer1 = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer1, 2)
    GUIRegisterMsg($WM_PAINT, "_WM_PAINT")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsClear($hGfxBuffer1, 0xFFFFFFFF)
    _Test($hGfxBuffer1, "abcdefg", "Arial", 30, 10, 90)
    _Test($hGfxBuffer1, "abcdefg", "Courier New", $iWidth / 2, 10, 90)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 97 To 103
    _Test($hGfxBuffer1, Chr($i), "Arial", 30 + ($i - 97) * 150, 230, 60)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _Test($hGfxBuffer1, "abcdefg", "Arial", 30, 470, 20)
    _Test($hGfxBuffer1, "abcdefg", "Courier New", 30, 570, 20)

    [/autoit] [autoit][/autoit] [autoit]

    _Test($hGfxBuffer1, "ÁA", "Arial", 300, 370, 180)
    _Test($hGfxBuffer1, "Q", "Courier New", 900, 370, 180)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Test($hGraphics, $sString, $sFont, $iX, $iY, $fSize, $iStyle = 0)
    Local $fX, $fY, $fW, $fH

    [/autoit] [autoit][/autoit] [autoit]

    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipGetDpiY", "hwnd", $hGraphics, "float*", 0)
    Local $fDPIY = $aResult[2]

    [/autoit] [autoit][/autoit] [autoit]

    Local $hPenR = _GDIPlus_PenCreate(0xFFFF0000)
    Local $hPenG = _GDIPlus_PenCreate(0xFF00FF00)
    Local $hPenB = _GDIPlus_PenCreate(0xFF0000FF)
    Local $hPenY = _GDIPlus_PenCreate(0xFFFFBB00)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBrushR = _GDIPlus_BrushCreateSolid(0x88FF0000)
    Local $hBrushG = _GDIPlus_BrushCreateSolid(0x8800FF00)
    Local $hBrushB = _GDIPlus_BrushCreateSolid(0x880000FF)
    Local $hBrushY = _GDIPlus_BrushCreateSolid(0x44FFBB00)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    Local $tLayout = _GDIPlus_RectFCreate($iX, $iY, 0, 0)
    Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "hwnd", $hGraphics, "int", 4)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Messen via MeasureString:
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hFormat)
    _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hFormat, $hBrushG)

    [/autoit] [autoit][/autoit] [autoit]

    $fX = DllStructGetData($aInfo[0], "X")
    $fY = DllStructGetData($aInfo[0], "Y")
    $fW = DllStructGetData($aInfo[0], "Width")
    $fH = DllStructGetData($aInfo[0], "Height")
    DllCall($ghGDIPDll, "int", "GdipDrawRectangle", "handle", $hGraphics, "handle", $hPenG, "float", $fX, "float", $fY, "float", $fW, "float", $fH)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Char Höhe auslesen:
    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetEmHeight", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $iEMHeight = $aResult[3]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetCellAscent", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $fAsc = Ceiling(($fSize / $iEMHeight * $aResult[3]) * $fDPIY / 72)

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetCellDescent", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $fDesc = Ceiling(($fSize / $iEMHeight * $aResult[3]) * $fDPIY / 72)

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetLineSpacing", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $fLnSpac = Ceiling(($fSize / $iEMHeight * $aResult[3]) * $fDPIY / 72)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $fX = $iX
    $fY = $iY + $fAsc
    $fH = 0
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGraphics, "handle", $hPenR, "float", $fX, "float", $fY, "float", $fX + $fW + 50, "float", $fY + $fH)

    [/autoit] [autoit][/autoit] [autoit]

    $fX += $fW + 10
    $fY = $iY
    $fW = 0
    $fH = $fAsc
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGraphics, "handle", $hPenR, "float", $fX, "float", $fY, "float", $fX + $fW, "float", $fY + $fH)

    [/autoit] [autoit][/autoit] [autoit]

    $fX += 10
    $fY += $fAsc
    $fH = $fDesc
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGraphics, "handle", $hPenR, "float", $fX, "float", $fY, "float", $fX + $fW, "float", $fY + $fH)

    [/autoit] [autoit][/autoit] [autoit]

    $fX += 10
    $fY = $iY
    $fH = $fLnSpac
    DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGraphics, "handle", $hPenR, "float", $fX, "float", $fY, "float", $fX + $fW, "float", $fY + $fH)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Box Größe auslesen:
    Local $tRanges = DllStructCreate("int Pos; int Cnt;")
    DllStructSetData($tRanges, "Pos", 0)
    DllStructSetData($tRanges, "Cnt", StringLen($sString))

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipSetStringFormatMeasurableCharacterRanges", "hwnd", $hFormat, "int", 1, "ptr", DllStructGetPtr($tRanges))

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetStringFormatMeasurableCharacterRangeCount", "hwnd", $hFormat, "int*", 0)
    Local $iCount = $aResult[2]
    If $iCount >= 1 Then
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateRegion", "int*", 0)
    Local $hRegion = $aResult[1]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipMeasureCharacterRanges", "hwnd", $hGraphics, "wstr", $sString, "int", -1, "hwnd", $hFont, "ptr", DllStructGetPtr($aInfo[0]), "hwnd", $hFormat, "int", 1, "hwnd*", $hRegion)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tBounds = DllStructCreate($tagGDIPRECTF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetRegionBounds", "hwnd", $hRegion, "hwnd", $hGraphics, "ptr", DllStructGetPtr($tBounds))

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipFillRegion", "hwnd", $hGraphics, "hwnd", $hBrushY, "hwnd", $hRegion)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipDeleteRegion", "hwnd", $hRegion)

    [/autoit] [autoit][/autoit] [autoit]

    $fX = DllStructGetData($tBounds, "X")
    $fY = DllStructGetData($tBounds, "Y")
    $fW = DllStructGetData($tBounds, "Width")
    $fH = DllStructGetData($tBounds, "Height")
    DllCall($ghGDIPDll, "int", "GdipDrawRectangle", "handle", $hGraphics, "handle", $hPenY, "float", $fX, "float", $fY, "float", $fW, "float", $fH)
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Messen via Path
    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreatePath", "int", 0, "int*", 0)
    Local $hPath = $aResult[2]

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipAddPathString", "hwnd", $hPath, "wstr", $sString, "int", -1, "hwnd", $hFamily, "int", $iStyle, "float", $fSize * $fDPIY / 72, "ptr", DllStructGetPtr($tLayout), "hwnd", $hFormat)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tBounds = DllStructCreate($tagGDIPRECTF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetPathWorldBounds", "hwnd", $hPath, "struct*", $tBounds, "hwnd", 0, "hwnd", 0)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGraphics, "hwnd", $hPenB, "hwnd", $hPath)

    [/autoit] [autoit][/autoit] [autoit]

    $fX = DllStructGetData($tBounds, "X")
    $fY = DllStructGetData($tBounds, "Y")
    $fW = DllStructGetData($tBounds, "Width")
    $fH = DllStructGetData($tBounds, "Height")
    DllCall($ghGDIPDll, "int", "GdipDrawRectangle", "handle", $hGraphics, "handle", $hPenB, "float", $fX, "float", $fY, "float", $fW, "float", $fH)
    DllCall($ghGDIPDll, "uint", "GdipDeletePath", "hwnd", $hPath)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BrushDispose($hBrushR)
    _GDIPlus_BrushDispose($hBrushG)
    _GDIPlus_BrushDispose($hBrushB)
    _GDIPlus_BrushDispose($hBrushY)
    _GDIPlus_PenDispose($hPenR)
    _GDIPlus_PenDispose($hPenG)
    _GDIPlus_PenDispose($hPenB)
    _GDIPlus_PenDispose($hPenY)
    EndFunc ;==>_Test

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _WM_PAINT($hWnd, $iMsg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>_WM_PAINT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_GraphicsDispose($hGfxBuffer1)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete($hGui)
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Der String wird mit DrawString in Grün gezeichnet. Der Umriß in Blau ist der String in einem Path.
    Achtung! Drawstring und PathString sind unterschiedlich breit! (zwar nur minimal, aber doch merkbar)

    Das grüne Rechteck ist der Bereich, welcher via _GDIPlus_GraphicsMeasureString berechnet wird.
    Die roten Linien zeigen die Höhe der Schrift: Ascent, Descent und LineSpacing
    Der gelbe Bereich zeigt die "Box" der Schrift an (diese Methode funktioniert auch Zeilenübergrifend und kann z.B. zum Markieren einer Textstelle verwendet werden)
    Das blaue Rechteck zeigt die tatsächliche Größe der Buchstaben. (Zeigt die Größe der Schrift im Path und entspricht leider nicht "ganz" genau der Breite von _GDIPlus_GraphicsDrawStringEx (noch größere Abweichung, wenn man GdipSetTextRenderingHint verändert!))

    lgE

  • Vielen Dank :)
    Das ist exakt das was ich gesucht habe.
    Mit all diesen Informationen müsste es machbar sein ein anständiges Renderingverfahren zu basteln.
    Wird zwar nicht besonderst schnell sein, aber mit GDI+ funktionieren, und darauf kommt es an :P

    lg
    Mars

  • Ich hab mich mal an einer Version versucht:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <StructureConstants.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $sText = 'Hallo' & @CRLF & 'Das sieht total seltsam aus...' & @CRLF & _
    'Sowas möchte ich nicht zum Frühstück essen !' & @CRLF & _
    'Dies is[s]t ein sehr krea[/s]tiver Text' & @CRLF & @CRLF & @CRLF & _
    '[size=50]Hallo[y=10]du[y=0] Spaßvogel[/size]' & @CRLF & @CRLF & @CRLF & @CRLF & _
    '[size=50]a[size=40]bcdefghijklmnopqrstuvwxyz[/size][/size]' & @CRLF & _
    '

    [/autoit] [autoit]
    C: 10
    Far[size=30]big

    [autoit]so [c=dunkelrot]mag[/code] i[/size]ch [c=80FF8040]das[/code] !' & _
    @CRLF & @CRLF & '[c=ff0000]Das ist [y=-5]ein[y=0] Test[/code]' & @CRLF & @CRLF & _
    '[x=100]Update auf Version 0.0.0.1[x=0]' & @CRLF & _
    '' & @CRLF & _
    'Neu:' & @CRLF & _
    ' - Account über Webseite registrieren' & @CRLF & _
    ' - Ingame Login' & @CRLF & _
    ' - Ingame Menu' & @CRLF & _
    ' - Ein Berg auf dem sich ein kleines Dorf mit allen' & @CRLF & _
    ' momentanen Models befindet.' & @CRLF & _
    ' - Leichte Vegetation' & @CRLF & _
    ' - Man kann sich die Landschaft ansehen' & @CRLF & _
    '' & @CRLF & _
    '[center]Bugfixes[/center]:' & @CRLF & _
    ' - Noch keine, da dies das "First Release" ist !' & @CRLF & _
    '' & @CRLF & _
    '[x=100]euer Team ;)[x=0]' & @CRLF & _
    '' & @CRLF & _
    '[y=-80][x=80][size=9]ich stehe einfach mittendrin :P'

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)
    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $iWidth = 500
    Global $iHeight = 700

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui = GUICreate("Test", $iWidth, $iHeight, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX))
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_SIZE, "_WM_SIZE")
    GUIRegisterMsg($WM_PAINT, "_WM_PAINT")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFFFFFFFF)
    ;_BBCode_Draw($sText, $hGfxBuffer, 10, 10, 780, 680, 4)
    _BBCode_Draw($sText, $hGfxBuffer, 10, 10, $iWidth-20, $iHeight-20, 0)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _BBCode_GetColor($sFormat)
    Local $aRegExp = StringRegExp($sFormat, "=\h*(.+)", 3)
    If Not IsArray($aRegExp) Then Return "0xFF000000"

    [/autoit] [autoit][/autoit] [autoit]

    Local $iColor = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    Local Static $aDosCol[16] = [0xFF000000, 0xFF800000, 0xFF008000, 0xFF808000, 0xFF000080, 0xFF800080, 0xFF008080, 0xFFC0C0C0, 0xFF808080, 0xFFFF0000, 0xFF00FF00, 0xFFFFFF00, 0xFF0000FF, 0xFFFF00FF, 0xFF00FFFF, 0xFFFFFFFF]
    Local Static $aNamenEn[16] = ['black', 'maroon', 'green', 'olive', 'navy', 'purple', 'teal', 'silver', 'gray', 'red', 'lime', 'yellow', 'blue', 'fuchsia', 'aqua', 'white']
    Local Static $aNamenDe[16] = ['schwarz', 'dunkelrot', 'dunkelgrün', 'oliv', 'dunkelblau', 'lila', 'türkis', 'hellgrau', 'grau', 'rot', 'grün', 'gelb', 'blau', 'pink', 'hellblau', 'weiß']
    If StringIsXDigit($iColor) Then
    Switch StringLen($iColor)
    Case 1, 2
    $iColor = Int($iColor)
    $iColor -= Int($iColor / 16) * 16
    Return "0x" & Hex($aDosCol[$iColor], 8)
    Case 6
    Return "0xFF" & $iColor
    Case 8
    Return "0x" & $iColor
    Case 10
    Return $iColor
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    Else
    For $i = 0 To 15 Step 1
    If ($iColor = $aNamenEn[$i]) Or ($iColor = $aNamenDe[$i]) Then
    Return "0x" & Hex($aDosCol[Int($i)], 8)
    EndIf
    Next
    EndIf
    Return "0xFF000000"
    EndFunc ;==>_BBCode_GetColor

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _BBCode_Format(ByRef $aFormat, $sFormat, $hFormat, ByRef $hFamily, ByRef $hFont, ByRef $hBrush, ByRef $fXOff, ByRef $fYOff)
    Local $aRegExp = StringRegExp($sFormat, "[^=]+", 3)
    If Not IsArray($aRegExp) Then
    MsgBox(0, "", "Error")
    Return
    EndIf
    Local $sCode = $aRegExp[0]
    Local $sFirst = StringLeft($sCode, 1)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $iStyle = 0, $fSize = 10, $iColor = 0xFF000000, $sFont = "Arial"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Switch $sFirst
    Case "/"
    $sCode = StringTrimLeft($sCode, 1)

    [/autoit] [autoit][/autoit] [autoit]

    Switch $sCode
    Case "i", "b", "u", "s" ;restore last style
    $aFormat[1] = StringRegExpReplace($aFormat[1], "([^;]*;)", "", 1)
    $aRegExp = StringRegExp($aFormat[1], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]
    $aRegExp = StringRegExp($aFormat[0], "([^;]*)", 3)
    If IsArray($aRegExp) Then $fSize = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! old Style: " & $iStyle & " size: " & $fSize & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle, 2)

    [/autoit] [autoit][/autoit] [autoit]

    Case "size" ;restore last size
    $aFormat[0] = StringRegExpReplace($aFormat[0], "([^;]*;)", "", 1)
    $aRegExp = StringRegExp($aFormat[1], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]
    $aRegExp = StringRegExp($aFormat[0], "([^;]*)", 3)
    If IsArray($aRegExp) Then $fSize = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! old Size: " & $fSize & " style: " & $iStyle & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle, 2)

    [/autoit] [autoit][/autoit] [autoit]

    Case "c" ;restore last color
    $aFormat[2] = StringRegExpReplace($aFormat[2], "([^;]*;)", "", 1)
    $aRegExp = StringRegExp($aFormat[2], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iColor = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BrushSetSolidColor($hBrush, $iColor)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! old color: " & $iColor & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Case "font"
    $aFormat[3] = StringRegExpReplace($aFormat[3], "([^;]*;)", "", 1)
    $aRegExp = StringRegExp($aFormat[3], "([^;]*)", 3)
    If IsArray($aRegExp) Then $sFont = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    $aRegExp = StringRegExp($aFormat[0], "([^;]*)", 3)
    If IsArray($aRegExp) Then $fSize = $aRegExp[0]
    $aRegExp = StringRegExp($aFormat[1], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! old Font: " & $sFont & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle, 2)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #cs
    Case "center"
    $iStyle = 0
    $aFormat[4] = StringRegExpReplace($aFormat[4], "([^;]*;)", "", 1)
    $aRegExp = StringRegExp($aFormat[4], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! Old Align: " & $iStyle & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_StringFormatSetAlign($hFormat,$iStyle)
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    Case Else
    Switch $sCode
    Case "i", "b", "u", "s" ;Set new Style
    $aRegExp = StringRegExp($aFormat[1], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]
    $aRegExp = StringRegExp($aFormat[0], "([^;]*)", 3)
    If IsArray($aRegExp) Then $fSize = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    Switch $sFirst
    Case "i" ;Kursiv
    $iStyle = BitOR($iStyle, 2)
    Case "b" ;Fett
    $iStyle = BitOR($iStyle, 1)
    Case "u" ;Unterstrichen
    $iStyle = BitOR($iStyle, 4)
    Case "s" ;Durchgestrichen
    $iStyle = BitOR($iStyle, 8)
    EndSwitch
    $aFormat[1] = $iStyle & ";" & $aFormat[1]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! new Style: " & $iStyle & " size: " & $fSize & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle, 2)

    [/autoit] [autoit][/autoit] [autoit]

    Case "size"
    $aRegExp = StringRegExp($aFormat[1], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    $aRegExp = StringRegExp($sFormat, "=\h*(.*)", 3)
    If IsArray($aRegExp) Then $fSize = StringStripWS($aRegExp[0], 8)

    [/autoit] [autoit][/autoit] [autoit]

    $aFormat[0] = $fSize & ";" & $aFormat[0]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! new Size: " & $fSize & " style: " & $iStyle & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle, 2)

    [/autoit] [autoit][/autoit] [autoit]

    Case "c" ;set new color
    $iColor = _BBCode_GetColor($sFormat)
    $aFormat[2] = $iColor & ";" & $aFormat[2]
    _GDIPlus_BrushSetSolidColor($hBrush, $iColor)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! new color: " & $iColor & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Case "x"
    $aRegExp = StringRegExp($sFormat, "=\h*(.*)", 3)
    If IsArray($aRegExp) Then $fXOff = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    Case "y"
    $aRegExp = StringRegExp($sFormat, "=\h*(.*)", 3)
    If IsArray($aRegExp) Then $fYOff = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Case "font"
    $aRegExp = StringRegExp($aFormat[0], "([^;]*)", 3)
    If IsArray($aRegExp) Then $fSize = $aRegExp[0]
    $aRegExp = StringRegExp($aFormat[1], "([^;]*)", 3)
    If IsArray($aRegExp) Then $iStyle = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    $aRegExp = StringRegExp($sFormat, "=\h*(.*)", 3)
    If IsArray($aRegExp) Then $sFont = $aRegExp[0]

    [/autoit] [autoit][/autoit] [autoit]

    $aFormat[3] = $sFont & ";" & $aFormat[3]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! new Font: " & $sFont & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle, 2)

    [/autoit] [autoit][/autoit] [autoit]

    #cs
    Case "center"
    $iStyle = 1
    $aFormat[4] = $iStyle & ";" & $aFormat[4]

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("! Set Align: " & $iStyle & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("Error: " & _GDIPlus_StringFormatSetAlign($hFormat,$iStyle) & @CRLF)
    #ce

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    EndSwitch
    EndSwitch
    EndFunc ;==>_BBCode_Format

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _BBCode_CalcDim($sChar, $hGraphics, $hFormat, $hFamily, $hFont, $tRectF)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipGetFontStyle", "hwnd", $hFont, "int*", 0)
    Local $iStyle = $aResult[2]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetFontSize", "hwnd", $hFont, "float*", 0)
    Local $fSize = $aResult[2]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetEmHeight", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $iEMHeight = $aResult[3]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetCellAscent", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $fAsc = $fSize / $iEMHeight * $aResult[3]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetCellDescent", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $fDesc = $fSize / $iEMHeight * $aResult[3]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetLineSpacing", "hwnd", $hFamily, "int", $iStyle, "ushort*", 0)
    Local $fLnSpac = $fSize / $iEMHeight * $aResult[3]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateRegion", "int*", 0)
    Local $hRegion = $aResult[1]

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall($ghGDIPDll, "uint", "GdipMeasureCharacterRanges", "hwnd", $hGraphics, "wstr", $sChar, "int", -1, "hwnd", $hFont, "ptr", DllStructGetPtr($tRectF), "hwnd", $hFormat, "int", 1, "hwnd*", $hRegion)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tBounds = DllStructCreate($tagGDIPRECTF)
    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetRegionBounds", "hwnd", $hRegion, "hwnd", $hGraphics, "ptr", DllStructGetPtr($tBounds))

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($ghGDIPDll, "uint", "GdipDeleteRegion", "hwnd", $hRegion)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRet[7]
    $aRet[0] = DllStructGetData($tBounds, "X")
    $aRet[1] = DllStructGetData($tBounds, "Y")
    $aRet[2] = DllStructGetData($tBounds, "Width")
    $aRet[3] = DllStructGetData($tBounds, "Height")
    $aRet[4] = $fAsc
    $aRet[5] = $fDesc
    $aRet[6] = $fLnSpac

    [/autoit] [autoit][/autoit] [autoit]

    Return $aRet
    EndFunc ;==>_BBCode_CalcDim

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _BBCode_Draw($sBBCode, $hGraphics, $iX, $iY, $iW, $iH, $iRenteringHint)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRegExp = StringRegExp($sBBCode, "\[(.*?)\]([^[]*)", 3)
    If Not IsArray($aRegExp) Then Return SetError(1, 1, False)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aFormat[6]
    $aFormat[0] = "12.5;" ;Size
    $aFormat[1] = "0;" ;Style
    $aFormat[2] = "0xFF000000;" ;Color
    $aFormat[3] = "Courier New;" ;Font
    $aFormat[4] = "0" ;Alignment = Left

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBmpText = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    Local $hGfxText = _GDIPlus_ImageGetGraphicsContext($hBmpText)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hPen = _GDIPlus_PenCreate(0xFFAA0000)
    _GDIPlus_GraphicsDrawRect($hGfxText, 0, 0, $iW - 1, $iH - 1, $hPen)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
    Local $hFormat = _GDIPlus_StringFormatCreate()
    Local $hFamily = _GDIPlus_FontFamilyCreate("Courier New")
    Local $tRectFZero = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    Local $tRectF = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    Local $hFont = _GDIPlus_FontCreate($hFamily, 12.5, 0, 2)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $tRanges = DllStructCreate("int Pos; int Cnt;")
    DllStructSetData($tRanges, "Pos", 0)
    DllStructSetData($tRanges, "Cnt", 1)
    DllCall($ghGDIPDll, "uint", "GdipSetStringFormatMeasurableCharacterRanges", "hwnd", $hFormat, "int", 1, "ptr", DllStructGetPtr($tRanges))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $hBmpLine = _GDIPlus_BitmapCreateFromGraphics($iW, $iH * 2, $hGfxText)
    Local $hGfxLine = _GDIPlus_ImageGetGraphicsContext($hBmpLine)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "hwnd", $hGfxLine, "int", $iRenteringHint)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iCnt = Ceiling(UBound($aRegExp) / 2)

    [/autoit] [autoit][/autoit] [autoit]

    Local $fPosX = 0, $fPosY = 0
    Local $fLineSpacing = 0
    Local $fPosXOff = 0, $fPosYOff = 0
    Local $fXOff = 0, $fYOff = 0

    [/autoit] [autoit][/autoit] [autoit]

    Local $aSplit, $aDim[7]
    For $i = 0 To UBound($aRegExp) - 1 Step 2
    ConsoleWrite("+ " & $aRegExp[$i] & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _BBCode_Format($aFormat, $aRegExp[$i], $hFormat, $hFamily, $hFont, $hBrush, $fXOff, $fYOff)

    [/autoit] [autoit][/autoit] [autoit]

    $aSplit = StringSplit(StringStripCR($aRegExp[$i + 1]), "")
    For $j = 1 To $aSplit[0]
    Switch $aSplit[$j]
    Case @LF
    $fPosY += $fPosYOff
    $fPosX = 0
    _GDIPlus_GraphicsDrawImage($hGfxText, $hBmpLine, 0, -$iH + $fPosY)
    _GDIPlus_GraphicsDispose($hGfxLine)
    _GDIPlus_BitmapDispose($hBmpLine)
    ;_GDIPlus_GraphicsDrawLine($hGfxText, 0, $fPosY, 10, $fPosY, $hPen)
    $hBmpLine = _GDIPlus_BitmapCreateFromGraphics($iW, $iH * 2, $hGfxText)
    $hGfxLine = _GDIPlus_ImageGetGraphicsContext($hBmpLine)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "hwnd", $hGfxLine, "int", $iRenteringHint)
    $fPosYOff = 0
    $fPosXOff = 0
    $aDim = _BBCode_CalcDim("-", $hGfxLine, $hFormat, $hFamily, $hFont, $tRectFZero)
    $aDim[0] = 0
    $aDim[2] = 0
    Case " "
    $aDim = _BBCode_CalcDim("-", $hGfxLine, $hFormat, $hFamily, $hFont, $tRectFZero)
    Case Else
    $aDim = _BBCode_CalcDim($aSplit[$j], $hGfxLine, $hFormat, $hFamily, $hFont, $tRectFZero)
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $fPosX += $fPosXOff
    $fPosXOff = $aDim[2]

    [/autoit] [autoit][/autoit] [autoit]

    If $fPosX + $fPosXOff + $fXOff >= $iW Then
    $fPosY += $fPosYOff
    $fPosX = 0
    _GDIPlus_GraphicsDrawImage($hGfxText, $hBmpLine, 0, -$iH + $fPosY)
    _GDIPlus_GraphicsDispose($hGfxLine)
    _GDIPlus_BitmapDispose($hBmpLine)
    $hBmpLine = _GDIPlus_BitmapCreateFromGraphics($iW, $iH * 2, $hGfxText)
    $hGfxLine = _GDIPlus_ImageGetGraphicsContext($hBmpLine)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "hwnd", $hGfxLine, "int", $iRenteringHint)
    $fPosYOff = 0
    ;$fPosXOff = 0
    $aDim = _BBCode_CalcDim("-", $hGfxLine, $hFormat, $hFamily, $hFont, $tRectFZero)
    ;$aDim[0] = 0
    $aDim[2] = 0
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($tRectF, "X", $fPosX - $aDim[0] + $fXOff)
    DllStructSetData($tRectF, "Y", $iH - $aDim[4] + $fYOff)
    If $aDim[6] > $fPosYOff Then $fPosYOff = Ceiling($aDim[6])
    _GDIPlus_GraphicsDrawStringEx($hGfxLine, $aSplit[$j], $hFont, $tRectF, $hFormat, $hBrush)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_PenDispose($hPen)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDispose($hGfxLine)
    _GDIPlus_BitmapDispose($hBmpLine)
    _GDIPlus_GraphicsDispose($hGfxText)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpText, $iX, $iY)
    _GDIPlus_BitmapDispose($hBmpText)
    EndFunc ;==>_BBCode_Draw

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _ReDraw()
    AdlibUnRegister("_ReDraw")
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFFFFFFFF)
    _BBCode_Draw($sText, $hGfxBuffer, 10, 10, $iWidth-20, $iHeight-20, 4)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    AdlibUnRegister("_ReDraw")
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    $iWidth = _WinAPI_LoWord($lParam)
    $iHeight = _WinAPI_HiWord($lParam)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_ReDraw", 100)

    [/autoit] [autoit][/autoit] [autoit]

    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _WM_PAINT($hWnd, $iMsg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>_WM_PAINT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete($hGui)
    Exit
    EndFunc ;==>_Exit

    [/autoit][/autoit]

    Beim verändern der Fensterbreite wird (mit etwas Verzögerung) der Text angepasst und mit RenderingHint=4 gezeichnet.

    E