cairo.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #! /usr/bin/env lua
  2. --
  3. -- Sample cairo application, based on http://cairographics.org/samples/
  4. --
  5. -- Renders all samples into separate PNG images
  6. --
  7. local math = require 'math'
  8. local lgi = require 'lgi'
  9. local cairo = lgi.cairo
  10. local dir = arg[0]:sub(1, arg[0]:find('[^%/\\]+$') - 1):gsub('[/\\]$', '')
  11. local imagename = dir .. '/gtk-demo/apple-red.png'
  12. local samples = {}
  13. function samples.arc(cr)
  14. local xc, yc = 128, 128
  15. local radius = 100
  16. local angle1, angle2 = math.rad(45), math.rad(180)
  17. cr.line_width = 10
  18. cr:arc(xc, yc, radius, angle1, angle2)
  19. cr:stroke()
  20. -- draw helping lines
  21. cr:set_source_rgba(1, 0.2, 0.2, 0.6)
  22. cr.line_width = 6
  23. cr:arc(xc, yc, 10, 0, math.rad(360))
  24. cr:fill()
  25. cr:arc(xc, yc, radius, angle1, angle1)
  26. cr:line_to(xc, yc)
  27. cr:arc(xc, yc, radius, angle2, angle2)
  28. cr:line_to(xc, yc)
  29. cr:stroke()
  30. end
  31. function samples.arc_negative(cr)
  32. local xc, yc = 128, 128
  33. local radius = 100
  34. local angle1, angle2 = math.rad(45), math.rad(180)
  35. cr.line_width = 10
  36. cr:arc_negative(xc, yc, radius, angle1, angle2)
  37. cr:stroke()
  38. -- draw helping lines
  39. cr:set_source_rgba(1, 0.2, 0.2, 0.6)
  40. cr.line_width = 6
  41. cr:arc(xc, yc, 10, 0, math.rad(360))
  42. cr:fill()
  43. cr:arc(xc, yc, radius, angle1, angle1)
  44. cr:line_to(xc, yc)
  45. cr:arc(xc, yc, radius, angle2, angle2)
  46. cr:line_to(xc, yc)
  47. cr:stroke()
  48. end
  49. function samples.clip(cr)
  50. cr:arc(128, 128, 76.8, 0, math.rad(360))
  51. cr:clip()
  52. -- current path is not consumed by cairo.Context.clip()
  53. cr:new_path()
  54. cr:rectangle(0, 0, 256, 256)
  55. cr:fill()
  56. cr:set_source_rgb(0, 1, 0)
  57. cr:move_to(0, 0)
  58. cr:line_to(256, 256)
  59. cr:move_to(256, 0)
  60. cr:line_to(0, 256)
  61. cr.line_width = 10
  62. cr:stroke()
  63. end
  64. function samples.clip_image(cr)
  65. cr:arc(128, 128, 76.8, 0, math.rad(360))
  66. cr:clip()
  67. cr:new_path()
  68. local image = cairo.ImageSurface.create_from_png(imagename)
  69. cr:scale(256 / image.width, 256 / image.height)
  70. cr:set_source_surface(image, 0, 0)
  71. cr:paint()
  72. end
  73. function samples.dash(cr)
  74. cr:set_dash({ 50, 10, 10, 10 }, -50)
  75. cr.line_width = 10
  76. cr:move_to(128, 25.6)
  77. cr:line_to(230.4, 230.4)
  78. cr:rel_line_to(-102.4, 0)
  79. cr:curve_to(51.2, 230.4, 51.2, 128, 128, 128)
  80. cr:stroke()
  81. end
  82. function samples.curve_to(cr)
  83. local x, y = 25.6, 128
  84. local x1, y1 = 102.4, 230.4
  85. local x2, y2 = 153.6, 25.6
  86. local x3, y3 = 230.4, 128
  87. cr:move_to(x, y)
  88. cr:curve_to(x1, y1, x2, y2, x3, y3)
  89. cr.line_width = 10
  90. cr:stroke()
  91. cr:set_source_rgba(1, 0.2, 0.2, 0.6)
  92. cr.line_width = 6
  93. cr:move_to(x, y)
  94. cr:line_to(x1, y1)
  95. cr:move_to(x2, y2)
  96. cr:line_to(x3, y3)
  97. cr:stroke()
  98. end
  99. function samples.fill_and_stroke(cr)
  100. cr:move_to(128, 25.6)
  101. cr:line_to(230.4, 230.4)
  102. cr:rel_line_to(-102.4, 0)
  103. cr:curve_to(51.2, 230.4, 51.2, 128, 128, 128)
  104. cr:close_path()
  105. cr:move_to(64, 25.6)
  106. cr:rel_line_to(51.2, 51.2)
  107. cr:rel_line_to(-51.2, 51.2)
  108. cr:rel_line_to(-51.2, -51.2)
  109. cr:close_path()
  110. cr.line_width = 10
  111. cr:set_source_rgb(0, 0, 1)
  112. cr:fill_preserve()
  113. cr:set_source_rgb(0, 0, 0)
  114. cr:stroke()
  115. end
  116. function samples.fill_style(cr)
  117. cr.line_width = 6
  118. cr:rectangle(12, 12, 232, 70)
  119. cr:new_sub_path()
  120. cr:arc(64, 64, 40, 0, math.rad(360))
  121. cr:new_sub_path()
  122. cr:arc_negative(192, 64, 40, 0, math.rad(-360))
  123. cr.fill_rule = 'EVEN_ODD'
  124. cr:set_source_rgb(0, 0.7, 0)
  125. cr:fill_preserve()
  126. cr:set_source_rgb(0, 0, 0)
  127. cr:stroke()
  128. cr:translate(0, 128)
  129. cr:rectangle(12, 12, 232, 70)
  130. cr:new_sub_path()
  131. cr:arc(64, 64, 40, 0, math.rad(360))
  132. cr:new_sub_path()
  133. cr:arc_negative(192, 64, 40, 0, math.rad(-360))
  134. cr.fill_rule = 'WINDING'
  135. cr:set_source_rgb(0, 0, 0.9)
  136. cr:fill_preserve()
  137. cr:set_source_rgb(0, 0, 0)
  138. cr:stroke()
  139. end
  140. function samples.gradient(cr)
  141. local pat = cairo.Pattern.create_linear(0, 0, 0, 256)
  142. pat:add_color_stop_rgba(1, 0, 0, 0, 1)
  143. pat:add_color_stop_rgba(0, 1, 1, 1, 1)
  144. cr:rectangle(0, 0, 256, 256)
  145. cr.source = pat
  146. cr:fill()
  147. pat = cairo.Pattern.create_radial(115.2, 102.4, 25.6,
  148. 102.4, 102.4, 128)
  149. pat:add_color_stop_rgba(0, 1, 1, 1, 1);
  150. pat:add_color_stop_rgba(1, 0, 0, 0, 0);
  151. cr.source = pat
  152. cr:arc(128, 128, 76.8, 0, math.rad(360))
  153. cr:fill()
  154. end
  155. function samples.image(cr)
  156. local image = cairo.ImageSurface.create_from_png(imagename)
  157. cr:translate(128, 128)
  158. cr:rotate(math.rad(45))
  159. cr:scale(256 / image.width, 256 / image.height)
  160. cr:translate(-image.width / 2, -image.height / 2)
  161. cr:set_source_surface(image, 0, 0)
  162. cr:paint()
  163. end
  164. function samples.imagepattern(cr)
  165. local image = cairo.ImageSurface.create_from_png(imagename)
  166. local pattern = cairo.Pattern.create_for_surface(image)
  167. pattern.extend = 'REPEAT'
  168. cr:translate(128, 128)
  169. cr:rotate(math.rad(45))
  170. cr:scale(1 / math.sqrt(2), 1 / math.sqrt(2))
  171. cr:translate(-128, -128)
  172. pattern.matrix = cairo.Matrix.create_scale(image.width / 256 * 5,
  173. image.height / 256 * 5)
  174. cr.source = pattern
  175. cr:rectangle(0, 0, 256, 256)
  176. cr:fill()
  177. end
  178. function samples.multisegment_caps(cr)
  179. cr:move_to(50, 75)
  180. cr:line_to(200, 75)
  181. cr:move_to(50, 125)
  182. cr:line_to(200, 125)
  183. cr:move_to(50, 175)
  184. cr:line_to(200, 175)
  185. cr.line_width = 30
  186. cr.line_cap = 'ROUND'
  187. cr:stroke()
  188. end
  189. function samples.rounded_rectangle(cr)
  190. local x, y, width, height = 25.6, 25.6, 204.8, 204.8
  191. local aspect = 1
  192. local corner_radius = height / 10
  193. local radius = corner_radius / aspect
  194. cr:new_sub_path()
  195. cr:arc(x + width - radius, y + radius, radius,
  196. math.rad(-90), math.rad(0))
  197. cr:arc(x + width - radius, y + height - radius, radius,
  198. math.rad(0), math.rad(90))
  199. cr:arc(x + radius, y + height - radius, radius,
  200. math.rad(90), math.rad(180))
  201. cr:arc(x + radius, y + radius, radius,
  202. math.rad(180), math.rad(270))
  203. cr:close_path()
  204. cr:set_source_rgb(0.5, 0.5, 1)
  205. cr:fill_preserve()
  206. cr:set_source_rgba(0.5, 0, 0, 0.5)
  207. cr.line_width = 10
  208. cr:stroke()
  209. end
  210. -- Iterate through all samples and create .png files from them
  211. for name, sample in pairs(samples) do
  212. local surface = cairo.ImageSurface.create('ARGB32', 256, 256)
  213. local cr = cairo.Context.create(surface)
  214. sample(cr)
  215. surface:write_to_png('cairodemo-' .. name .. '.png')
  216. end