react-native-svg icon indicating copy to clipboard operation
react-native-svg copied to clipboard

Unicode Emojis are rendered at fixed size, causing blurry rendering if the SVG is small

Open TPXP opened this issue 2 months ago • 5 comments

Description

Hi all 👋 — first, thank you so much for this awesome open-source project ❤️. react-native-svg is a great tool and I deeply appreciate the work put into it.

🐛 Bug description

When rendering emojis (or other glyphs) inside a <Text> component, they become blurry or pixelated if the rendered size on screen is larger than the Text's font size.

It seems the emoji is rasterized based on the font size and then upscaled, rather than being rendered at the actual rendering resolution.

🔍 Possible root cause / suspicious code area

I believe the code in charge of emoji rendering was introduced in PR #746 (“Implement basic support for unicode emoji”) on this repo. I'm not sure if the code has changed much since, but I'm guessing the issue is somewhere in these files.

The heuristic or logic there may inadvertently constrain the rendering resolution to the fontSize of the text element or some fallback internal canvas size, causing upscaling artifacts when the displayed size is larger.

⚙️ Workaround

Scaling up all dimensions in the SVG file (using viewBox) seems to cause the Text to render natively at a higher resolution, fixing the issue. Unfortunately this is very tedious to do on the complex SVG files I'm given 😓

🧪 Reproduction

I’ve prepared a minimal reproduction here: https://gist.github.com/TPXP/a2595d2f2f85c4524f470fc343787450

It shows 2 SVG: the one on the left has a smaller viewbox, while the right one has a larger viewbox and all dimensions multiplied by 10. As you can see, the right one looks less blurry.

Image

Steps to reproduce

  1. Create an SVG with a small viewbox, add text containing emojis in it.
  2. Render the emoji at a size much bigger than its viewbox
  3. Emoji looks blurry 😢
  4. Try to multiply all dimensions in the SVG by 10, use save rendering sizes
  5. Emoji looks better 😄 (it may still look a little blurry because iOS emojis are raster images but you get the idea)

Snack or a link to a repository

https://gist.github.com/TPXP/a2595d2f2f85c4524f470fc343787450

SVG version

15.12.0

React Native version

0.79.3

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Paper (Old Architecture)

Build type

Debug app & dev bundle

Device

iOS simulator

Device model

Screenshot for the issue comes from an iPad (10th generation simulator) running iPadOS 18.5. I'm seeing the same issue on an actual iPad device

Acknowledgements

Yes

TPXP avatar Sep 26 '25 12:09 TPXP

That bot needs support for gists 😛 https://github.com/software-mansion-labs/swmansion-bot/pull/7

TPXP avatar Sep 26 '25 12:09 TPXP

Hi @TPXP, Thanks for reporting!

I've created PR #2785, which should resolve your issue. Could you test it and let me know if it works for you?

kacperzolkiewski avatar Sep 29 '25 12:09 kacperzolkiewski

Hey @kacperzolkiewski , thanks for your reply and for working on this! Your patch does work on my reproduction, yet I'm seeing another issue on another SVG of my app - the emojis don't render where they should (positions seem flipped horizontally)! Also they don't fit well between text characters - I've updated the gist.

Test code
const Test3 = () => (
  <Svg
    width={500}
    height={500}
    viewBox={`0 0 50 50`}>
    <Path fill={'#fff'} d="M0 0h360v180H0z" />
    <Text
      x={10}
      y={40}
      textAnchor="middle"
      fontSize={3}
      fill={'#000'}
      fontWeight={'bold'}>
      {'>>>🥳X🥳<'}
    </Text>
    <Text
      x={40}
      y={10}
      textAnchor="middle"
      fontSize={3}
      fill={'#000'}
      fontWeight={'bold'}>
      {'X😊<<<'}
    </Text>
  </Svg>
);

The emojis don't render between the other characters somehow 🤔

Image

TPXP avatar Oct 01 '25 22:10 TPXP

Hi @TPXP,

Thanks for testing my solution. There was indeed an issue with emoji positioning but I’ve updated my PR and it should now be fixed. I’d really appreciate it if you could test it again and let me know how it behaves.

kacperzolkiewski avatar Oct 02 '25 12:10 kacperzolkiewski

Looking better indeed, I confirm the updated PR works well!

TPXP avatar Oct 12 '25 20:10 TPXP