美文网首页
2024-03-07 flutter StrutStyle和Te

2024-03-07 flutter StrutStyle和Te

作者: 我是小胡胡分胡 | 来源:发表于2024-03-06 12:20 被阅读0次

    StrutStyle和TextStyle区别

    WX20240307-121045@2x.png

    1,style和strutStyle

    StrutStyle({
        String? fontFamily,
        List<String>? fontFamilyFallback,
        this.fontSize,
        this.height,
        this.leadingDistribution,
        this.leading,
        this.fontWeight,
        this.fontStyle, ///fontStyle
        this.forceStrutHeight,
        this.debugLabel,
        String? package,
      }) 
    
    
    
    
    TextStyle({
        this.inherit = true,
        this.color,
        this.backgroundColor,
        this.fontSize,
        this.fontWeight,
        this.fontStyle, ///fontStyle
        this.letterSpacing,
        this.wordSpacing,
        this.textBaseline,
        this.height,
        this.leadingDistribution,
        this.locale,
        this.foreground,
        this.background,
        this.shadows,
        this.fontFeatures,
        this.fontVariations,
        this.decoration,
        this.decorationColor,
        this.decorationStyle,
        this.decorationThickness,
        this.debugLabel,
        String? fontFamily,
        List<String>? fontFamilyFallback,
        String? package,
        this.overflow,
      })
    

    都有fontSize,height,fontWeight,fontStyle,fontFamily,fontFamilyFallback属性

    flutter 源码:

       final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
        TextStyle? effectiveTextStyle = style;
        if (style == null || style!.inherit) {
          effectiveTextStyle = defaultTextStyle.style.merge(style);
        }
        if (MediaQuery.boldTextOverride(context)) {
          effectiveTextStyle = effectiveTextStyle!.merge(const TextStyle(fontWeight: FontWeight.bold));
        }
    
     RichText(
     
          strutStyle: strutStyle,
     
          text: TextSpan(
            style: effectiveTextStyle, //style传递给 style: TextSpan text属性了
            text: data,
            children: textSpan != null ? <InlineSpan>[textSpan!] : null,
          ),
        );
    
    
    
      @override
      RenderParagraph createRenderObject(BuildContext context) {
        assert(textDirection != null || debugCheckHasDirectionality(context));
        return RenderParagraph(text, ///text: style传递给 style: TextSpan text属性了
          textAlign: textAlign,
          textDirection: textDirection ?? Directionality.of(context),
          softWrap: softWrap,
          overflow: overflow,
          textScaleFactor: textScaleFactor,
          maxLines: maxLines,
          strutStyle: strutStyle, //  strutStyle
          textWidthBasis: textWidthBasis,
          textHeightBehavior: textHeightBehavior,
          locale: locale ?? Localizations.maybeLocaleOf(context),
          registrar: selectionRegistrar,
          selectionColor: selectionColor,
        );
      }
    
    
    
    
     RenderParagraph(InlineSpan text, { ///text: style传递给 style: TextSpan text属性了
        TextAlign textAlign = TextAlign.start,
        required TextDirection textDirection,
        bool softWrap = true,
        TextOverflow overflow = TextOverflow.clip,
        double textScaleFactor = 1.0,
        int? maxLines,
        Locale? locale,
        StrutStyle? strutStyle,
        TextWidthBasis textWidthBasis = TextWidthBasis.parent,
        ui.TextHeightBehavior? textHeightBehavior,
        List<RenderBox>? children,
        Color? selectionColor,
        SelectionRegistrar? registrar,
      }) :  
           _softWrap = softWrap,
           _overflow = overflow,
           _selectionColor = selectionColor,
           _textPainter = TextPainter(
             text: text, /////text: style传递给 style: TextSpan text属性了
             textAlign: textAlign,
             textDirection: textDirection,
             textScaleFactor: textScaleFactor,
             maxLines: maxLines,
             ellipsis: overflow == TextOverflow.ellipsis ? _kEllipsis : null,
             locale: locale,
             strutStyle: strutStyle, //  strutStyle
             textWidthBasis: textWidthBasis,
             textHeightBehavior: textHeightBehavior,
           ) {
        addAll(children);
        _extractPlaceholderSpans(text);
        this.registrar = registrar;
      }
    
    
    
      TextPainter({
        InlineSpan? text, ///////text: style传递给 style: TextSpan text属性了
        TextAlign textAlign = TextAlign.start,
        TextDirection? textDirection,
        double textScaleFactor = 1.0,
        int? maxLines,
        String? ellipsis,
        Locale? locale,
        StrutStyle? strutStyle,// //  strutStyle
        TextWidthBasis textWidthBasis = TextWidthBasis.parent,
        ui.TextHeightBehavior? textHeightBehavior,
      }) : assert(text == null || text.debugAssertIsValid()),
           assert(textAlign != null),
           assert(textScaleFactor != null),
           assert(maxLines == null || maxLines > 0),
           assert(textWidthBasis != null),
           _text = text, ///////text: style传递给 style: TextSpan text属性了
           _textAlign = textAlign,
           _textDirection = textDirection,
           _textScaleFactor = textScaleFactor,
           _maxLines = maxLines,
           _ellipsis = ellipsis,
           _locale = locale,
           _strutStyle = strutStyle,//  strutStyle
           _textWidthBasis = textWidthBasis,
           _textHeightBehavior = textHeightBehavior;
    
    
    
      void _createParagraph() {
        assert(_paragraph == null || _rebuildParagraphForPaint);
        final InlineSpan? text = this.text;////text: style传递给 style: TextSpan text属性了
        if (text == null) {
          throw StateError('TextPainter.text must be set to a non-null value before using the TextPainter.');
        }
        final ui.ParagraphBuilder builder = ui.ParagraphBuilder(_createParagraphStyle());/////  strutStyle
    
    
        /// //text: style传递给 style: TextSpan text属性了,
        //builder: strutStyle
        text.build(builder, textScaleFactor: textScaleFactor, dimensions: _placeholderDimensions);
    
    
    
        _inlinePlaceholderScales = builder.placeholderScales;
        assert(() {
          _debugMarkNeedsLayoutCallStack = null;
          return true;
        }());
    
    
    
        _paragraph = builder.build();
    
    
    
        _rebuildParagraphForPaint = false;
      }
    
    
    
     ParagraphBuilder(ParagraphStyle style)
        : _defaultLeadingDistribution = style._leadingDistribution {
          List<String>? strutFontFamilies;
          final StrutStyle? strutStyle = style._strutStyle;
          final ByteData? encodedStrutStyle;
          if (strutStyle != null && strutStyle._enabled) {//style._strutStyle;
            final String? fontFamily = strutStyle._fontFamily;
            strutFontFamilies = <String>[
              if (fontFamily != null) fontFamily,
              ...?strutStyle._fontFamilyFallback,
            ];
    
            assert(TextLeadingDistribution.values.length <= 2);
            final TextLeadingDistribution leadingDistribution = strutStyle._leadingDistribution
              ?? style._leadingDistribution;
            encodedStrutStyle = strutStyle._encoded;
            int bitmask = encodedStrutStyle.getInt8(0);
            bitmask |= (leadingDistribution.index) << 3;
            encodedStrutStyle.setInt8(0, bitmask);
          } else {
            encodedStrutStyle = null;
          }
          _constructor(
            style._encoded,
            encodedStrutStyle,/////style._strutStyle;
            style._fontFamily ?? '',
            strutFontFamilies,
            style._fontSize ?? 0,
            style._height ?? 0,
            style._ellipsis ?? '',
            _encodeLocale(style._locale)
          );
      }
    
    ///text.build
    
     void build(
        ui.ParagraphBuilder builder, {   //builder: strutStyle
        double textScaleFactor = 1.0,
        List<PlaceholderDimensions>? dimensions,
      }) {
        assert(debugAssertIsValid());
        final bool hasStyle = style != null;////text: style传递给 style: TextSpan text属性了
        if (hasStyle) {
    
    
          builder.pushStyle(style!.getTextStyle(textScaleFactor: textScaleFactor));
    
    
        }
        if (text != null) {
          try {
            
    
            builder.addText(text!); ////text: style传递给 style: TextSpan text属性了
    
    
          } on ArgumentError catch (exception, stack) {
            FlutterError.reportError(FlutterErrorDetails(
              exception: exception,
              stack: stack,
              library: 'painting library',
              context: ErrorDescription('while building a TextSpan'),
            ));
            // Use a Unicode replacement character as a substitute for invalid text.
            builder.addText('\uFFFD');
          }
        }
        if (children != null) {
          for (final InlineSpan child in children!) {
            assert(child != null);
            child.build(
              builder, ////builder: strutStyle
              textScaleFactor: textScaleFactor,
              dimensions: dimensions,
            );
          }
        }
        if (hasStyle) {
          builder.pop();
        }
      }
    
    
        //builder.addText(text!); ////text: style传递给 style: TextSpan text属性了
      void addText(String text) {
        final String? error = _addText(text);
        if (error != null) {
          throw ArgumentError(error);
        }
      }
    
    
    //ParagraphBuilder builder
    //builder.buildui.ParagraphBuilder
    
    
      @FfiNative<Void Function(Pointer<Void>, Handle)>('ParagraphBuilder::build')
      external void _build(Paragraph outParagraph);
    
    

    style给TextSpan的text之外
    strutStyle给ui.ParagraphBuilder builder

      text.build(builder, textScaleFactor: textScaleFactor, dimensions: _placeholderDimensions);
        builder.pushStyle(style!.getTextStyle(textScaleFactor: textScaleFactor));
    
          _paragraph = builder.build();
            @FfiNative<Void Function(Pointer<Void>, Handle)>('ParagraphBuilder::build')
      external void _build(Paragraph outParagraph);
    
    

    textStyle和strutStyle

    没有什么交集了。是两个独立的东西

    2, style和defaultTextStyle,inherit

     defaultTextStyle.style.merge(style);
     // merge的意思就是 传得style如果有对应属性,就用传的,如果没有就用默认的
       TextStyle merge(TextStyle? other) {
        if (other == null) {
          return this;
        }
        if (!other.inherit) {
          return other;
        }
     
        return copyWith(
          color: other.color,
          backgroundColor: other.backgroundColor,
          fontSize: other.fontSize,
          fontWeight: other.fontWeight,
          fontStyle: other.fontStyle,
          letterSpacing: other.letterSpacing,
          wordSpacing: other.wordSpacing,
          textBaseline: other.textBaseline,
          height: other.height,
          leadingDistribution: other.leadingDistribution,
          locale: other.locale,
          foreground: other.foreground,
          background: other.background,
          shadows: other.shadows,
          fontFeatures: other.fontFeatures,
          fontVariations: other.fontVariations,
          decoration: other.decoration,
          decorationColor: other.decorationColor,
          decorationStyle: other.decorationStyle,
          decorationThickness: other.decorationThickness,
          debugLabel: mergedDebugLabel,
          fontFamily: other._fontFamily,
          fontFamilyFallback: other._fontFamilyFallback,
          package: other._package,
          overflow: other.overflow,
        );
    
    
    
    
        TextStyle copyWith({
        bool? inherit,
     
        FontStyle? fontStyle,
     
        String? fontFamily,
        List<String>? fontFamilyFallback,
     
      }) {
     
        return TextStyle(
        
    
          fontStyle: fontStyle ?? this.fontStyle,
     
          fontFamily: fontFamily ?? _fontFamily,
          fontFamilyFallback: fontFamilyFallback ?? _fontFamilyFallback,
     
        );
      }
    

    3, 结论

    textStyle和strutStyle 是两个比较独立的东西 最底层的代码flutter层看不到 对于文中前面提到的他们相同的属性fontSize,height,fontWeight,fontStyle,fontFamily,fontFamilyFallback如何使用的不清楚

    应用其他网友的实验效果:
    strutStyle对应类是StrutStyle,这个类是一个单独的文件,感觉应该挺重要
    不过这个类看得不是非常懂,貌似是使用一个字体的骨架,但不用这个字体。
    可以看出不同字体的基线是不同的,如果多种字体同时出现,未免会造成差别
    使用统一的strutStyle可以让基线统一的同时又能保持字体的不同,大概就这个意思吧

    相关文章

      网友评论

          本文标题:2024-03-07 flutter StrutStyle和Te

          本文链接:https://www.haomeiwen.com/subject/mrejzdtx.html