DISTRHO Plugin Framework
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.

581 lines
14KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2014 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. #include "../NanoWidget.hpp"
  17. // -----------------------------------------------------------------------
  18. #define NANOVG_GL2_IMPLEMENTATION
  19. #include "nanovg/nanovg_gl.h"
  20. #if defined(NANOVG_GL2)
  21. # define nvgCreateGL nvgCreateGL2
  22. # define nvgDeleteGL nvgDeleteGL2
  23. #elif defined(NANOVG_GL3)
  24. # define nvgCreateGL nvgCreateGL3
  25. # define nvgDeleteGL nvgDeleteGL3
  26. #elif defined(NANOVG_GLES2)
  27. # define nvgCreateGL nvgCreateGLES2
  28. # define nvgDeleteGL nvgDeleteGLES2
  29. #elif defined(NANOVG_GLES3)
  30. # define nvgCreateGL nvgCreateGLES3
  31. # define nvgDeleteGL nvgDeleteGLES3
  32. #endif
  33. START_NAMESPACE_DGL
  34. // -----------------------------------------------------------------------
  35. // Conversions
  36. NanoWidget::Color::Color() noexcept
  37. : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {}
  38. NanoWidget::Color::Color(const NVGcolor& c) noexcept
  39. : r(c.r), g(c.g), b(c.b), a(c.a) {}
  40. NanoWidget::Color::operator NVGcolor() const noexcept
  41. {
  42. NVGcolor nc = { r, g, b, a };
  43. return nc;
  44. }
  45. NanoWidget::Paint::Paint() noexcept
  46. : radius(0.0f), feather(0.0f), innerColor(), outerColor(), imageId(0), repeat(REPEAT_NONE)
  47. {
  48. std::memset(xform, 0, sizeof(float)*6);
  49. std::memset(extent, 0, sizeof(float)*2);
  50. }
  51. NanoWidget::Paint::Paint(const NVGpaint& p) noexcept
  52. : radius(p.radius), feather(p.feather), innerColor(p.innerColor), outerColor(p.outerColor), imageId(p.image), repeat(static_cast<PatternRepeat>(p.repeat))
  53. {
  54. std::memcpy(xform, p.xform, sizeof(float)*6);
  55. std::memcpy(extent, p.extent, sizeof(float)*2);
  56. }
  57. NanoWidget::Paint::operator NVGpaint() const noexcept
  58. {
  59. NVGpaint p;
  60. p.radius = radius;
  61. p.feather = feather;
  62. p.innerColor = innerColor;
  63. p.outerColor = outerColor;
  64. p.image = imageId;
  65. p.repeat = repeat;
  66. std::memcpy(p.xform, xform, sizeof(float)*6);
  67. std::memcpy(p.extent, extent, sizeof(float)*2);
  68. return p;
  69. }
  70. // -----------------------------------------------------------------------
  71. // NanoImage
  72. static NVGcontext* sLastContext = nullptr;
  73. NanoImage::NanoImage(const char* filename)
  74. : fContext(sLastContext),
  75. fImageId((fContext != nullptr) ? nvgCreateImage(fContext, filename) : 0) {}
  76. NanoImage::NanoImage(uchar* data, int ndata)
  77. : fContext(sLastContext),
  78. fImageId((fContext != nullptr) ? nvgCreateImageMem(fContext, data, ndata) : 0) {}
  79. NanoImage::NanoImage(int w, int h, const uchar* data)
  80. : fContext(sLastContext),
  81. fImageId((fContext != nullptr) ? nvgCreateImageRGBA(fContext, w, h, data) : 0) {}
  82. NanoImage::~NanoImage()
  83. {
  84. if (fContext != nullptr && fImageId != 0)
  85. nvgDeleteImage(fContext, fImageId);
  86. }
  87. Size<int> NanoImage::getSize() const
  88. {
  89. int w=0, h=0;
  90. if (fContext != nullptr && fImageId != 0)
  91. nvgImageSize(fContext, fImageId, &w, &h);
  92. return Size<int>(w, h);
  93. }
  94. void NanoImage::updateImage(const uchar* data)
  95. {
  96. if (fContext != nullptr && fImageId != 0)
  97. nvgUpdateImage(fContext, fImageId, data);
  98. }
  99. // -----------------------------------------------------------------------
  100. // NanoWidget
  101. NanoWidget::NanoWidget(Window& parent)
  102. : Widget(parent),
  103. fContext(nvgCreateGL(512, 512, NVG_ANTIALIAS))
  104. {
  105. DISTRHO_SAFE_ASSERT_RETURN(fContext != nullptr,);
  106. }
  107. NanoWidget::~NanoWidget()
  108. {
  109. if (fContext == nullptr)
  110. return;
  111. nvgDeleteGL(fContext);
  112. }
  113. // -----------------------------------------------------------------------
  114. void NanoWidget::beginFrame(Alpha alpha)
  115. {
  116. nvgBeginFrame(fContext, getWidth(), getHeight(), 1.0f, static_cast<NVGalpha>(alpha));
  117. }
  118. void NanoWidget::endFrame()
  119. {
  120. nvgEndFrame(fContext);
  121. }
  122. // -----------------------------------------------------------------------
  123. // Color utils
  124. NanoWidget::Color NanoWidget::RGB(uchar r, uchar g, uchar b)
  125. {
  126. return nvgRGB(r, g, b);
  127. }
  128. NanoWidget::Color NanoWidget::RGBf(float r, float g, float b)
  129. {
  130. return nvgRGBf(r, g, b);
  131. }
  132. NanoWidget::Color NanoWidget::RGBA(uchar r, uchar g, uchar b, uchar a)
  133. {
  134. return nvgRGBA(r, g, b, a);
  135. }
  136. NanoWidget::Color NanoWidget::RGBAf(float r, float g, float b, float a)
  137. {
  138. return nvgRGBAf(r, g, b, a);
  139. }
  140. NanoWidget::Color NanoWidget::lerpRGBA(const Color& c0, const Color& c1, float u)
  141. {
  142. return nvgLerpRGBA(c0, c1, u);
  143. }
  144. NanoWidget::Color NanoWidget::HSL(float h, float s, float l)
  145. {
  146. return nvgHSL(h, s, l);
  147. }
  148. NanoWidget::Color NanoWidget::HSLA(float h, float s, float l, uchar a)
  149. {
  150. return nvgHSLA(h, s, l, a);
  151. }
  152. // -----------------------------------------------------------------------
  153. // State Handling
  154. void NanoWidget::save()
  155. {
  156. nvgSave(fContext);
  157. }
  158. void NanoWidget::restore()
  159. {
  160. nvgRestore(fContext);
  161. }
  162. void NanoWidget::reset()
  163. {
  164. nvgReset(fContext);
  165. }
  166. // -----------------------------------------------------------------------
  167. // Render styles
  168. void NanoWidget::strokeColor(const Color& color)
  169. {
  170. nvgStrokeColor(fContext, color);
  171. }
  172. void NanoWidget::strokePaint(const Paint& paint)
  173. {
  174. nvgStrokePaint(fContext, paint);
  175. }
  176. void NanoWidget::fillColor(const Color& color)
  177. {
  178. nvgFillColor(fContext, color);
  179. }
  180. void NanoWidget::fillPaint(const Paint& paint)
  181. {
  182. nvgFillPaint(fContext, paint);
  183. }
  184. void NanoWidget::miterLimit(float limit)
  185. {
  186. nvgMiterLimit(fContext, limit);
  187. }
  188. void NanoWidget::strokeWidth(float size)
  189. {
  190. nvgStrokeWidth(fContext, size);
  191. }
  192. void NanoWidget::lineCap(NanoWidget::LineCap cap)
  193. {
  194. nvgLineCap(fContext, cap);
  195. }
  196. void NanoWidget::lineJoin(NanoWidget::LineCap join)
  197. {
  198. nvgLineJoin(fContext, join);
  199. }
  200. // -----------------------------------------------------------------------
  201. // Transforms
  202. void NanoWidget::resetTransform()
  203. {
  204. nvgResetTransform(fContext);
  205. }
  206. void NanoWidget::transform(float a, float b, float c, float d, float e, float f)
  207. {
  208. nvgTransform(fContext, a, b, c, d, e, f);
  209. }
  210. void NanoWidget::translate(float x, float y)
  211. {
  212. nvgTranslate(fContext, x, y);
  213. }
  214. void NanoWidget::rotate(float angle)
  215. {
  216. nvgRotate(fContext, angle);
  217. }
  218. void NanoWidget::skewX(float angle)
  219. {
  220. nvgSkewX(fContext, angle);
  221. }
  222. void NanoWidget::skewY(float angle)
  223. {
  224. nvgSkewY(fContext, angle);
  225. }
  226. void NanoWidget::scale(float x, float y)
  227. {
  228. nvgScale(fContext, x, y);
  229. }
  230. void NanoWidget::currentTransform(float xform[6])
  231. {
  232. nvgCurrentTransform(fContext, xform);
  233. }
  234. void NanoWidget::transformIdentity(float dst[6])
  235. {
  236. nvgTransformIdentity(dst);
  237. }
  238. void NanoWidget::transformTranslate(float dst[6], float tx, float ty)
  239. {
  240. nvgTransformTranslate(dst, tx, ty);
  241. }
  242. void NanoWidget::transformScale(float dst[6], float sx, float sy)
  243. {
  244. nvgTransformScale(dst, sx, sy);
  245. }
  246. void NanoWidget::transformRotate(float dst[6], float a)
  247. {
  248. nvgTransformRotate(dst, a);
  249. }
  250. void NanoWidget::transformSkewX(float dst[6], float a)
  251. {
  252. nvgTransformSkewX(dst, a);
  253. }
  254. void NanoWidget::transformSkewY(float dst[6], float a)
  255. {
  256. nvgTransformSkewY(dst, a);
  257. }
  258. void NanoWidget::transformMultiply(float dst[6], const float src[6])
  259. {
  260. nvgTransformMultiply(dst, src);
  261. }
  262. void NanoWidget::transformPremultiply(float dst[6], const float src[6])
  263. {
  264. nvgTransformPremultiply(dst, src);
  265. }
  266. int NanoWidget::transformInverse(float dst[6], const float src[6])
  267. {
  268. return nvgTransformInverse(dst, src);
  269. }
  270. void NanoWidget::transformPoint(float& dstx, float& dsty, const float xform[6], float srcx, float srcy)
  271. {
  272. nvgTransformPoint(&dstx, &dsty, xform, srcx, srcy);
  273. }
  274. float NanoWidget::degToRad(float deg)
  275. {
  276. return nvgDegToRad(deg);
  277. }
  278. float NanoWidget::radToDeg(float rad)
  279. {
  280. return nvgRadToDeg(rad);
  281. }
  282. // -----------------------------------------------------------------------
  283. // Images
  284. NanoImage NanoWidget::createImage(const char* filename)
  285. {
  286. sLastContext = fContext;
  287. return NanoImage(filename);
  288. }
  289. NanoImage NanoWidget::createImageMem(uchar* data, int ndata)
  290. {
  291. sLastContext = fContext;
  292. return NanoImage(data, ndata);
  293. }
  294. NanoImage NanoWidget::createImageRGBA(int w, int h, const uchar* data)
  295. {
  296. sLastContext = fContext;
  297. return NanoImage(w, h, data);
  298. }
  299. // -----------------------------------------------------------------------
  300. // Paints
  301. NanoWidget::Paint NanoWidget::linearGradient(float sx, float sy, float ex, float ey, const NanoWidget::Color& icol, const NanoWidget::Color& ocol)
  302. {
  303. return nvgLinearGradient(fContext, sx, sy, ex, ey, icol, ocol);
  304. }
  305. NanoWidget::Paint NanoWidget::boxGradient(float x, float y, float w, float h, float r, float f, const NanoWidget::Color& icol, const NanoWidget::Color& ocol)
  306. {
  307. return nvgBoxGradient(fContext, x, y, w, h, r, f, icol, ocol);
  308. }
  309. NanoWidget::Paint NanoWidget::radialGradient(float cx, float cy, float inr, float outr, const NanoWidget::Color& icol, const NanoWidget::Color& ocol)
  310. {
  311. return nvgRadialGradient(fContext, cx, cy, inr, outr, icol, ocol);
  312. }
  313. NanoWidget::Paint NanoWidget::imagePattern(float ox, float oy, float ex, float ey, float angle, const NanoImage& image, NanoWidget::PatternRepeat repeat)
  314. {
  315. return nvgImagePattern(fContext, ox, oy, ex, ey, angle, image.fImageId, repeat);
  316. }
  317. // -----------------------------------------------------------------------
  318. // Scissoring
  319. void NanoWidget::scissor(float x, float y, float w, float h)
  320. {
  321. nvgScissor(fContext, x, y, w, h);
  322. }
  323. void NanoWidget::resetScissor()
  324. {
  325. nvgResetScissor(fContext);
  326. }
  327. // -----------------------------------------------------------------------
  328. // Paths
  329. void NanoWidget::beginPath()
  330. {
  331. nvgBeginPath(fContext);
  332. }
  333. void NanoWidget::moveTo(float x, float y)
  334. {
  335. nvgMoveTo(fContext, x, y);
  336. }
  337. void NanoWidget::lineTo(float x, float y)
  338. {
  339. nvgLineTo(fContext, x, y);
  340. }
  341. void NanoWidget::bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y)
  342. {
  343. nvgBezierTo(fContext, c1x, c1y, c2x, c2y, x, y);
  344. }
  345. void NanoWidget::arcTo(float x1, float y1, float x2, float y2, float radius)
  346. {
  347. nvgArcTo(fContext, x1, y1, x2, y2, radius);
  348. }
  349. void NanoWidget::closePath()
  350. {
  351. nvgClosePath(fContext);
  352. }
  353. void NanoWidget::pathWinding(NanoWidget::Winding dir)
  354. {
  355. nvgPathWinding(fContext, dir);
  356. }
  357. void NanoWidget::arc(float cx, float cy, float r, float a0, float a1, NanoWidget::Winding dir)
  358. {
  359. nvgArc(fContext, cx, cy, r, a0, a1, dir);
  360. }
  361. void NanoWidget::rect(float x, float y, float w, float h)
  362. {
  363. nvgRect(fContext, x, y, w, h);
  364. }
  365. void NanoWidget::roundedRect(float x, float y, float w, float h, float r)
  366. {
  367. nvgRoundedRect(fContext, x, y, w, h, r);
  368. }
  369. void NanoWidget::ellipse(float cx, float cy, float rx, float ry)
  370. {
  371. nvgEllipse(fContext, cx, cy, rx, ry);
  372. }
  373. void NanoWidget::circle(float cx, float cy, float r)
  374. {
  375. nvgCircle(fContext, cx, cy, r);
  376. }
  377. void NanoWidget::fill()
  378. {
  379. nvgFill(fContext);
  380. }
  381. void NanoWidget::stroke()
  382. {
  383. nvgStroke(fContext);
  384. }
  385. // -----------------------------------------------------------------------
  386. // Text
  387. NanoWidget::FontId NanoWidget::createFont(const char* name, const char* filename)
  388. {
  389. return nvgCreateFont(fContext, name, filename);
  390. }
  391. NanoWidget::FontId NanoWidget::createFontMem(const char* name, uchar* data, int ndata, bool freeData)
  392. {
  393. return nvgCreateFontMem(fContext, name, data, ndata, freeData);
  394. }
  395. NanoWidget::FontId NanoWidget::findFont(const char* name)
  396. {
  397. return nvgFindFont(fContext, name);
  398. }
  399. void NanoWidget::fontSize(float size)
  400. {
  401. nvgFontSize(fContext, size);
  402. }
  403. void NanoWidget::fontBlur(float blur)
  404. {
  405. nvgFontBlur(fContext, blur);
  406. }
  407. void NanoWidget::textLetterSpacing(float spacing)
  408. {
  409. nvgTextLetterSpacing(fContext, spacing);
  410. }
  411. void NanoWidget::textLineHeight(float lineHeight)
  412. {
  413. nvgTextLineHeight(fContext, lineHeight);
  414. }
  415. void NanoWidget::textAlign(NanoWidget::Align align)
  416. {
  417. nvgTextAlign(fContext, align);
  418. }
  419. void NanoWidget::fontFaceId(FontId font)
  420. {
  421. nvgFontFaceId(fContext, font);
  422. }
  423. void NanoWidget::fontFace(const char* font)
  424. {
  425. nvgFontFace(fContext, font);
  426. }
  427. float NanoWidget::text(float x, float y, const char* string, const char* end)
  428. {
  429. return nvgText(fContext, x, y, string, end);
  430. }
  431. void NanoWidget::textBox(float x, float y, float breakRowWidth, const char* string, const char* end)
  432. {
  433. nvgTextBox(fContext, x, y, breakRowWidth, string, end);
  434. }
  435. float NanoWidget::textBounds(float x, float y, const char* string, const char* end, float* bounds)
  436. {
  437. return nvgTextBounds(fContext, x, y, string, end, bounds);
  438. }
  439. void NanoWidget::textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds)
  440. {
  441. nvgTextBoxBounds(fContext, x, y, breakRowWidth, string, end, bounds);
  442. }
  443. int NanoWidget::textGlyphPositions(float x, float y, const char* string, const char* end, NanoWidget::GlyphPosition* positions, int maxPositions)
  444. {
  445. return nvgTextGlyphPositions(fContext, x, y, string, end, (NVGglyphPosition*)positions, maxPositions);
  446. }
  447. void NanoWidget::textMetrics(float* ascender, float* descender, float* lineh)
  448. {
  449. nvgTextMetrics(fContext, ascender, descender, lineh);
  450. }
  451. int NanoWidget::textBreakLines(const char* string, const char* end, float breakRowWidth, NanoWidget::TextRow* rows, int maxRows)
  452. {
  453. return nvgTextBreakLines(fContext, string, end, breakRowWidth, (NVGtextRow*)rows, maxRows);
  454. }
  455. // -----------------------------------------------------------------------
  456. END_NAMESPACE_DGL
  457. extern "C" {
  458. #include "nanovg/nanovg.c"
  459. }
  460. // -----------------------------------------------------------------------