Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CairoWidget.hpp 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * DISTRHO Plugin Toolkit (DPT)
  3. * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DGL_CAIRO_WIDGET_HPP_INCLUDED
  17. #define DGL_CAIRO_WIDGET_HPP_INCLUDED
  18. #include "Widget.hpp"
  19. #include <cairo.h>
  20. START_NAMESPACE_DGL
  21. // -----------------------------------------------------------------------
  22. class CairoWidget : public Widget
  23. {
  24. public:
  25. CairoWidget(Window& parent)
  26. : Widget(parent),
  27. fContext(nullptr),
  28. fSurface(nullptr),
  29. fTextureId(0)
  30. {
  31. }
  32. protected:
  33. virtual void cairoDisplay(cairo_t* const context) = 0;
  34. private:
  35. void onReshape(int width, int height) override
  36. {
  37. // handle resize
  38. setSize(width, height);
  39. Widget::onReshape(width, height);
  40. // free previous if needed
  41. onClose();
  42. // create new
  43. fSurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
  44. fContext = cairo_create(fSurface);
  45. glGenTextures(1, &fTextureId);
  46. }
  47. void onClose() override
  48. {
  49. if (fContext != nullptr)
  50. {
  51. cairo_destroy(fContext);
  52. fContext = nullptr;
  53. }
  54. if (fSurface != nullptr)
  55. {
  56. cairo_surface_destroy(fSurface);
  57. fSurface = nullptr;
  58. }
  59. if (fTextureId != 0)
  60. {
  61. glDeleteTextures(1, &fTextureId);
  62. fTextureId = 0;
  63. }
  64. }
  65. void onDisplay() override
  66. {
  67. // wait for first resize
  68. if (fSurface == nullptr || fContext == nullptr)
  69. {
  70. glClear(GL_COLOR_BUFFER_BIT);
  71. return;
  72. }
  73. const int width = getWidth();
  74. const int height = getHeight();
  75. // draw cairo stuff
  76. cairoDisplay(fContext);
  77. // get cairo surface data (RGB24)
  78. unsigned char* const surfaceData = cairo_image_surface_get_data(fSurface);
  79. // enable GL texture
  80. glEnable(GL_TEXTURE_RECTANGLE_ARB);
  81. // set texture params
  82. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  83. glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  84. glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  85. // bind texture to surface data
  86. glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fTextureId);
  87. glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, surfaceData);
  88. // draw the texture
  89. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  90. glBegin(GL_QUADS);
  91. glTexCoord2i(0, height);
  92. glVertex2i(0, height);
  93. glTexCoord2i(width, height);
  94. glVertex2i(width, height);
  95. glTexCoord2i(width, 0);
  96. glVertex2i(width, 0);
  97. glTexCoord2i(0, 0);
  98. glVertex2i(0, 0);
  99. glEnd();
  100. // cleanup
  101. glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
  102. glDisable(GL_TEXTURE_RECTANGLE_ARB);
  103. }
  104. private:
  105. cairo_t* fContext;
  106. cairo_surface_t* fSurface;
  107. GLuint fTextureId;
  108. };
  109. // -----------------------------------------------------------------------
  110. END_NAMESPACE_DGL
  111. #endif // DGL_CAIRO_WIDGET_HPP_INCLUDED