LCOV - code coverage report
Current view: top level - xenolith/renderer/material2d/base - MaterialLabel.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 74 109 67.9 %
Date: 2024-05-12 00:16:13 Functions: 9 13 69.2 %

          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 "MaterialLabel.h"
      24             : #include "MaterialSurface.h"
      25             : #include "MaterialStyleContainer.h"
      26             : #include "MaterialSurfaceInterior.h"
      27             : #include "XLFrameInfo.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler::xenolith::material2d {
      30             : 
      31             : struct TypescalePersistentStyle {
      32             :         font::FontSize size;
      33             :         font::FontWeight weight;
      34             : 
      35          10 :         constexpr TypescalePersistentStyle(TypescaleRole role) {
      36          10 :                 switch (role) {
      37           0 :                 case TypescaleRole::DisplayLarge: size = font::FontSize(57); weight = font::FontWeight(400); break; // 57 400
      38           0 :                 case TypescaleRole::DisplayMedium: size = font::FontSize(45); weight = font::FontWeight(400); break; // 45 400
      39           0 :                 case TypescaleRole::DisplaySmall: size = font::FontSize(36); weight = font::FontWeight(400); break; // 36 400
      40           0 :                 case TypescaleRole::HeadlineLarge: size = font::FontSize(32); weight = font::FontWeight(400); break; // 32 400
      41           0 :                 case TypescaleRole::HeadlineMedium: size = font::FontSize(28); weight = font::FontWeight(400); break; // 28 400
      42           0 :                 case TypescaleRole::HeadlineSmall: size = font::FontSize(24); weight = font::FontWeight(400); break; // 24 400
      43           0 :                 case TypescaleRole::TitleLarge: size = font::FontSize(22); weight = font::FontWeight(400); break; // 22 400
      44           0 :                 case TypescaleRole::TitleMedium: size = font::FontSize(16); weight = font::FontWeight(500); break; // 16 500
      45           0 :                 case TypescaleRole::TitleSmall: size = font::FontSize(14); weight = font::FontWeight(500); break; // 14 500
      46           0 :                 case TypescaleRole::LabelLarge: size = font::FontSize(14); weight = font::FontWeight(500); break; // 14 500
      47           0 :                 case TypescaleRole::LabelMedium: size = font::FontSize(12); weight = font::FontWeight(500); break; // 12 500
      48           0 :                 case TypescaleRole::LabelSmall: size = font::FontSize(11); weight = font::FontWeight(500); break; // 11 500
      49           0 :                 case TypescaleRole::BodyLarge: size = font::FontSize(16); weight = font::FontWeight(400); break; // 16 400 0.5
      50           0 :                 case TypescaleRole::BodyMedium: size = font::FontSize(14); weight = font::FontWeight(400); break; // 14 400 0.25
      51           0 :                 case TypescaleRole::BodySmall: size = font::FontSize(12); weight = font::FontWeight(400); break; // 12 400 0.4
      52          10 :                 case TypescaleRole::Unknown: break;
      53             :                 }
      54          10 :         }
      55             : 
      56           0 :         bool operator==(const font::FontParameters &f) const { return f.fontSize == size && f.fontWeight == weight; }
      57             : };
      58             : 
      59             : static TypescalePersistentStyle s_persistentVariants[] = {
      60             :         TypescalePersistentStyle(TypescaleRole::DisplayLarge), // 57 400
      61             :         TypescalePersistentStyle(TypescaleRole::DisplayMedium), // 45 400
      62             :         TypescalePersistentStyle(TypescaleRole::DisplaySmall), // 36 400
      63             :         TypescalePersistentStyle(TypescaleRole::HeadlineLarge), // 32 400
      64             :         TypescalePersistentStyle(TypescaleRole::HeadlineMedium), // 28 400
      65             :         TypescalePersistentStyle(TypescaleRole::HeadlineSmall), // 24 400
      66             :         TypescalePersistentStyle(TypescaleRole::TitleLarge), // 22 400
      67             :         TypescalePersistentStyle(TypescaleRole::TitleMedium), // 16 500
      68             :         TypescalePersistentStyle(TypescaleRole::TitleSmall), // 14 500
      69             :         TypescalePersistentStyle(TypescaleRole::LabelLarge), // 14 500
      70             :         TypescalePersistentStyle(TypescaleRole::LabelMedium), // 12 500
      71             :         TypescalePersistentStyle(TypescaleRole::LabelSmall), // 11 500
      72             :         TypescalePersistentStyle(TypescaleRole::BodyLarge), // 16 400 0.5
      73             :         TypescalePersistentStyle(TypescaleRole::BodyMedium), // 14 400 0.25
      74             :         TypescalePersistentStyle(TypescaleRole::BodySmall), // 12 400 0.4
      75             :         TypescalePersistentStyle(TypescaleRole::Unknown),
      76             : };
      77             : 
      78           6 : TypescaleLabel::DescriptionStyle TypescaleLabel::getTypescaleRoleStyle(TypescaleRole role, float density) {
      79           6 :         DescriptionStyle style;
      80           6 :         style.font.fontFamily = StringView("sans");
      81           6 :         style.font.density = density;
      82             : 
      83           6 :         if (role != TypescaleRole::Unknown) {
      84           6 :                 auto &variant = s_persistentVariants[toInt(role)];
      85             : 
      86           6 :                 style.font.fontSize = variant.size;
      87           6 :                 style.font.fontWeight = variant.weight;
      88             :         }
      89             : 
      90           6 :         return style;
      91             : }
      92             : 
      93         472 : bool TypescaleLabel::init(TypescaleRole role) {
      94         472 :         if (!Label::init()) {
      95           0 :                 return false;
      96             :         }
      97             : 
      98         472 :         setFontFamily("sans");
      99         472 :         setRole(role);
     100         472 :         return true;
     101             : }
     102             : 
     103          50 : bool TypescaleLabel::init(TypescaleRole role, StringView str) {
     104          50 :         if (!Label::init(str)) {
     105           0 :                 return false;
     106             :         }
     107             : 
     108          50 :         setFontFamily("sans");
     109          50 :         setRole(role);
     110          50 :         return true;
     111             : }
     112             : 
     113           0 : bool TypescaleLabel::init(TypescaleRole role, StringView str, float w, TextAlign a) {
     114           0 :         if (!Label::init(str, w, a)) {
     115           0 :                 return false;
     116             :         }
     117             : 
     118           0 :         setFontFamily("sans");
     119           0 :         setRole(role);
     120           0 :         return true;
     121             : }
     122             : 
     123         522 : void TypescaleLabel::setRole(TypescaleRole role) {
     124         522 :         _role = role;
     125             : 
     126         522 :         if (role != TypescaleRole::Unknown) {
     127         522 :                 auto &variant = s_persistentVariants[toInt(role)];
     128             : 
     129         522 :                 setFontSize(variant.size);
     130         522 :                 setFontWeight(variant.weight);
     131             :         }
     132         522 : }
     133             : 
     134         190 : void TypescaleLabel::setBlendColor(ColorRole rule, float value) {
     135         190 :         if (_blendColorRule != rule || _blendValue != value) {
     136         157 :                 _blendColorRule = rule;
     137         157 :                 _blendValue = value;
     138             :         }
     139         190 : }
     140             : 
     141          30 : void TypescaleLabel::setBlendColor(const Color4F &c, float value) {
     142          30 :         setBlendColor(ColorRole::Undefined, 0.0f);
     143          30 :         _blendColor = c;
     144          30 :         _blendValue = value;
     145          30 : }
     146             : 
     147           0 : void TypescaleLabel::setPreserveOpacity(bool value) {
     148           0 :         _preserveOpacity = value;
     149           0 : }
     150             : 
     151           0 : bool TypescaleLabel::isPreserveOpacity() const {
     152           0 :         return _preserveOpacity;
     153             : }
     154             : 
     155        7522 : bool TypescaleLabel::visitDraw(FrameInfo &frame, NodeFlags parentFlags) {
     156        7522 :         if (!_visible || empty()) {
     157        1743 :                 return false;
     158             :         }
     159             : 
     160        5779 :         auto style = frame.getComponent<SurfaceInterior>(SurfaceInterior::ComponentFrameTag);
     161        5779 :         auto styleContainer = frame.getComponent<StyleContainer>(StyleContainer::ComponentFrameTag);
     162        5779 :         if (style) {
     163        5779 :                 auto &s = style->getStyle();
     164             : 
     165        5779 :                 if (styleContainer) {
     166        5779 :                         if (auto scheme = styleContainer->getScheme(s.schemeTag)) {
     167        5779 :                                 if (_blendValue > 0.0f && _blendColorRule != ColorRole::Undefined) {
     168         350 :                                         auto c = scheme->get(_blendColorRule);
     169         350 :                                         if (c != _blendColor) {
     170          10 :                                                 _blendColor = c;
     171             :                                         }
     172             :                                 }
     173             : 
     174        5779 :                                 setSelectionColor(scheme->get(material2d::ColorRole::Secondary));
     175             :                         }
     176             :                 }
     177             : 
     178        5779 :                 auto color = s.colorOn.asColor4F();
     179        5779 :                 if (_blendValue > 0.0f) {
     180         350 :                         color = color * (1.0f - _blendValue) + _blendColor * _blendValue;
     181             :                 }
     182             : 
     183        5779 :                 if (color != getColor()) {
     184        2589 :                         setColor(color, !_preserveOpacity);
     185             :                 }
     186             : 
     187        5779 :                 if (getRenderingLevel() != RenderingLevel::Default) {
     188        5779 :                         if (s.colorElevation.a < 1.0f && style->getStyle().colorElevation.a > 0.0f) {
     189         270 :                                 setRenderingLevel(RenderingLevel::Transparent);
     190             :                         } else {
     191        5509 :                                 setRenderingLevel(RenderingLevel::Surface);
     192             :                         }
     193             :                 }
     194             : 
     195        5779 :                 if (_themeType != style->getStyle().themeType) {
     196           0 :                         _themeType = style->getStyle().themeType;
     197           0 :                         setLabelDirty();
     198             :                 }
     199             :         }
     200             : 
     201        5779 :         return Label::visitDraw(frame, parentFlags);
     202        5779 : }
     203             : 
     204         988 : void TypescaleLabel::specializeStyle(DescriptionStyle &style, float density) const {
     205         988 :         if (_themeType == ThemeType::DarkTheme) {
     206           0 :                 style.font.fontGrade = font::FontGrade(style.font.fontGrade.get() - 50);
     207             :         }
     208             : 
     209         988 :         Label::specializeStyle(style, density);
     210         988 :         if (!_persistentLayout) {
     211         598 :                 if ((style.font.fontGrade == font::FontGrade::Normal || style.font.fontGrade == font::FontGrade::Normal)
     212         598 :                                 && style.font.fontStretch.get() % 100 == 0
     213        1196 :                                 && (style.font.fontStyle == font::FontStyle::Italic || style.font.fontStyle == font::FontStyle::Oblique)) {
     214             : 
     215           0 :                         for (auto &it : s_persistentVariants) {
     216           0 :                                 if (it == style.font) {
     217           0 :                                         style.font.persistent = true;
     218             :                                 }
     219             :                         }
     220             :                 }
     221             :         }
     222         988 : }
     223             : 
     224             : }

Generated by: LCOV version 1.14