Skip to content

Commit

Permalink
content: Use emoji font to show emoji nodes
Browse files Browse the repository at this point in the history
For emoji like ❤ U+2764 HEAVY BLACK HEART, this causes us to show a
colorful, larger glyph like ❤️ from the emoji font, instead of a glyph
like ❤︎ that comes from a plain-text font and has the color and size
of plain text.

Fixes: zulip#1104
  • Loading branch information
gnprice committed Dec 6, 2024
1 parent 9391867 commit f7421bf
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
15 changes: 14 additions & 1 deletion lib/widgets/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
textStylePlainParagraph: _plainParagraphCommon(context).copyWith(
color: const HSLColor.fromAHSL(1, 0, 0, 0.15).toColor(),
debugLabel: 'ContentTheme.textStylePlainParagraph'),
textStyleEmoji: TextStyle(
fontFamily: emojiFontFamily, fontFamilyFallback: const []),
codeBlockTextStyles: CodeBlockTextStyles.light(context),
textStyleError: const TextStyle(fontSize: kBaseFontSize, color: Colors.red)
.merge(weightVariableTextStyle(context, wght: 700)),
Expand Down Expand Up @@ -85,6 +87,8 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
textStylePlainParagraph: _plainParagraphCommon(context).copyWith(
color: const HSLColor.fromAHSL(1, 0, 0, 0.85).toColor(),
debugLabel: 'ContentTheme.textStylePlainParagraph'),
textStyleEmoji: TextStyle(
fontFamily: emojiFontFamily, fontFamilyFallback: const []),
codeBlockTextStyles: CodeBlockTextStyles.dark(context),
textStyleError: const TextStyle(fontSize: kBaseFontSize, color: Colors.red)
.merge(weightVariableTextStyle(context, wght: 700)),
Expand Down Expand Up @@ -113,6 +117,7 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
required this.colorTableHeaderBackground,
required this.colorThematicBreak,
required this.textStylePlainParagraph,
required this.textStyleEmoji,
required this.codeBlockTextStyles,
required this.textStyleError,
required this.textStyleErrorCode,
Expand Down Expand Up @@ -152,6 +157,9 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
/// should not need styles from other sources, such as Material defaults.
final TextStyle textStylePlainParagraph;

/// The [TextStyle] to use for Unicode emoji.
final TextStyle textStyleEmoji;

final CodeBlockTextStyles codeBlockTextStyles;
final TextStyle textStyleError;
final TextStyle textStyleErrorCode;
Expand Down Expand Up @@ -201,6 +209,7 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
Color? colorTableHeaderBackground,
Color? colorThematicBreak,
TextStyle? textStylePlainParagraph,
TextStyle? textStyleEmoji,
CodeBlockTextStyles? codeBlockTextStyles,
TextStyle? textStyleError,
TextStyle? textStyleErrorCode,
Expand All @@ -222,6 +231,7 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
colorTableHeaderBackground: colorTableHeaderBackground ?? this.colorTableHeaderBackground,
colorThematicBreak: colorThematicBreak ?? this.colorThematicBreak,
textStylePlainParagraph: textStylePlainParagraph ?? this.textStylePlainParagraph,
textStyleEmoji: textStyleEmoji ?? this.textStyleEmoji,
codeBlockTextStyles: codeBlockTextStyles ?? this.codeBlockTextStyles,
textStyleError: textStyleError ?? this.textStyleError,
textStyleErrorCode: textStyleErrorCode ?? this.textStyleErrorCode,
Expand Down Expand Up @@ -250,6 +260,7 @@ class ContentTheme extends ThemeExtension<ContentTheme> {
colorTableHeaderBackground: Color.lerp(colorTableHeaderBackground, other.colorTableHeaderBackground, t)!,
colorThematicBreak: Color.lerp(colorThematicBreak, other.colorThematicBreak, t)!,
textStylePlainParagraph: TextStyle.lerp(textStylePlainParagraph, other.textStylePlainParagraph, t)!,
textStyleEmoji: TextStyle.lerp(textStyleEmoji, other.textStyleEmoji, t)!,
codeBlockTextStyles: CodeBlockTextStyles.lerp(codeBlockTextStyles, other.codeBlockTextStyles, t),
textStyleError: TextStyle.lerp(textStyleError, other.textStyleError, t)!,
textStyleErrorCode: TextStyle.lerp(textStyleErrorCode, other.textStyleErrorCode, t)!,
Expand Down Expand Up @@ -1031,7 +1042,9 @@ class _InlineContentBuilder {
child: UserMention(ambientTextStyle: widget.style, node: node));

case UnicodeEmojiNode():
return TextSpan(text: node.emojiUnicode, recognizer: _recognizer);
return TextSpan(text: node.emojiUnicode, recognizer: _recognizer,
style: widget.style
.merge(ContentTheme.of(_context!).textStyleEmoji));

case ImageEmojiNode():
return WidgetSpan(alignment: PlaceholderAlignment.middle,
Expand Down
6 changes: 5 additions & 1 deletion lib/widgets/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,13 @@ const kDefaultFontFamily = 'Source Sans 3';

/// The [TextStyle.fontFamilyFallback] for use with [kDefaultFontFamily].
List<String> get defaultFontFamilyFallback => [
_useAppleEmoji ? 'Apple Color Emoji' : 'Noto Color Emoji',
emojiFontFamily,
];

String get emojiFontFamily {
return _useAppleEmoji ? 'Apple Color Emoji' : 'Noto Color Emoji';
}

/// Whether to use the Apple Color Emoji font for showing emoji.
///
/// When false, we use Noto Color Emoji instead.
Expand Down
13 changes: 13 additions & 0 deletions test/widgets/content_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,19 @@ void main() {
testContentSmoke(ContentExample.emojiUnicode);
testContentSmoke(ContentExample.emojiUnicodeMultiCodepoint);
testContentSmoke(ContentExample.emojiUnicodeLiteral);

testWidgets('use emoji font', (tester) async {
// Compare [ContentExample.emojiUnicode].
const emojiHeartHtml =
'<p><span aria-label="heart" class="emoji emoji-2764" role="img" title="heart">:heart:</span></p>';
await prepareContent(tester, plainContent(emojiHeartHtml));
check(mergedStyleOf(tester, '\u{2764}')).isNotNull()
.fontFamily.equals(switch (defaultTargetPlatform) {
TargetPlatform.android => 'Noto Color Emoji',
TargetPlatform.iOS => 'Apple Color Emoji',
_ => throw StateError('unexpected platform in test'),
});
}, variant: const TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS}));
});

group('inline math', () {
Expand Down

0 comments on commit f7421bf

Please sign in to comment.