LCOV - code coverage report
Current view: top level - xenolith/renderer/basic2d - XL2dLayer.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 84 138 60.9 %
Date: 2024-05-12 00:16:13 Functions: 10 20 50.0 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  **/
      22             : 
      23             : #include "XL2dLayer.h"
      24             : #include "XL2dFrameContext.h"
      25             : #include "XLTexture.h"
      26             : #include "XLFrameInfo.h"
      27             : 
      28             : namespace STAPPLER_VERSIONIZED stappler::xenolith::basic2d {
      29             : 
      30             : const Vec2 SimpleGradient::Horizontal(0.0f, 1.0f);
      31             : const Vec2 SimpleGradient::Vertical(-1.0f, 0.0f);
      32             : 
      33           0 : SimpleGradient SimpleGradient::progress(const SimpleGradient &a, const SimpleGradient &b, float p) {
      34           0 :         SimpleGradient ret;
      35           0 :         ret.colors[0] = stappler::progress(a.colors[0], b.colors[0], p);
      36           0 :         ret.colors[1] = stappler::progress(a.colors[1], b.colors[1], p);
      37           0 :         ret.colors[2] = stappler::progress(a.colors[2], b.colors[2], p);
      38           0 :         ret.colors[3] = stappler::progress(a.colors[3], b.colors[3], p);
      39           0 :         return ret;
      40             : }
      41             : 
      42        1425 : SimpleGradient::SimpleGradient() {
      43        1425 :         colors[0] = Color4B(255, 255, 255, 255);
      44        1425 :         colors[1] = Color4B(255, 255, 255, 255);
      45        1425 :         colors[2] = Color4B(255, 255, 255, 255);
      46        1425 :         colors[3] = Color4B(255, 255, 255, 255);
      47        1425 : }
      48             : 
      49           0 : SimpleGradient::SimpleGradient(ColorRef color) {
      50           0 :         colors[0] = colors[1] = colors[2] = colors[3] = color;
      51           0 : }
      52             : 
      53         740 : SimpleGradient::SimpleGradient(ColorRef start, ColorRef end, const Vec2 &alongVector) {
      54         740 :         float h = alongVector.length();
      55         740 :         if (h == 0) {
      56           0 :                 return;
      57             :         }
      58             : 
      59         740 :         float c = sqrtf(2.0f);
      60         740 :         Vec2 u(alongVector.x / h, alongVector.y / h);
      61             : 
      62             :         // Compressed Interpolation mode
      63         740 :         float h2 = 1 / ( fabsf(u.x) + fabsf(u.y) );
      64         740 :         u = u * (h2 * c);
      65             : 
      66         740 :         Color4B S( start.r, start.g, start.b, start.a  );
      67         740 :         Color4B E( end.r, end.g, end.b, end.a );
      68             : 
      69             :         // (-1, -1)
      70         740 :         colors[0].r = E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c));
      71         740 :         colors[0].g = E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c));
      72         740 :         colors[0].b = E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c));
      73         740 :         colors[0].a = E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c));
      74             :         // (1, -1)
      75         740 :         colors[1].r = E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c));
      76         740 :         colors[1].g = E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c));
      77         740 :         colors[1].b = E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c));
      78         740 :         colors[1].a = E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c));
      79             :         // (-1, 1)
      80         740 :         colors[2].r = E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c));
      81         740 :         colors[2].g = E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c));
      82         740 :         colors[2].b = E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c));
      83         740 :         colors[2].a = E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c));
      84             :         // (1, 1)
      85         740 :         colors[3].r = E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c));
      86         740 :         colors[3].g = E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c));
      87         740 :         colors[3].b = E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c));
      88         740 :         colors[3].a = E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c));
      89             : }
      90             : 
      91           0 : SimpleGradient::SimpleGradient(ColorRef bl, ColorRef br, ColorRef tl, ColorRef tr) {
      92           0 :         colors[0] = bl;
      93           0 :         colors[1] = br;
      94           0 :         colors[2] = tl;
      95           0 :         colors[3] = tr;
      96           0 : }
      97             : 
      98        4003 : bool SimpleGradient::hasAlpha() const {
      99        4003 :         return colors[0].a != 255 || colors[1].a != 255 || colors[2].a != 255 || colors[3].a != 255;
     100             : }
     101             : 
     102           0 : bool SimpleGradient::isMono() const {
     103           0 :         return colors[0] == colors[1] && colors[2] == colors[3] && colors[1] == colors[2];
     104             : }
     105             : 
     106           0 : bool SimpleGradient::operator==(const SimpleGradient &other) const {
     107           0 :         return memcmp(colors, other.colors, sizeof(Color4B) * 4) == 0;
     108             : }
     109             : 
     110           0 : bool SimpleGradient::operator!=(const SimpleGradient &other) const {
     111           0 :         return memcmp(colors, other.colors, sizeof(Color4B) * 4) != 0;
     112             : }
     113             : 
     114         460 : bool Layer::init() {
     115         460 :         return init(Color4F::WHITE);
     116             : }
     117             : 
     118        1425 : bool Layer::init(const Color4F &c) {
     119        1425 :         if (!Sprite::init(core::SolidTextureName)) {
     120           0 :                 return false;
     121             :         }
     122             : 
     123        1425 :         setColor(c, true);
     124        1425 :         setColorMode(core::ColorMode(core::ComponentMapping::R, core::ComponentMapping::One));
     125             : 
     126        1425 :         return true;
     127             : }
     128             : 
     129           0 : bool Layer::init(const SimpleGradient &grad) {
     130           0 :         if (!Sprite::init(core::SolidTextureName)) {
     131           0 :                 return false;
     132             :         }
     133             : 
     134           0 :         setColor(Color4F::WHITE, true);
     135           0 :         setGradient(grad);
     136           0 :         setColorMode(core::ColorMode(core::ComponentMapping::R, core::ComponentMapping::One));
     137             : 
     138           0 :         return true;
     139             : }
     140             : 
     141        4590 : void Layer::onContentSizeDirty() {
     142        4590 :         Sprite::onContentSizeDirty();
     143        4590 : }
     144             : 
     145         740 : void Layer::setGradient(const SimpleGradient &g) {
     146         740 :         _gradient = g;
     147         740 :         _contentSizeDirty = true;
     148         740 : }
     149             : 
     150           0 : const SimpleGradient &Layer::getGradient() const {
     151           0 :         return _gradient;
     152             : }
     153             : 
     154        4580 : void Layer::updateVertexes() {
     155        4580 :         _vertexes.clear();
     156        4580 :         auto quad = _vertexes.addQuad()
     157        4580 :                 .setGeometry(Vec4::ZERO, _contentSize)
     158        4580 :                 .setTextureRect(_textureRect, 1.0f, 1.0f, _flippedX, _flippedY, _rotated);
     159             : 
     160        4580 :         Color4F color[4];
     161       22900 :         for (int i = 0; i < 4; i++) {
     162       18320 :                 color[i] = Color4F(
     163       18320 :                                 _displayedColor.r * (_gradient.colors[i].r / 255.0f),
     164       18320 :                                 _displayedColor.g * (_gradient.colors[i].g / 255.0f),
     165       18320 :                                 _displayedColor.b * (_gradient.colors[i].b / 255.0f),
     166       18320 :                                 _displayedColor.a * _gradient.colors[i].a / 255.0f );
     167             :         }
     168             : 
     169        4580 :         quad.setColor(makeSpanView(color, 4));
     170        4580 : }
     171             : 
     172        9916 : void Layer::updateVertexesColor() {
     173        9916 :         if (!_vertexes.empty()) {
     174        9916 :                 Color4F color[4];
     175       49580 :                 for (int i = 0; i < 4; i++) {
     176       39664 :                         color[i] = Color4F(
     177       39664 :                                         _displayedColor.r * (_gradient.colors[i].r / 255.0f),
     178       39664 :                                         _displayedColor.g * (_gradient.colors[i].g / 255.0f),
     179       39664 :                                         _displayedColor.b * (_gradient.colors[i].b / 255.0f),
     180       39664 :                                         _displayedColor.a * _gradient.colors[i].a / 255.0f );
     181             :                 }
     182             : 
     183        9916 :                 _vertexes.getQuad(0, 0).setColor(makeSpanView(color, 4));
     184             :         }
     185        9916 : }
     186             : 
     187        4173 : RenderingLevel Layer::getRealRenderingLevel() const {
     188        4173 :         auto level = _renderingLevel;
     189        4173 :         if (level == RenderingLevel::Default) {
     190        4173 :                 if (_displayedColor.a < 1.0f || _gradient.hasAlpha() || !_texture || _materialInfo.getLineWidth() != 0.0f) {
     191        1595 :                         level = RenderingLevel::Transparent;
     192        2578 :                 } else if (_colorMode.getMode() == core::ColorMode::Solid) {
     193           0 :                         if (_texture->hasAlpha()) {
     194           0 :                                 level = RenderingLevel::Transparent;
     195             :                         } else {
     196           0 :                                 level = RenderingLevel::Solid;
     197             :                         }
     198             :                 } else {
     199        2578 :                         auto alphaMapping = _colorMode.getA();
     200        2578 :                         switch (alphaMapping) {
     201           0 :                         case core::ComponentMapping::Identity:
     202           0 :                                 if (_texture->hasAlpha()) {
     203           0 :                                         level = RenderingLevel::Transparent;
     204             :                                 } else {
     205           0 :                                         level = RenderingLevel::Solid;
     206             :                                 }
     207           0 :                                 break;
     208           0 :                         case core::ComponentMapping::Zero:
     209           0 :                                 level = RenderingLevel::Transparent;
     210           0 :                                 break;
     211        2578 :                         case core::ComponentMapping::One:
     212        2578 :                                 level = RenderingLevel::Solid;
     213        2578 :                                 break;
     214           0 :                         default:
     215           0 :                                 level = RenderingLevel::Transparent;
     216           0 :                                 break;
     217             :                         }
     218             :                 }
     219             :         }
     220        4173 :         return level;
     221             : }
     222             : 
     223           0 : void Layer::pushShadowCommands(FrameInfo &frame, NodeFlags flags, const Mat4 &t, SpanView<TransformVertexData> data) {
     224           0 :         auto shadowIndex = frame.depthStack.back();
     225             : 
     226           0 :         FrameContextHandle2d *handle = static_cast<FrameContextHandle2d *>(frame.currentContext);
     227           0 :         handle->shadows->pushSdfGroup(t, handle->getCurrentState(), shadowIndex, [&, this] (CmdSdfGroup2D &cmd) {
     228           0 :                 cmd.addRect2D(Rect(Vec2(0, 0), _contentSize));
     229           0 :         });
     230           0 : }
     231             : 
     232             : }

Generated by: LCOV version 1.14