LCOV - code coverage report
Current view: top level - core/geom - SPGeometry.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 188 193 97.4 %
Date: 2024-05-12 00:16:13 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2010-2012 cocos2d-x.org
       3             : Copyright (c) 2013-2014 Chukong Technologies
       4             : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
       5             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       6             : 
       7             : Permission is hereby granted, free of charge, to any person obtaining a copy
       8             : of this software and associated documentation files (the "Software"), to deal
       9             : in the Software without restriction, including without limitation the rights
      10             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      11             : copies of the Software, and to permit persons to whom the Software is
      12             : furnished to do so, subject to the following conditions:
      13             : 
      14             : The above copyright notice and this permission notice shall be included in
      15             : all copies or substantial portions of the Software.
      16             : 
      17             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      18             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      19             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      20             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      21             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      22             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      23             : THE SOFTWARE.
      24             : **/
      25             : 
      26             : #include "SPGeometry.h"
      27             : #include "SPMat4.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler::geom {
      30             : 
      31        1475 : bool Metric::readStyleValue(StringView r, bool resolutionMetric, bool allowEmptyMetric) {
      32        1475 :         r.skipChars<StringView::CharGroup<CharGroupId::WhiteSpace>>();
      33        1475 :         if (!resolutionMetric && r.starts_with("auto")) {
      34          25 :                 r += 4;
      35          25 :                 this->metric = Metric::Units::Auto;
      36          25 :                 this->value = 0.0f;
      37          25 :                 return true;
      38             :         }
      39             : 
      40        1450 :         auto fRes = r.readFloat();
      41        1450 :         if (!fRes.valid()) {
      42           0 :                 return false;
      43             :         }
      44             : 
      45        1450 :         auto fvalue = fRes.get();
      46        1450 :         if (fvalue == 0.0f) {
      47         100 :                 this->value = fvalue;
      48         100 :                 this->metric = Metric::Units::Px;
      49         100 :                 return true;
      50             :         }
      51             : 
      52        1350 :         r.skipChars<StringView::CharGroup<CharGroupId::WhiteSpace>>();
      53             : 
      54        1350 :         auto str = r.readUntil<StringView::CharGroup<CharGroupId::WhiteSpace>>();
      55             : 
      56        1350 :         if (!resolutionMetric) {
      57        1275 :                 if (str.is('%')) {
      58          75 :                         ++ str;
      59          75 :                         this->value = fvalue / 100.0f;
      60          75 :                         this->metric = Metric::Units::Percent;
      61          75 :                         return true;
      62        1200 :                 } else if (str == "em") {
      63          25 :                         str += 2;
      64          25 :                         this->value = fvalue;
      65          25 :                         this->metric = Metric::Units::Em;
      66          25 :                         return true;
      67        1175 :                 } else if (str == "rem") {
      68          25 :                         str += 3;
      69          25 :                         this->value = fvalue;
      70          25 :                         this->metric = Metric::Units::Rem;
      71          25 :                         return true;
      72        1150 :                 } else if (str == "px") {
      73          50 :                         str += 2;
      74          50 :                         this->value = fvalue;
      75          50 :                         this->metric = Metric::Units::Px;
      76          50 :                         return true;
      77        1100 :                 } else if (str == "pt") {
      78          25 :                         str += 2;
      79          25 :                         this->value = fvalue * 4.0f / 3.0f;
      80          25 :                         this->metric = Metric::Units::Px;
      81          25 :                         return true;
      82        1075 :                 } else if (str == "pc") {
      83          25 :                         str += 2;
      84          25 :                         this->value = fvalue * 15.0f;
      85          25 :                         this->metric = Metric::Units::Px;
      86          25 :                         return true;
      87        1050 :                 } else if (str == "mm") {
      88          25 :                         str += 2;
      89          25 :                         this->value = fvalue * 3.543307f;
      90          25 :                         this->metric = Metric::Units::Px;
      91          25 :                         return true;
      92        1025 :                 } else if (str == "cm") {
      93          25 :                         str += 2;
      94          25 :                         this->value = fvalue * 35.43307f;
      95          25 :                         this->metric = Metric::Units::Px;
      96          25 :                         return true;
      97        1000 :                 } else if (str == "in") {
      98          25 :                         str += 2;
      99          25 :                         this->value = fvalue * 90.0f;
     100          25 :                         this->metric = Metric::Units::Px;
     101          25 :                         return true;
     102         975 :                 } else if (str == "vw") {
     103          25 :                         str += 2;
     104          25 :                         this->value = fvalue;
     105          25 :                         this->metric = Metric::Units::Vw;
     106          25 :                         return true;
     107         950 :                 } else if (str == "vh") {
     108          25 :                         str += 2;
     109          25 :                         this->value = fvalue;
     110          25 :                         this->metric = Metric::Units::Vh;
     111          25 :                         return true;
     112         925 :                 } else if (str == "vmin") {
     113          25 :                         str += 4;
     114          25 :                         this->value = fvalue;
     115          25 :                         this->metric = Metric::Units::VMin;
     116          25 :                         return true;
     117         900 :                 } else if (str == "vmax") {
     118          25 :                         str += 4;
     119          25 :                         this->value = fvalue;
     120          25 :                         this->metric = Metric::Units::VMax;
     121          25 :                         return true;
     122             :                 }
     123             :         } else {
     124          75 :                 if (str == "dpi") {
     125          25 :                         str += 3;
     126          25 :                         this->value = fvalue;
     127          25 :                         this->metric = Metric::Units::Dpi;
     128          25 :                         return true;
     129          50 :                 } else if (str == "dpcm") {
     130          25 :                         str += 4;
     131          25 :                         this->value = fvalue / 2.54f;
     132          25 :                         this->metric = Metric::Units::Dpi;
     133          25 :                         return true;
     134          25 :                 } else if (str == "dppx") {
     135          25 :                         str += 4;
     136          25 :                         this->value = fvalue;
     137          25 :                         this->metric = Metric::Units::Dppx;
     138          25 :                         return true;
     139             :                 }
     140             :         }
     141             : 
     142         875 :         if (allowEmptyMetric) {
     143         850 :                 this->value = fvalue;
     144         850 :                 return true;
     145             :         }
     146             : 
     147          25 :         return false;
     148             : }
     149             : 
     150          50 : bool Rect::containsPoint(const Vec2& point, float padding) const {
     151          50 :         bool bRet = false;
     152             : 
     153          50 :         if (point.x >= getMinX() - padding && point.x <= getMaxX() + padding && point.y >= getMinY() - padding && point.y <= getMaxY() + padding) {
     154          25 :                 bRet = true;
     155             :         }
     156             : 
     157          50 :         return bRet;
     158             : }
     159             : 
     160          25 : bool Rect::intersectsRect(const Rect& rect) const {
     161          50 :         return !( getMaxX() < rect.getMinX() ||
     162          25 :                         rect.getMaxX() < getMinX() ||
     163          25 :                         getMaxY() < rect.getMinY() ||
     164          50 :                         rect.getMaxY() < getMinY());
     165             : }
     166             : 
     167         100 : bool Rect::intersectsCircle(const Vec2 &center, float radius) const {
     168         100 :         Vec2 rectangleCenter((origin.x + size.width / 2),
     169         100 :                         (origin.y + size.height / 2));
     170             : 
     171         100 :         float w = size.width / 2;
     172         100 :         float h = size.height / 2;
     173             : 
     174         100 :         float dx = fabs(center.x - rectangleCenter.x);
     175         100 :         float dy = fabs(center.y - rectangleCenter.y);
     176             : 
     177         100 :         if (dx > (radius + w) || dy > (radius + h)) {
     178          25 :                 return false;
     179             :         }
     180             : 
     181          75 :         Vec2 circleDistance(fabs(center.x - origin.x - w),
     182          75 :                         fabs(center.y - origin.y - h));
     183             : 
     184          75 :         if (circleDistance.x <= (w)) {
     185          25 :                 return true;
     186             :         }
     187             : 
     188          50 :         if (circleDistance.y <= (h)) {
     189          25 :                 return true;
     190             :         }
     191             : 
     192          25 :         float cornerDistanceSq = powf(circleDistance.x - w, 2) + powf(circleDistance.y - h, 2);
     193             : 
     194          25 :         return (cornerDistanceSq <= (powf(radius, 2)));
     195             : }
     196             : 
     197          25 : void Rect::merge(const Rect& rect) {
     198          25 :         float top1 = getMaxY();
     199          25 :         float left1 = getMinX();
     200          25 :         float right1 = getMaxX();
     201          25 :         float bottom1 = getMinY();
     202             : 
     203          25 :         float top2 = rect.getMaxY();
     204          25 :         float left2 = rect.getMinX();
     205          25 :         float right2 = rect.getMaxX();
     206          25 :         float bottom2 = rect.getMinY();
     207          25 :         origin.x = std::min(left1, left2);
     208          25 :         origin.y = std::min(bottom1, bottom2);
     209          25 :         size.width = std::max(right1, right2) - origin.x;
     210          25 :         size.height = std::max(top1, top2) - origin.y;
     211          25 : }
     212             : 
     213          50 : Rect Rect::unionWithRect(const Rect & rect) const {
     214          50 :         float thisLeftX = origin.x;
     215          50 :         float thisRightX = origin.x + size.width;
     216          50 :         float thisTopY = origin.y + size.height;
     217          50 :         float thisBottomY = origin.y;
     218             : 
     219          50 :         if (thisRightX < thisLeftX) {
     220           0 :                 std::swap(thisRightX, thisLeftX);   // This rect has negative width
     221             :         }
     222             : 
     223          50 :         if (thisTopY < thisBottomY) {
     224           0 :                 std::swap(thisTopY, thisBottomY);   // This rect has negative height
     225             :         }
     226             : 
     227          50 :         float otherLeftX = rect.origin.x;
     228          50 :         float otherRightX = rect.origin.x + rect.size.width;
     229          50 :         float otherTopY = rect.origin.y + rect.size.height;
     230          50 :         float otherBottomY = rect.origin.y;
     231             : 
     232          50 :         if (otherRightX < otherLeftX) {
     233           0 :                 std::swap(otherRightX, otherLeftX);   // Other rect has negative width
     234             :         }
     235             : 
     236          50 :         if (otherTopY < otherBottomY) {
     237           0 :                 std::swap(otherTopY, otherBottomY);   // Other rect has negative height
     238             :         }
     239             : 
     240          50 :         float combinedLeftX = std::min(thisLeftX, otherLeftX);
     241          50 :         float combinedRightX = std::max(thisRightX, otherRightX);
     242          50 :         float combinedTopY = std::max(thisTopY, otherTopY);
     243          50 :         float combinedBottomY = std::min(thisBottomY, otherBottomY);
     244             : 
     245          50 :         return Rect(combinedLeftX, combinedBottomY, combinedRightX - combinedLeftX, combinedTopY - combinedBottomY);
     246             : }
     247             : 
     248          50 : bool URect::containsPoint(const UVec2 &point) const {
     249          50 :         bool bRet = false;
     250             : 
     251          50 :         if (point.x >= getMinX() && point.x <= getMaxX() && point.y >= getMinY() && point.y <= getMaxY()) {
     252          25 :                 bRet = true;
     253             :         }
     254             : 
     255          50 :         return bRet;
     256             : }
     257             : 
     258         175 : bool URect::intersectsRect(const URect &rect) const {
     259         275 :         return !( getMaxX() < rect.getMinX() ||
     260         100 :                         rect.getMaxX() < getMinX() ||
     261          25 :                         getMaxY() < rect.getMinY() ||
     262         200 :                         rect.getMaxY() < getMinY());
     263             : }
     264             : 
     265          25 : Rect TransformRect(const Rect& rect, const Mat4& transform) {
     266          25 :         const float top = rect.getMinY();
     267          25 :         const float left = rect.getMinX();
     268          25 :         const float right = rect.getMaxX();
     269          25 :         const float bottom = rect.getMaxY();
     270             : 
     271          25 :         Vec2 topLeft(left, top);
     272          25 :         Vec2 topRight(right, top);
     273          25 :         Vec2 bottomLeft(left, bottom);
     274          25 :         Vec2 bottomRight(right, bottom);
     275             : 
     276          25 :         transform.transformPoint(&topLeft);
     277          25 :         transform.transformPoint(&topRight);
     278          25 :         transform.transformPoint(&bottomLeft);
     279          25 :         transform.transformPoint(&bottomRight);
     280             : 
     281          25 :         const float minX = min(min(topLeft.x, topRight.x), min(bottomLeft.x, bottomRight.x));
     282          25 :         const float maxX = max(max(topLeft.x, topRight.x), max(bottomLeft.x, bottomRight.x));
     283          25 :         const float minY = min(min(topLeft.y, topRight.y), min(bottomLeft.y, bottomRight.y));
     284          25 :         const float maxY = max(max(topLeft.y, topRight.y), max(bottomLeft.y, bottomRight.y));
     285             : 
     286          25 :         return Rect(minX, minY, (maxX - minX), (maxY - minY));
     287             : }
     288             : 
     289             : #ifdef __LCC__
     290             : 
     291             : constexpr Size2 Size2::ZERO(0.0f, 0.0f);
     292             : constexpr Size3 Size3::ZERO = Size3(0.0f, 0.0f, 0.0f);
     293             : constexpr Extent2 Extent2::ZERO = Extent2(0, 0);
     294             : constexpr Extent3 Extent3::ZERO = Extent3(0, 0, 0);
     295             : constexpr Rect Rect::ZERO = Rect(0.0f, 0.0f, 0.0f, 0.0f);
     296             : 
     297             : #endif
     298             : 
     299             : }

Generated by: LCOV version 1.14