Modify

Opened 10 years ago

Closed 7 years ago

#1846 closed Feature Request (Rejected)

change _GdiPlus_GraphicsDraw/Fill* functions to corresponding floating point version

Reported by: Eukalyptus Owned by: Gary
Milestone: Component: Standard UDFs
Version: Severity: None
Keywords: Cc:

Description

all _GdiPlus_GraphicsDraw/Fill functions use the integer version.
to get smoother results it´s better to use the float versions of:
GdipDrawArcI
GdipDrawBezierI
GdipDrawClosedCurveI
GdipDrawCurveI
GdipDrawEllipseI
GdipDrawLineI
GdipDrawPieI
GdipDrawPolygonI
GdipDrawRectangleI

GdipFillClosedCurveI
GdipFillEllipseI
GdipFillPieI
GdipFillPolygonI
GdipFillRectangleI

example:
red line = int / green line = float

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)

Global Const $Pi = ATan(1) * 4
Global Const $DegToRad = $Pi / 180

_GDIPlus_Startup()

Global $hGui = GUICreate("Test", 800, 600)
GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphics)
Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
_GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)

GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUISetState()

Global $hPenR = _GDIPlus_PenCreate(0xFFFF0000, 3)
Global $hPenG = _GDIPlus_PenCreate(0xFF00FF00, 3)

Global $nX, $nY

For $i = 0 To 800 Step 0.1
	_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
	_GDIPlus_GraphicsDrawLine($hGfxBuffer, $i, 0, $i, 100, $hPenR)
	_GDIPlus_GraphicsDrawLine_Float($hGfxBuffer, $i, 100, $i, 200, $hPenG)

	$nX = Cos($i * $DegToRad) * 200
	$nY = Sin($i * $DegToRad) * 200
	_GDIPlus_GraphicsDrawLine($hGfxBuffer, 200, 400, 200 + $nX, 400 + $nY, $hPenR)
	_GDIPlus_GraphicsDrawLine_Float($hGfxBuffer, 600, 400, 600 + $nX, 400 + $nY, $hPenG)

	_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Next

_Exit()


Func _GDIPlus_GraphicsDrawLine_Float($hGraphics, $nX1, $nY1, $nX2, $nY2, $hPen = 0)
	__GDIPlus_PenDefCreate($hPen)
	Local $aResult = DllCall($ghGDIPDll, "int", "GdipDrawLine", "handle", $hGraphics, "handle", $hPen, "float", $nX1, "float", $nY1, _
			"float", $nX2, "float", $nY2)
	Local $tmpError = @error, $tmpExtended = @extended
	__GDIPlus_PenDefDispose()
	If $tmpError Then Return SetError($tmpError, $tmpExtended, False)
	Return $aResult[0] = 0
EndFunc   ;==>_GDIPlus_GraphicsDrawLine_Float


Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
	_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_PAINT


Func _Exit()
	_GDIPlus_PenDispose($hPenR)
	_GDIPlus_PenDispose($hPenG)
	_GDIPlus_GraphicsDispose($hGfxBuffer)
	_GDIPlus_BitmapDispose($hBmpBuffer)
	_GDIPlus_GraphicsDispose($hGraphics)
	_GDIPlus_Shutdown()
	Exit
EndFunc   ;==>_Exit

I suggest to change the "int" functions to "float" and add the "int" in addition, named like this: _GDIPlus_GraphicsDrawLineI
(...GDIp.au3 ;))

E

Attachments (0)

Change History (7)

comment:1 Changed 10 years ago by TicketCleanup

  • Version 3.3.6.1 deleted

Automatic ticket cleanup.

comment:2 follow-up: Changed 10 years ago by mvg

If! its taken in consideration. A additional (trailing) "$fFloat = False" or $fInt = True" function parameter seems more logical. (instead of racking up a whole bunch of almost duplicate function's)

comment:3 Changed 10 years ago by mvg

In case no code change change is going to be made, a note about this in the help might be a idea.

Modded example after playing around with it a bit. (partial/changed code part)

Global $hPenR = _GDIPlus_PenCreate(0xFFFFFF00, 3) ;; yello
Global $hPenG = _GDIPlus_PenCreate(0xFF00FFFF, 3) ;; cyaan

Global $nX, $nY
;~ Global $iTime = TimerInit(), $sTimeLog = '', $NL =  @CRLF
;~ $sTimeLog &= '[Loop] = "For $i = 100 To 700 Step 5.1"' & $NL
For $j = 0 To 10 Step 0.1
	_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)
	Switch 1
		Case 1
;~ 	$iTime = TimerInit()
			For $i = 100 To 700 Step 5.1
				_GDIPlus_GraphicsDrawLine($hGfxBuffer, $i + $j, 300 - 250, $i + $j, 300 - 1, $hPenR) ;; walking line, left/yello
			Next
;~ 	$sTimeLog &= '['&$j&'][I] =' & TimerDiff($iTime) & $NL
;~ 	$iTime = TimerInit()
			For $i = 100 To 700 Step 5.1
				_GDIPlus_GraphicsDrawLine_Float($hGfxBuffer, $i + $j, 300 + 1, $i + $j, 300 + 250, $hPenG) ;; walking line, right/cyaan
			Next
;~ 	$sTimeLog &= '['&$j&'][F] =' & TimerDiff($iTime) & $NL
		Case 2

			For $i = 1 To 360 Step 360/123
				$nX = Cos(($i+$j) * $DegToRad)
				$nY = Sin(($i+$j) * $DegToRad)
				_GDIPlus_GraphicsDrawLine($hGfxBuffer, 200+($nX*50), 300+($nY*50), 200 + ($nX*200), 300 + ($nY*200), $hPenR) ;; rotating line. left/yello
				_GDIPlus_GraphicsDrawLine_Float($hGfxBuffer, 600+($nX*50), 300+($nY*50), 600 + ($nX*200), 300 + ($nY*200), $hPenG) ;; rotating line. right/cyaan
			Next

	EndSwitch
	_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Next
;~ ConsoleWrite('$sTimeLog:' & $NL & $sTimeLog)
Sleep(1000 * 2)
_Exit()

comment:4 in reply to: ↑ 2 Changed 10 years ago by mvg

Replying to mvg:

If! its taken in consideration. A additional (trailing) "$fFloat = False" or $fInt = True" function parameter seems more logical. (instead of racking up a whole bunch of almost duplicate function's)

That was before I noted the "GdipDrawLineI" and "GdipDrawLine" difference of course. :P

comment:5 Changed 10 years ago by Eukalyptus

Thx for the great example - it clearly shows the difference.
If smoothingmode is set to 0 (default) then the float version produces exact pixel lines too, but the values are rounded instead of truncated
3.7 = 3 int
3.7 = 4 float

I don´t think it´s a good idea to add a "$fFloat = False" or $fInt = True" flag, because the GDI+ functions should be as fast as possible.
(
and I don´t want to have ONE function (somewhere in the future) for all these gdiplus-functions:
GdipDrawCurve
GdipDrawCurveI
GdipDrawCurve2
GdipDrawCurve2I
GdipDrawCurve3
GdipDrawCurve3I
;)
)

E

comment:6 Changed 10 years ago by mvg

For additional GDI+ functions there is the GDIP.au3 UDF.

Think that is makes sense to have the GDI+ functions in AutoIt follow the GDI+ class names.

Issue in that case.

  • Only rename the current("int") one's. (float versions could go into the GDIP.au3 UDF) (real code breaker I imagine)
  • Rename the "int", but also add the "float" version. (less of a code breaker?)

Alternatively: No change to AutoIt, But relative float versions go into GDIP.au3 with a trailing 'F' to the function names. (least desirable solution I think.)

That about it from me.

comment:7 Changed 7 years ago by Jon

  • Resolution set to Rejected
  • Status changed from new to closed

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as closed The owner will remain Gary.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.