Jump to content
Sign in to follow this  
Artisan

GDI+ Wrapping Text

Recommended Posts

Artisan

Hi all. I need a little help with GDI+.

I am attempting to display a block of pre-wrapped text using GDI+. (Ultimately I want to be able to print it, so I'm using GDI+ with GRS' UDF. But that doesn't come into play here.) I want to be able to calculate the height and width automatically based on the font and text used. I made a "small" application that asks a user for a font/style and displays a block of typical Latin "lorem ipsum" text. I'm using Melba32's and as far as I can tell it works perfectly. The size it comes up with should be large enough to hold the text. GDI+ disagrees with me, and wraps the text occasionally, causing some lines to have only 1 word and pushing lower lines out of view. Below is my code. Can anyone help me figure out what's causing this? The only current workaround I've found is to pad the width returned by _StringSize by 30 pixels, and I'd really rather not rely on something like that. I suspect there's some kind of a "frame" issue going on, like margin/padding issues in CSS, but I just can't nail it down. Thanks in advance!

EDIT - How do I preserve the tabs in my code when pasting here?

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

; GDI Fonts
; Get a font, show some text.


; Credit: Melba
; For: StringSize UDF
; http://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/

; Credit: ReFran and UEZ
; For: GDI Repainting
; Source: http://www.autoitscript.com/forum/topic/135199-table-wit-gdiborder-lines-dont-redraw/

; Credit: loremipsum.net
; For: Lorem Ipsum text
; Source: http://www.loremipsum.net/


AutoItSetOption("MustDeclareVars", 1)
Global Const $_ATTRIB = 1, $_NAME = 2, $_SIZE = 3, $_WEIGHT = 4, $_COLOR = 7 ; $aFont indices
Global Const $_TEXT = 0, $_WIDTH = 2, $_HEIGHT = 3 ; $aStringSize indices
Global $aFont, $aStringSize, $hGUI, $hGraphic, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo, $sText
Main()

Func Main()

; Sample Text
$sText = _
" 1 - Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt" & @CRLF & _
" 2 - ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci" & @CRLF & _
" 3 - tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum" & @CRLF & _
" 4 - iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat" & @CRLF & _
" 5 - nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum" & @CRLF & _
" 6 - zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis" & @CRLF & _
" 7 - eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non" & @CRLF & _
" 8 - habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes" & @CRLF & _
" 9 - demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus" & @CRLF & _
"10 - dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica," & @CRLF & _
"11 - quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta " & @CRLF & _
"12 - decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes" & @CRLF & _
"13 - in futurum. ##"

; Get font data
$aFont = _ChooseFont()
If Not IsArray($aFont) Then Return -1
$aFont[$_ATTRIB] = Number($aFont[$_ATTRIB]) ; _ChooseFont() returns an array of strings which must be converted for use
$aFont[$_SIZE] = Number($aFont[$_SIZE])
$aFont[$_WEIGHT] = Number($aFont[$_WEIGHT])
$aStringSize = _StringSize($sText, $aFont[$_SIZE], $aFont[$_WEIGHT], $aFont[$_ATTRIB], $aFont[$_NAME])
If Not IsArray($aStringSize) Then Return -1

; Build GUI
$hGUI = GUICreate("GDI+ Font Test (13 Lines)", $aStringSize[$_WIDTH] + 20, $aStringSize[$_HEIGHT] + 50)
GUICtrlCreateLabel("Font: " & $aFont[$_NAME] & ", Size: " & $aFont[$_SIZE] & ", Attribute: " & $aFont[$_ATTRIB] & ", Weight: " & $aFont[$_WEIGHT] & ", Color: " & $aFont[$_COLOR], 10, 10, $aStringSize[$_WIDTH], 20)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBrush = _GDIPlus_BrushCreateSolid("0xFF" & StringMid($aFont[$_COLOR], 3))
$hFormat = _GDIPlus_StringFormatCreate()
$hFamily = _GDIPlus_FontFamilyCreate($aFont[$_NAME])
$hFont = _GDIPlus_FontCreate($hFamily, $aFont[$_SIZE], $aFont[$_ATTRIB])
$tLayout = _GDIPlus_RectFCreate(10, 30, $aStringSize[$_WIDTH], $aStringSize[$_HEIGHT])
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aStringSize[$_TEXT], $hFont, $tLayout, $hFormat)
GUIRegisterMsg($WM_PAINT, "_WMPAINT")
GUISetState(@SW_SHOW, $hGUI)

; Message Loop
Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

; Clean up
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
EndFunc

Func _WMPAINT()
; Repaints the GDI+ stuff (border & text)
; I only tested this on Win7 (x32 and x64), but it *should* be compatible with other Windows versions
_WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_UPDATENOW)
_GDIPlus_GraphicsDrawStringEx($hGraphic, $aStringSize[$_TEXT], $hFont, $aInfo[0], $hFormat, $hBrush)
_GDIPlus_GraphicsDrawRect($hGraphic, 10, 30, $aStringSize[$_WIDTH], $aStringSize[$_HEIGHT])
_WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_VALIDATE)
EndFunc
Edited by Artisan

Share this post


Link to post
Share on other sites
UEZ

Try this:

 

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
;~ #include "StringSize.au3"

; GDI Fonts
; Get a font, show some text.


; Credit: Melba
; For: StringSize UDF
; http://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/

; Credit: ReFran and UEZ
; For: GDI Repainting
; Source: http://www.autoitscript.com/forum/topic/135199-table-wit-gdiborder-lines-dont-redraw/

; Credit: loremipsum.net
; For: Lorem Ipsum text
; Source: http://www.loremipsum.net/


AutoItSetOption("MustDeclareVars", 1)
Global Const $_ATTRIB = 1, $_NAME = 2, $_SIZE = 3, $_WEIGHT = 4, $_COLOR = 7 ; $aFont indices
Global Const $_TEXT = 0, $_WIDTH = 2, $_HEIGHT = 3 ; $aStringSize indices
Global $aFont, $aStringSize, $hGUI, $hGraphic, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo, $sText
Main()

Func Main()

    ; Sample Text
    $sText = _
            " 1 - Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt" & @CRLF & _
            " 2 - ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci" & @CRLF & _
            " 3 - tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum" & @CRLF & _
            " 4 - iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat" & @CRLF & _
            " 5 - nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum" & @CRLF & _
            " 6 - zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis" & @CRLF & _
            " 7 - eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non" & @CRLF & _
            " 8 - habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes" & @CRLF & _
            " 9 - demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus" & @CRLF & _
            "10 - dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica," & @CRLF & _
            "11 - quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta " & @CRLF & _
            "12 - decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes" & @CRLF & _
            "13 - in futurum. ##"

    ; Get font data
    $aFont = _ChooseFont()
    If Not IsArray($aFont) Then Return -1
    _GDIPlus_Startup()
    $aFont[$_ATTRIB] = Number($aFont[$_ATTRIB]) ; _ChooseFont() returns an array of strings which must be converted for use
    $aFont[$_SIZE] = Number($aFont[$_SIZE])
    $aFont[$_WEIGHT] = Number($aFont[$_WEIGHT])
;~  $aStringSize = _StringSize($sText, $aFont[$_SIZE], $aFont[$_WEIGHT], $aFont[$_ATTRIB], $aFont[$_NAME])
    $aStringSize = _GDIPlus_MeasureString($sText, $aFont[$_NAME], $aFont[$_SIZE], $aFont[$_ATTRIB])

;~  _GDIPlus_MeasureString($sString, $sFont = "Arial", $fSize = 12, $iStyle = 0)
    If Not IsArray($aStringSize) Then Return -1

    ; Build GUI
    $hGUI = GUICreate("GDI+ Font Test (13 Lines)", $aStringSize[0] + 20, $aStringSize[1] + 50)
    GUICtrlCreateLabel("Font: " & $aFont[$_NAME] & ", Size: " & $aFont[$_SIZE] & ", Attribute: " & $aFont[$_ATTRIB] & ", Weight: " & $aFont[$_WEIGHT] & ", Color: " & $aFont[$_COLOR], 10, 10, $aStringSize[0], 20)

    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBrush = _GDIPlus_BrushCreateSolid("0xFF" & StringMid($aFont[$_COLOR], 3))
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate($aFont[$_NAME])
    $hFont = _GDIPlus_FontCreate($hFamily, $aFont[$_SIZE], $aFont[$_ATTRIB])
    $tLayout = _GDIPlus_RectFCreate(10, 30, $aStringSize[0], $aStringSize[1])
;~  $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sText, $hFont, $tLayout, $hFormat)
    GUIRegisterMsg($WM_PAINT, "_WMPAINT")
    GUISetState(@SW_SHOW, $hGUI)

    ; Message Loop
    Do
    Until GUIGetMsg() == $GUI_EVENT_CLOSE

    ; Clean up
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
EndFunc   ;==>Main

Func _WMPAINT()
    ; Repaints the GDI+ stuff (border & text)
    ; I only tested this on Win7 (x32 and x64), but it *should* be compatible with other Windows versions
    _WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_UPDATENOW)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, $sText, $hFont, $tLayout, $hFormat, $hBrush)
    _GDIPlus_GraphicsDrawRect($hGraphic, 10, 30, $aStringSize[0], $aStringSize[1])
    _WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_VALIDATE)
EndFunc   ;==>_WMPAINT

Func _GDIPlus_MeasureString($sString, $sFont = "Arial", $fSize = 12, $iStyle = 0, $bRound = True)
    Local $aSize[2]
    Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFont)
    If Not $hFamily Then Return SetError(1, 0, $aSize)
    Local Const $hFormat = _GDIPlus_StringFormatCreate()
    Local Const $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle)
    Local Const $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    Local Const $hGraphic = _GDIPlus_GraphicsCreateFromHWND(0)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    $aSize[0] = $bRound ? Round($aInfo[0].Width, 0) : $aInfo[0].Width
    $aSize[1] = $bRound ? Round($aInfo[0].Height, 0) : $aInfo[0].Height
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_GraphicsDispose($hGraphic)
    Return $aSize
EndFunc   ;==>_GDIPlus_MeasureString

Br,

UEZ

Edited by UEZ
  • Like 1

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
Artisan

Very clever, using a "dummy" GDI graphic with no defined size to get the size needed.  It works well.  Thanks UEZ!

Share this post


Link to post
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
Sign in to follow this  

  • Similar Content

    • nacerbaaziz
      By nacerbaaziz
      hi dears, i have an question please if you can help me.
      i maked an program to do some functions
      and this program works with the global hot keys
      i added an option to the users to change the hot keys
      when i searched about how to do that i found this UDF
      GUIHotkey.au3
      http://www.autoitscript.com/forum/index.php?showtopic=107965
      but the problem here that this UDF cant be detect the win key.
      can you help me to add it, or if there are any others UDFSS wich do that work please give me some.
      i hope that my question is clear for you.
      thanks in advance
    • mdepot
      By mdepot
      I have a situation where I am repeatedly capturing a region of the screen and feeding it into Tesseract OCR.  Since the OCR is a relatively slow operation, I would like to create an in memory cache of the ocr results.  An ideal hash key for this cache would be a checksum of the captured image.  With this I could capture the region, checksum it, and then only if I don't get a cache hit I would write the image out to disk for external OCR.
      Now I know I can do this by saving the captured image out to disk, and then summing the disk file with _Crypt_HashFile().  But that's still slower than I would like, and it shouldn't be necessary.  Ideally, it should be possible to checksum the image data directly in memory so I don't have to go to disk at all.  In order to do that, I need a way to dump a representation of the image into a string  (or some equivalent).  Then I could use the _Crypt_HashData() function against that string to create my cache hash key.
      Googling around I found an article here that shows a way to convert an image object to a byte array using System.Drawing.  This was the closest thing I found to what I'm trying to do.  I don't know if that method could be used from within AutoIT, or if perhaps there may be a better way I don't know about.  If someone could give me a shove in the right direction it would be a big help.  Thanks!
    • Silas
      By Silas
      Hello everyone,
      I have a radio button ($Radio1), which I want to disable as soon as another one get's checked (Radio5). (The system fails if the radio button i'm troubling with also gets checked).
      I know how to disable him:
      If GUICtrlRead($Radio1)=1 And Not BitAND(GUICtrlGetState($Radio5), $GUI_DISABLE) Then GUICtrlSetState($Radio5, 128) But if i try to enable $Radio5 again, after $Radio1 isn't checked anymore, it fails:
      If GUICtrlRead($Radio1)=Not 1 And Not BitAND(GUICtrlGetState($Radio5), $GUI_ENABLE) Then GUICtrlSetState($Radio5, 64)  
      Anyone knows why?
    • caramen
      By caramen
      Hey.  
       
      I requested help about how to get a value from a text in a variable. 
      Now i know how to do that. But i learned with the command FileRead. Now i whould like to know how to replace the command :
      FileRead('Dossier.txt') The purpose is to read a webpage text. To find some value inside. 
       
      Btw i tryed to play with WindowsInfo.au3 but i dont got much thing.  
    • UEZ
      By UEZ
      Here some graphical examples written completely in FreeBasic just for fun.  
      3D Starfield Rotating Flight 3D Starfield Scrolling v1 Booster 3D Starfield Scrolling v3 Booster CreateWindowEx (hGUI) Example FB File2Bas Code Generator (AutoIt script) FB GFX Examples Fire Particles FMOD Examples GDI - GDI+ 3D Sinus Wave GDI - GDI+ Animated Pythagoras Tree GDI - GDI+ Particles - Repulsive Force Sim v2.0 GDI - GDI+ Plasma v5 Booster GDI - GDI+ Random Pattern GDI - GDI+ Space Flight GDI - GDI+ Tunnel Flight - WipeOut Style GDI Classic Raytraced Tunnel GDI Elastic Twister Effect GDI Exploding Pixels GDI Infinite Image Zoom Flight GDI Liquid Pixels GDI Particle Repulsion Grid GDI Particles Mouse Attraction GDI Starfield GDI The Nautilus Raymarcher GDI Worm Tunnel Flight GDI+ Impossible Possible GDI+ Kaleidoscope GDI+ Performance Test - Au3 vs FB GDI+ Polar Clock GDI+ Rotating Earth GDI+ Star Wars Scroller GDI+ Streamer GDI+ Swiss Railway Clock Ini Read - Write Mandelbrot Plasma Puristic Clock Rutt_Etra_Izer_Booster Tunnel Flight uFMOD _WinAPI_SetWindowTitleIcon  
      Download: FreeBasic Examples build 2018-07-10.rar
       
      I will add new examples from time to time.
       
      FreeBasic source codes are also included.
       
×