// Copyright 2021 Google LLC. #include "experimental/sktext/include/Processor.h" #include "experimental/sktext/src/Shaper.h" namespace skia { namespace text { // TODO: calculate intrinsic sizes // Shape the text in one line bool Shaper::process() { auto text(fProcessor->fText); for (auto& block : fProcessor->fFontBlocks) { SkFont font(this->createFont(block)); SkShaper::TrivialFontRunIterator fontIter(font, text.size()); SkShaper::TrivialLanguageRunIterator langIter(text.c_str(), text.size()); std::unique_ptr bidiIter( SkShaper::MakeSkUnicodeBidiRunIterator( fProcessor->fUnicode.get(), text.c_str(), text.size(), fDefaultTextDirection == TextDirection::kLtr ? 0 : 1)); std::unique_ptr scriptIter( SkShaper::MakeSkUnicodeHbScriptRunIterator(fProcessor->fUnicode.get(), text.c_str(), text.size())); auto shaper = SkShaper::MakeShapeDontWrapOrReorder(); if (shaper == nullptr) { // For instance, loadICU does not work. We have to stop the process return false; } shaper->shape(text.c_str(), text.size(), fontIter, *bidiIter, *scriptIter, langIter, std::numeric_limits::max(), this); } return true; } void Shaper::commitRunBuffer(const RunInfo&) { fCurrentRun->commit(); fProcessor->fRuns.emplace_back(std::move(*fCurrentRun)); } SkFont Shaper::createFont(const FontBlock& block) { sk_sp typeface = matchTypeface(block.fFontFamily, block.fFontStyle); SkFont font(std::move(typeface), block.fFontSize); font.setEdging(SkFont::Edging::kAntiAlias); font.setHinting(SkFontHinting::kSlight); font.setSubpixel(true); return font; } sk_sp Shaper::matchTypeface(const SkString& fontFamily, SkFontStyle fontStyle) { sk_sp set(fFontManager->matchFamily(fontFamily.c_str())); if (!set || set->count() == 0) { return nullptr; } sk_sp match(set->matchStyle(fontStyle)); if (match) { return match; } return nullptr; } } // namespace text } // namespace skia