Guest User

Untitled

a guest
Aug 21st, 2016
101
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* -*- C++ -*- include/005-drawing ------------------------------------------ */
  2. #define __included_drawing__
  3.  
  4. #ifdef ENABLE_DRAWING
  5. #include <cairo/cairo-xcb.h>
  6. #include <cairo/cairo.h>
  7. #include <xcb/xcb.h>
  8. #include <xcb/xcb_icccm.h>
  9. #include <xcb/xcb_image.h>
  10.  
  11. #ifdef debug
  12. #undef debug
  13. #endif
  14.  
  15. #define debug(...) __VA_ARGS__
  16.  
  17. namespace {
  18. namespace draw {
  19. struct rgba {
  20. double r;
  21. double g;
  22. double b;
  23. double a;
  24. };
  25.  
  26. struct window {
  27. size_t width = 0;
  28. size_t height = 0;
  29. size_t window_width = 0;
  30. size_t window_height = 0;
  31.  
  32. cairo_surface_t* surface = nullptr;
  33. cairo_surface_t* image = nullptr;
  34. cairo_t* cairo = nullptr;
  35. cairo_t* display = nullptr;
  36. };
  37.  
  38. void rectangle(window& w, point p0, point p1, rgba color) {
  39. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  40. cairo_new_path(w.cairo);
  41. cairo_rectangle(w.cairo, p0.x, p0.y, p1.x - p0.x, p1.y - p0.y);
  42. cairo_stroke(w.cairo);
  43. }
  44.  
  45. void square(window& w, point p0, double size, rgba color) {
  46. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  47. cairo_new_path(w.cairo);
  48. cairo_rectangle(w.cairo, p0.x - size / 2., p0.y - size / 2., size, size);
  49. cairo_stroke(w.cairo);
  50. }
  51.  
  52. void line(window& w, point p0, point p1, rgba color) {
  53. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  54. cairo_new_path(w.cairo);
  55. cairo_move_to(w.cairo, p0.x, p0.y);
  56. cairo_line_to(w.cairo, p1.x, p1.y);
  57. cairo_stroke(w.cairo);
  58. }
  59.  
  60. void line(window& w, std::vector<point> const& points, rgba color) {
  61. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  62. cairo_new_path(w.cairo);
  63. cairo_move_to(w.cairo, points[0].x, points[0].y);
  64. for (auto& point : points)
  65. cairo_line_to(w.cairo, point.x, point.y);
  66. cairo_stroke(w.cairo);
  67. }
  68.  
  69. void arrow(window& w, point p0, point p1, rgba color) {
  70. line(w, p0, p1, color);
  71. if (p0 == p1)
  72. return;
  73.  
  74. auto dp = normalized(p1 - p0);
  75. line(w, p1 - dp * 50. + point{static_cast<scalar>(-dp.y), static_cast<scalar>(dp.x)} * 25, p1, color);
  76. line(w, p1 - dp * 50. - point{static_cast<scalar>(-dp.x), static_cast<scalar>(dp.x)} * 25, p1, color);
  77. }
  78.  
  79. void circle(window& w, point c, double radius, rgba color) {
  80. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  81. cairo_new_path(w.cairo);
  82. cairo_arc(w.cairo, c.x, c.y, radius, 0.0, M_PI * 2.);
  83. cairo_stroke(w.cairo);
  84. }
  85.  
  86. template <typename... Ts> inline void join(std::ostream& str, char const* sep, Ts&&... as) {
  87. auto n = sizeof...(as);
  88. (int[]){(str << std::forward<Ts>(as) << (--n == 0 ? "" : sep), 0)...};
  89. }
  90. template <typename... Ts> inline std::string join(char const* sep, Ts&&... as) {
  91. auto str = std::stringstream{};
  92. join(str, sep, std::forward<Ts>(as)...);
  93. return str.str();
  94. }
  95.  
  96. template <typename... Ts> void text(window& w, point p, rgba color, Ts&&... as) {
  97. auto text = join(" ", forward<Ts>(as)...);
  98. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  99. cairo_move_to(w.cairo, p.x, p.y);
  100. cairo_show_text(w.cairo, text.c_str());
  101. }
  102.  
  103. auto xcb = xcb_connect(nullptr, nullptr);
  104.  
  105. window init(size_t width, size_t height, size_t window_width = 1280, size_t window_height = 720, std::string const& title = "DEBUG") {
  106. auto w = window{};
  107. w.width = width;
  108. w.height = height;
  109. w.window_width = window_width;
  110. w.window_height = window_height;
  111.  
  112. assert(xcb);
  113. assert(!xcb_connection_has_error(xcb));
  114.  
  115. auto window = xcb_generate_id(xcb);
  116. auto screen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data;
  117.  
  118. unsigned params[] = {1, XCB_EVENT_MASK_EXPOSURE};
  119. xcb_create_window(xcb, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, w.window_width, w.window_height, 5, XCB_WINDOW_CLASS_INPUT_OUTPUT,
  120. screen->root_visual, XCB_CW_BACK_PIXEL, params);
  121. xcb_icccm_set_wm_class(xcb, window, std::strlen("CodinGame"), "CodinGame");
  122. xcb_icccm_set_wm_name(xcb, window, XCB_ATOM_STRING, 8, title.size(), title.c_str());
  123. xcb_map_window(xcb, window);
  124. xcb_flush(xcb);
  125.  
  126. for (auto depth_iter = xcb_screen_allowed_depths_iterator(screen); w.surface == nullptr && depth_iter.rem; xcb_depth_next(&depth_iter)) {
  127. for (auto visual_iter = xcb_depth_visuals_iterator(depth_iter.data); w.surface == nullptr && visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
  128. if (screen->root_visual != visual_iter.data->visual_id)
  129. continue;
  130.  
  131. w.surface = cairo_xcb_surface_create(xcb, window, visual_iter.data, 1, 1);
  132. }
  133. }
  134. assert(w.surface);
  135. cairo_xcb_surface_set_size(w.surface, w.window_width, w.window_height);
  136. xcb_flush(xcb);
  137.  
  138. auto const scalex = w.window_width / static_cast<double>(w.width);
  139. auto const scaley = w.window_height / static_cast<double>(w.height);
  140. cairo_surface_set_device_scale(w.surface, scalex, scaley);
  141.  
  142. w.display = cairo_create(w.surface);
  143. assert(w.display);
  144.  
  145. w.image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w.window_width, w.window_height);
  146. cairo_surface_set_device_scale(w.image, scalex, scaley);
  147.  
  148. w.cairo = cairo_create(w.image);
  149. assert(w.cairo);
  150.  
  151. cairo_select_font_face(w.cairo, "DejaVu Sans Mono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  152.  
  153. cairo_set_line_width(w.cairo, 1. / max(scalex, scaley));
  154. cairo_set_font_size(w.cairo, w.width * 0.0078125);
  155. cairo_set_antialias(w.cairo, CAIRO_ANTIALIAS_SUBPIXEL);
  156.  
  157. cairo_set_source_rgba(w.cairo, 0.0, 0.0, 0.0, 1.0);
  158. cairo_paint(w.cairo);
  159.  
  160. xcb_flush(xcb);
  161. return w;
  162. }
  163.  
  164. void flush(window& w) {
  165. cairo_set_source_surface(w.display, w.image, 0, 0);
  166. cairo_paint(w.display);
  167.  
  168. cairo_surface_flush(w.surface);
  169. xcb_flush(xcb);
  170. }
  171.  
  172. void clear(window& w, rgba color = rgba{0.0, 0.0, 0.0, 1.0}) {
  173. cairo_set_source_rgba(w.cairo, color.r, color.g, color.b, color.a);
  174. cairo_paint(w.cairo);
  175. }
  176. }
  177. }
  178.  
  179. #else
  180. #define debug(...)
  181. #endif
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×