pixmap.monkey2 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. Namespace std.graphics
  2. #rem monkeydoc Pixmaps allow you to store and manipulate rectangular blocks of pixel data.
  3. A pixmap contains a block of memory used to store a rectangular array of pixels.
  4. #end
  5. Class Pixmap
  6. #rem monkeydoc @hidden
  7. #end
  8. Field OnDiscarded:Void()
  9. #rem monkeydoc Creates a new pixmap.
  10. @param width The width of the pixmap in pixels.
  11. @param height The height of the pixmap in pixels.
  12. @param format The pixmap format.
  13. @param data A pointer to the pixmap data.
  14. @param pitch The pitch of the data.
  15. #end
  16. Method New( width:Int,height:Int,format:PixelFormat=PixelFormat.RGBA32 )
  17. Local depth:=PixelFormatDepth( format )
  18. Local pitch:=width*depth
  19. Local data:=Cast<UByte Ptr>( libc.malloc( pitch*height ) )
  20. _width=width
  21. _height=height
  22. _format=format
  23. _depth=depth
  24. _data=data
  25. _pitch=pitch
  26. OnDiscarded=Lambda()
  27. libc.free( data )
  28. End
  29. End
  30. Method New( width:Int,height:Int,format:PixelFormat,data:UByte Ptr,pitch:Int )
  31. Local depth:=PixelFormatDepth( format )
  32. _width=width
  33. _height=height
  34. _format=format
  35. _depth=depth
  36. _data=data
  37. _pitch=pitch
  38. End
  39. #rem monkeydoc Releases the memory used by a pixmap.
  40. Memory is only released if the pixmap was created using New, Copy, Convert or Load.
  41. If the pixmap represents a 'window' into another pixmap (ie: it was created using Window) then memory is not released.
  42. Discarding a pixmap also sets its width, height, pitch and depth to 0.
  43. #end
  44. Method Discard()
  45. If Not _data Return
  46. _width=0
  47. _height=0
  48. _pitch=0
  49. _depth=0
  50. _data=Null
  51. OnDiscarded()
  52. End
  53. #rem monkeydoc The pixmap width.
  54. #end
  55. Property Width:Int()
  56. Return _width
  57. End
  58. #rem monkeydoc The pixmap height.
  59. #end
  60. Property Height:Int()
  61. Return _height
  62. End
  63. #rem monkeydoc The pixmap format.
  64. #end
  65. Property Format:PixelFormat()
  66. Return _format
  67. End
  68. #rem monkeydoc The pixmap depth.
  69. The number of bytes per pixel.
  70. #end
  71. Property Depth:Int()
  72. Return _depth
  73. End
  74. #rem monkeydoc The raw pixmap data.
  75. #end
  76. Property Data:UByte Ptr()
  77. Return _data
  78. End
  79. #rem monkeydoc The pixmap pitch.
  80. This is the number of bytes between one row of pixels in the pixmap and the next.
  81. #end
  82. Property Pitch:Int()
  83. Return _pitch
  84. End
  85. #rem monkeydoc Gets a pointer to a pixel in the pixmap.
  86. @param x the x coordinate of the pixel.
  87. @param y the y coordinate of the pixel.
  88. @return the address of the pixel at `x`, `y`.
  89. #end
  90. Method PixelPtr:UByte Ptr( x:Int,y:Int )
  91. Return _data + y*_pitch + x*_depth
  92. End
  93. #rem monkeydoc Sets a pixel to a color.
  94. Sets the pixel at `x`, `y` to `pixel`.
  95. In debug builds, a runtime error will occur if the pixel coordinates lie outside of the pixmap area.
  96. @param x The x coordinate of the pixel.
  97. @param y The y coordinate of the pixel.
  98. @param color The color to set the pixel to.
  99. #end
  100. Method SetPixel( x:Int,y:Int,color:Color )
  101. DebugAssert( x>=0 And y>=0 And x<_width And y<_height )
  102. Local p:=PixelPtr( x,y )
  103. Select _format
  104. Case Format.A8
  105. p[0]=color.a * 255
  106. Case Format.I8
  107. p[0]=color.r * 255
  108. Case Format.IA16
  109. p[0]=color.r * 255
  110. p[1]=color.a * 255
  111. Case Format.RGB24
  112. p[0]=color.r * 255
  113. p[1]=color.g * 255
  114. p[2]=color.b * 255
  115. Case Format.RGBA32
  116. p[0]=color.r * 255
  117. p[1]=color.g * 255
  118. p[2]=color.b * 255
  119. p[3]=color.a * 255
  120. Default
  121. Assert( False )
  122. End
  123. End
  124. #rem monkeydoc Gets the color of a pixel.
  125. Gets the pixel at `x`, `y` and returns it in ARGB format.
  126. In debug builds, a runtime error will occur if the pixel coordinates lie outside of the pixmap area.
  127. @param x The x coordinate of the pixel.
  128. @param y The y coordinate of the pixel.
  129. @return The color of the pixel at `x`, `y`.
  130. #end
  131. Method GetPixel:Color( x:Int,y:Int )
  132. DebugAssert( x>=0 And y>=0 And x<_width And y<_height )
  133. Local p:=PixelPtr( x,y )
  134. Select _format
  135. Case Format.A8
  136. Return New Color( 0,0,0,p[0]/255.0 )
  137. Case Format.I8
  138. Local i:=p[0]/255.0
  139. Return New Color( i,i,i,1 )
  140. Case Format.IA16
  141. Local i:=p[0]/255.0
  142. Return New Color( i,i,i,p[1]/255.0 )
  143. Case Format.RGB24
  144. Return New Color( p[0]/255.0,p[1]/255.0,p[2]/255.0,1 )
  145. Case Format.RGBA32
  146. Return New Color( p[0]/255.0,p[1]/255.0,p[2]/255.0,p[3]/255.0 )
  147. Default
  148. Assert( False )
  149. End
  150. Return Color.None
  151. End
  152. #rem monkeydoc Sets a pixel to an ARGB color.
  153. Sets the pixel at `x`, `y` to `pixel`.
  154. In debug builds, a runtime error will occur if the pixel coordinates lie outside of the pixmap area.
  155. @param x The x coordinate of the pixel.
  156. @param y The y coordinate of the pixel.
  157. @param color The pixel to set in ARGB format.
  158. #end
  159. Method SetPixelARGB( x:Int,y:Int,color:UInt )
  160. DebugAssert( x>=0 And y>=0 And x<_width And y<_height )
  161. Local p:=PixelPtr( x,y )
  162. Select _format
  163. Case Format.A8
  164. p[0]=color Shr 24
  165. Case Format.I8
  166. p[0]=color Shr 16
  167. Case Format.IA16
  168. p[0]=color Shr 24
  169. p[1]=color Shr 16
  170. Case Format.RGB24
  171. p[0]=color Shr 16
  172. p[1]=color Shr 8
  173. p[2]=color
  174. Case Format.RGBA32
  175. p[0]=color Shr 16
  176. p[1]=color Shr 8
  177. p[2]=color
  178. p[3]=color Shr 24
  179. Default
  180. Assert( False )
  181. End
  182. End
  183. #rem monkeydoc Gets the ARGB color of a pixel.
  184. Get the pixel at `x`, `y` and returns it in ARGB format.
  185. @param x the x coordinate of the pixel.
  186. @param y the y coordinate of the pixel.
  187. @return the pixel at `x`, `y` in ARGB format.
  188. #end
  189. Method GetPixelARGB:UInt( x:Int,y:Int )
  190. DebugAssert( x>=0 And y>=0 And x<_width And y<_height )
  191. Local p:=PixelPtr( x,y )
  192. Select _format
  193. Case Format.A8
  194. Return p[0] Shl 24
  195. Case Format.I8
  196. Local i:=p[0]
  197. Return UByte($ff) Shl 24 | i Shl 16 | i Shl 8 | i
  198. Case Format.IA16
  199. Local i:=p[1]
  200. Return p[0] Shl 24 | i Shl 16 | i Shl 8 | i
  201. Case Format.RGB24
  202. Return UByte($ff) Shl 24 | p[0] Shl 16 | p[1] Shl 8 | p[2]
  203. Case Format.RGBA32
  204. Return p[3] Shl 24 | p[0] Shl 16 | p[1] Shl 8 | p[2]
  205. Default
  206. Assert( False )
  207. End
  208. Return 0
  209. End
  210. 'Optimize!
  211. '
  212. #rem monkeydoc Clears the pixmap to a given color.
  213. @param color The color to clear the pixmap to.
  214. #end
  215. Method Clear( color:Color )
  216. For Local y:=0 Until _height
  217. For Local x:=0 Until _width
  218. SetPixel( x,y,color )
  219. Next
  220. Next
  221. End
  222. #rem monkeydoc Clears the pixmap to an ARGB color.
  223. @param color ARGB color to clear the pixmap to.
  224. #end
  225. Method ClearARGB( color:UInt )
  226. For Local y:=0 Until _height
  227. For Local x:=0 Until _width
  228. SetPixelARGB( x,y,color )
  229. Next
  230. next
  231. End
  232. #rem monkeydoc Paste a pixmap to the pixmap.
  233. In debug builds, a runtime error will occur if the operation would write to pixels outside of the pixmap.
  234. Note: No alpha blending is performed - pixels in the pixmap are simply overwritten.
  235. @param pixmap The pixmap to paste.
  236. @param x The x coordinate.
  237. @param y The y coordinate.
  238. #end
  239. Method Paste( pixmap:Pixmap,x:Int,y:Int )
  240. DebugAssert( x>=0 And x+pixmap._width<=_width And y>=0 And y+pixmap._height<=_height )
  241. For Local ty:=0 Until pixmap._height
  242. For Local tx:=0 Until pixmap._width
  243. SetPixel( x+tx,y+ty,pixmap.GetPixel( tx,ty ) )
  244. Next
  245. Next
  246. End
  247. 'Optimize!
  248. '
  249. #rem monkeydoc Creates a copy of the pixmap.
  250. @return A new pixmap.
  251. #end
  252. Method Copy:Pixmap()
  253. Return Convert( _format )
  254. End
  255. 'Optimize!
  256. '
  257. #rem monkeydoc Converts the pixmap to a different format.
  258. @param format The pixel format to convert the pixmap to.
  259. @return A new pixmap.
  260. #end
  261. Method Convert:Pixmap( format:PixelFormat )
  262. Local t:=New Pixmap( _width,_height,format )
  263. For Local y:=0 Until _height
  264. For Local x:=0 Until _width
  265. t.SetPixel( x,y,GetPixel( x,y ) )
  266. Next
  267. Next
  268. Return t
  269. End
  270. 'Optimize!
  271. '
  272. #rem monkeydoc Premultiply pixmap r,g,b components by alpha.
  273. #end
  274. Method PremultiplyAlpha()
  275. Select _format
  276. Case PixelFormat.IA16,PixelFormat.RGBA32
  277. For Local y:=0 Until _height
  278. For Local x:=0 Until _width
  279. Local color:=GetPixel( x,y )
  280. color.r*=color.a
  281. color.g*=color.a
  282. color.b*=color.a
  283. SetPixel( x,y,color )
  284. Next
  285. Next
  286. End
  287. End
  288. #rem monkeydoc Returns a rectangular window into the pixmap.
  289. In debug builds, a runtime error will occur if the rectangle lies outside of the pixmap area.
  290. @param x The x coordinate of the top left of the rectangle.
  291. @param y The y coordinate of the top left of the rectangle.
  292. @param width The width of the rectangle.
  293. @param height The height of the rectangle.
  294. #end
  295. Method Window:Pixmap( x:Int,y:Int,width:Int,height:Int )
  296. DebugAssert( x>=0 And y>=0 And width>=0 And height>=0 And x+width<=_width And y+height<=_height )
  297. Return New Pixmap( width,height,_format,PixelPtr( x,y ),_pitch )
  298. End
  299. #rem monkeydoc Saves the pixmap to a file.
  300. The only save format currently suppoted is PNG.
  301. #End
  302. Method Save:Bool( path:String )
  303. Return SavePixmap( Self,path )
  304. End
  305. #rem monkeydoc Loads a pixmap from a file.
  306. @param path The file path.
  307. @param format The format to load the pixmap in.
  308. @return Null if the file could not be opened, or contained invalid image data.
  309. #end
  310. Function Load:Pixmap( path:String,format:PixelFormat=PixelFormat.Unknown )
  311. Return LoadPixmap( path,format )
  312. End
  313. Private
  314. Field _width:Int
  315. Field _height:Int
  316. Field _format:PixelFormat
  317. Field _depth:Int
  318. Field _data:UByte Ptr
  319. Field _pitch:Int
  320. End