From f8c9221afea4516c0719ebfac8d7853ae01e405f Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 23 Sep 2024 19:29:05 -0300 Subject: [PATCH] Add way to disable ligatures when shaping text Related to: https://github.com/aseprite/aseprite/issues/4679 --- examples/text_shape.cpp | 5 ++++- text/skia_text_blob.h | 3 ++- text/skia_text_blob_shaper.cpp | 11 ++++++++++- text/text_blob.h | 8 +++++++- text/text_blob_shaper.cpp | 6 ++++-- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/examples/text_shape.cpp b/examples/text_shape.cpp index ce1289020..448425ad9 100644 --- a/examples/text_shape.cpp +++ b/examples/text_shape.cpp @@ -63,8 +63,11 @@ struct TextEdit { } void makeBlob(FontMgrRef& fontMgr, FontRef& font) { + // Create a blob without ligatures (to edit char by char) BoxBuilder handler; - blob = TextBlob::MakeWithShaper(fontMgr, font, text, &handler); + TextBlob::ShaperFeatures features; + features.ligatures = false; + blob = TextBlob::MakeWithShaper(fontMgr, font, text, &handler, features); boxes = handler.boxes(); } }; diff --git a/text/skia_text_blob.h b/text/skia_text_blob.h index a53a7abd7..7bd179fc1 100644 --- a/text/skia_text_blob.h +++ b/text/skia_text_blob.h @@ -32,7 +32,8 @@ class SkiaTextBlob : public TextBlob { const FontMgrRef& fontMgr, const FontRef& font, const std::string& text, - TextBlob::RunHandler* handler); + TextBlob::RunHandler* handler, + const TextBlob::ShaperFeatures features); private: sk_sp m_skTextBlob; diff --git a/text/skia_text_blob_shaper.cpp b/text/skia_text_blob_shaper.cpp index 19bb56404..cc7c72204 100644 --- a/text/skia_text_blob_shaper.cpp +++ b/text/skia_text_blob_shaper.cpp @@ -23,6 +23,7 @@ #include "modules/skshaper/include/SkShaper.h" #include +#include namespace text { @@ -125,7 +126,8 @@ TextBlobRef SkiaTextBlob::MakeWithShaper( const FontMgrRef& fontMgr, const FontRef& font, const std::string& text, - TextBlob::RunHandler* handler) + TextBlob::RunHandler* handler, + const TextBlob::ShaperFeatures features) { ASSERT(font); ASSERT(font->type() == FontType::Native); @@ -150,12 +152,19 @@ TextBlobRef SkiaTextBlob::MakeWithShaper( SkFontStyle::Normal(), &*languageRun); + std::vector ft; + if (!features.ligatures) { + ft.emplace_back(SkShaper::Feature{ + SkSetFourByteTag('l', 'i', 'g', 'a'), 0, 0, text.size() }); + } + shaper->shape(text.c_str(), text.size(), *fontRun, *bidiRun, *scriptRun, *languageRun, + ft.data(), ft.size(), std::numeric_limits::max(), &shaperHandler); diff --git a/text/text_blob.h b/text/text_blob.h index bbffd0ac3..12a45e18c 100644 --- a/text/text_blob.h +++ b/text/text_blob.h @@ -57,6 +57,11 @@ namespace text { gfx::RectF getGlyphBounds(size_t i) const; }; + struct ShaperFeatures { + bool ligatures = true; + ShaperFeatures() { } + }; + class RunHandler { public: virtual ~RunHandler() = default; @@ -94,7 +99,8 @@ namespace text { const FontMgrRef& fontMgr, const FontRef& font, const std::string& text, - RunHandler* handler = nullptr); + RunHandler* handler = nullptr, + const ShaperFeatures features = {}); private: gfx::RectF m_bounds; diff --git a/text/text_blob_shaper.cpp b/text/text_blob_shaper.cpp index f33553748..60adecb65 100644 --- a/text/text_blob_shaper.cpp +++ b/text/text_blob_shaper.cpp @@ -23,7 +23,8 @@ TextBlobRef TextBlob::MakeWithShaper( const FontMgrRef& fontMgr, const FontRef& font, const std::string& text, - TextBlob::RunHandler* handler) + TextBlob::RunHandler* handler, + const TextBlob::ShaperFeatures features) { ASSERT(font); switch (font->type()) { @@ -37,7 +38,8 @@ TextBlobRef TextBlob::MakeWithShaper( #if LAF_SKIA case FontType::Native: - return SkiaTextBlob::MakeWithShaper(fontMgr, font, text, handler); + return SkiaTextBlob::MakeWithShaper( + fontMgr, font, text, handler, features); #endif default: