At the time of this writing, the following task is listed on the page "Tasks not implemented in AutoHotkey":
http://rosettacode.org/wiki/Mandelbrot_set
I have tried to use GDI+ library and came up with some messy code and slow solution (but you can watch the picture growing

):
Code:
;~ File := "MandelBrot.gdip.bmp"
Width := Height := 400
#Include gdip.ahk
If !pToken := Gdip_Startup() {
MsgBox, 48, GDI+ Error, GDI+ failed to start.
ExitApp
}
; +E0x80000 : must be used for UpdateLayeredWindow to work
Gui, -Caption +E0x80000 +LastFound
Gui, Show,, MandelBrot
hwnd1 := WinExist()
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
xx := (A_ScreenWidth - Width) // 2
yy := (A_ScreenHeight - Height) // 2
Gosub, CreateColours
Gosub, CreatePixels
;~ pBitmap := Gdip_BitmapFromScreen(xx "|" yy "|" Width "|" Height)
;~ Gdip_SaveBitmapToFile(pBitmap, File)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Return
GuiClose:
GuiEscape:
Gdip_Shutdown(pToken)
ExitApp
;---------------------------------------------------------------------------
CreatePixels: ; create pixels for [-2 < x < 1] [-1.5 < y < 1.5]
;---------------------------------------------------------------------------
Max_Iteration := 64
Loop, % Height // 2 + 1 {
yi := A_Index - 1
y0 := -1.5 + yi / Height * 3 ; range -1.5 .. +1.5
Loop, %Width% {
xi := A_Index - 1
x0 := -2 + xi / Width * 3 ; range -2 .. +1
Gosub, Mandelbrot
pPen := Gdip_CreatePen(Colour, 1)
Gdip_DrawLine(G, pPen, xi, yi, xi+1, yi)
Gdip_DrawLine(G, pPen, xi, Height-yi, xi+1, Height-yi)
Gdip_DeletePen(pPen)
UpdateLayeredWindow(hwnd1, hdc, xx, yy, Width, Height)
}
}
Return
;---------------------------------------------------------------------------
Mandelbrot: ; calculate a colour for each pixel
;---------------------------------------------------------------------------
x := y := Iteration := 0
While, (x*x + y*y <= 4) And (Iteration < Max_Iteration) {
xtemp := x*x - y*y + x0
y := 2*x*y + y0
x := xtemp
Iteration++
}
Colour := Iteration = Max_Iteration ? 0xFF000000 : Colour_%Iteration%
Return
;---------------------------------------------------------------------------
CreateColours: ; borrowed from PureBasic example
;---------------------------------------------------------------------------
Loop, 64 {
i4 := (i3 := (i2 := (i1 := A_Index - 1) + 64) + 64) + 64
Colour_%i1% := RGB(4*i1 + 128, 4*i1, 0)
Colour_%i2% := RGB(64, 255, 4*i1)
Colour_%i3% := RGB(64, 255 - 4*i1, 255)
Colour_%i4% := RGB(64, 0, 255 - 4*i1)
}
Return
;---------------------------------------------------------------------------
RGB(r, g, b) { ; return 32bit color value
;---------------------------------------------------------------------------
SetFormat, Integer, Hex
r := SubStr("0" SubStr(r + 0, 3), -1)
g := SubStr("0" SubStr(g + 0, 3), -1)
b := SubStr("0" SubStr(b + 0, 3), -1)
SetFormat, Integer, D
Return, "0xFF" r g b
}
Then I went on to create a Bitmap in memory, save that and display it, much faster, 4 times the size (800*800 pixel rather than 400*400), but you can't see the picture grow, so I added a progress bar to look at instead:
Code:
File := "MandelBrot.bmp"
Width := Height := 800
Progress, b2 w400 fs9, %A_Space%
Gosub, CreateColours
Gosub, CreateBitmap
Progress, Off
Gui, -Caption
Gui, Margin, 0, 0
Gui, Add, Picture,, %File%
Gui, Show,, MandelBrot
Return
GuiClose:
GuiEscape:
ExitApp
;---------------------------------------------------------------------------
CreateBitmap: ; create and save a 32bit bitmap file
;---------------------------------------------------------------------------
; define header details
HeaderBMP := 14
HeaderDIB := 40
DataOffset := HeaderBMP + HeaderDIB
ImageSize := Width * Height * 4 ; 32bit
FileSize := DataOffset + ImageSize
Resolution := 3780 ; from mspaint
; create bitmap header
VarSetCapacity(IMAGE, FileSize, 0)
NumPut(Asc("B") , IMAGE, 0x00, "Char")
NumPut(Asc("M") , IMAGE, 0x01, "Char")
NumPut(FileSize , IMAGE, 0x02, "UInt")
NumPut(DataOffset , IMAGE, 0x0A, "UInt")
NumPut(HeaderDIB , IMAGE, 0x0E, "UInt")
NumPut(Width , IMAGE, 0x12, "UInt")
NumPut(Height , IMAGE, 0x16, "UInt")
NumPut(1 , IMAGE, 0x1A, "Short") ; Planes
NumPut(32 , IMAGE, 0x1C, "Short") ; Bits per Pixel
NumPut(ImageSize , IMAGE, 0x22, "UInt")
NumPut(Resolution , IMAGE, 0x26, "UInt")
NumPut(Resolution , IMAGE, 0x2A, "UInt")
; fill in Data
Gosub, CreatePixels
; save Bitmap to file
FileDelete, %File%
Handle := DllCall("CreateFile", "Str", File, "UInt", 0x40000000
, "UInt", 0, "UInt", 0, "UInt", 2, "UInt", 0, "UInt", 0)
DllCall("WriteFile", "UInt", Handle, "UInt", &IMAGE, "UInt"
, FileSize, "UInt *", Bytes, "UInt", 0)
DllCall("CloseHandle", "UInt", Handle)
Return
;---------------------------------------------------------------------------
CreatePixels: ; create pixels for [-2 < x < 1] [-1.5 < y < 1.5]
;---------------------------------------------------------------------------
Max_Iteration := 64
Loop, % Height // 2 + 1 {
yi := A_Index - 1
y0 := -1.5 + yi / Height * 3 ; range -1.5 .. +1.5
Progress, % 200*yi // Height, % "Current line: " 2*yi " / " Height
Loop, %Width% {
xi := A_Index - 1
x0 := -2 + xi / Width * 3 ; range -2 .. +1
Gosub, Mandelbrot
p1 := DataOffset + 4 * (Width * yi + xi)
NumPut(Colour, IMAGE, p1, "UInt")
p2 := DataOffset + 4 * (Width * (Height-yi) + xi)
NumPut(Colour, IMAGE, p2, "UInt")
}
}
Return
;---------------------------------------------------------------------------
Mandelbrot: ; calculate a colour for each pixel
;---------------------------------------------------------------------------
x := y := Iteration := 0
While, (x*x + y*y <= 4) And (Iteration < Max_Iteration) {
xtemp := x*x - y*y + x0
y := 2*x*y + y0
x := xtemp
Iteration++
}
Colour := Iteration = Max_Iteration ? 0x00000000 : Colour_%Iteration%
Return
;---------------------------------------------------------------------------
CreateColours: ; borrowed from PureBasic example
;---------------------------------------------------------------------------
Loop, 64 {
i4 := (i3 := (i2 := (i1 := A_Index - 1) + 64) + 64) + 64
Colour_%i1% := RGB(4*i1 + 128, 4*i1, 0)
Colour_%i2% := RGB(64, 255, 4*i1)
Colour_%i3% := RGB(64, 255 - 4*i1, 255)
Colour_%i4% := RGB(64, 0, 255 - 4*i1)
}
Return
;---------------------------------------------------------------------------
RGB(r, g, b) { ; return 32bit color value
;---------------------------------------------------------------------------
SetFormat, Integer, Hex
r := SubStr("0" SubStr(r + 0, 3), -1)
g := SubStr("0" SubStr(g + 0, 3), -1)
b := SubStr("0" SubStr(b + 0, 3), -1)
SetFormat, Integer, D
Return, "0x00" r g b
}
PS: I will tomorrow post a shorter version, that writes the BMP-Header in one go, it was just easier to construct this way. I have to rest now, there was a lot of waiting (for pictures) involved during development here.