I already did till the point to draw each word with a different color, now I'm trying to find a way to calculate and drawn the text in the correct position according to the hFormat choosen:
While searching i have found GdipMeasureString:
Code: Select all
MeasureString: 5.195312|51.718750|389.609375|96.562500|28|2
Txt: This is a Multi Colored Text
Code in progress, I'm still trying to figure out how to calculate the correct position of the text:
Code: Select all
VarSetCapacity(SI, 24, 0)
Numput(1, SI, 0, "Int")
If !DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", GDIPToken, "Ptr", &SI, "Ptr", 0)
File = %A_ScriptDir%\pbitmap.png
DllCall("gdiplus.dll\GdipCreateBitmapFromFile", "WStr", File, "PtrP",pBitmap)
Gui, Font, s25, Tahoma
Gui, Add, Text, hwndTEXT_HWND hidden,
OBJ := {hWnd: TEXT_HWND
, Txt: "This is a Multi Colored Text"
, TxtPos: "Center"}
DrawMultiColorTxt(OBJ, pBitmap)
DllCall( "gdiplus\GdipCreateHBITMAPFromBitmap", "PTR",pBitmap, "PTR*",hBitmap, "UInt",0 )
Gui, Add, Picture, x0 y0, % "HBITMAP:" . hBitmap
Gui, Show, w600 h200, DrawTxt
return
DrawMultiColorTxt(OBJ, PBITMAP) {
Txt := OBJ.Txt
TxtPos := OBJ.TxtPos
HWND := OBJ.hWnd
; Create the FONT from the given HWND.
HFONT := DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x31, "Ptr", 0, "Ptr", 0, "Ptr")
DC := DllCall("User32.dll\GetDC", "Ptr", HWND, "Ptr")
DllCall("Gdi32.dll\SelectObject", "Ptr", DC, "Ptr", HFONT)
DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr", DC, "PtrP", PFONT)
DllCall("User32.dll\ReleaseDC", "Ptr", HWND, "Ptr", DC)
DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", HFONT)
; Get the pointer to the bitmap graphics.
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", PBITMAP, "PtrP", PGRAPHICS)
; Set render quality to system default
DllCall("Gdiplus.dll\GdipSetTextRenderingHint", "Ptr", PGRAPHICS, "Int", 0)
; Create a StringFormat object
static HFORMAT_L, HFORMAT_R, HFORMAT_C
if (HFORMAT_L = "") {
;FileAppend, HFORMAT! `n,*
DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", HFORMAT_L)
DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr", HFORMAT_L, "Int", 0x00)
DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr", HFORMAT_L, "Int", 1)
}
if (HFORMAT_R = "") {
DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", HFORMAT_R)
DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr", HFORMAT_R, "Int", 0x02)
DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr", HFORMAT_R, "Int", 1)
}
if (HFORMAT_C = "") {
DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", HFORMAT_C)
; Horizontal alignment.
DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr", HFORMAT_C, "Int", 0x01)
; Vertical alignment.
DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr", HFORMAT_C, "Int", 1)
}
if (TxtPos = "Left")
hFORMAT := HFORMAT_L
else if (TxtPos = "Right")
hFORMAT := HFORMAT_R
else ; Center
hFORMAT := HFORMAT_C
; Create a rect.
DllCall("gdiplus\GdipGetImageDimension", Ptr, pBitmap, "float*", Width, "float*", Height)
VarSetCapacity(RECT, 16, 0)
NumPut(Width, RECT, 8, "Float")
NumPut(Height, RECT, 12, "Float")
Array := StrSplit(Txt, " ")
for each, Txt in Array {
; No need for a separate function
VarSetCapacity(RC, 16)
DllCall("gdiplus\GdipMeasureString", UPtr, pGraphics, "WStr", Txt, "int", -1, Ptr, PFONT, Ptr, &Rec, Ptr, hFORMAT, Ptr, &RC, "uint*", 0, "uint*", 0)
CurrentTxtW := NumGet(RC, 8, "float")
;------------------------------------
VarSetCapacity(RECT, 16, 0)
NumPut(X, RECT, 0, "Float")
NumPut(0, RECT, 4, "Float")
NumPut(CurrentTxtW, RECT, 8, "Float")
NumPut(Height, RECT, 12, "Float")
WordSpacing := 5
X += CurrentTxtW + WordSpacing
; Generate a random color.
Random, vRand, 0, 0xFFFFFF
TxtColor := 0xFF000000 | vRand
; Fill the text color
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", TxtColor, "PtrP", PBRUSH)
; Draw the text.
DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", Txt, "Int", -1, "Ptr", PFONT, "Ptr", &RECT, "Ptr", hFORMAT, "Ptr", PBRUSH)
DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH)
}
;DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr", HFORMAT)
DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", PGRAPHICS)
}
Edit
I think i did it, the spacing is not 100% but looks good:
Spoiler
Still working in a better way to calculate the spacing, it may not look good on different size/length.The code is usable, and i wonder if it could be done in any other way.
Code: Select all
VarSetCapacity(SI, 24, 0)
Numput(1, SI, 0, "Int")
If !DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", GDIPToken, "Ptr", &SI, "Ptr", 0)
File = %A_ScriptDir%\pbitmap.png
DllCall("gdiplus.dll\GdipCreateBitmapFromFile", "WStr", File, "PtrP",pBitmap)
Gui, Font, s23, Tahoma
Gui, Add, Text, hwndTEXT_HWND hidden,
OBJ := {hWnd: TEXT_HWND
, Txt: "This is a Multi Colored Text"
, TxtPos: "Left"}
DrawMultiColorTxt(OBJ, pBitmap)
DllCall( "gdiplus\GdipCreateHBITMAPFromBitmap", "PTR",pBitmap, "PTR*",hBitmap, "UInt",0 )
Gui, Add, Picture, x0 y0, % "HBITMAP:" . hBitmap
Gui, Add, Text, xm100 y+10 , How it should be spaced:
; ===============================================================
DllCall("gdiplus.dll\GdipCreateBitmapFromFile", "WStr", File, "PtrP",pBitmap)
DrawMultiColorTxt(OBJ, PBITMAP, 1)
DllCall( "gdiplus\GdipCreateHBITMAPFromBitmap", "PTR",pBitmap, "PTR*",hBitmap, "UInt",0 )
Gui, Add, Picture, x0 y+10, % "HBITMAP:" . hBitmap
Gui, Show, w600 h460, DrawTxt
return
DrawMultiColorTxt(OBJ, PBITMAP, SingleColor:=0) {
Txt := OBJ.Txt
TxtPos := OBJ.TxtPos
HWND := OBJ.hWnd
; Create the FONT from the given HWND.
HFONT := DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", 0x31, "Ptr", 0, "Ptr", 0, "Ptr")
DC := DllCall("User32.dll\GetDC", "Ptr", HWND, "Ptr")
DllCall("Gdi32.dll\SelectObject", "Ptr", DC, "Ptr", HFONT)
DllCall("Gdiplus.dll\GdipCreateFontFromDC", "Ptr", DC, "PtrP", PFONT)
DllCall("User32.dll\ReleaseDC", "Ptr", HWND, "Ptr", DC)
DllCall("Gdiplus.dll\GdipDeleteFont", "Ptr", HFONT)
; Get the pointer to the bitmap graphics.
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", PBITMAP, "PtrP", PGRAPHICS)
; Set render quality to system default
DllCall("Gdiplus.dll\GdipSetTextRenderingHint", "Ptr", PGRAPHICS, "Int", 0)
; Create a StringFormat object
if (TxtPos = "Left")
N := 0x00
else if (TxtPos = "Right")
N := 0x02
else ; Center
N := 0x01
DllCall("Gdiplus.dll\GdipStringFormatGetGenericTypographic", "PtrP", hFORMAT)
; Horizontal alignment.
DllCall("Gdiplus.dll\GdipSetStringFormatAlign", "Ptr", hFORMAT, "Int", N)
; Vertical alignment.
DllCall("Gdiplus.dll\GdipSetStringFormatLineAlign", "Ptr", hFORMAT, "Int", 1)
; Create a rect.
DllCall("gdiplus\GdipGetImageDimension", Ptr, pBitmap, "float*", Width, "float*", Height)
VarSetCapacity(RECT, 16, 0)
NumPut(Width, RECT, 8, "Float")
NumPut(Height, RECT, 12, "Float")
Array := StrSplit(Txt, " ")
; ===========================================
Lines := 0
Chars := 0
VarSetCapacity(RC, 16)
DllCall("gdiplus\GdipMeasureString", UPtr, pGraphics, "WStr", Txt, "int", -1, Ptr, PFONT, Ptr, &Rect, Ptr, hFORMAT, Ptr, &RC, "uint*", Chars, "uint*", Lines)
X2 := NumGet(RC, 0, "float")
Y2 := NumGet(RC, 4, "float")
Width2 := NumGet(RC, 8, "float")
Height2 := NumGet(RC, 12, "float")
FileAppend, X: %X2%`n,*
FileAppend, Y: %Y2%`n,*
FileAppend, W: %Width2%`n,*
FileAppend, H: %Height2%`n,*
FileAppend, Chars: %Chars%`n,*
WordSpacing := Width2 / Chars
FileAppend, WordSpacing: %WordSpacing%`n`n,*
X := X2
; ======================================
if (SingleColor) {
; Generate a random color.
Random, vRand, 0, 0xFFFFFF
TxtColor := 0xFF000000 | vRand
; Fill the text color
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", TxtColor, "PtrP", PBRUSH)
; Draw the text.
DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", Txt, "Int", -1, "Ptr", PFONT, "Ptr", &RECT, "Ptr", hFORMAT, "Ptr", PBRUSH)
DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH)
}
else {
for each, Txt in Array {
VarSetCapacity(RC, 16)
DllCall("gdiplus\GdipMeasureString", UPtr, pGraphics, "WStr", Txt, "int", -1, Ptr, PFONT, Ptr, &Rec, Ptr, hFORMAT, Ptr, &RC, "uint*", 0, "uint*", 0)
CurrentTxtW := NumGet(RC, 8, "float")
;------------------------------------
VarSetCapacity(RECT, 16, 0)
NumPut(X, RECT, 0, "Float")
NumPut(0, RECT, 4, "Float")
NumPut(CurrentTxtW, RECT, 8, "Float")
NumPut(Height, RECT, 12, "Float")
X += CurrentTxtW + WordSpacing
; Generate a random color.
Random, vRand, 0, 0xFFFFFF
TxtColor := 0xFF000000 | vRand
; Fill the text color
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", TxtColor, "PtrP", PBRUSH)
; Draw the text.
DllCall("Gdiplus.dll\GdipDrawString", "Ptr", PGRAPHICS, "WStr", Txt, "Int", -1, "Ptr", PFONT, "Ptr", &RECT, "Ptr", hFORMAT, "Ptr", PBRUSH)
DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", PBRUSH)
}
}
;DllCall("Gdiplus.dll\GdipDeleteStringFormat", "Ptr", HFORMAT)
DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", PGRAPHICS)
}
Spoiler