Commit ea6047e9 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

implement a simple font fallback mechanism

parent ce95f3b7
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ bool font_find_fc(

ReturnCode font_find(DefaultFont font_name, FontInfo* font_info) {
  std::string font_fc;
  std::string font_file;

  switch (font_name) {
    default:
@@ -265,18 +266,20 @@ ReturnCode font_find(DefaultFont font_name, FontInfo* font_info) {
      break;
  }

  if (!font_find_fc(font_fc, &font_info->font_file)) {
  if (!font_find_fc(font_fc, &font_file)) {
    return ERROR;
  }

  if (auto rc = font_load(font_info->font_file, &font_info->font); !rc) {
  FontRef font_ref;
  if (auto rc = font_load(font_file, &font_ref); !rc) {
    return errorf(
        ERROR,
        "unble to load font '{}': {}",
        font_info->font_file,
        font_file,
        rc.message);
  }

  font_info->fonts.insert(font_info->fonts.begin(), font_ref);
  return OK;
}

@@ -312,8 +315,6 @@ ReturnCode font_find_expr(const Expr* expr, FontInfo* font_info) {
  }

  // custom font
  *font_info = FontInfo{};

  std::vector<std::string> font_names;
  std::string font_fc;
  std::string font_style_fc;
@@ -367,18 +368,23 @@ ReturnCode font_find_expr(const Expr* expr, FontInfo* font_info) {
    font_fc += ":style=" + font_style_fc;
  }

  if (!font_find_fc(font_fc, &font_info->font_file)) {
  std::string font_file;
  if (!font_find_fc(font_fc, &font_file)) {
    return errorf(ERROR, "unble to find font: {}", expr_inspect(expr));
  }

  if (auto rc = font_load(font_info->font_file, &font_info->font); !rc) {
  FontRef font_ref;
  if (auto rc = font_load(font_file, &font_ref); !rc) {
    return errorf(
        ERROR,
        "unble to load font '{}': {}",
        font_info->font_file,
        font_file,
        rc.message);
  }

  font_info->fonts.insert(font_info->fonts.begin(), font_ref);
  font_info->font_family_css.clear();

  return OK;
}

+1 −2
Original line number Diff line number Diff line
@@ -22,8 +22,7 @@ struct FontStorage;
using FontRef = std::shared_ptr<FontStorage>;

struct FontInfo {
  FontRef font;
  std::string font_file;
  std::vector<FontRef> fonts;
  std::string font_family_css;
  double font_weight_css;
};
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ Status svg_text_span_embed(
      Path gp;

      auto rc = font_get_glyph_path(
          s.font.font,
          s.font,
          op.style.font_size,
          dpi,
          g.codepoint,
+1 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ Status Rasterizer::strokePath(const layer_ops::BrushStrokeOp& op) {

Status Rasterizer::drawText(const layer_ops::TextSpanOp& op) {
  for (const auto& span : op.spans) {
    auto ft_font = static_cast<FT_Face>(font_get_freetype(span.font.font));
    auto ft_font = static_cast<FT_Face>(font_get_freetype(span.font));

    auto font_size_ft = op.style.font_size * (72.0 / dpi) * 64;
    if (FT_Set_Char_Size(ft_font, 0, font_size_ft, dpi, dpi)) {
+26 −22
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ namespace fviz {
namespace text {

struct GlyphGroup {
  FontInfo font;
  FontRef font;
  std::vector<GlyphInfo> glyphs;
};

@@ -40,34 +40,38 @@ Status text_layout_with_font_fallback(
        text.end(),
        locale_gen("en_US.UTF-8"));

  for (const auto& grapheme_str : grapheme_iter) {
    GlyphGroup grapheme;
    grapheme.font = font_info;
  for (const auto& grapheme : grapheme_iter) {
    GlyphGroup group;

    for (const auto& font : font_info.fonts) {
      group.font = font;
      group.glyphs.clear();

      auto rc = shaper->shapeText(
        grapheme_str,
        font_info,
          grapheme,
          font,
          font_size,
          dpi,
        &grapheme.glyphs);
          &group.glyphs);

      if (rc != OK) {
        return rc;
      }

      bool font_ok = true;
    for (const auto& g : grapheme.glyphs) {
      for (const auto& g : group.glyphs) {
        if (g.codepoint == 0) {
          font_ok = false;
          break;
        }
      }

    if (!font_ok) {
      continue;
      if (font_ok) {
        break;
      }
    }

    glyph_groups->emplace_back(grapheme);
    glyph_groups->emplace_back(group);
  }

  return OK;
Loading