Hi Guys, i succeeded to use gdiplus to draw a rainbow text on a window/control DC but i´m failing to try to understand why is it working:
The resultant effect is this:

Which is the same as

Taken at:
https://stackoverrun.com/ru/q/1858879Also there are some good examples made by Mikl here (But, it is for 64 bits and not 32):
https://board.flatassembler.net/topic.php?p=205372https://board.flatassembler.net/topic.php?p=205373and
https://wasm.in/threads/rectf-pointf-kak-realizovat.32727On wasm forum the example05.zip is like this:

But it is not working and also is in 64Bits, instead 32

Also. Mikl seem to do an outline text, but how to do it ? I mean, to display something like:

MY version i s working, but i´m failing to understand why.
What i did so far was:
; Variables and macros used:
[Pointf:
Pointf.X: F$ 10.0;.0
Pointf.Y: F$ 100.0;.0
Pointf.W: F$ 0 ; ??? What is this ???
Pointf.H: F$ 0] ; ??? What is this ???
; Macro GDIP_ARGB
[GDIP_ARGB | (#4 or (#3 shl 8) or (#2 shl 16) or (#1 shl 24))]
;;
hSrcDC(in) - The DC of teh window/control where the text should appear
pFontName(in) - Point a Ansi Null Terminated String representing the font name
pText(in) - Point a Ansi Null Terminated String representing the Text to be placed onto the DC
;;
Proc GdiTextPaint:
Arguments @hSrcDC, @pFontName, @pText
Local @pGraphics, @pFontFamily, @hStatus, @pFont, @pBlackBrush, @nativeFormat, @FontSize, @hGdiPlusStringFormat
Structure @FontNameWDis (&MAX_PATH*2)
Uses ecx, edx, edi
finit
mov D@FontSize 24
lea eax D@FontSize
fild D@FontSize | fstp F@FontSize
call 'Rosmem.ZeroMemory' D@FontNameWDis, (&MAX_PATH*2) ; Clean up the Variable used for the font name
lea eax D@pGraphics
call 'gdiplus.GdipCreateFromHDC' D@hSrcDC, eax
mov D@hStatus eax
call 'kernel32.MultiByteToWideChar' &CP_ACP, 0, D@pFontName, 0-1, D@FontNameWDis, (&MAX_PATH-1)
; quality mode
call 'gdiplus.GdipSetTextRenderingHint' D@pGraphics, TEXTRENDERINGHINT_ANTIALIAS
; Create the font
lea eax D@pFontFamily
call 'gdiplus.GdipCreateFontFamilyFromName' D@FontNameWDis, &NULL, eax
If_And eax = &S_OK, D@pFontFamily <> 0
lea eax D@pFont
call 'gdiplus.GdipCreateFont' D@pFontFamily, D@FontSize, (GDIP_FONT_STYLE_ITALIC+GDIP_FONT_STYLE_UNDERLINE), GDIP_UNIT_POINT, eax
call 'gdiplus.GdipDeleteFontFamily' D@pFontFamily
End_If
; create a gradient text
lea eax D@pBlackBrush
call GdipCreateGradientbrush 10, 100, 100, 100, {GDIP_ARGB 255, 255, 0, 0}, {GDIP_ARGB 255, 255, 255, 0}, eax
;;
; Create a solid brush . Ok to do without the rainbow effect.
lea eax D@pBlackBrush
call 'gdiplus.GdipCreateSolidFill' {GDIP_ARGB 255, 0, 0, 190}, eax
;;
; Draw the string
call 'RosMem.FastZeroMem' D@FontNameWDis, (&MAX_PATH*2)
call 'kernel32.MultiByteToWideChar' &CP_ACP, 0, D@pText, 0-1, D@FontNameWDis, (&MAX_PATH-1)
; format the string
lea eax D@hGdiPlusStringFormat
call 'gdiplus.GdipCreateStringFormat' 0 , &LANG_NEUTRAL, eax
call 'gdiplus.GdipSetStringFormatAlign' D@hGdiPlusStringFormat, GDIPLUS_STRINGALIGNMENT_NEAR;GDIPLUS_STRINGALIGNMENT_CENTER
call 'GDIPLUS.GdipSetStringFormatLineAlign' D@hGdiPlusStringFormat, GDIPLUS_STRINGALIGNMENT_NEAR;GDIPLUS_STRINGALIGNMENT_CENTER
; Draw the string
call 'gdiplus.GdipDrawString' D@pGraphics, D@FontNameWDis, 0-1, D@pFont, Pointf, D@hGdiPlusStringFormat, D@pBlackBrush
; Cleanup
If D@pFont <> 0
call 'gdiplus.GdipDeleteFont' D@pFont
End_If
If D@pBlackBrush <> 0
call 'gdiplus.GdipDeleteBrush' D@pBlackBrush
End_If
If D@pGraphics <> 0
call 'gdiplus.GdipDeleteGraphics' D@pGraphics
End_If
EndP
; GdipCreateGradientbrush is the main function responsible to create the gradient text effect
[RECT.leftDis 0
RECT.topDis 4
RECT.rightDis 8
RECT.bottomDis 12]
; LineGradient Mode
[LINEAR_GRADIENTMODE_HORIZONTAL 0
LINEAR_GRADIENTMODE_VERTICAL 1
LINEAR_GRADIENTMODE_FORWARDDIAGONAL 2
LINEAR_GRADIENTMODE_BACKWARDDIAGONAL 3]
; WarpMode constants
[WARPMODE_PERSPECTIVE 0
WARPMODE_BILINEAR 1]
Proc GdipCreateGradientbrush:
Arguments @XPos, @YPos, @Width, @Height, @Color1, @Color2, @lineGradient
Structure @RECT 16, @RECT.leftDis 0, @RECT.topDis 4, @RECT.rightDis 8, @RECT.bottomDis 12
Uses ecx, edx
mov ecx D@RECT
mov eax D@XPos | mov D$ecx+RECT.leftDis eax
mov eax D@YPos | mov D$ecx+RECT.topDis eax
mov eax D@Width | mov D$ecx+RECT.rightDis eax
mov eax D@Height | mov D$ecx+RECT.bottomDis eax
call 'gdiplus.GdipCreateLineBrushFromRectI' D@RECT, D@Color1, D@Color2, LINEAR_GRADIENTMODE_HORIZONTAL, WARPMODE_PERSPECTIVE, D@lineGradient
EndP
Example of usage:
; the following function can be placed in WM_PAINT message
call GdiTextPaint D@hMemDC, {B$ "Arial", 0}, {B$ "Hello World!", 0} ; must be placed before the bitblt to avoid flicker
call 'GDI32.BitBlt' D@hDC, 0, 0, D@Width, D@Height, D@hMemDC, 0, 0, &SRCCOPY
At GdipCreateGradientbrush what is being passed onto GdipCreateLineBrushFromRectI ??? I mean, the X, YPos seems to be the same ones as used in Pointf structure from GdipDrawString but....what are the width and height from this structure? Should it be always set to 0 ???
Also....what are the Width and Height in GdipCreateLineBrushFromRectI ? Are they the width/height of the whole control/window dc or it can be any aleatory value ? On this example, i only succeeded to make it work setting Width = 100 Height = 100 and keeping X = 10, Y = 100
Note:Btw...The goal (once it is fixed) is try to port the below to masm/RosAsm etc to we do things like these:



As described in:
https://www.codeproject.com/Articles/42529/Outline-Text