Page 1 of 1

Gdi+ Example: Circle of Text

Posted: 23 May 2017, 11:47
by Capn Odin
Circle of Text
Image
Function
Given a string it will generate a bitmap of the characters drawn with a given angle between each char, if the angle is 0 it will try to make the string fill the entire circle.

Code: Select all

CircularText(Angle, Str, Width, Height, Font, Options){
	pBitmap := Gdip_CreateBitmap(Width, Height)
	
	G := Gdip_GraphicsFromImage(pBitmap)
	
	Gdip_SetSmoothingMode(G, 4)
	
	if(!Angle) {
		Angle := 360 / StrLen(Str)
	}
	
	for i, chr in StrSplit(Str) {
		RotateAroundCenter(G, Angle, Width, Height)
		Gdip_TextToGraphics(G, chr, Options, Font, Width, Height)
	}
	
	Gdip_DeleteGraphics(G)
	
	Return pBitmap
}

RotateAroundCenter(G, Angle, Width, Height) {
	Gdip_TranslateWorldTransform(G, Width / 2, Height / 2)
	Gdip_RotateWorldTransform(G, Angle)
	Gdip_TranslateWorldTransform(G, - Width / 2, - Height / 2)
}
Test

Code: Select all

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk

Width := 600, Height := 600

Angle := 0
Font := "Arial"
Options := "x" Width / 2 " y5p w10 Centre cbbffffff r4 s30"
Str := "I thought what I'd do was, I'd pretend I was one of those deaf-mutes. "

Init()

;Gdip_FillEllipse(G, pBrush, 0, 0, Width, Height)
Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20)

UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth-Width)//2, (A_ScreenHeight-Height)//2, Width, Height)

pText := CircularText(Angle, Str, Width, Height, Font, Options)

loop {
	Angle -= 0.2
	Gdip_GraphicsClear(G)
	;Gdip_FillEllipse(G, pBrush, 0, 0, Width, Height)
	Gdip_FillRoundedRectangle(G, pBrush, 0, 0, Width, Height, 20)
	RotateAroundCenter(G, Angle, Width, Height)
	Gdip_DrawImage(G, pText)
	UpdateLayeredWindow(hwnd1, hdc)
	Gdip_ResetWorldTransform(G)
	;Sleep, 25
}
Return

CircularText(Angle, Str, Width, Height, Font, Options){
	pBitmap := Gdip_CreateBitmap(Width, Height)
	
	G := Gdip_GraphicsFromImage(pBitmap)
	
	Gdip_SetSmoothingMode(G, 4)
	
	if(!Angle) {
		Angle := 360 / StrLen(Str)
	}
	
	for i, chr in StrSplit(Str) {
		Gdip_TextToGraphics(G, chr, Options, Font, Width, Height)
		RotateAroundCenter(G, Angle, Width, Height)
	}
	
	Gdip_DeleteGraphics(G)
	
	Return pBitmap
}

RotateAroundCenter(G, Angle, Width, Height) {
	Gdip_TranslateWorldTransform(G, Width / 2, Height / 2)
	Gdip_RotateWorldTransform(G, Angle)
	Gdip_TranslateWorldTransform(G, - Width / 2, - Height / 2)
}

Init() {
	Global
	; Start gdi+
	if(!pToken := Gdip_Startup()) {
		MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
		ExitApp
	}
	OnExit, Exit

	Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
	Gui, 1: Show, NA

	hwnd1 := WinExist()

	hbm := CreateDIBSection(Width, Height)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetSmoothingMode(G, 4)
	pBrush := Gdip_BrushCreateSolid(0xaa000000)
	
	OnMessage(0x201, "WM_LBUTTONDOWN")
}

WM_LBUTTONDOWN() {
	PostMessage, 0xA1, 2
}

Exit:
	; Select the object back into the hdc
	SelectObject(hdc, obm)

	; Now the bitmap may be deleted
	DeleteObject(hbm)

	; Also the device context related to the bitmap may be deleted
	DeleteDC(hdc)

	; The graphics may now be deleted
	Gdip_DeleteGraphics(G)
	
	Gdip_DisposeImage(pText)
	
	; gdi+ may now be shutdown on exiting the program
	Gdip_Shutdown(pToken)
	ExitApp
Return

Re: Gdi+ Example: Circle of Text

Posted: 23 May 2017, 12:09
by noname
Very nice Capn Odin, I struggled with this some time ago to make an old fashioned volume meter dial.Your code is much simpler and cleaner!
Thanks for sharing :)

Re: Gdi+ Example: Circle of Text

Posted: 23 May 2017, 12:41
by Helgef
Very cool! :geek:
Thanks for sharing.

Re: Gdi+ Example: Circle of Text

Posted: 23 May 2017, 14:28
by hunter99
I like it, very nice.
Thanks

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 03:47
by noname
Image

Off topic but how do you add a named download Capn Odin ?

Thanks in advance.

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 03:54
by Capn Odin
In the full editor click on Select code or use these parameters in the code tag code=autohotkey file=Untitled.ahk

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 05:49
by noname
Great, arigato !

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 08:12
by IMEime
Looks good.

I am new to Gdip
I'm trying to test it.
It gives me nothing.

I do not know how to use it.
I have "Gdip standard library v1.45" at 'LIb' folder.
AHK 64 1.1.25.02 Unicode

Regards

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 08:51
by Capn Odin
IMEime wrote:Looks good.

I am new to Gdip
I'm trying to test it.
It gives me nothing.

I do not know how to use it.
I have "Gdip standard library v1.45" at 'LIb' folder.

Regards
Are you trying to run the test file or implementing the function in your own script ?
If it is the first then make sure that your gdi+ script in lib is named Gdip.ahk it may be called Gdip_All.ahk

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 09:07
by IMEime
Thanks, quick reply.

I have Gdip.ahk.
I copied your code (all of the 'Test' part) and ran it.

Regards

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 09:13
by Helgef
IMEime, I've had no luck (in general) with Gdip.ahk. I have renamed Gdip_All.ahk to Gdip.ahk, and put it in my user lib, that is,

Code: Select all

Msgbox, % A_MyDocuments "\AutoHotkey\lib"
Cheers.

Re: Gdi+ Example: Circle of Text

Posted: 24 May 2017, 09:20
by IMEime
Helgef wrote:.. I have renamed Gdip_All.ahk to Gdip.ahk, and put it in my user lib..
God, thanks..
It works.
It rounds with gray color !!
How nice.

Thanks you two.

Regards