duskmoon314 / typst-fontawesome

A Typst library for Font Awesome icons through the desktop fonts.
https://typst.app/universe/package/fontawesome
MIT License
12 stars 0 forks source link

Text-based lookup does not seem to work #5

Closed kaimast closed 1 week ago

kaimast commented 3 months ago

The following works fine #fa-envelope. But#fa-icon("envelope") just renders the text envelope. Similarly, #fa-icon("github", fa-set: "Brands") does not work but #fa-github(fa-set: "Brands") does.

Is that expected behavior? If so, the README migth be outdated.

I am on Arch linux with typst 0.11 and Font Awesome 6 installed from pacman. I use "@preview/fontawesome:0.1.0" to import this package. Happy to help debug this.

duskmoon314 commented 3 months ago

That is not the expected behavior. Please provide your typst code and the output pdf (an image capture is enough) to help me reproduce this problem.

fa-icon uses Font Awesome's ligature feature to render icons; in some circumstances, this cannot work (typst/typst#2578). But your problem seems different.

jeslinmx commented 1 month ago

image

I am able to reproduce this with typst 0.11.1 running on NixOS (nixpkgs 63143ac2c9186be6d9da6035fa22620018c85932).

duskmoon314 commented 1 month ago

I might find out why the ligature is not working in v0.2.0.

Currently, the implementation of fa-icon is:

#let fa-icon(
  /// The name of the icon.
  ///
  /// This can be used with the ligature feature or the unicode of the glyph.
  name,

  /// Whether the icon is solid or not.
  solid: false,

  ..args
) = {
  text(
    font: (
      "Font Awesome 6 Free" + if solid { " Solid" },
      "Font Awesome 6 Brands",
    ),
    weight: if solid { 900 } else { 400 },
    name,
    ..args
  )
}

Thus, #fa-icon("facebook") first tries Font Awesome 6 Free and renders FACEBOOK. The icon is rendered correctly if we specify the font to Font Awesome 6 Brands (#fa-icon("facebook", font: "Font Awesome 6 Brands"))

I need to figure out how to fix this. Helps needed.

duskmoon314 commented 1 month ago

One solution could be to rely on something other than ligatures, like using many if-else blocks to render the correct icon...

jeslinmx commented 1 month ago

image Seems to also occur on non-brands icons as well though...

duskmoon314 commented 1 month ago

Seems to also occur on non-brands icons as well though...

Does #fa-chess-queen() render a square in your pdf? This doesn't seem correct. It should be an icon.

jeslinmx commented 1 month ago

Indeed it does. Today it instead renders as some sort of Cambodian (?) character: image

Which makes no sense at all, especially since I'm running NixOS - I would know when stuff changes in my environment...

duskmoon314 commented 1 month ago

I think the latest image shows that typst used its font fallback mechanism and rendered an incorrect glyph.

Could you provide the output of typst fonts | grep Awesome to check whether typst can find FontAwesome fonts on your machine?

It should be something like:

$ typst fonts | grep Awesome
Font Awesome 6 Brands
Font Awesome 6 Free
Font Awesome 6 Free Solid
jeslinmx commented 1 month ago

Thanks! I realized I did, in fact, change something in my environment: $TYPST_FONT_PATHS. After unsetting it, the square chess queen is back. image

Doesn't seem that any FA fonts have been picked up by typst, but somehow it's rendering the Brands icons fine. 2 different non-brands icons render different incorrect symbols.

Based on that, I tried it again with fallback disabled, and no icons render. So it seems that it's indeed the case that typst is simply not picking up on any FA font, but that doesn't explain where the Brands icons are coming from... image

duskmoon314 commented 1 month ago

I assume the icons come from some nerd fonts that integrated several font awesome's glyphs.

Typst looks up fonts in the system directory and custom path. Could you set up the fonts, make sure that typst can find them, and try again?

jeslinmx commented 1 month ago

...I didn't notice the package doesn't magically bring along the font 🤦‍♂️. That's what I get for not paying attention to the README. It works for me now! Thanks for catching that the glyphs came from Nerd Fonts, I was wondering why my facebook icon looked different from the default FA one.

Sorry @kaimast , not sure if I ended up hijacking your thread for an unrelated but similar-presenting issue.

duskmoon314 commented 1 month ago

Thus, #fa-icon("facebook") first tries Font Awesome 6 Free and renders FACEBOOK. The icon is rendered correctly if we specify the font to Font Awesome 6 Brands (#fa-icon("facebook", font: "Font Awesome 6 Brands"))

I need to figure out how to fix this. Helps needed.

I have an idea of how to fix this and want to hear some feedback:

  1. We impl the fa-icon like this:

    #let fa-icon(
    name,
    solid: false,
    fa-icon-map: (:),
    ..args,
    ) = {
    text(
    font: (
      "Font Awesome 6 Free" + if solid { " Solid" },
      "Font Awesome 6 Brands",
    ),
    weight: if solid { 900 } else { 400 },
    
    // If the name is in the map, use the Unicode from the map
    // If not, pass the name and let the ligature feature handle it
    fa-icon-map.at(name, default: name),
    
    ..args,
    )
    }
  2. Then we generate a big map fa-icon-map from the metadata
  3. We export fa-icon as fa-icon.with(fa-icon-map: fa-icon-map)

In this way, the icon name is first looked up in the map. If it is found, the Unicode is used and should render the correct glyph. If it is not in the map, it is passed to text, and ligature is used.

I think this should solve the problem @kaimast met and might partially solve the problem mentioned in #2.

tomowang commented 2 weeks ago

After upgrade to 0.2.1 version (https://github.com/tomowang/typst-twentysecondcv/commit/1c6cec159ec579d92825e5c65b3345682cc071dd), now I can just use the fa-icon("chess-queen") version and it works fine.

This fix seems to bypass the ligature issue mentioned in https://github.com/typst/typst/issues/2578.

duskmoon314 commented 1 week ago

I haven't heard of any similar problem for three weeks. I assume this issue is fixed for Free and Brand sets.

Close for now.