Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Default text color should be theme aware",
"packageName": "react-native-windows",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4191,7 +4191,7 @@ exports[`Home UIA Tree Dump Native Perf Benchmark 1`] = `
},
"Comment": "Native Perf Benchmark",
"Offset": "0, 0, 0",
"Size": "966, 77",
"Size": "966, 78",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -4937,12 +4937,12 @@ exports[`Home UIA Tree Dump Pressable 1`] = `
},
{
"Offset": "16, 45, 0",
"Size": "934, 17",
"Size": "934, 16",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "934, 17",
"Size": "934, 16",
"Visual Type": "SpriteVisual",
},
],
Expand Down Expand Up @@ -5099,12 +5099,12 @@ exports[`Home UIA Tree Dump ScrollView 1`] = `
},
{
"Offset": "16, 45, 0",
"Size": "934, 16",
"Size": "934, 17",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "934, 16",
"Size": "934, 17",
"Visual Type": "SpriteVisual",
},
],
Expand Down Expand Up @@ -5678,7 +5678,7 @@ exports[`Home UIA Tree Dump Switch 1`] = `
},
"Comment": "Switch",
"Offset": "0, 0, 0",
"Size": "966, 78",
"Size": "966, 77",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -5759,7 +5759,7 @@ exports[`Home UIA Tree Dump Text 1`] = `
},
"Comment": "Text",
"Offset": "0, 0, 0",
"Size": "966, 77",
"Size": "966, 78",
"Visual Type": "SpriteVisual",
"__Children": [
{
Expand Down Expand Up @@ -6169,12 +6169,12 @@ exports[`Home UIA Tree Dump TransferProperties 1`] = `
"__Children": [
{
"Offset": "16, 16, 0",
"Size": "144, 25",
"Size": "144, 24",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "144, 25",
"Size": "144, 24",
"Visual Type": "SpriteVisual",
},
],
Expand Down Expand Up @@ -6331,12 +6331,12 @@ exports[`Home UIA Tree Dump TransparentHitTestExample 1`] = `
"__Children": [
{
"Offset": "16, 16, 0",
"Size": "214, 24",
"Size": "214, 25",
"Visual Type": "SpriteVisual",
"__Children": [
{
"Offset": "0, 0, 0",
"Size": "214, 24",
"Size": "214, 25",
"Visual Type": "SpriteVisual",
},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "TextAttributes.h"

#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/core/conversions.h>
#include <react/renderer/core/graphicsConversions.h>
#include <react/utils/FloatComparison.h>
#include <cmath>

#include <react/renderer/debug/debugStringConvertibleUtils.h>

namespace facebook::react {

void TextAttributes::apply(TextAttributes textAttributes) {
// Color
foregroundColor = textAttributes.foregroundColor
? textAttributes.foregroundColor
: foregroundColor;
backgroundColor = textAttributes.backgroundColor
? textAttributes.backgroundColor
: backgroundColor;
opacity =
!std::isnan(textAttributes.opacity) ? textAttributes.opacity : opacity;

// Font
fontFamily = !textAttributes.fontFamily.empty() ? textAttributes.fontFamily
: fontFamily;
fontSize =
!std::isnan(textAttributes.fontSize) ? textAttributes.fontSize : fontSize;
fontSizeMultiplier = !std::isnan(textAttributes.fontSizeMultiplier)
? textAttributes.fontSizeMultiplier
: fontSizeMultiplier;
fontWeight = textAttributes.fontWeight.has_value() ? textAttributes.fontWeight
: fontWeight;
fontStyle = textAttributes.fontStyle.has_value() ? textAttributes.fontStyle
: fontStyle;
fontVariant = textAttributes.fontVariant.has_value()
? textAttributes.fontVariant
: fontVariant;
allowFontScaling = textAttributes.allowFontScaling.has_value()
? textAttributes.allowFontScaling
: allowFontScaling;
maxFontSizeMultiplier = !std::isnan(textAttributes.maxFontSizeMultiplier)
? textAttributes.maxFontSizeMultiplier
: maxFontSizeMultiplier;
dynamicTypeRamp = textAttributes.dynamicTypeRamp.has_value()
? textAttributes.dynamicTypeRamp
: dynamicTypeRamp;
letterSpacing = !std::isnan(textAttributes.letterSpacing)
? textAttributes.letterSpacing
: letterSpacing;
textTransform = textAttributes.textTransform.has_value()
? textAttributes.textTransform
: textTransform;

// Paragraph Styles
lineHeight = !std::isnan(textAttributes.lineHeight)
? textAttributes.lineHeight
: lineHeight;
alignment = textAttributes.alignment.has_value() ? textAttributes.alignment
: alignment;
baseWritingDirection = textAttributes.baseWritingDirection.has_value()
? textAttributes.baseWritingDirection
: baseWritingDirection;
lineBreakStrategy = textAttributes.lineBreakStrategy.has_value()
? textAttributes.lineBreakStrategy
: lineBreakStrategy;
lineBreakMode = textAttributes.lineBreakMode.has_value()
? textAttributes.lineBreakMode
: lineBreakMode;

// Decoration
textDecorationColor = textAttributes.textDecorationColor
? textAttributes.textDecorationColor
: textDecorationColor;
textDecorationLineType = textAttributes.textDecorationLineType.has_value()
? textAttributes.textDecorationLineType
: textDecorationLineType;
textDecorationStyle = textAttributes.textDecorationStyle.has_value()
? textAttributes.textDecorationStyle
: textDecorationStyle;

// Shadow
textShadowOffset = textAttributes.textShadowOffset.has_value()
? textAttributes.textShadowOffset.value()
: textShadowOffset;
textShadowRadius = !std::isnan(textAttributes.textShadowRadius)
? textAttributes.textShadowRadius
: textShadowRadius;
textShadowColor = textAttributes.textShadowColor
? textAttributes.textShadowColor
: textShadowColor;

// Special
isHighlighted = textAttributes.isHighlighted.has_value()
? textAttributes.isHighlighted
: isHighlighted;
// TextAttributes "inherits" the isPressable value from ancestors, so this
// only applies the current node's value for isPressable if it is truthy.
isPressable =
textAttributes.isPressable.has_value() && *textAttributes.isPressable
? textAttributes.isPressable
: isPressable;
layoutDirection = textAttributes.layoutDirection.has_value()
? textAttributes.layoutDirection
: layoutDirection;
accessibilityRole = textAttributes.accessibilityRole.has_value()
? textAttributes.accessibilityRole
: accessibilityRole;
role = textAttributes.role.has_value() ? textAttributes.role : role;
}

#pragma mark - Operators

bool TextAttributes::operator==(const TextAttributes& rhs) const {
return std::tie(
foregroundColor,
backgroundColor,
fontFamily,
fontWeight,
fontStyle,
fontVariant,
allowFontScaling,
dynamicTypeRamp,
alignment,
baseWritingDirection,
lineBreakStrategy,
textDecorationColor,
textDecorationLineType,
textDecorationStyle,
textShadowOffset,
textShadowColor,
isHighlighted,
isPressable,
layoutDirection,
accessibilityRole,
role,
textTransform) ==
std::tie(
rhs.foregroundColor,
rhs.backgroundColor,
rhs.fontFamily,
rhs.fontWeight,
rhs.fontStyle,
rhs.fontVariant,
rhs.allowFontScaling,
rhs.dynamicTypeRamp,
rhs.alignment,
rhs.baseWritingDirection,
rhs.lineBreakStrategy,
rhs.textDecorationColor,
rhs.textDecorationLineType,
rhs.textDecorationStyle,
rhs.textShadowOffset,
rhs.textShadowColor,
rhs.isHighlighted,
rhs.isPressable,
rhs.layoutDirection,
rhs.accessibilityRole,
rhs.role,
rhs.textTransform) &&
floatEquality(maxFontSizeMultiplier, rhs.maxFontSizeMultiplier) &&
floatEquality(opacity, rhs.opacity) &&
floatEquality(fontSize, rhs.fontSize) &&
floatEquality(fontSizeMultiplier, rhs.fontSizeMultiplier) &&
floatEquality(letterSpacing, rhs.letterSpacing) &&
floatEquality(lineHeight, rhs.lineHeight) &&
floatEquality(textShadowRadius, rhs.textShadowRadius);
}

TextAttributes TextAttributes::defaultTextAttributes() {
static auto textAttributes = [] {
auto defaultAttrs = TextAttributes{};
// Non-obvious (can be different among platforms) default text attributes.
defaultAttrs.foregroundColor = facebook::react::Color { // [Windows] override default color to not be black
.m_color = {},
.m_platformColor = {"TextFillColorPrimary"},
};
defaultAttrs.backgroundColor = clearColor();
defaultAttrs.fontSize = 14.0;
defaultAttrs.fontSizeMultiplier = 1.0;
return defaultAttrs;
}();
return textAttributes;
}

#pragma mark - DebugStringConvertible

#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
const auto& textAttributes = TextAttributes::defaultTextAttributes();
return {
// Color
debugStringConvertibleItem(
"backgroundColor", backgroundColor, textAttributes.backgroundColor),
debugStringConvertibleItem(
"foregroundColor", foregroundColor, textAttributes.foregroundColor),
debugStringConvertibleItem("opacity", opacity, textAttributes.opacity),

// Font
debugStringConvertibleItem(
"fontFamily", fontFamily, textAttributes.fontFamily),
debugStringConvertibleItem("fontSize", fontSize, textAttributes.fontSize),
debugStringConvertibleItem(
"fontSizeMultiplier",
fontSizeMultiplier,
textAttributes.fontSizeMultiplier),
debugStringConvertibleItem(
"fontWeight", fontWeight, textAttributes.fontWeight),
debugStringConvertibleItem(
"fontStyle", fontStyle, textAttributes.fontStyle),
debugStringConvertibleItem(
"fontVariant", fontVariant, textAttributes.fontVariant),
debugStringConvertibleItem(
"allowFontScaling",
allowFontScaling,
textAttributes.allowFontScaling),
debugStringConvertibleItem(
"maxFontSizeMultiplier",
maxFontSizeMultiplier,
textAttributes.maxFontSizeMultiplier),
debugStringConvertibleItem(
"dynamicTypeRamp", dynamicTypeRamp, textAttributes.dynamicTypeRamp),
debugStringConvertibleItem(
"letterSpacing", letterSpacing, textAttributes.letterSpacing),

// Paragraph Styles
debugStringConvertibleItem(
"lineHeight", lineHeight, textAttributes.lineHeight),
debugStringConvertibleItem(
"alignment", alignment, textAttributes.alignment),
debugStringConvertibleItem(
"writingDirection",
baseWritingDirection,
textAttributes.baseWritingDirection),
debugStringConvertibleItem(
"lineBreakStrategyIOS",
lineBreakStrategy,
textAttributes.lineBreakStrategy),
debugStringConvertibleItem(
"lineBreakModeIOS", lineBreakMode, textAttributes.lineBreakMode),

// Decoration
debugStringConvertibleItem(
"textDecorationColor",
textDecorationColor,
textAttributes.textDecorationColor),
debugStringConvertibleItem(
"textDecorationLineType",
textDecorationLineType,
textAttributes.textDecorationLineType),
debugStringConvertibleItem(
"textDecorationStyle",
textDecorationStyle,
textAttributes.textDecorationStyle),

// Shadow
debugStringConvertibleItem(
"textShadowOffset",
textShadowOffset,
textAttributes.textShadowOffset),
debugStringConvertibleItem(
"textShadowRadius",
textShadowRadius,
textAttributes.textShadowRadius),
debugStringConvertibleItem(
"textShadowColor", textShadowColor, textAttributes.textShadowColor),

// Special
debugStringConvertibleItem(
"isHighlighted", isHighlighted, textAttributes.isHighlighted),
debugStringConvertibleItem(
"isPressable", isPressable, textAttributes.isPressable),
debugStringConvertibleItem(
"layoutDirection", layoutDirection, textAttributes.layoutDirection),
debugStringConvertibleItem(
"accessibilityRole",
accessibilityRole,
textAttributes.accessibilityRole),
debugStringConvertibleItem("role", role, textAttributes.role),
};
}
#endif

} // namespace facebook::react
Loading
Loading