record-extend.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * Copyright © 2007 Red Hat, Inc.
  3. * Copyright © 2011 Intel Corporation
  4. *
  5. * Permission is hereby granted, free of charge, to any person
  6. * obtaining a copy of this software and associated documentation
  7. * files (the "Software"), to deal in the Software without
  8. * restriction, including without limitation the rights to use, copy,
  9. * modify, merge, publish, distribute, sublicense, and/or sell copies
  10. * of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  20. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. *
  25. * Authors:
  26. * Behdad Esfahbod <behdad@behdad.org>
  27. * Chris Wilson <chris@chris-wilson.co.uk>
  28. */
  29. #include "cairo-test.h"
  30. #include <math.h>
  31. #include <stdio.h>
  32. #define SIZE 90
  33. /* This is written using clip+paint to exercise a bug that once was in the
  34. * recording surface.
  35. */
  36. static cairo_surface_t *
  37. source (cairo_surface_t *surface)
  38. {
  39. cairo_t *cr;
  40. /* Create a 4-pixel image surface with my favorite four colors in each
  41. * quadrant. */
  42. cr = cairo_create (surface);
  43. cairo_surface_destroy (surface);
  44. /* upper-left = white */
  45. cairo_set_source_rgb (cr, 1, 1, 1);
  46. cairo_rectangle (cr, 0, 0, 1, 1);
  47. cairo_fill (cr);
  48. /* upper-right = red */
  49. cairo_set_source_rgb (cr, 1, 0, 0);
  50. cairo_rectangle (cr, 1, 0, 1, 1);
  51. cairo_fill (cr);
  52. /* lower-left = green */
  53. cairo_set_source_rgb (cr, 0, 1, 0);
  54. cairo_rectangle (cr, 0, 1, 1, 1);
  55. cairo_fill (cr);
  56. /* lower-right = blue */
  57. cairo_set_source_rgb (cr, 0, 0, 1);
  58. cairo_rectangle (cr, 1, 1, 1, 1);
  59. cairo_fill (cr);
  60. surface = cairo_surface_reference (cairo_get_target (cr));
  61. cairo_destroy (cr);
  62. return surface;
  63. }
  64. static cairo_surface_t *
  65. image (cairo_t *cr)
  66. {
  67. return source (cairo_image_surface_create (CAIRO_FORMAT_RGB24, 2, 2));
  68. }
  69. static cairo_surface_t *
  70. similar (cairo_t *cr)
  71. {
  72. return source (cairo_surface_create_similar (cairo_get_target (cr),
  73. CAIRO_CONTENT_COLOR, 2, 2));
  74. }
  75. static cairo_t *
  76. extend (cairo_t *cr, cairo_surface_t *(*surface)(cairo_t *), cairo_extend_t mode)
  77. {
  78. cairo_surface_t *s;
  79. cairo_set_source_rgb (cr, 0, 1, 1);
  80. cairo_paint (cr);
  81. /* Now use extend modes to cover most of the surface with those 4 colors */
  82. s = surface (cr);
  83. cairo_set_source_surface (cr, s, SIZE/2 - 1, SIZE/2 - 1);
  84. cairo_surface_destroy (s);
  85. cairo_pattern_set_extend (cairo_get_source (cr), mode);
  86. cairo_rectangle (cr, 10, 10, SIZE-20, SIZE-20);
  87. cairo_clip (cr);
  88. cairo_paint (cr);
  89. return cr;
  90. }
  91. static cairo_t *
  92. extend_none (cairo_t *cr,
  93. cairo_surface_t *(*pattern)(cairo_t *))
  94. {
  95. return extend (cr, pattern, CAIRO_EXTEND_NONE);
  96. }
  97. static cairo_t *
  98. extend_pad (cairo_t *cr,
  99. cairo_surface_t *(*pattern)(cairo_t *))
  100. {
  101. return extend (cr, pattern, CAIRO_EXTEND_PAD);
  102. }
  103. static cairo_t *
  104. extend_repeat (cairo_t *cr,
  105. cairo_surface_t *(*pattern)(cairo_t *))
  106. {
  107. return extend (cr, pattern, CAIRO_EXTEND_REPEAT);
  108. }
  109. static cairo_t *
  110. extend_reflect (cairo_t *cr,
  111. cairo_surface_t *(*pattern)(cairo_t *))
  112. {
  113. return extend (cr, pattern, CAIRO_EXTEND_REFLECT);
  114. }
  115. static cairo_t *
  116. record_create (cairo_t *target)
  117. {
  118. cairo_surface_t *surface;
  119. cairo_t *cr;
  120. surface = cairo_recording_surface_create (cairo_surface_get_content (cairo_get_target (target)), NULL);
  121. cr = cairo_create (surface);
  122. cairo_surface_destroy (surface);
  123. return cr;
  124. }
  125. static cairo_surface_t *
  126. record_get (cairo_t *target)
  127. {
  128. cairo_surface_t *surface;
  129. surface = cairo_surface_reference (cairo_get_target (target));
  130. cairo_destroy (target);
  131. return surface;
  132. }
  133. static cairo_test_status_t
  134. record_replay (cairo_t *cr,
  135. cairo_t *(*func)(cairo_t *,
  136. cairo_surface_t *(*pattern)(cairo_t *)),
  137. cairo_surface_t *(*pattern)(cairo_t *),
  138. int width, int height)
  139. {
  140. cairo_surface_t *surface;
  141. int x, y;
  142. surface = record_get (func (record_create (cr), pattern));
  143. cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  144. cairo_set_source_surface (cr, surface, 0, 0);
  145. cairo_surface_destroy (surface);
  146. cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
  147. for (y = 0; y < height; y += 2) {
  148. for (x = 0; x < width; x += 2) {
  149. cairo_rectangle (cr, x, y, 2, 2);
  150. cairo_clip (cr);
  151. cairo_paint (cr);
  152. cairo_reset_clip (cr);
  153. }
  154. }
  155. return CAIRO_TEST_SUCCESS;
  156. }
  157. static cairo_test_status_t
  158. record_extend_none (cairo_t *cr, int width, int height)
  159. {
  160. return record_replay (cr, extend_none, image, width, height);
  161. }
  162. static cairo_test_status_t
  163. record_extend_pad (cairo_t *cr, int width, int height)
  164. {
  165. return record_replay (cr, extend_pad, image, width, height);
  166. }
  167. static cairo_test_status_t
  168. record_extend_repeat (cairo_t *cr, int width, int height)
  169. {
  170. return record_replay (cr, extend_repeat, image, width, height);
  171. }
  172. static cairo_test_status_t
  173. record_extend_reflect (cairo_t *cr, int width, int height)
  174. {
  175. return record_replay (cr, extend_reflect, image, width, height);
  176. }
  177. static cairo_test_status_t
  178. record_extend_none_similar (cairo_t *cr, int width, int height)
  179. {
  180. return record_replay (cr, extend_none, similar, width, height);
  181. }
  182. static cairo_test_status_t
  183. record_extend_pad_similar (cairo_t *cr, int width, int height)
  184. {
  185. return record_replay (cr, extend_pad, similar, width, height);
  186. }
  187. static cairo_test_status_t
  188. record_extend_repeat_similar (cairo_t *cr, int width, int height)
  189. {
  190. return record_replay (cr, extend_repeat, similar, width, height);
  191. }
  192. static cairo_test_status_t
  193. record_extend_reflect_similar (cairo_t *cr, int width, int height)
  194. {
  195. return record_replay (cr, extend_reflect, similar, width, height);
  196. }
  197. CAIRO_TEST (record_extend_none,
  198. "Test CAIRO_EXTEND_NONE for recorded surface patterns",
  199. "record, extend", /* keywords */
  200. NULL, /* requirements */
  201. SIZE, SIZE,
  202. NULL, record_extend_none)
  203. CAIRO_TEST (record_extend_pad,
  204. "Test CAIRO_EXTEND_PAD for recorded surface patterns",
  205. "record, extend", /* keywords */
  206. NULL, /* requirements */
  207. SIZE, SIZE,
  208. NULL, record_extend_pad)
  209. CAIRO_TEST (record_extend_repeat,
  210. "Test CAIRO_EXTEND_REPEAT for recorded surface patterns",
  211. "record, extend", /* keywords */
  212. NULL, /* requirements */
  213. SIZE, SIZE,
  214. NULL, record_extend_repeat)
  215. CAIRO_TEST (record_extend_reflect,
  216. "Test CAIRO_EXTEND_REFLECT for recorded surface patterns",
  217. "record, extend", /* keywords */
  218. NULL, /* requirements */
  219. SIZE, SIZE,
  220. NULL, record_extend_reflect)
  221. CAIRO_TEST (record_extend_none_similar,
  222. "Test CAIRO_EXTEND_NONE for recorded surface patterns",
  223. "record, extend", /* keywords */
  224. NULL, /* requirements */
  225. SIZE, SIZE,
  226. NULL, record_extend_none_similar)
  227. CAIRO_TEST (record_extend_pad_similar,
  228. "Test CAIRO_EXTEND_PAD for recorded surface patterns",
  229. "record, extend", /* keywords */
  230. NULL, /* requirements */
  231. SIZE, SIZE,
  232. NULL, record_extend_pad_similar)
  233. CAIRO_TEST (record_extend_repeat_similar,
  234. "Test CAIRO_EXTEND_REPEAT for recorded surface patterns",
  235. "record, extend", /* keywords */
  236. NULL, /* requirements */
  237. SIZE, SIZE,
  238. NULL, record_extend_repeat_similar)
  239. CAIRO_TEST (record_extend_reflect_similar,
  240. "Test CAIRO_EXTEND_REFLECT for recorded surface patterns",
  241. "record, extend", /* keywords */
  242. NULL, /* requirements */
  243. SIZE, SIZE,
  244. NULL, record_extend_reflect_similar)