Jump to content

GDI outline text scaled in gui


marcoauto
 Share

Recommended Posts

ciao,

I need to scale an outlined GDI text in a GUI. The problem is that I can't do this. The outline is often out of the GUI

I started from this script:

https://www.autoitscript.com/autoit3/docs/libfunctions/_GDIPlus_PathTransform.htm

that fit a string to windows and I changed

 $aBounds = _GDIPlus_PathGetWorldBounds($hPath) ;Get bounding rectangle of the path

$aBounds = _GDIPlus_PathGetWorldBounds($hPath) ;Get bounding rectangle of the path

with 

$aBounds = _GDIPlus_PathGetWorldBounds($hPath,$hMatrix,$hPen) ;Get bounding rectangle of the path with pen size

but doesn't work

so, I tried to change other thins, but nothing... Sometimes works, but if I change the string often result change

This is my script:

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

Example()

Func Example()
    Local $iW, $iH, $hGUI, $hGraphic, $hBrush, $hPen, $hPath, $hFamily, $tLayout, $hMatrix, $aBounds

    ; Create GUI
    $iW = 650
    $iH = 300
    $hGUI = GUICreate("GDI+", $iW, $iH)
    GUISetState(@SW_SHOW)

    ; Draw a string using path
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing)
;~  _GDIPlus_GraphicsClear($hGraphic, 0xFF000000)

    $MergedImageBackgroundColor = 0x00000000
    _GDIPlus_GraphicsClear($hGraphic, $MergedImageBackgroundColor)

    $hBrush = _GDIPlus_BrushCreateSolid(0xFFDD2200)
    $stroke_size = 15
    $hPen = _GDIPlus_PenCreate(0xFFFFBB00, $stroke_size)    ;stroke size in pixel
        $hPen2 = _GDIPlus_PenCreate(0xFFFFff00, 2)  ;stroke size in pixel
    _GDIPlus_PenSetLineJoin($hPen,$GDIP_PENSETLINEJOIN_ROUND)

    $hPath = _GDIPlus_PathCreate() ;Create new path object
;~  $fSize = 20
    $hFamily = _GDIPlus_FontFamilyCreate("Myriad Pro") ;Create font family object
    $tLayout = _GDIPlus_RectFCreate() ;Create string bounding rectangle X=0, Y=0

    Local $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_PathAddString($hPath, "autoitForeverLollipop", $tLayout, $hFamily);, 0, $fSize, $hFormat) ;Add the outline of the string to the path
;~     _GDIPlus_PathAddString($hPath, $sText, $tLayout, $hFamily, 0, $fSize, $hFormat)

    ; Tranform Path to fit to window
    $aBounds = _GDIPlus_PathGetWorldBounds($hPath) ;Get bounding rectangle of the path
    $aPoints = _GDIPlus_PathGetPoints($hPath)
    ConsoleWrite($aBounds[0] & @CRLF)
    ConsoleWrite($aBounds[1] & @CRLF)
    ConsoleWrite($aBounds[2] & @CRLF)
    ConsoleWrite($aBounds[3] & @CRLF)
    ConsoleWrite($aPoints[$aPoints[0][0]][0] & " - " & $aPoints[1][0] & " + 2*" & $stroke_size & " = " & $aPoints[$aPoints[0][0]][0]-$aPoints[1][0]+2*$stroke_size & @CRLF)
;~ $aBounds[0] = $aBounds[0]

    $aBoundsNp = _GDIPlus_PathGetWorldBounds($hPath,0,$hPen) ;Get bounding rectangle of the path with pen
    ConsoleWrite($aBoundsNp[0] & @CRLF)
    ConsoleWrite($aBoundsNp[1] & @CRLF)
    ConsoleWrite($aBoundsNp[2] & @CRLF)
    ConsoleWrite($aBoundsNp[3] & @CRLF)
    ConsoleWrite($iW & " / 2 = "  & $iW / 2 & @CRLF)
    ConsoleWrite("$ih / 2 = "  & $iH / 2 & @CRLF)
;~  ConsoleWrite($iW & " $aBounds[2] = "  & $iW / $aBounds[2] & @CRLF)
    ConsoleWrite($iW & " $aBoundsNp[2] = "  & $iW / $aBoundsNp[2] & @CRLF)
    ConsoleWrite($iH & " $aBoundsNp[3] = "  & $iH / $aBoundsNp[3] & @CRLF)
;~ _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen) ;Draw path to graphics handle (GUI)
;~  _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush) ;Fill path to graphics handle (GUI)
    $hMatrix = _GDIPlus_MatrixCreate()
    $iW = $iW - $stroke_size ;+ $stroke_size
    $iH = $iH - $stroke_size
    ConsoleWrite(" -$aBounds[0]+1*$stroke_size/72 = " &  -$aBounds[0]+1*$stroke_size/72 & @CRLF)
    ConsoleWrite(" -1.8+1*$stroke_size/72 = " &  -1.8+1*$stroke_size/72 & @CRLF)
    _GDIPlus_MatrixTranslate($hMatrix, -$aBounds[0]+2*$stroke_size/72, -$aBounds[1]+1*$stroke_size/72) ;Translate Matrix to the offset of the bounding rectangle
;~  _GDIPlus_MatrixTranslate($hMatrix, -1.59166666666667+0*($stroke_size/72), -$aBounds[1]+1*$stroke_size/72) ;Translate Matrix to the offset of the bounding rectangle
;~  _GDIPlus_MatrixScale($hMatrix, $iW / $aBounds[2], $iH / $aBounds[3], True) ;Scale Matrix
    _GDIPlus_MatrixScale($hMatrix, $iW / $aBounds[2], $iH / $aBounds[3], True) ;Scale Matrix
    _GDIPlus_PathTransform($hPath, $hMatrix) ;Translate and Scale Path

    $aBoundsNp = _GDIPlus_PathGetWorldBounds($hPath,0,$hPen) ;Get bounding rectangle of the path with pen
    ConsoleWrite($aBoundsNp[0] & @CRLF)
    ConsoleWrite($aBoundsNp[1] & @CRLF)
    ConsoleWrite($aBoundsNp[2] & @CRLF)
    ConsoleWrite($aBoundsNp[3] & @CRLF)

;~  _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush) ;Fill path to graphics handle (GUI)
    _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen) ;Draw path to graphics handle (GUI)
    _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush) ;Fill path to graphics handle (GUI)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>Example

if you change the line 

_GDIPlus_PathAddString($hPath, "autoitForeverLollipop", $tLayout, $hFamily);, 0, $fSize, $hFormat) ;Add the outline of the string to the path

with a smaller string

_GDIPlus_PathAddString($hPath, "autoitFitted", $tLayout, $hFamily);, 0, $fSize, $hFormat) ;Add the outline of the string to the path

the result is ok

Can someone can help me?

Thankyou

Link to comment
Share on other sites

After I installed the font "Myriad Pro" your script worked unchanged properly. The result is ok.

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

Can you please change 

_GDIPlus_PathAddString($hPath, "autoitFitted", $tLayout, $hFamily);, 0, $fSize, $hFormat) ;Add the outline of the string to the path

with

_GDIPlus_PathAddString($hPath, "123", $tLayout, $hFamily);, 0, $fSize, $hFormat) ;Add the outline of the string to the path

and tell me if the result is ok? Because for me is not ok. I've attached an image where you can see that the only correct result is where the string is "Autofitted". The other three string are wrong: "autoit" is cut to the right and a bit on the bottom, same thing for "123" and "autoitForeverLollipop" is cut on the left.

I think I'm wrong somewhere... 

After hours of tests I tried to divide by 72 the $strokeSize of the pen. I've tried 72 because the screen is 72dpi but I don't know if is a good idea.

these problems there are with all fonts that I've tried (Arial, too)

thanks and sorry for my bad english

marco

fitToWindows.jpg

Link to comment
Share on other sites

Does this work for you?

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

Example()

Func Example()
    Local $iW, $iH, $hGUI, $hGraphic, $hBrush, $hPen, $hPath, $hFamily, $tLayout, $hMatrix, $aBounds

    ; Create GUI
    $iW = 800
    $iH = 400
    $hGUI = GUICreate("GDI+", $iW, $iH)
    GUISetState(@SW_SHOW)

    ; Draw a string using path
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing)
    _GDIPlus_GraphicsClear($hGraphic, 0xFF000000)

    $hBrush = _GDIPlus_BrushCreateSolid(0xFFDD2200)
    $iPenWidth = 8
    $hPen = _GDIPlus_PenCreate(0xFFFFBB00, $iPenWidth)

    $hPath = _GDIPlus_PathCreate() ;Create new path object

    $hFamily = _GDIPlus_FontFamilyCreate("Arial") ;Create font family object
    $tLayout = _GDIPlus_RectFCreate() ;Create string bounding rectangle X=0, Y=0
    _GDIPlus_PathAddString($hPath, "123", $tLayout, $hFamily) ;Add the outline of the string to the path

    ; Tranform Path to fit to window
    $aBounds = _GDIPlus_PathGetWorldBounds($hPath) ;Get bounding rectangle of the path

    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, -$aBounds[0], -$aBounds[1]) ;Translate Matrix to the offset of the bounding rectangle
    _GDIPlus_MatrixScale($hMatrix, ($iW - Ceiling(($iPenWidth + 1) / 2)) / $aBounds[2], ($iH - Ceiling(($iPenWidth + 1)/ 2)) / $aBounds[3], True) ;Scale Matrix
    _GDIPlus_PathTransform($hPath, $hMatrix) ;Translate and Scale Path

    _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush) ;Fill path to graphics handle (GUI)
    _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen) ;Draw path to graphics handle (GUI)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>Example

 

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

ciao Uez,

thanks for the reply, but unfortunately, the bug is still there.

If you write "Autoit" you will see the error

But I have found the solution. This works!!!!

Thankyou for the help!

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

Example()

Func Example()
    Local $iW, $iH, $hGUI, $hGraphic, $hBrush, $hPen, $hPath, $hFamily, $tLayout, $hMatrix, $aBounds

    ; Create GUI
    $iW = 800
    $iH = 400
    $hGUI = GUICreate("GDI+", $iW, $iH)
    GUISetState(@SW_SHOW)

    ; Draw a string using path
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;Sets the graphics object rendering quality (antialiasing)
    _GDIPlus_GraphicsClear($hGraphic, 0xFF000000)

    $hBrush = _GDIPlus_BrushCreateSolid(0xFFDD2200)
    $iPenWidth = 16
    $hPen = _GDIPlus_PenCreate(0xFFFFBB00, $iPenWidth)
    _GDIPlus_PenSetLineJoin($hPen,$GDIP_PENSETLINEJOIN_ROUND)

    $hPath = _GDIPlus_PathCreate() ;Create new path object

    $hFamily = _GDIPlus_FontFamilyCreate("Arial") ;Create font family object
    $tLayout = _GDIPlus_RectFCreate() ;Create string bounding rectangle X=0, Y=0
    _GDIPlus_PathAddString($hPath, "Autoit", $tLayout, $hFamily) ;Add the outline of the string to the path

    ; Tranform Path to fit to window
    $aBounds = _GDIPlus_PathGetWorldBounds($hPath) ;Get bounding rectangle of the path
    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixScale($hMatrix, ($iW - $iPenWidth) / ($aBounds[2]), ($iH - $iPenWidth) / $aBounds[3], False) ;Scale Matrix
    _GDIPlus_PathTransform($hPath, $hMatrix) ;Translate and Scale Path

    $aBounds = _GDIPlus_PathGetWorldBounds($hPath)
    _GDIPlus_MatrixSetElements($hMatrix, 1, 0, 0, 1, 0, 0) ;Reset Matrix
    _GDIPlus_MatrixTranslate($hMatrix, -$aBounds[0]+$iPenWidth/2, -$aBounds[1]+$iPenWidth/2)
    _GDIPlus_PathTransform($hPath, $hMatrix) ;Translate and Scale Path

    _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen) ;Draw path to graphics handle (GUI)
    _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush) ;Fill path to graphics handle (GUI)

    ; Loop until the user exits.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ; Clean up resources
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>Example

 

Link to comment
Share on other sites

@marcoauto: well done! :thumbsup:

Even shorter:

...
    ; Tranform Path to fit to window
    $aBounds = _GDIPlus_PathGetWorldBounds($hPath) ;Get bounding rectangle of the path
    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, -$aBounds[0], -$aBounds[1]) ;Translate Matrix to the offset of the bounding rectangle
    _GDIPlus_MatrixScale($hMatrix, ($iW - $iPenWidth) / $aBounds[2], ($iH - $iPenWidth) / $aBounds[3], True) ;Scale Matrix
    _GDIPlus_PathTransform($hPath, $hMatrix) ;Translate and Scale Path
    _GDIPlus_MatrixSetElements($hMatrix, 1, 0, 0, 1, 0, 0)
    _GDIPlus_MatrixTranslate($hMatrix, $iPenWidth / 2, $iPenWidth / 2)
    _GDIPlus_PathTransform($hPath, $hMatrix)

    _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush) ;Fill path to graphics handle (GUI)
    _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen) ;Draw path to graphics handle (GUI)
...

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

×
×
  • Create New...