Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface resvg font fallback warnings #50

Open
hukka opened this issue Apr 6, 2023 · 10 comments
Open

Surface resvg font fallback warnings #50

hukka opened this issue Apr 6, 2023 · 10 comments
Labels
enhancement New feature or request

Comments

@hukka
Copy link

hukka commented Apr 6, 2023

For some reason if text with character "₂" (subscript 2) is rendered with vg2png, the whole text is rendered as bold. vg2svg and the online vega editor do not render the text like that.

For example this document

{
  "width": 500,
  "height": 500,
  "autosize": "pad",
  "marks": [
    {
      "type": "text",
      "from": {"data": "table"},
      "encode": {
        "enter": {
          "x": {"field": {"group": "width"}, "mult": 0.5},
          "radius": {"signal": "width / 2 - 10"},
          "text": {
            "signal": "datum.id"
          },
          "fill": {"value": "#000"},
          "fontSize": {"value": 20},
          "baseline": {"value": "middle"},
          "y": {"field": {"group": "width"}, "mult": 0.5},
          "theta": {"signal": "(datum.startAngle + datum.endAngle)/2"}
        }
      }
    },
    {
      "type": "arc",
      "from": {"data": "table"},
      "encode": {
        "enter": {
          "fill": {"scale": "color", "field": "id"},
          "x": {"signal": "width / 2"},
          "y": {"signal": "width / 2"}
        },
        "update": {
          "startAngle": {"field": "startAngle"},
          "endAngle": {"field": "endAngle"},
          "innerRadius": {"value": 120},
          "outerRadius": {"value": 140}
        }
      }
    }
  ],
  "scales": [
    {
      "name": "color",
      "type": "ordinal",
      "domain": {"data": "table", "field": "id"},
      "range": {"scheme": "blueorange"}
    }
  ],
  "legends": [
    {
      "fill": "color",
      "labelFontSize": 30
    }
  ],
  "$schema": "https//vega.github.io/schema/vega/v5.json",
  "data": [
    {
      "name": "table",
      "values": [
        {
          "id": "foo₂",
          "field": 4
        },
        {
          "id": "foofoo₂",
          "field": 6
        },
        {
          "id": "bar",
          "field": 10
        }
      ],
      "transform": [
        {"type": "pie", "field": "field", "sort": true},
        {
          "type": "window",
          "groupby": [],
          "ops": ["sum"],
          "fields": ["field"],
          "as": ["total"],
          "frame": [null, null]
        }
      ]
    }
  ],
  "background": "white",
  "description": "A basic donut chart example.",
  "config": {}
}

with command vl-convert vg2png --input visualization.vg.json --output test.png will render like
image

while vl-convert vg2svg --input visualization.vg.json --output test.svg like
image

@jonmmease
Copy link
Collaborator

Thanks for the report @hukka. I'm having trouble reproducing the issue though. What version of vl-convert are you using?

vl-convert --version

With current main, 0.7.0, and 0.6.0 I'm getting this PNG image (running on a M1 mac)

subscript_bold

@hukka
Copy link
Author

hukka commented Apr 6, 2023

0.7.0. This is on Linux, so the binary is of course a bit different, but does it use anything from the system for rendering?

@jonmmease
Copy link
Collaborator

The PNG rendering is handled by resvg which uses rustybuzz for text shaping. This library uses system fonts, but performs it's own text shaping.

Let's see if we can reproduce this using resvg directly and a simpler SVG. Copy this text into an SVG file named simple_subscript_bold.svg.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100" height="100">
    <rect width="100%" height="100%" fill="white" />
    <text transform="translate(10,30)" font-family="sans-serif" font-size="20px" fill="#000">foo₂</text>
    <text transform="translate(10,60)" font-family="sans-serif" font-size="20px" fill="#000">bar</text>
</svg>

Then download and extract resvg-linux-x86_64.tar.gz from https://github.com/RazrFalcon/resvg/releases/tag/v0.30.0. This should give you a CLI executable named resvg.

Convert the SVG above to PNG with:

./resvg simple_subscript_bold.svg simple_subscript_bold.png

When I do this, here's the PNG I end up with:
simple_subscript_bold

The following warning is shown by resvg:

Warning (in usvg_text_layout:1398): Fallback from Arial to Arial Unicode MS.

Do you see the bold effect in this example? We may need to play with the --sans-serif-family resvg flag to specify a particular font by name.

@hukka
Copy link
Author

hukka commented Apr 6, 2023

Indeed without the font flag, it just complains that there's no match for font family. With ./resvg --sans-serif-family "Nimbus Sans" simple_subscript_bold.svg simple_subscript_bold.png I see the bold bug, in the png, and output wans:
Warning (in usvg_text_layout:1398): Fallback from Nimbus Sans to Noto Sans Mono.

With ./resvg --sans-serif-family "DejaVu Sans" simple_subscript_bold.svg simple_subscript_bold.png there are no warnings, and no rendering bugs. So this is a a bug in the fonts themselves? Or at most resvg, but I suppose at least not in Vega.

@jonmmease
Copy link
Collaborator

If you're willing, I think it's probably worth opening an issue in the resvg repo with this example. ("Nimbus Sans" turning subscript text bold and "DejaVu Sans" not doing so).

On the vl-convert side, we vendor "Liberation Sans" as a fallback (as it matches Arial quite well), so I'm guessing that you're also seeing the issue with Liberation Sans.

@hukka
Copy link
Author

hukka commented Apr 6, 2023

Oddly fc-match "Liberation Sans" returns LiberationSans-Regular.ttf: "Liberation Sans" "Regular" but ./resvg --sans-serif-family "Liberation Sans" simple_subscript_bold.svg simple_subscript_bold.png warns Warning (in usvg_text_layout:1398): Fallback from Liberation Sans to Noto Sans Mono. .

I'll see if I can figure out why it doesn't seem to find fonts that should be there

@hukka
Copy link
Author

hukka commented Apr 6, 2023

Ah, it's of course because resvg is trying to find a bold font, and I don't have Liberation Sans bold installed (if it even exists). If I remove the subscript from the svg, it uses Liberation Sans without complaints.

@hukka
Copy link
Author

hukka commented Apr 6, 2023

Also oddly, ./resvg --sans-serif-family "Noto Sans Mono" simple_subscript_bold.svg simple_subscript_bold.png renders without warnings, and the result is not bolded. But I cannot find a bold Noto Sans Mono in the system. I'll try to look at the rendered result and try to identify what is it actually using.

@hukka
Copy link
Author

hukka commented Apr 6, 2023

Filed as linebender/resvg#609. I suppose the only thing vl-convert could do here is to show the warnings that resvg outputs.

@jonmmease jonmmease changed the title vg2png renders text with subscripts as bold Surface resvg font fallback warnings Sep 12, 2023
@jonmmease jonmmease added the enhancement New feature or request label Sep 12, 2023
@jonmmease
Copy link
Collaborator

jonmmease commented Jun 20, 2024

Font fallback was significantly revamped in #170, so we now have a place to raise a warning or exception if we want to.

See

pub fn custom_fallback_selector() -> FallbackSelectionFn<'static> {

We do currently write a warning log with the rust log crate, but turning this into a Python warning will take a bit of routing.

Related: #47

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants