GDI+ Library in V2 Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

GDI+ Library in V2

Post by Spitzi » 16 May 2023, 05:13

Hi there.

I'm trying to make the switch to AHKV2.I use the GDIP-Library a lot. There seems to be a V2 version out and already 2 years old:

https://github.com/mmikeww/AHKv2-Gdip

When I include it in my script, i get an error:
... AutoHotKey\CuMoS_ProgData\Gdip_All_V1V2.ahk (396) : ==> Missing comma
Specifically: CreateRectF(ByRef RectF, x, y, w, h)

I guess V2 does not use the keyword ByRef anymore, but an ampersand to indicate byRef variables. Is there a newer version of the GDI+-Library, that I should use? I can't find any version of GDI+ without ByRefs in the function definitions.

This is the code that I use to test:

Code: Select all

#SingleInstance
#include Gdip_All_V2.ahk

MsgBox "Test"

main := Gui()
textElement := main.add("Text" , , "Hello World")
textElement.OnEvent("click", ShowMessage)
main.show()

ShowMessage(*) {
	MsgBox "Ok"
}
I must be missing something very stupid.


Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 16 May 2023, 06:44

Thank you boiler.

I get this one warning:

Warning: This variable appears to never be assigned a value.
▶ 1038: MsgBox("Skipping wrong points " . ToString(coords))

@buliasz: I replaced the line with

Code: Select all

MsgBox("Skipping wrong points " . String(coords))

buliasz
Posts: 26
Joined: 10 Oct 2016, 14:31
Contact:

Re: GDI+ Library in V2

Post by buliasz » 16 May 2023, 07:31

Thank you for pointing this out. I've just merged fixed version. The String(coords) would throw an Error when executed.

dmcnaugh15
Posts: 13
Joined: 24 Mar 2019, 16:42

Re: GDI+ Library in V2

Post by dmcnaugh15 » 04 Jun 2023, 10:11

This is a known issue detailed on the github site: https://github.com/mmikeww/AHKv2-Gdip/issues/31

I don't have the time and energy to update it myself.

If anyone does, or learns of an unofficial updated version, I'd really appreciate a link to it.

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 14 Jun 2023, 04:36

@buliasz , i found another little "bug" in the library

This function:

Code: Select all

Gdip_DrawImage(pGraphics, pBitmap, dx:="", dy:="", dw:="", dh:="", sx:="", sy:="", sw:="", sh:="", Matrix:=1)
{
	if !IsNumber(Matrix)
		ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
	else if (Matrix != 1)
		ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")

	if (sx = "" && sy = "" && sw = "" && sh = "")
	{
		if (dx = "" && dy = "" && dw = "" && dh = "")
		{
			sx := dx := 0, sy := dy := 0
			sw := dw := Gdip_GetImageWidth(pBitmap)
			sh := dh := Gdip_GetImageHeight(pBitmap)
		}
		else
		{
			sx := sy := 0
			sw := Gdip_GetImageWidth(pBitmap)
			sh := Gdip_GetImageHeight(pBitmap)
		}
	}

	_E := DllCall("gdiplus\GdipDrawImageRectRect"
				, "UPtr", pGraphics
				, "UPtr", pBitmap
				, "Float", dx
				, "Float", dy
				, "Float", dw
				, "Float", dh
				, "Float", sx
				, "Float", sy
				, "Float", sw
				, "Float", sh
				, "Int", 2
				, "UPtr", ImageAttr ? ImageAttr : 0
				, "UPtr", 0
				, "UPtr", 0)
	if ImageAttr
		Gdip_DisposeImageAttributes(ImageAttr)
	return _E
}
throws a warning because ImageAttr is not set. I changed it for me to by inserting
ImageAttr := 0
in the first line, as in

Code: Select all

Gdip_DrawImage(pGraphics, pBitmap, dx:="", dy:="", dw:="", dh:="", sx:="", sy:="", sw:="", sh:="", Matrix:=1)
{
	ImageAttr := 0
	if !IsNumber(Matrix)
		ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
	else if (Matrix != 1)
		ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")

	if (sx = "" && sy = "" && sw = "" && sh = "")
	{
		if (dx = "" && dy = "" && dw = "" && dh = "")
		{
			sx := dx := 0, sy := dy := 0
			sw := dw := Gdip_GetImageWidth(pBitmap)
			sh := dh := Gdip_GetImageHeight(pBitmap)
		}
		else
		{
			sx := sy := 0
			sw := Gdip_GetImageWidth(pBitmap)
			sh := Gdip_GetImageHeight(pBitmap)
		}
	}

	_E := DllCall("gdiplus\GdipDrawImageRectRect"
				, "UPtr", pGraphics
				, "UPtr", pBitmap
				, "Float", dx
				, "Float", dy
				, "Float", dw
				, "Float", dh
				, "Float", sx
				, "Float", sy
				, "Float", sw
				, "Float", sh
				, "Int", 2
				, "UPtr", ImageAttr ? ImageAttr : 0
				, "UPtr", 0
				, "UPtr", 0)
	if ImageAttr
		Gdip_DisposeImageAttributes(ImageAttr)
	return _E
}

buliasz
Posts: 26
Joined: 10 Oct 2016, 14:31
Contact:

Re: GDI+ Library in V2

Post by buliasz » 14 Jun 2023, 07:22

Spitzi wrote:
14 Jun 2023, 04:36
I changed it for me to by inserting
ImageAttr := 0
in the first line
Thank you @Spitzi , I've added your fix to the GitHub repo.

EDIT: I've just noticed my notifications for pull requests didn't work. Thank you, I've approved and applied all of those.

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 27 Jun 2023, 01:52

Hello @buliasz. Thanks for your updates.

From time to time i get the following error from your GDIP-Libary:

Error: An exception was thrown.

Specifically: 0xc0000005

---- G:\AutoHotKey\CuMoS_ProgData\Gdip_All_V2.ahk
1712: }
1727: {
▶ 1728: DllCall("gdiplus\GdipGetImageWidth", "UPtr", pBitmap, "uint*", &Width:=0)
1729: DllCall("gdiplus\GdipGetImageHeight", "UPtr", pBitmap, "uint*", &Height:=0)
1730: }

The current thread will exit.

Call stack:
G:\AutoHotKey\CuMoS_ProgData\Gdip_All_V2.ahk (1728) : [DllCall] DllCall("gdiplus\GdipGetImageWidth", "UPtr", pBitmap, "uint*", &Width:=0)
G:\AutoHotKey\CuMoS_ProgData\Gdip_All_V2.ahk (1728) : [Gdip_GetImageDimensions] DllCall("gdiplus\GdipGetImageWidth", "UPtr", pBitmap, "uint*", &Width:=0)
G:\AutoHotKey\CuMoS_Dev_V2.ahk (2697) : [Gdip_CropBitmap] Gdip_GetImageDimensions(pBitmap, &origW, &origH)


It's weird, because the error happens only sporadically. can you make sense of it?

Also: calling
Gdip_Shutdown(pToken)
will crash AHK V2.0.2

Thanks!!

buliasz
Posts: 26
Joined: 10 Oct 2016, 14:31
Contact:

Re: GDI+ Library in V2

Post by buliasz » 01 Jul 2023, 13:51

Hi @Spitzi, for the 0xc0000005 exception I'm guessing it happens sporadically when some resource in your memory gets freed before you use it. It may be memory released by AHK or by Windows or maybe GDI+ even. You can try checking if your code may prevent it or catch the exception and retry if that's not dependent on your code. I've had similar situation with another library where resources were freed by system on some conditions so I had to reinit library sometimes.

For the Gdip_Shutdown(pToken) crashing I only use shutdown on AHK exit routine, so I don't really care in my code. You may find it useful to add something similar to your code on startup:

Code: Select all

OnExit((*)=>Gdip_Shutdown(_GDIP_TOKEN))
If you find any bug within the Gdip_Shutdown function please let me know. You can try removing

Code: Select all

if hModule := DllCall("GetModuleHandle", "str", "gdiplus", "UPtr") {
	DllCall("FreeLibrary", "UPtr", hModule)
}
and see if this solves the issue.

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 01 Jul 2023, 15:30

Hi @buliasz . Thanks for your help.

Sure, I also only shutdown gdi on application exit, but it is still not nice. I removed the line in the if-clause of gdip_shutdown, like you said
Gdip_Shutdown(pToken)
{
DllCall("gdiplus\GdiplusShutdown", "UPtr", pToken)
if hModule := DllCall("GetModuleHandle", "str", "gdiplus", "UPtr") {
; DllCall("FreeLibrary", "UPtr", hModule)
}

return 0
}
No AHK-Crash this way! Is the commented out DLLCall important?

buliasz
Posts: 26
Joined: 10 Oct 2016, 14:31
Contact:

Re: GDI+ Library in V2

Post by buliasz » 01 Jul 2023, 18:01

This one is to free resource loaded in Gdip_Startup() by LoadLibrary. You can read more about all of LoadLibrary, FreeLibrary and GetModuleHandle here.
I have just pushed some fix. The LoadLibrary was conditional, so if it it was not executed then FreeLibrary should not be called either in case multiple Gdip were loaded for AHK. Let me know if that fixes your issue, I've tested it locally and it works here.

FYI calling LoadLibrary multiple times is totally ok, as it only will increase internal counter when it is already loaded. Calling more times FreeLibrary than LoadLibrary is not ok, that's probably why you've got the error before.

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 03 Jul 2023, 04:37

@buliasz: Thank you!!!

I'll let you know...

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 05 Jul 2023, 03:13

hi there @buliasz

No more crashes! Thanks again. I noticed another problem:

Code: Select all

#Include "CuMoS_ProgData\Gdip_All_V2_03072023.ahk"


global pToken := Gdip_StartUp()
CreateImageWithText("C\Temp\image.png", "Test")


; https://www.autohotkey.com/boards/viewtopic.php?style=19&t=89978
; creates an image with the given text, 1000x500pixels big
; creates the directory if not existing
CreateImageWithText(saveFilePath, textToWrite) {

	SplitPath(saveFilePath, &fileName, &fileDir)
	if !FileExist(fileDir) {
		DirCreate(fileDir)
	}

	canvasBitmap := Gdip_CreateBitmap(1000, 500)
	canvasG := Gdip_GraphicsFromImage(canvasBitmap)

	Gdip_TextToGraphics(canvasG, textToWrite, "x20 y225 s50 CFF98CB4A", "Arial")

	Gdip_Savebitmaptofile(canvasBitmap, saveFilePath)
	Gdip_DisposeImage(canvasBitmap)
	Gdip_DeleteGraphics(canvasG)
}

ExitApp
This trows this error
Spoiler


By the way, an error is thrown in this function

Code: Select all

Gdip_TextToGraphics(pGraphics, Text, Options, Font:="Arial", Width:="", Height:="", Measure:=0)
{
	IWidth := Width, IHeight:= Height, PassBrush := 0

	pattern_opts := "i)"
	RegExMatch(Options, pattern_opts "X([\-\d\.]+)(p*)", &xpos:="")
	RegExMatch(Options, pattern_opts "Y([\-\d\.]+)(p*)", &ypos:="")
	RegExMatch(Options, pattern_opts "W([\-\d\.]+)(p*)", &Width:="")
	RegExMatch(Options, pattern_opts "H([\-\d\.]+)(p*)", &Height:="")
	RegExMatch(Options, pattern_opts "C(?!(entre|enter))([a-f\d]+)", &Colour:="")
	RegExMatch(Options, pattern_opts "Top|Up|Bottom|Down|vCentre|vCenter", &vPos:="")
	RegExMatch(Options, pattern_opts "NoWrap", &NoWrap:="")
	RegExMatch(Options, pattern_opts "R(\d)", &Rendering:="")
	RegExMatch(Options, pattern_opts "S(\d+)(p*)", &Size:="")

	if Colour && IsInteger(Colour[2]) && !Gdip_DeleteBrush(Gdip_CloneBrush(Colour[2])) {
		PassBrush := 1, pBrush := Colour[2]
	}

	if !(IWidth && IHeight) && ((xpos && xpos[2]) || (ypos && ypos[2]) || (Width && Width[2]) || (Height && Height[2]) || (Size && Size[2])) {
		return -1
	}

	Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
	for eachStyle, valStyle in StrSplit( Styles, "|" ) {
		if RegExMatch(Options, "\b" valStyle)
			Style |= (valStyle != "StrikeOut") ? (A_Index-1) : 8
	}

	Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
	for eachAlignment, valAlignment in StrSplit( Alignments, "|" ) {
		if RegExMatch(Options, "\b" valAlignment) {
			Align |= A_Index*10//21	; 0|0|1|1|2|2
		}
	}

	xpos := (xpos && (xpos[1] != "")) ? xpos[2] ? IWidth*(xpos[1]/100) : xpos[1] : 0
	ypos := (ypos && (ypos[1] != "")) ? ypos[2] ? IHeight*(ypos[1]/100) : ypos[1] : 0
	Width := (Width && Width[1]) ? Width[2] ? IWidth*(Width[1]/100) : Width[1] : IWidth
	Height := (Height && Height[1]) ? Height[2] ? IHeight*(Height[1]/100) : Height[1] : IHeight

	if !PassBrush {
		Colour := "0x" (Colour && Colour[2] ? Colour[2] : "ff000000")
	}

	Rendering := (Rendering && (Rendering[1] >= 0) && (Rendering[1] <= 5)) ? Rendering[1] : 4
	Size := (Size && (Size[1] > 0)) ? Size[2] ? IHeight*(Size[1]/100) : Size[1] : 12

	hFamily := Gdip_FontFamilyCreate(Font)
	hFont := Gdip_FontCreate(hFamily, Size, Style)
	FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
	hFormat := Gdip_StringFormatCreate(FormatStyle)
	pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)

	if !(hFamily && hFont && hFormat && pBrush && pGraphics) {
		return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
	}

	CreateRectF(&RC:="", xpos, ypos, Width, Height)
	Gdip_SetStringFormatAlign(hFormat, Align)
	Gdip_SetTextRenderingHint(pGraphics, Rendering)
	ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, &RC)

	if vPos {
		ReturnRC := StrSplit(ReturnRC, "|")

		if (vPos[0] = "vCentre") || (vPos[0] = "vCenter")
			ypos += (Height-ReturnRC[4])//2
		else if (vPos[0] = "Top") || (vPos[0] = "Up")
			ypos := 0
		else if (vPos[0] = "Bottom") || (vPos[0] = "Down")
			ypos := Height-ReturnRC[4]

		CreateRectF(&RC, xpos, ypos, Width, ReturnRC[4])
		ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, &RC)
	}

	if !Measure {
		_E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, &RC)
	}

	if !PassBrush {
		Gdip_DeleteBrush(pBrush)
	}

	Gdip_DeleteStringFormat(hFormat)
	Gdip_DeleteFont(hFont)
	Gdip_DeleteFontFamily(hFamily)

	return _E ? _E : ReturnRC
}
because local PassBrush is not always defined. I added the line

PassBrush := 0

at the beginning to solve it. Maybe you can correct it on github?

buliasz
Posts: 26
Joined: 10 Oct 2016, 14:31
Contact:

Re: GDI+ Library in V2

Post by buliasz » 05 Jul 2023, 07:09

Added, thanks

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 02 Aug 2023, 03:47

Hi @buliasz

Can you take a look at the following sample code, which used to work in V1, but throws an error in the GDIP-Library in V2:

Code: Select all

#Include "Gdip_All_V2_03072023.ahk"						; access to GDI-functions (GraphicsDeviceInterface)     from      https://github.com/buliasz/AHKv2-Gdip
#SingleInstance Force

global pToken := Gdip_StartUp()

CreateImageWithText("C:\Temp\test.png", "Some Text")


ExitApp

; https://www.autohotkey.com/boards/viewtopic.php?style=19&t=89978
; creates an image with the given text, 1000x500pixels big
; creates the directory if not existing
CreateImageWithText(saveFilePath, textToWrite) {

	SplitPath(saveFilePath, &fileName, &fileDir)
	if !FileExist(fileDir) {
		DirCreate(fileDir)
	}

	canvasBitmap := Gdip_CreateBitmap(1000, 500)
	canvasG := Gdip_GraphicsFromImage(canvasBitmap)

	Gdip_TextToGraphics(canvasG, textToWrite, "x20 y225 s50 CFF98CB4A", "Arial")

	Gdip_Savebitmaptofile(canvasBitmap, saveFilePath)
	Gdip_DisposeImage(canvasBitmap)
	Gdip_DeleteGraphics(canvasG)
}
The error is:

Error: Invalid parameter(s).

---- G:\A-1-Radiologie\04-Aerzte\Spitzi\Programme\AutoHotKey\CuMoS_ProgData\Gdip_All_V2_03072023.ahk
377: {
378: RectF := Buffer(16)
▶ 379: NumPut("Float", x, RectF, 0), NumPut("Float", y, RectF, 4), NumPut("Float", w, RectF, 8), NumPut("Float", h, RectF, 12)
380: }
395: {


Thanks and greets. Simon

buliasz
Posts: 26
Joined: 10 Oct 2016, 14:31
Contact:

Re: GDI+ Library in V2

Post by buliasz » 02 Aug 2023, 13:13

I guess x, y, w or h is not a float number. You can check by adding temporary code before NumPut like this:

Code: Select all

if (!IsFloat(x) || !IsFloat(y) || !IsFloat(w) || !IsFloat(h) {
    MsgBox("Received not a float value: x=" x " y=" y " w=" w " h=" h)
}
EDIT: Actually AHK documentation says that NumPut number values are expected to be of Integer type, so instead of IsFloat probably you should use IsInteger. But on the other hand when you click on the hyperlinked Integer in the documentation it leads not to Integer description but to Number so I guess it is a documentation glitch and actually IsNumber is the one to use :crazy:. Anyway checking the real value of those variables may lead to a solution.

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 03 Aug 2023, 08:36

Hi @buliasz

You are right. I added width and height information to the call

Code: Select all

Gdip_TextToGraphics(canvasG, textToWrite, "x20 y225 w960 h50 s50 center CFF98CB4A", "Arial")
Now it works. It would be nice for it to work without the width and height information. In V1, I used this function from the GDIP-Library:

Code: Select all

Gdip_TextToGraphics(pGraphics, Text, Options, Font:="Arial", Width:="", Height:="", Measure:=0, userBrush:=0, Unit:=0, acceptTabStops:=0) {
; Font parameter can be a name of an already installed font or it can point to a font file
; to be loaded and used to draw the string.
;
; Set Unit to 3 [Pts] to have the texts rendered at the same size
; with the texts rendered in GUIs with -DPIscale
;
; userBrush - if a pBrush object is passed, this will be used to draw the text
;
; Remarks: by changing the alignment, the text will be rendered at a different X
; coordinate position; the position of the text is set relative to
; the given X position coordinate and the text width..
; See also Gdip_SetStringFormatAlign().
;
; On success, the function returns a string in the following format:
; "x|y|width|height|chars|lines"
; The first four elements represent the boundaries of the text.
; The string is returned by Gdip_MeasureString()

   Static Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
        , Alignments := "Near|Left|Centre|Center|Far|Right"

   OWidth := Width
   IWidth := Width, IHeight:= Height
   pattern_opts := (A_AhkVersion < "2") ? "iO)" : "i)"
   RegExMatch(Options, pattern_opts "X([\-\d\.]+)(p*)", xpos)
   RegExMatch(Options, pattern_opts "Y([\-\d\.]+)(p*)", ypos)
   RegExMatch(Options, pattern_opts "W([\-\d\.]+)(p*)", PWidth)
   RegExMatch(Options, pattern_opts "H([\-\d\.]+)(p*)", Height)
   RegExMatch(Options, pattern_opts "C(?!(entre|enter))([a-f\d]+)", Colour)
   RegExMatch(Options, pattern_opts "Top|Up|Bottom|Down|vCentre|vCenter", vPos)
   RegExMatch(Options, pattern_opts "NoWrap", NoWrap)
   RegExMatch(Options, pattern_opts "R(\d)", Rendering)
   RegExMatch(Options, pattern_opts "S(\d+)(p*)", Size)
   Width := PWidth

   if !(IWidth && IHeight) && ((xpos && xpos[2]) || (ypos && ypos[2]) || (Width && Width[2]) || (Height && Height[2]) || (Size && Size[2]))
      return -1

   fColor := (Colour && Colour[2]) ? Colour[2] : "ff000000"
   If (StrLen(fColor)=6)
      fColor := "ff" fColor

   if (fColor && !userBrush)
      pBrush := Gdip_BrushCreateSolid("0x" fColor)

   Style := 0
   For eachStyle, valStyle in StrSplit(Styles, "|")
   {
      if RegExMatch(Options, "\b" valStyle)
         Style |= (valStyle != "StrikeOut") ? (A_Index-1) : 8
   }

   Align := 0
   For eachAlignment, valAlignment in StrSplit(Alignments, "|")
   {
      if RegExMatch(Options, "\b" valAlignment)
         Align |= A_Index//2.1   ; 0|0|1|1|2|2
   }

   xpos := (xpos && (xpos[1] != "")) ? xpos[2] ? IWidth*(xpos[1]/100) : xpos[1] : 0
   ypos := (ypos && (ypos[1] != "")) ? ypos[2] ? IHeight*(ypos[1]/100) : ypos[1] : 0
   Width := (Width && Width[1]) ? Width[2] ? IWidth*(Width[1]/100) : Width[1] : IWidth
   Height := (Height && Height[1]) ? Height[2] ? IHeight*(Height[1]/100) : Height[1] : IHeight
   Rendering := (Rendering && (Rendering[1] >= 0) && (Rendering[1] <= 5)) ? Rendering[1] : 4
   Size := (Size && (Size[1] > 0)) ? Size[2] ? IHeight*(Size[1]/100) : Size[1] : 12
   If RegExMatch(Font, "^(.\:\\.)")
   {
      hFontCollection := Gdip_NewPrivateFontCollection()
      hFontFamily := Gdip_CreateFontFamilyFromFile(Font, hFontCollection)
   } Else hFontFamily := Gdip_FontFamilyCreate(Font)

   If !hFontFamily
      hFontFamily := Gdip_FontFamilyCreateGeneric(1)

   hFont := Gdip_FontCreate(hFontFamily, Size, Style, Unit)
   FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
   hStringFormat := Gdip_StringFormatCreate(FormatStyle)
   If !hStringFormat
      hStringFormat := Gdip_StringFormatGetGeneric(1)

   thisBrush := userBrush ? userBrush : pBrush
   if !(hFontFamily && hFont && hStringFormat && thisBrush && pGraphics)
   {
      E := !pGraphics ? -2 : !hFontFamily ? -3 : !hFont ? -4 : !hStringFormat ? -5 : !pBrush ? -6 : 0
      If pBrush
         Gdip_DeleteBrush(pBrush)
      If hStringFormat
         Gdip_DeleteStringFormat(hStringFormat)
      If hFont
         Gdip_DeleteFont(hFont)
      If hFontFamily
         Gdip_DeleteFontFamily(hFontFamily)
      If hFontCollection
         Gdip_DeletePrivateFontCollection(hFontCollection)
      return E
   }

   CreateRectF(RC, xpos, ypos, Width, Height)
   If (acceptTabStops=1)
      Gdip_SetStringFormatTabStops(hStringFormat, [50,100,200])

   Gdip_SetStringFormatAlign(hStringFormat, Align)
   If InStr(Options, "autotrim")
      Gdip_SetStringFormatTrimming(hStringFormat, 3)

   Gdip_SetTextRenderingHint(pGraphics, Rendering)
   ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hStringFormat, RC)
   ReturnRCtest := StrSplit(ReturnRC, "|")
   testX := Floor(ReturnRCtest[1]) - 2
   If (testX>xpos && NoWrap && (PWidth>2 || OWidth>2))
   {
      ; error correction of posX for different text alignments
      ; when width is given, but no text wrap
      nxpos := Floor(xpos - (testX - xpos))
      CreateRectF(RC, nxpos, ypos, Width, Height)
      ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hStringFormat, RC)
      ; MsgBox, % nxpos "--" xpos "--" ypos "`n" width "--" height "`n" ReturnRC
   }

   If vPos
   {
      ReturnRC := StrSplit(ReturnRC, "|")
      if (vPos[0] = "vCentre") || (vPos[0] = "vCenter")
         ypos += (Height-ReturnRC[4])//2
      else if (vPos[0] = "Top") || (vPos[0] = "Up")
         ypos += 0
      else if (vPos[0] = "Bottom") || (vPos[0] = "Down")
         ypos += Height-ReturnRC[4]

      CreateRectF(RC, xpos, ypos, Width, ReturnRC[4])
      ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hStringFormat, RC)
   }

   if !Measure
      _E := Gdip_DrawString(pGraphics, Text, hFont, hStringFormat, thisBrush, RC)

   If pBrush
      Gdip_DeleteBrush(pBrush)
   Gdip_DeleteStringFormat(hStringFormat)
   Gdip_DeleteFont(hFont)
   Gdip_DeleteFontFamily(hFontFamily)
   If hFontCollection
      Gdip_DeletePrivateFontCollection(hFontCollection)
   return _E ? _E : ReturnRC
}
It does not depend on witdth/height options.

Anyway. Good enough for me right now. Thanks for your help!!! Spitzi

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 09 Aug 2023, 07:19

Hi there, @buliasz

I was wondering if you could put your AHKV2-Gdip Library on GitHub unter a official licence, for example the MIT-License or GLP-License?

Thanks and greets Spitzi

iseahound
Posts: 1444
Joined: 13 Aug 2016, 21:04
Contact:

Re: GDI+ Library in V2

Post by iseahound » 10 Aug 2023, 19:17

I'm not sure what the license is for GDI+ v2, since it is heavily based on other people's work, and would require all of their consent.

Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

Re: GDI+ Library in V2

Post by Spitzi » 12 Aug 2023, 03:01

Sure. But it would be nice to have something more official. Since everybody is using the library as is, without license, it's very probable that these people are ok with, e.g. an MIT-Licence.

Post Reply

Return to “Ask for Help (v2)”