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

perform text shaping on a per-grapheme basis

parent 2fcbf615
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ find_package(Freetype)
find_package(HarfBuzz)
find_package(Fontconfig)
find_package(PNG)
include_directories(${CAIRO_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIRS} ${HARFBUZZ_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
find_package(Boost COMPONENTS locale REQUIRED)
include_directories(${CAIRO_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIRS} ${HARFBUZZ_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}})


# Build: fviz Library
@@ -58,7 +59,7 @@ file(GLOB source_files "core/*.cc" "core/**/*.cc" "elements/*.cc" "elements/**/*
list(REMOVE_ITEM source_files "core/cli.cc")
add_library(fviz STATIC ${source_files})
set_target_properties(fviz PROPERTIES PUBLIC_HEADER "core/fviz.h")
set(fviz_LDFLAGS fviz ${CAIRO_LIBRARIES} ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES} ${HARFBUZZ_ICU_LIBRARIES} ${PNG_LIBRARIES} ${FONTCONFIG_LIBRARIES} fmt)
set(fviz_LDFLAGS fviz ${CAIRO_LIBRARIES} ${FREETYPE_LIBRARIES} ${HARFBUZZ_LIBRARIES} ${HARFBUZZ_ICU_LIBRARIES} ${PNG_LIBRARIES} ${FONTCONFIG_LIBRARIES} ${Boost_LIBRARIES} fmt)


# Build: CLI
+65 −18
Original line number Diff line number Diff line
@@ -15,9 +15,52 @@
#include "graphics/text_layout.h"
#include "graphics/text_shaper.h"

#include <boost/locale.hpp>

namespace fviz {
namespace text {

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

Status text_layout_with_font_fallback(
    const std::string& text,
    const FontInfo& font_info,
    double font_size,
    double dpi,
    const TextShaper* shaper,
    std::vector<TextRun>* text_runs) {

  boost::locale::generator locale_gen;
  boost::locale::boundary::ssegment_index grapheme_iter(
        boost::locale::boundary::character,
        text.begin(),
        text.end(),
        locale_gen("en_US.UTF-8"));

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

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

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

    text_runs->emplace_back(grapheme);
  }

  return OK;
}

Status text_layout_ltr(
    const std::string& text,
    const FontInfo& font_info,
@@ -26,22 +69,25 @@ Status text_layout_ltr(
    const TextShaper* shaper,
    std::vector<GlyphPlacement>* glyphs,
    Rectangle* bbox) {
  std::vector<GlyphInfo> glyphs_raw;
  auto rc = shaper->shapeText(
  std::vector<TextRun> text_runs;

  auto shaping_rc = text_layout_with_font_fallback(
      text,
      font_info,
      font_size,
      dpi,
      &glyphs_raw);
      shaper,
      &text_runs);

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

  double line_length = 0.0f;
  double line_top = 0.0f;
  double line_bottom = 0.0f;
  for (const auto& gi : glyphs_raw) {
  for (const auto& r : text_runs) {
    for (const auto& gi : r.glyphs) {
      GlyphPlacement gp = {
        .codepoint = gi.codepoint,
        .x = line_length,
@@ -56,6 +102,7 @@ Status text_layout_ltr(
      line_top = std::min(-gi.metrics_ascender, line_top);
      line_bottom = std::max(-gi.metrics_descender, line_bottom);
    }
  }

  *bbox = Rectangle(
      0,
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@
  <text x="617.748636" y="461.333333" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">09:26:36</text>
  <text x="697.427926" y="461.333333" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">10:02:27</text>
  <text x="777.107216" y="461.333333" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">10:38:17</text>
  <text x="857.333333" y="461.333333" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">11:14:08</text>
  <text x="856.786458" y="461.333333" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">11:14:08</text>
  <path stroke-width="0.000000" stroke="#000000" fill="none" d="M88.5406 14.6667 L88.5406 435.6 "/>
  <path stroke-width="0.000000" stroke="#000000" fill="none" d="M88.5406 435.6 L93.874 435.6 "/>
  <path stroke-width="0.000000" stroke="#000000" fill="none" d="M88.5406 393.507 L93.874 393.507 "/>
+5 −5
Original line number Diff line number Diff line
@@ -8,12 +8,12 @@
  <path fill="#000000" d="M604 264.372 M596 264.372 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 "/>
  <path fill="#000000" d="M896.667 222.67 M888.667 222.67 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 "/>
  <path fill="#000000" d="M1189.33 226.504 M1181.33 226.504 a4 4 0 1 0 8 0 a4 4 0 1 0 -8 0 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M886.647 379.467 L1170.67 379.467 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M885.834 379.467 L1170.67 379.467 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M1170.67 379.467 L1170.67 420.933 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M886.647 420.933 L1170.67 420.933 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M886.647 379.467 L886.647 420.933 "/>
  <text x="917.446875" y="405.200000" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">Series A</text>
  <path fill="#cccccc" d="M909.014 400.2 M898.014 400.2 a5.5 5.5 0 1 0 11 0 a5.5 5.5 0 1 0 -11 0 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M885.834 420.933 L1170.67 420.933 "/>
  <path stroke-width="1.000000" stroke="#000000" fill="none" d="M885.834 379.467 L885.834 420.933 "/>
  <text x="916.634375" y="405.200000" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">Series A</text>
  <path fill="#cccccc" d="M908.201 400.2 M897.201 400.2 a5.5 5.5 0 1 0 11 0 a5.5 5.5 0 1 0 -11 0 "/>
  <text x="1002.887500" y="405.200000" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">Series B</text>
  <path fill="#888888" d="M994.454 400.2 M983.454 400.2 a5.5 5.5 0 1 0 11 0 a5.5 5.5 0 1 0 -11 0 "/>
  <text x="1089.140625" y="405.200000" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">Combined</text>
+1 −1
Original line number Diff line number Diff line
@@ -46,5 +46,5 @@
  <text x="14.666667" y="181.946673" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">09:26:36</text>
  <text x="14.666667" y="127.853327" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">10:02:27</text>
  <text x="14.666667" y="73.759981" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">10:38:17</text>
  <text x="15.760417" y="19.666667" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">11:14:08</text>
  <text x="14.666667" y="19.666667" fill="#000000" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif" font-weight="500.000000">11:14:08</text>
</svg>
 No newline at end of file
Loading