Jump to content

Transparency and font, low quality?


Recommended Posts

I'm playing with a font ( and maybe other controls, but for now is only a label ) with a full trasparent gui. Searching aroud the best way is use _WinAPI_SetLayeredWindowAttributes. Yes, the GUI is trasparent but the "quality" of the font is horrible, i have tested on a couple of OS and the result is the same, i mean chek the image:

34imgxj.png

Around the font there is something like a outline, is not smooth...i have try with different Font quality of GUICtrlSetFont, with or without GUICtrlSetBkColor but always the same result. What i'm miss? Thanks

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>
#include <SendMessage.au3>

HotKeySet("ESC", "_Exit")

$hGUI = GUICreate("Test", 500, 500, 100, 1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED))
GUISetBkColor(0xABCDEF)

GUICtrlCreateLabel("Press ESC to exit", 1, 1, 500, 500, 0x1000)
GUICtrlSetFont(-1, 50, 400, Default, "Arial")
;~ GUICtrlSetBkColor(-1, 0xABCDEF)

GUISetState(@SW_SHOW)

_WinAPI_SetLayeredWindowAttributes($hGUI, 0xABCDEF, 255)

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
;~         Case $GUI_EVENT_PRIMARYDOWN
;~             _SendMessage($hGUI, $WM_SYSCOMMAND, 0xF012, 0)
    EndSwitch

WEnd



Func _Exit()
    Exit
EndFunc

 

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Try this version

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

_GDIPlus_Startup()
$hGUI = GUICreate("Test", 500, 200, 100, 1, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)
$hBmpGDI = _GDIPlus_BitmapCreateText("Press ESC to exit", 500, 200, 85)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate(), _
                $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font), _
                $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2)

    _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT)
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    _GDIPlus_PathAddString($hPath, $sText, _GDIPlus_RectFCreate(0, 0, $iW, $iH), $hFamily, $iFontStyle, $fFontSize, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

 

For 3.3.8.1 compatibility:

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

_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012, $__g_hGDIPDll = $ghGDIPDll

$hGUI = GUICreate("Test", 500, 200, 100, 1, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
    $hBmpGDI = _GDIPlus_BitmapCreateText("Press ESC to exit" & @CRLF & @HOUR & ":" & @MIN & ":" & @SEC, 500, 200, 60)
    _WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate(), _
                $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font), _
                $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2)

    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY = 2
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ;$GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT = 3
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    _GDIPlus_PathAddString($hPath, $sText, _GDIPlus_RectFCreate(0, 0, $iW, $iH), $hFamily, $iFontStyle, $fFontSize, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    Local $aGUIStyle = GUIGetStyle($hGUI)
    If Not BitAND($aGUIStyle[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate("struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct") ;$tagBITMAP = struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllStructSetData($tSize, "X", DllStructGetData($tDim, "bmWidth"))
    DllStructSetData($tSize, "Y", DllStructGetData($tDim, "bmHeight"))
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc


Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipCreatePath", "int", $iFillMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[2]
EndFunc   ;==>_GDIPlus_PathCreate

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $iTextRenderingHint)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetTextRenderingHint", "handle", $hGraphics, "int", $iTextRenderingHint)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint

Func _GDIPlus_StringFormatSetLineAlign($hStringFormat, $iStringAlign)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetStringFormatLineAlign", "handle", $hStringFormat, "int", $iStringAlign)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_StringFormatSetLineAlign

Func _GDIPlus_PathAddString($hPath, $sString, $tLayout, $hFamily, $iStyle = 0, $fSize = 8.5, $hFormat = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipAddPathString", "handle", $hPath, "wstr", $sString, "int", -1, _
            "handle", $hFamily, "int", $iStyle, "float", $fSize, "struct*", $tLayout, "handle", $hFormat)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_PathAddString

Func _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
    __GDIPlus_PenDefCreate($hPen)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDrawPath", "handle", $hGraphics, "handle", $hPen, "handle", $hPath)
    __GDIPlus_PenDefDispose() ; does destroyed @error, @extended
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_GraphicsDrawPath

Func _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
    __GDIPlus_BrushDefCreate($hBrush)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipFillPath", "handle", $hGraphics, "handle", $hBrush, "handle", $hPath)
    __GDIPlus_BrushDefDispose()
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_GraphicsFillPath

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDeletePath", "handle", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_PathDispose

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Hi UEZ,

Since i'm still using the 3.3.8.1 for compatibility reason i don't have test your script. I have added all the missing function but i have an error for 'Variable must be of type "Object"' on the line '$tSize.X = $tDim.bmWidth'

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

_GDIPlus_Startup()
$hGUI = GUICreate("Test", 500, 200, 100, 1, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)
$hBmpGDI = _GDIPlus_BitmapCreateText("Press ESC to exit", 500, 200, 85)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown() ; a little mistake --> _GDIPlus_Startup()
            Exit
    EndSwitch
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFFFFFFFF, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate(), _
            $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font), _
            $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2)

    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ; $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    _GDIPlus_PathAddString($hPath, $sText, _GDIPlus_RectFCreate(0, 0, $iW, $iH), $hFamily, $iFontStyle, $fFontSize, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateText

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    Local $aStyle = GUIGetStyle($hGUI)
    If IsArray($aStyle) And Not BitAND($aStyle[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local Const $tagBITMAP = 'long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;'
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc   ;==>_WinAPI_BitmapDisplayTransparentInGUI

#region 3.3.8.1
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", $iFillMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_PathCreate

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $iTextRenderingHint)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipSetTextRenderingHint", "handle", $hGraphics, "int", $iTextRenderingHint)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint

Func _GDIPlus_StringFormatSetLineAlign($hStringFormat, $iStringAlign)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipSetStringFormatLineAlign", "handle", $hStringFormat, "int", $iStringAlign)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_StringFormatSetLineAlign

Func _GDIPlus_PathAddString($hPath, $sString, $tLayout, $hFamily, $iStyle = 0, $fSize = 8.5, $hFormat = 0)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathString", "handle", $hPath, "wstr", $sString, "int", -1, _
            "handle", $hFamily, "int", $iStyle, "float", $fSize, "struct*", $tLayout, "handle", $hFormat)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_PathAddString

Func _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
    __GDIPlus_PenDefCreate($hPen)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawPath", "handle", $hGraphics, "handle", $hPen, "handle", $hPath)
    __GDIPlus_PenDefDispose() ; does destroyed @error, @extended
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsDrawPath

Func _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
    __GDIPlus_BrushDefCreate($hBrush)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipFillPath", "handle", $hGraphics, "handle", $hBrush, "handle", $hPath)
    __GDIPlus_BrushDefDispose()
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsFillPath

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($ghGDIPDll, "int", "GdipDeletePath", "handle", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_PathDispose
#endregion

Since i need to update this text very often ( like 300-400ms ) is GDI+ a good choice? How? Is not easy like GuiCtrlSetData :D

Do you know why SetLayeredWindowAttributes has that problem? Is not a matter of quality like i have think, is the "transparency color key" the problem. Example, if you make the color white and the text is black, the outline is white, if you make the color red and the text is black, the outline is red and so on...so that color did you see in the screenshot is pratically 0xABCDEF

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

I just updated the code from post#2 which should run on 3.3.8.1.

It's easy to update the text as to use GuiCtrlSetData! ;) SetLayeredWindowAttributes cuts off the color and the edges become fuzzy depending on the background whereas the solution from post#2 creates a bitmap without loosing antialiasing.

If you change from 0xABCDEF to 0x7F8081 you should get a border color which is in the middle of the color space but still fuzzy on some backgrounds.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

There is something i don't understand, the position of the GUI. If example i'll put 0 and 0 for left and top the text isn't at 0 and 0 but approx at 30 point from the top and the left of the screen. Why? :ermm:

And also i can't move to 0 with the mouse, come back down

 

EDIT: I have try to use the StringSize by Melba for check if is a GUI size but give me the same problem:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include "StringSize.au3"

_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012, $__g_hGDIPDll = $ghGDIPDll



$aSize = _StringSize("Press ESC to exit", 60, Default, Default, "Arial")

$hGUI = GUICreate("Test", $aSize[2], $aSize[3], 0, 0, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

$hBmpGDI = _GDIPlus_BitmapCreateText("Press ESC to exit", $aSize[2], $aSize[3], 60)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Result:

2vaiobd.png

Again, why?

 

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

GDI+ never  starts from the origin (0, 0) to create the text. A simple function call and an adjustment will do it!

 

3.3.8.1 code:

;#AutoIt3Wrapper_AutoIt3Dir=c:\Program Files (x86)\AutoIt3\3.3.8.1
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>

_GDIPlus_Startup()
Global Const $SC_DRAGMOVE = 0xF012, $__g_hGDIPDll = $ghGDIPDll

$hGUI = GUICreate("Test", 500, 200, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
    $hBmpGDI = _GDIPlus_BitmapCreateText("Press ESC to exit" & @CRLF & @HOUR & ":" & @MIN & ":" & @SEC, 500, 200, 60)
    _WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate(), _
                $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font), _
                $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2)

    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY = 2
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ;$GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT = 3
    _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    Local $tRectF = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    _GDIPlus_PathAddString($hPath, $sText, $tRectF, $hFamily, $iFontStyle, $fFontSize, $hFormat)
    Local Const $aWB = _GDIPlus_PathGetWorldBounds($hPath)
    _GDIPlus_PathReset($hPath)
    DllStructSetData($tRectF, "X", -$aWB[0])
    DllStructSetData($tRectF, "Y", -$aWB[1])
    _GDIPlus_PathAddString($hPath, $sText, $tRectF, $hFamily, $iFontStyle, $fFontSize, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    Local $aGUIStyle = GUIGetStyle($hGUI)
    If Not BitAND($aGUIStyle[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate("struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct") ;$tagBITMAP = struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllStructSetData($tSize, "X", DllStructGetData($tDim, "bmWidth"))
    DllStructSetData($tSize, "Y", DllStructGetData($tDim, "bmHeight"))
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc


Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipCreatePath", "int", $iFillMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[2]
EndFunc   ;==>_GDIPlus_PathCreate

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $iTextRenderingHint)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetTextRenderingHint", "handle", $hGraphics, "int", $iTextRenderingHint)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint

Func _GDIPlus_StringFormatSetLineAlign($hStringFormat, $iStringAlign)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetStringFormatLineAlign", "handle", $hStringFormat, "int", $iStringAlign)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_StringFormatSetLineAlign

Func _GDIPlus_PathAddString($hPath, $sString, $tLayout, $hFamily, $iStyle = 0, $fSize = 8.5, $hFormat = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipAddPathString", "handle", $hPath, "wstr", $sString, "int", -1, _
            "handle", $hFamily, "int", $iStyle, "float", $fSize, "struct*", $tLayout, "handle", $hFormat)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_PathAddString

Func _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
    __GDIPlus_PenDefCreate($hPen)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDrawPath", "handle", $hGraphics, "handle", $hPen, "handle", $hPath)
    __GDIPlus_PenDefDispose() ; does destroyed @error, @extended
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_GraphicsDrawPath

Func _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
    __GDIPlus_BrushDefCreate($hBrush)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipFillPath", "handle", $hGraphics, "handle", $hBrush, "handle", $hPath)
    __GDIPlus_BrushDefDispose()
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_GraphicsFillPath

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDeletePath", "handle", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_PathDispose

Func _GDIPlus_PathGetWorldBounds($hPath, $hMatrix = 0, $hPen = 0)
    Local $tRectF = DllStructCreate($tagGDIPRECTF)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPathWorldBounds", "handle", $hPath, "struct*", $tRectF, "handle", $hMatrix, "handle", $hPen)
    If @error Then Return SetError(@error, @extended, -1)
    If $aResult[0] Then Return SetError(10, $aResult[0], -1)

    Local $aRectF[4]
    For $iI = 1 To 4
        $aRectF[$iI - 1] = DllStructGetData($tRectF, $iI)
    Next
    Return $aRectF
EndFunc   ;==>_GDIPlus_PathGetWorldBounds

Func _GDIPlus_PathReset($hPath)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipResetPath", "handle", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)

    Return True
EndFunc   ;==>_GDIPlus_PathReset

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

UEZ my last two question about this :D

The first is:

The font size. Does not corresponding to the internal GUICtrlSetFont and for me can be a problem. I have make a script with:

GUICtrlCreateLabel("TEST", 8, 8, 100, 42)
GUICtrlSetFont(-1, 25, 400, 0, "Arial")
GUICtrlSetColor(-1, 0xFF00000)
GUICtrlSetBkColor(-1, 0x000000)

And yours ( i have add a bk color just for see the difference ) with:

$hBmpGDI = _GDIPlus_BitmapCreateText("TEST", 100, 100, 25, "Arial", 0xFFFF0000)

Your version, on the top of the screenshot, is smaller then the autoit one:

2ivbdvt.png

I prefer that GDI+ version to be exactly or very very similar to the internal function

Second:

Can you show me your super math knowledge for centering the text vertically-horizontally inside the $iW and $iH? For dragging purpose is better to have it at center with a GUI of the same size of the text ( for this reason i'm using _StringSize ) but having 0 and 0 is good place to start for make the text on the corner

Again thanks

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

1) As far as I can remember you have to multiply the font size with 1.66666 to get the same size as the GUI version

2) The centering was done in the previous version but you wanted to have it at 0,0. 

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

UEZ please run this:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
;~ #include "StringSize.au3" ; included for testing only

_GDIPlus_Startup()
Global Const $__g_hGDIPDll = $ghGDIPDll

Global $aSize = _StringSize("TEST", 25, Default, Default, "Arial")

$hGUI = GUICreate("A", $aSize[2], $aSize[3], 10, 10, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

$hBmpGDI = _GDIPlus_BitmapCreateText("TEST", $aSize[2], $aSize[3], 25 * 1.666666, "Arial", 0xFFFF0000)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

$hGUI_2 = GUICreate("B", $aSize[2], $aSize[3], 10, 70, $WS_POPUP)
GUICtrlCreateLabel("TEST", 0, 0, $aSize[2], $aSize[3])
GUICtrlSetFont(-1, 25, 400, 0, "Arial")
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlSetBkColor(-1, 0x000000)

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate()
    Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font)
    Local Const $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2), $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000) ; TEST ONLY <<<<<<<<<<<<<<<
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY = 2
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ;$GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT = 3
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    _GDIPlus_PathAddString($hPath, $sText, _GDIPlus_RectFCreate(0, 0, $iW, $iH), $hFamily, $iFontStyle, $fFontSize, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_GraphicsDispose($hBackbuffer)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateText

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    Local $aGUIStyle = GUIGetStyle($hGUI)
    If Not IsArray($aGUIStyle) And Not BitAND($aGUIStyle[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate("struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct") ;$tagBITMAP = struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllStructSetData($tSize, "X", DllStructGetData($tDim, "bmWidth"))
    DllStructSetData($tSize, "Y", DllStructGetData($tDim, "bmHeight"))
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc   ;==>_WinAPI_BitmapDisplayTransparentInGUI

;~ Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
;~  _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
;~ EndFunc   ;==>_WM_LBUTTONDOWN

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipCreatePath", "int", $iFillMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_PathCreate

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $iTextRenderingHint)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetTextRenderingHint", "handle", $hGraphics, "int", $iTextRenderingHint)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint

Func _GDIPlus_StringFormatSetLineAlign($hStringFormat, $iStringAlign)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetStringFormatLineAlign", "handle", $hStringFormat, "int", $iStringAlign)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_StringFormatSetLineAlign

Func _GDIPlus_PathAddString($hPath, $sString, $tLayout, $hFamily, $iStyle = 0, $fSize = 8.5, $hFormat = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipAddPathString", "handle", $hPath, "wstr", $sString, "int", -1, _
            "handle", $hFamily, "int", $iStyle, "float", $fSize, "struct*", $tLayout, "handle", $hFormat)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_PathAddString

Func _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
    __GDIPlus_PenDefCreate($hPen)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDrawPath", "handle", $hGraphics, "handle", $hPen, "handle", $hPath)
    __GDIPlus_PenDefDispose() ; does destroyed @error, @extended
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsDrawPath

Func _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
    __GDIPlus_BrushDefCreate($hBrush)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipFillPath", "handle", $hGraphics, "handle", $hBrush, "handle", $hPath)
    __GDIPlus_BrushDefDispose()
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsFillPath

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDeletePath", "handle", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_PathDispose

;############################# STRINGSIZE

; #INDEX# ============================================================================================================
; Title .........: _StringSize
; AutoIt Version : v3.2.12.1 or higher
; Language ......: English
; Description ...: Returns size of rectangle required to display string - maximum width can be chosen
; Remarks .......:
; Note ..........:
; Author(s) .....:  Melba23 - thanks to trancexx for the default DC code
; ====================================================================================================================

;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; #CURRENT# ==========================================================================================================
; _StringSize: Returns size of rectangle required to display string - maximum width can be chosen
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _StringSize_Error_Close: Releases DC and deletes font object after error
; _StringSize_DefaultFontName: Determines Windows default font
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _StringSize
; Description ...: Returns size of rectangle required to display string - maximum permitted width can be chosen
; Syntax ........: _StringSize($sText[, $iSize[, $iWeight[, $iAttrib[, $sName[, $iWidth[, $hWnd]]]]]])
; Parameters ....: $sText   - String to display
;                  $iSize   - [optional] Font size in points - (default = 8.5)
;                  $iWeight - [optional] Font weight - (default = 400 = normal)
;                  $iAttrib - [optional] Font attribute (0-Normal (default), 2-Italic, 4-Underline, 8 Strike)
;                             + 1 if tabs are to be expanded before sizing
;                  $sName   - [optional] Font name - (default = Tahoma)
;                  $iWidth  - [optional] Max width for rectangle - (default = 0 => width of original string)
;                  $hWnd    - [optional] GUI in which string will be displayed - (default 0 => normally not required)
; Requirement(s) : v3.2.12.1 or higher
; Return values .: Success - Returns 4-element array: ($iWidth set // $iWidth not set)
;                  |$array[0] = String reformatted with additonal @CRLF // Original string
;                  |$array[1] = Height of single line in selected font // idem
;                  |$array[2] = Width of rectangle required for reformatted // original string
;                  |$array[3] = Height of rectangle required for reformatted // original string
;                  Failure - Returns 0 and sets @error:
;                  |1 - Incorrect parameter type (@extended = parameter index)
;                  |2 - DLL call error - extended set as follows:
;                       |1 - GetDC failure
;                       |2 - SendMessage failure
;                       |3 - GetDeviceCaps failure
;                       |4 - CreateFont failure
;                       |5 - SelectObject failure
;                       |6 - GetTextExtentPoint32 failure
;                  |3 - Font too large for chosen max width - a word will not fit
; Author ........: Melba23 - thanks to trancexx for the default DC code
; Modified ......:
; Remarks .......: The use of the $hWnd parameter is not normally necessary - it is only required if the UDF does not
;                   return correct dimensions without it.
; Related .......:
; Link ..........:
; Example .......: Yes
;=====================================================================================================================
Func _StringSize($sText, $iSize = 8.5, $iWeight = 400, $iAttrib = 0, $sName = "", $iMaxWidth = 0, $hWnd = 0)

    ; Set parameters passed as Default
    If $iSize = Default Then $iSize = 8.5
    If $iWeight = Default Then $iWeight = 400
    If $iAttrib = Default Then $iAttrib = 0
    If $sName = "" Or $sName = Default Then $sName = _StringSize_DefaultFontName()

    ; Check parameters are correct type
    If Not IsString($sText) Then Return SetError(1, 1, 0)
    If Not IsNumber($iSize) Then Return SetError(1, 2, 0)
    If Not IsInt($iWeight) Then Return SetError(1, 3, 0)
    If Not IsInt($iAttrib) Then Return SetError(1, 4, 0)
    If Not IsString($sName) Then Return SetError(1, 5, 0)
    If Not IsNumber($iMaxWidth) Then Return SetError(1, 6, 0)
    If Not IsHwnd($hWnd) And $hWnd <> 0 Then Return SetError(1, 7, 0)

    Local $aRet, $hDC, $hFont, $hLabel = 0, $hLabel_Handle

    ; Check for tab expansion flag
    Local $iExpTab = BitAnd($iAttrib, 1)
    ; Remove possible tab expansion flag from font attribute value
    $iAttrib = BitAnd($iAttrib, BitNot(1))

    ; If GUI handle was passed
    If IsHWnd($hWnd) Then
        ; Create label outside GUI borders
        $hLabel = GUICtrlCreateLabel("", -10, -10, 10, 10)
        $hLabel_Handle = GUICtrlGetHandle(-1)
        GUICtrlSetFont(-1, $iSize, $iWeight, $iAttrib, $sName)
        ; Create DC
        $aRet = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hLabel_Handle)
        If @error Or $aRet[0] = 0 Then
            GUICtrlDelete($hLabel)
            Return SetError(2, 1, 0)
        EndIf
        $hDC = $aRet[0]
        $aRet = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hLabel_Handle, "int", 0x0031, "wparam", 0, "lparam", 0) ; $WM_GetFont
        If @error Or $aRet[0] = 0 Then
            GUICtrlDelete($hLabel)
            Return SetError(2, _StringSize_Error_Close(2, $hDC), 0)
        EndIf
        $hFont = $aRet[0]
    Else
        ; Get default DC
        $aRet = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hWnd)
        If @error Or $aRet[0] = 0 Then Return SetError(2, 1, 0)
        $hDC = $aRet[0]
        ; Create required font
        $aRet = DllCall("gdi32.dll", "int", "GetDeviceCaps", "handle", $hDC, "int", 90) ; $LOGPIXELSY
        If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(3, $hDC), 0)
        Local $iInfo = $aRet[0]
        $aRet = DllCall("gdi32.dll", "handle", "CreateFontW", "int", -$iInfo * $iSize / 72, "int", 0, "int", 0, "int", 0, _
            "int", $iWeight, "dword", BitAND($iAttrib, 2), "dword", BitAND($iAttrib, 4), "dword", BitAND($iAttrib, 8), "dword", 0, "dword", 0, _
            "dword", 0, "dword", 5, "dword", 0, "wstr", $sName)
        If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(4, $hDC), 0)
        $hFont = $aRet[0]
    EndIf

    ; Select font and store previous font
    $aRet = DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hFont)
    If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(5, $hDC, $hFont, $hLabel), 0)
    Local $hPrevFont = $aRet[0]

    ; Declare variables
    Local $avSize_Info[4], $iLine_Length, $iLine_Height = 0, $iLine_Count = 0, $iLine_Width = 0, $iWrap_Count, $iLast_Word, $sTest_Line
    ; Declare and fill Size structure
    Local $tSize = DllStructCreate("int X;int Y")
    DllStructSetData($tSize, "X", 0)
    DllStructSetData($tSize, "Y", 0)

    ; Ensure EoL is @CRLF and break text into lines
    $sText = StringRegExpReplace($sText, "((?<!\x0d)\x0a|\x0d(?!\x0a))", @CRLF)
    Local $asLines = StringSplit($sText, @CRLF, 1)

    ; For each line
    For $i = 1 To $asLines[0]
        ; Expand tabs if required
        If $iExpTab Then
            $asLines[$i] = StringReplace($asLines[$i], @TAB, " XXXXXXXX")
        EndIf
        ; Size line
        $iLine_Length = StringLen($asLines[$i])
        DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $asLines[$i], "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
        If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
        If DllStructGetData($tSize, "X") > $iLine_Width Then $iLine_Width = DllStructGetData($tSize, "X")
        If DllStructGetData($tSize, "Y") > $iLine_Height Then $iLine_Height = DllStructGetData($tSize, "Y")
    Next

    ; Check if $iMaxWidth has been both set and exceeded
    If $iMaxWidth <> 0 And $iLine_Width > $iMaxWidth Then ; Wrapping required
        ; For each Line
        For $j = 1 To $asLines[0]
            ; Size line unwrapped
            $iLine_Length = StringLen($asLines[$j])
            DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $asLines[$j], "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
            If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
            ; Check wrap status
            If DllStructGetData($tSize, "X") < $iMaxWidth - 4 Then
                ; No wrap needed so count line and store
                $iLine_Count += 1
                $avSize_Info[0] &= $asLines[$j] & @CRLF
            Else
                ; Wrap needed so zero counter for wrapped lines
                $iWrap_Count = 0
                ; Build line to max width
                While 1
                    ; Zero line width
                    $iLine_Width = 0
                    ; Initialise pointer for end of word
                    $iLast_Word = 0
                    ; Add characters until EOL or maximum width reached
                    For $i = 1 To StringLen($asLines[$j])
                        ; Is this just past a word ending?
                        If StringMid($asLines[$j], $i, 1) = " " Then $iLast_Word = $i - 1
                        ; Increase line by one character
                        $sTest_Line = StringMid($asLines[$j], 1, $i)
                        ; Get line length
                        $iLine_Length = StringLen($sTest_Line)
                        DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sTest_Line, "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
                        If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
                        $iLine_Width = DllStructGetData($tSize, "X")
                        ; If too long exit the loop
                        If $iLine_Width >= $iMaxWidth - 4 Then ExitLoop
                    Next
                    ; End of the line of text?
                    If $i > StringLen($asLines[$j]) Then
                        ; Yes, so add final line to count
                        $iWrap_Count += 1
                        ; Store line
                        $avSize_Info[0] &= $sTest_Line & @CRLF
                        ExitLoop
                    Else
                        ; No, but add line just completed to count
                        $iWrap_Count += 1
                        ; Check at least 1 word completed or return error
                        If $iLast_Word = 0 Then Return SetError(3, _StringSize_Error_Close(0, $hDC, $hFont, $hLabel), 0)
                        ; Store line up to end of last word
                        $avSize_Info[0] &= StringLeft($sTest_Line, $iLast_Word) & @CRLF
                        ; Strip string to point reached
                        $asLines[$j] = StringTrimLeft($asLines[$j], $iLast_Word)
                        ; Trim leading whitespace
                        $asLines[$j] = StringStripWS($asLines[$j], 1)
                        ; Repeat with remaining characters in line
                    EndIf
                WEnd
                ; Add the number of wrapped lines to the count
                $iLine_Count += $iWrap_Count
            EndIf
        Next
        ; Reset any tab expansions
        If $iExpTab Then
            $avSize_Info[0] = StringRegExpReplace($avSize_Info[0], "\x20?XXXXXXXX", @TAB)
        EndIf
        ; Complete return array
        $avSize_Info[1] = $iLine_Height
        $avSize_Info[2] = $iMaxWidth
        ; Convert lines to pixels and add drop margin
        $avSize_Info[3] = ($iLine_Count * $iLine_Height) + 4
    Else ; No wrapping required
        ; Create return array (add drop margin to height)
        Local $avSize_Info[4] = [$sText, $iLine_Height, $iLine_Width, ($asLines[0] * $iLine_Height) + 4]
    EndIf

    ; Clear up
    DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hPrevFont)
    DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hFont)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $hDC)
    If $hLabel Then GUICtrlDelete($hLabel)

    Return $avSize_Info

EndFunc ;==>_StringSize

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _StringSize_Error_Close
; Description ...: Releases DC and deleted font object if required after error
; Syntax ........: _StringSize_Error_Close ($iExtCode, $hDC, $hGUI)
; Parameters ....: $iExtCode   - code to return
;                  $hDC, $hGUI - handles as set in _StringSize function
; Return value ..: $iExtCode as passed
; Author ........: Melba23
; Modified.......:
; Remarks .......: This function is used internally by _StringSize
; ===============================================================================================================================
Func _StringSize_Error_Close($iExtCode, $hDC = 0, $hFont = 0, $hLabel = 0)

    If $hFont <> 0 Then DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hFont)
    If $hDC <> 0 Then DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $hDC)
    If $hLabel Then GUICtrlDelete($hLabel)

    Return $iExtCode

EndFunc ;=>_StringSize_Error_Close

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _StringSize_DefaultFontName
; Description ...: Determines Windows default font
; Syntax ........: _StringSize_DefaultFontName()
; Parameters ....: None
; Return values .: Success - Returns name of system default font
;                  Failure - Returns "Tahoma"
; Author ........: Melba23, based on some original code by Larrydalooza
; Modified.......:
; Remarks .......: This function is used internally by _StringSize
; ===============================================================================================================================
Func _StringSize_DefaultFontName()
    ; Get default system font data
    Local $tNONCLIENTMETRICS = DllStructCreate("uint;int;int;int;int;int;byte[60];int;int;byte[60];int;int;byte[60];byte[60];byte[60]")
    DLLStructSetData($tNONCLIENTMETRICS, 1, DllStructGetSize($tNONCLIENTMETRICS))
    DLLCall("user32.dll", "int", "SystemParametersInfo", "int", 41, "int", DllStructGetSize($tNONCLIENTMETRICS), "ptr", DllStructGetPtr($tNONCLIENTMETRICS), "int", 0)
    Local $tLOGFONT = DllStructCreate("long;long;long;long;long;byte;byte;byte;byte;byte;byte;byte;byte;char[32]", DLLStructGetPtr($tNONCLIENTMETRICS, 13))
    If IsString(DllStructGetData($tLOGFONT, 14)) Then
        Return DllStructGetData($tLOGFONT, 14)
    Else
        Return "Tahoma"
    EndIf
EndFunc ;=>_StringSize_DefaultFontName

As you can see multiply the font don't give the correct size. The final result i want to archive is like the second one but with your nice code for add the trasparency:

jg7bjn.png

 

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

No, with 1.33333 i see "TES" instead of "TEST" :D

Without any multiplier the font size isn't correct based on the GUI size.

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

As you can see GDI+ draws not at 0,0. Thus you have to adjust the bitmap size.

Global $fFontSize = 100
Global $aSize = _StringSize("TEST", $fFontSize, Default, Default, "Arial")

$hGUI = GUICreate("A", $aSize[2], $aSize[3], 10, 10, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

$hBmpGDI = _GDIPlus_BitmapCreateText("TEST", $aSize[2] * 1.25, $aSize[3] * 1.15, $fFontSize * 1.3, "Arial", 0xFFFF0000)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

$hGUI_2 = GUICreate("B", $aSize[2], $aSize[3], 30, 200, $WS_POPUP)
GUICtrlCreateLabel("TEST", 0, 0, $aSize[2], $aSize[3])
GUICtrlSetFont(-1, $fFontSize, 400, 0, "Arial")
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlSetBkColor(-1, 0x000000)

 

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

UEZ,

After some research i have understood the problem with the font. Is _GDIPlus_PathAddString, in particular with $fSize --> The em size, in world units, of the string characters. Need a conversion, for this reason there is a difference with the internal one. I have found this, there are other links but is always the same formula:

Get a font’s size in pixels and use it to draw similar text in a GraphicsPath object in C#

Font in 'GraphicsPath.AddString' is smaller than usual font

Can you provide with it? I don't know where to take DpiY or DpiX. Thanks

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Try this:

;#AutoIt3Wrapper_AutoIt3Dir=c:\Program Files (x86)\AutoIt3\3.3.8.1
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
;~ #include "StringSize.au3" ; included for testing only

_GDIPlus_Startup()
Global Const $__g_hGDIPDll = $ghGDIPDll

Global $fFontSize = 100
Global $aSize = _StringSize("TEST", $fFontSize, Default, Default, "Arial")

$hGUI = GUICreate("A", $aSize[2], $aSize[3], 10, 10, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

$hBmpGDI = _GDIPlus_BitmapCreateText("TEST", $aSize[2] * 1.25, $aSize[3] * 1.15, $fFontSize, "Arial", 0xFFFF0000)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

$hGUI_2 = GUICreate("B", $aSize[2], $aSize[3], 30, 200, $WS_POPUP)
GUICtrlCreateLabel("TEST", 0, 0, $aSize[2], $aSize[3])
GUICtrlSetFont(-1, $fFontSize, 400, 0, "Arial")
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlSetBkColor(-1, 0x000000)

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate()
    Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font)
    Local Const $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2), $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000) ; TEST ONLY <<<<<<<<<<<<<<<
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY = 2
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ;$GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT = 3
    _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    Local Const $iDPI = _GDIPlus_ImageGetHorizontalResolution($hBitmap)
    _GDIPlus_PathAddString($hPath, $sText, _GDIPlus_RectFCreate(0, 0, $iW, $iH), $hFamily, $iFontStyle, $fFontSize / 72 * $iDPI, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_GraphicsDispose($hBackbuffer)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateText

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    Local $aGUIStyle = GUIGetStyle($hGUI)
    If Not IsArray($aGUIStyle) And Not BitAND($aGUIStyle[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate("struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct") ;$tagBITMAP = struct;long bmType;long bmWidth;long bmHeight;long bmWidthBytes;ushort bmPlanes;ushort bmBitsPixel;ptr bmBits;endstruct
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllStructSetData($tSize, "X", DllStructGetData($tDim, "bmWidth"))
    DllStructSetData($tSize, "Y", DllStructGetData($tDim, "bmHeight"))
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc   ;==>_WinAPI_BitmapDisplayTransparentInGUI

;~ Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
;~  _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
;~ EndFunc   ;==>_WM_LBUTTONDOWN

Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iPixelFormat = $GDIP_PXF32ARGB, $iStride = 0, $pScan0 = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

Func _GDIPlus_PathCreate($iFillMode = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipCreatePath", "int", $iFillMode, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_PathCreate

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $iTextRenderingHint)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetTextRenderingHint", "handle", $hGraphics, "int", $iTextRenderingHint)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint

Func _GDIPlus_StringFormatSetLineAlign($hStringFormat, $iStringAlign)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetStringFormatLineAlign", "handle", $hStringFormat, "int", $iStringAlign)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_StringFormatSetLineAlign

Func _GDIPlus_PathAddString($hPath, $sString, $tLayout, $hFamily, $iStyle = 0, $fSize = 8.5, $hFormat = 0)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipAddPathString", "handle", $hPath, "wstr", $sString, "int", -1, _
            "handle", $hFamily, "int", $iStyle, "float", $fSize, "struct*", $tLayout, "handle", $hFormat)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_PathAddString

Func _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
    __GDIPlus_PenDefCreate($hPen)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDrawPath", "handle", $hGraphics, "handle", $hPen, "handle", $hPath)
    __GDIPlus_PenDefDispose() ; does destroyed @error, @extended
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsDrawPath

Func _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
    __GDIPlus_BrushDefCreate($hBrush)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipFillPath", "handle", $hGraphics, "handle", $hBrush, "handle", $hPath)
    __GDIPlus_BrushDefDispose()
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_GraphicsFillPath

Func _GDIPlus_PathDispose($hPath)
    Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipDeletePath", "handle", $hPath)
    If @error Then Return SetError(@error, @extended, False)
    If $aResult[0] Then Return SetError(10, $aResult[0], False)
    Return True
EndFunc   ;==>_GDIPlus_PathDispose

;############################# STRINGSIZE

; #INDEX# ============================================================================================================
; Title .........: _StringSize
; AutoIt Version : v3.2.12.1 or higher
; Language ......: English
; Description ...: Returns size of rectangle required to display string - maximum width can be chosen
; Remarks .......:
; Note ..........:
; Author(s) .....:  Melba23 - thanks to trancexx for the default DC code
; ====================================================================================================================

;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; #CURRENT# ==========================================================================================================
; _StringSize: Returns size of rectangle required to display string - maximum width can be chosen
; ====================================================================================================================

; #INTERNAL_USE_ONLY#=================================================================================================
; _StringSize_Error_Close: Releases DC and deletes font object after error
; _StringSize_DefaultFontName: Determines Windows default font
; ====================================================================================================================

; #FUNCTION# =========================================================================================================
; Name...........: _StringSize
; Description ...: Returns size of rectangle required to display string - maximum permitted width can be chosen
; Syntax ........: _StringSize($sText[, $iSize[, $iWeight[, $iAttrib[, $sName[, $iWidth[, $hWnd]]]]]])
; Parameters ....: $sText   - String to display
;                  $iSize   - [optional] Font size in points - (default = 8.5)
;                  $iWeight - [optional] Font weight - (default = 400 = normal)
;                  $iAttrib - [optional] Font attribute (0-Normal (default), 2-Italic, 4-Underline, 8 Strike)
;                             + 1 if tabs are to be expanded before sizing
;                  $sName   - [optional] Font name - (default = Tahoma)
;                  $iWidth  - [optional] Max width for rectangle - (default = 0 => width of original string)
;                  $hWnd    - [optional] GUI in which string will be displayed - (default 0 => normally not required)
; Requirement(s) : v3.2.12.1 or higher
; Return values .: Success - Returns 4-element array: ($iWidth set // $iWidth not set)
;                  |$array[0] = String reformatted with additonal @CRLF // Original string
;                  |$array[1] = Height of single line in selected font // idem
;                  |$array[2] = Width of rectangle required for reformatted // original string
;                  |$array[3] = Height of rectangle required for reformatted // original string
;                  Failure - Returns 0 and sets @error:
;                  |1 - Incorrect parameter type (@extended = parameter index)
;                  |2 - DLL call error - extended set as follows:
;                       |1 - GetDC failure
;                       |2 - SendMessage failure
;                       |3 - GetDeviceCaps failure
;                       |4 - CreateFont failure
;                       |5 - SelectObject failure
;                       |6 - GetTextExtentPoint32 failure
;                  |3 - Font too large for chosen max width - a word will not fit
; Author ........: Melba23 - thanks to trancexx for the default DC code
; Modified ......:
; Remarks .......: The use of the $hWnd parameter is not normally necessary - it is only required if the UDF does not
;                   return correct dimensions without it.
; Related .......:
; Link ..........:
; Example .......: Yes
;=====================================================================================================================
Func _StringSize($sText, $iSize = 8.5, $iWeight = 400, $iAttrib = 0, $sName = "", $iMaxWidth = 0, $hWnd = 0)

    ; Set parameters passed as Default
    If $iSize = Default Then $iSize = 8.5
    If $iWeight = Default Then $iWeight = 400
    If $iAttrib = Default Then $iAttrib = 0
    If $sName = "" Or $sName = Default Then $sName = _StringSize_DefaultFontName()

    ; Check parameters are correct type
    If Not IsString($sText) Then Return SetError(1, 1, 0)
    If Not IsNumber($iSize) Then Return SetError(1, 2, 0)
    If Not IsInt($iWeight) Then Return SetError(1, 3, 0)
    If Not IsInt($iAttrib) Then Return SetError(1, 4, 0)
    If Not IsString($sName) Then Return SetError(1, 5, 0)
    If Not IsNumber($iMaxWidth) Then Return SetError(1, 6, 0)
    If Not IsHwnd($hWnd) And $hWnd <> 0 Then Return SetError(1, 7, 0)

    Local $aRet, $hDC, $hFont, $hLabel = 0, $hLabel_Handle

    ; Check for tab expansion flag
    Local $iExpTab = BitAnd($iAttrib, 1)
    ; Remove possible tab expansion flag from font attribute value
    $iAttrib = BitAnd($iAttrib, BitNot(1))

    ; If GUI handle was passed
    If IsHWnd($hWnd) Then
        ; Create label outside GUI borders
        $hLabel = GUICtrlCreateLabel("", -10, -10, 10, 10)
        $hLabel_Handle = GUICtrlGetHandle(-1)
        GUICtrlSetFont(-1, $iSize, $iWeight, $iAttrib, $sName)
        ; Create DC
        $aRet = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hLabel_Handle)
        If @error Or $aRet[0] = 0 Then
            GUICtrlDelete($hLabel)
            Return SetError(2, 1, 0)
        EndIf
        $hDC = $aRet[0]
        $aRet = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hLabel_Handle, "int", 0x0031, "wparam", 0, "lparam", 0) ; $WM_GetFont
        If @error Or $aRet[0] = 0 Then
            GUICtrlDelete($hLabel)
            Return SetError(2, _StringSize_Error_Close(2, $hDC), 0)
        EndIf
        $hFont = $aRet[0]
    Else
        ; Get default DC
        $aRet = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hWnd)
        If @error Or $aRet[0] = 0 Then Return SetError(2, 1, 0)
        $hDC = $aRet[0]
        ; Create required font
        $aRet = DllCall("gdi32.dll", "int", "GetDeviceCaps", "handle", $hDC, "int", 90) ; $LOGPIXELSY
        If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(3, $hDC), 0)
        Local $iInfo = $aRet[0]
        $aRet = DllCall("gdi32.dll", "handle", "CreateFontW", "int", -$iInfo * $iSize / 72, "int", 0, "int", 0, "int", 0, _
            "int", $iWeight, "dword", BitAND($iAttrib, 2), "dword", BitAND($iAttrib, 4), "dword", BitAND($iAttrib, 8), "dword", 0, "dword", 0, _
            "dword", 0, "dword", 5, "dword", 0, "wstr", $sName)
        If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(4, $hDC), 0)
        $hFont = $aRet[0]
    EndIf

    ; Select font and store previous font
    $aRet = DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hFont)
    If @error Or $aRet[0] = 0 Then Return SetError(2, _StringSize_Error_Close(5, $hDC, $hFont, $hLabel), 0)
    Local $hPrevFont = $aRet[0]

    ; Declare variables
    Local $avSize_Info[4], $iLine_Length, $iLine_Height = 0, $iLine_Count = 0, $iLine_Width = 0, $iWrap_Count, $iLast_Word, $sTest_Line
    ; Declare and fill Size structure
    Local $tSize = DllStructCreate("int X;int Y")
    DllStructSetData($tSize, "X", 0)
    DllStructSetData($tSize, "Y", 0)

    ; Ensure EoL is @CRLF and break text into lines
    $sText = StringRegExpReplace($sText, "((?<!\x0d)\x0a|\x0d(?!\x0a))", @CRLF)
    Local $asLines = StringSplit($sText, @CRLF, 1)

    ; For each line
    For $i = 1 To $asLines[0]
        ; Expand tabs if required
        If $iExpTab Then
            $asLines[$i] = StringReplace($asLines[$i], @TAB, " XXXXXXXX")
        EndIf
        ; Size line
        $iLine_Length = StringLen($asLines[$i])
        DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $asLines[$i], "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
        If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
        If DllStructGetData($tSize, "X") > $iLine_Width Then $iLine_Width = DllStructGetData($tSize, "X")
        If DllStructGetData($tSize, "Y") > $iLine_Height Then $iLine_Height = DllStructGetData($tSize, "Y")
    Next

    ; Check if $iMaxWidth has been both set and exceeded
    If $iMaxWidth <> 0 And $iLine_Width > $iMaxWidth Then ; Wrapping required
        ; For each Line
        For $j = 1 To $asLines[0]
            ; Size line unwrapped
            $iLine_Length = StringLen($asLines[$j])
            DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $asLines[$j], "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
            If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
            ; Check wrap status
            If DllStructGetData($tSize, "X") < $iMaxWidth - 4 Then
                ; No wrap needed so count line and store
                $iLine_Count += 1
                $avSize_Info[0] &= $asLines[$j] & @CRLF
            Else
                ; Wrap needed so zero counter for wrapped lines
                $iWrap_Count = 0
                ; Build line to max width
                While 1
                    ; Zero line width
                    $iLine_Width = 0
                    ; Initialise pointer for end of word
                    $iLast_Word = 0
                    ; Add characters until EOL or maximum width reached
                    For $i = 1 To StringLen($asLines[$j])
                        ; Is this just past a word ending?
                        If StringMid($asLines[$j], $i, 1) = " " Then $iLast_Word = $i - 1
                        ; Increase line by one character
                        $sTest_Line = StringMid($asLines[$j], 1, $i)
                        ; Get line length
                        $iLine_Length = StringLen($sTest_Line)
                        DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sTest_Line, "int", $iLine_Length, "ptr", DllStructGetPtr($tSize))
                        If @error Then Return SetError(2, _StringSize_Error_Close(6, $hDC, $hFont, $hLabel), 0)
                        $iLine_Width = DllStructGetData($tSize, "X")
                        ; If too long exit the loop
                        If $iLine_Width >= $iMaxWidth - 4 Then ExitLoop
                    Next
                    ; End of the line of text?
                    If $i > StringLen($asLines[$j]) Then
                        ; Yes, so add final line to count
                        $iWrap_Count += 1
                        ; Store line
                        $avSize_Info[0] &= $sTest_Line & @CRLF
                        ExitLoop
                    Else
                        ; No, but add line just completed to count
                        $iWrap_Count += 1
                        ; Check at least 1 word completed or return error
                        If $iLast_Word = 0 Then Return SetError(3, _StringSize_Error_Close(0, $hDC, $hFont, $hLabel), 0)
                        ; Store line up to end of last word
                        $avSize_Info[0] &= StringLeft($sTest_Line, $iLast_Word) & @CRLF
                        ; Strip string to point reached
                        $asLines[$j] = StringTrimLeft($asLines[$j], $iLast_Word)
                        ; Trim leading whitespace
                        $asLines[$j] = StringStripWS($asLines[$j], 1)
                        ; Repeat with remaining characters in line
                    EndIf
                WEnd
                ; Add the number of wrapped lines to the count
                $iLine_Count += $iWrap_Count
            EndIf
        Next
        ; Reset any tab expansions
        If $iExpTab Then
            $avSize_Info[0] = StringRegExpReplace($avSize_Info[0], "\x20?XXXXXXXX", @TAB)
        EndIf
        ; Complete return array
        $avSize_Info[1] = $iLine_Height
        $avSize_Info[2] = $iMaxWidth
        ; Convert lines to pixels and add drop margin
        $avSize_Info[3] = ($iLine_Count * $iLine_Height) + 4
    Else ; No wrapping required
        ; Create return array (add drop margin to height)
        Local $avSize_Info[4] = [$sText, $iLine_Height, $iLine_Width, ($asLines[0] * $iLine_Height) + 4]
    EndIf

    ; Clear up
    DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hPrevFont)
    DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hFont)
    DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $hDC)
    If $hLabel Then GUICtrlDelete($hLabel)

    Return $avSize_Info

EndFunc ;==>_StringSize

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _StringSize_Error_Close
; Description ...: Releases DC and deleted font object if required after error
; Syntax ........: _StringSize_Error_Close ($iExtCode, $hDC, $hGUI)
; Parameters ....: $iExtCode   - code to return
;                  $hDC, $hGUI - handles as set in _StringSize function
; Return value ..: $iExtCode as passed
; Author ........: Melba23
; Modified.......:
; Remarks .......: This function is used internally by _StringSize
; ===============================================================================================================================
Func _StringSize_Error_Close($iExtCode, $hDC = 0, $hFont = 0, $hLabel = 0)

    If $hFont <> 0 Then DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hFont)
    If $hDC <> 0 Then DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $hDC)
    If $hLabel Then GUICtrlDelete($hLabel)

    Return $iExtCode

EndFunc ;=>_StringSize_Error_Close

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _StringSize_DefaultFontName
; Description ...: Determines Windows default font
; Syntax ........: _StringSize_DefaultFontName()
; Parameters ....: None
; Return values .: Success - Returns name of system default font
;                  Failure - Returns "Tahoma"
; Author ........: Melba23, based on some original code by Larrydalooza
; Modified.......:
; Remarks .......: This function is used internally by _StringSize
; ===============================================================================================================================
Func _StringSize_DefaultFontName()
    ; Get default system font data
    Local $tNONCLIENTMETRICS = DllStructCreate("uint;int;int;int;int;int;byte[60];int;int;byte[60];int;int;byte[60];byte[60];byte[60]")
    DLLStructSetData($tNONCLIENTMETRICS, 1, DllStructGetSize($tNONCLIENTMETRICS))
    DLLCall("user32.dll", "int", "SystemParametersInfo", "int", 41, "int", DllStructGetSize($tNONCLIENTMETRICS), "ptr", DllStructGetPtr($tNONCLIENTMETRICS), "int", 0)
    Local $tLOGFONT = DllStructCreate("long;long;long;long;long;byte;byte;byte;byte;byte;byte;byte;byte;char[32]", DLLStructGetPtr($tNONCLIENTMETRICS, 13))
    If IsString(DllStructGetData($tLOGFONT, 14)) Then
        Return DllStructGetData($tLOGFONT, 14)
    Else
        Return "Tahoma"
    EndIf
EndFunc ;=>_StringSize_DefaultFontName

 

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Yes UEZ we are very very near :D

I don't understand why that GDI+ function require so much WIDTH space. Now with the conversion we have make very similar the same size of the internal one, tha space required is calulated by _StringSize. I'm using you 0,0 version for vertically center the text, but example for Arial 100 he want an extra space of 56 ( not 55 ) or it will not show the last letter, the T of TEST. The stripped code:

;#AutoIt3Wrapper_AutoIt3Dir=c:\Program Files (x86)\AutoIt3\3.3.8.1
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
;~ #include "StringSize.au3" ; included for testing only

_GDIPlus_Startup()
Global Const $__g_hGDIPDll = $ghGDIPDll

Global $fFontSize = 100
Global $aSize = _StringSize("TEST", $fFontSize, Default, Default, "Arial")

$hGUI = GUICreate("A", $aSize[2], $aSize[3], 10, 10, $WS_POPUP, $WS_EX_LAYERED)
GUISetState(@SW_SHOW)

$hBmpGDI = _GDIPlus_BitmapCreateText("TEST", $aSize[2], $aSize[3], $fFontSize, "Arial", 0xFFFF0000)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

$hGUI_2 = GUICreate("B", $aSize[2], $aSize[3], 10, $aSize[3] + 20, $WS_POPUP)
GUICtrlCreateLabel("TEST", 0, 0, $aSize[2], $aSize[3])
GUICtrlSetFont(-1, $fFontSize, 400, 0, "Arial")
GUICtrlSetColor(-1, 0xFF0000)
GUICtrlSetBkColor(-1, 0x000000)
GUISetState(@SW_SHOW)

Sleep(2000)

$hBmpGDI = _GDIPlus_BitmapCreateText("TEST", $aSize[2]+56, $aSize[3], $fFontSize, "Arial", 0xFFFF0000)
_WinAPI_BitmapDisplayTransparentInGUI($hBmpGDI, $hGUI)

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            _GDIPlus_Shutdown()
            Exit
    EndSwitch
WEnd

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate(), _
            $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font), _
            $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2), $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000) ; TEST ONLY <<<<<<<<<<<<<<<
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY = 2
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ;$GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT = 3
    _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    Local $tRectF = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    Local Const $iDPI = _GDIPlus_ImageGetHorizontalResolution($hBitmap)
    _GDIPlus_PathAddString($hPath, $sText, $tRectF, $hFamily, $iFontStyle, $fFontSize / 72 * $iDPI, $hFormat)
    Local Const $aWB = _GDIPlus_PathGetWorldBounds($hPath)
    _GDIPlus_PathReset($hPath)
    DllStructSetData($tRectF, "X", -$aWB[0] + 1)
    DllStructSetData($tRectF, "Y", -$aWB[1] + Int($iH / 7)) ; center vertically, is correct? <<<<<<<
    _GDIPlus_PathAddString($hPath, $sText, $tRectF, $hFamily, $iFontStyle, $fFontSize / 72 * $iDPI, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateText

Image of what i'm talking, the first you is GDI, second is internal:

So much space but don't show nothing:

os93qa.png

Too much space for show:

152yy5k.png

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Link to comment
Share on other sites

Try this function:

Func _GDIPlus_BitmapCreateText($sText, $iW, $iH, $fFontSize, $sFontname = "Arial", $iColor_Font = 0xFFFFFFFF, $iColor_FontBorder = 0xFF101010, $iFontStyle = 0, $bGDI = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), $hPath = _GDIPlus_PathCreate(), _
            $hFamily = _GDIPlus_FontFamilyCreate($sFontname), $hFormat = _GDIPlus_StringFormatCreate(), $hBrush = _GDIPlus_BrushCreateSolid($iColor_Font), _
            $hPen = _GDIPlus_PenCreate($iColor_FontBorder, 2), $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000) ; TEST ONLY <<<<<<<<<<<<<<<
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, 2) ;$GDIP_SMOOTHINGMODE_HIGHQUALITY = 2
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 3) ;$GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT = 3

    Local Const $iDPI = _GDIPlus_ImageGetHorizontalResolution($hBitmap), $fDPI_Scale = $iDPI / 72.75
    Local $tRectF = _GDIPlus_RectFCreate(0, 0, $iW * $fDPI_Scale, $iH * $fDPI_Scale)
    _GDIPlus_PathAddString($hPath, $sText, $tRectF, $hFamily, $iFontStyle, ($fFontSize - 1) * $fDPI_Scale, $hFormat)
    Local Const $aWB = _GDIPlus_PathGetWorldBounds($hPath)
    _GDIPlus_PathReset($hPath)
    DllStructSetData($tRectF, "X", -$aWB[0] + 2)
    DllStructSetData($tRectF, "Y", ($iH - $aWB[3]) / 2 - $aWB[1])
    _GDIPlus_PathAddString($hPath, $sText, $tRectF, $hFamily, $iFontStyle, ($fFontSize - 1) * $fDPI_Scale, $hFormat)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_PenCreate($hPen)
    _GDIPlus_GraphicsDispose($hGfx)
    _GDIPlus_PathDispose($hPath)
    If $bGDI Then
        $hBmpGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hBmpGDI
    EndIf
    Return $hBitmap
EndFunc   ;==>_GDIPlus_BitmapCreateText

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...