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.

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