Add HarfBuzz Text Shaping and Font Fallback Support (#3611)

Co-authored-by: alan wei chen <alanchenboy@gmail.com>
This commit is contained in:
Stefan Karschti
2025-07-29 23:00:27 +03:00
committed by GitHub
parent 60264349c1
commit 09d395d0db
82 changed files with 27006 additions and 151 deletions

View File

@@ -202,7 +202,8 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_,
parameters.mode,
parameters.pixelRatio,
parameters.debugOptions & MapDebugOptions::Collision,
parameters.dynamicTextureAtlas),
parameters.dynamicTextureAtlas,
parameters.glyphManager->getFontFaces()),
fileSource(parameters.fileSource),
glyphManager(parameters.glyphManager),
imageManager(parameters.imageManager),
@@ -373,10 +374,48 @@ void GeometryTile::onError(std::exception_ptr err, const uint64_t resultCorrelat
observer->onTileError(*this, std::move(err));
}
void GeometryTile::onGlyphsAvailable(GlyphMap glyphs) {
void GeometryTile::onGlyphsAvailable(GlyphMap glyphMap, [[maybe_unused]] HBShapeRequests requests) {
MLN_TRACE_FUNC();
worker.self().invoke(&GeometryTileWorker::onGlyphsAvailable, std::move(glyphs));
HBShapeResults results;
#ifdef MLN_TEXT_SHAPING_HARFBUZZ
for (auto& fontStackIT : requests) {
auto fontStack = fontStackIT.first;
auto& fontTypes = fontStackIT.second;
for (auto& typesIT : fontTypes) {
auto type = typesIT.first;
auto& strs = typesIT.second;
for (auto& str : strs) {
std::vector<GlyphID> shapedGlyphIDs;
std::shared_ptr<std::vector<HBShapeAdjust>> shapedAdjusts =
std::make_shared<std::vector<HBShapeAdjust>>();
glyphManager->hbShaping(str, fontStack, type, shapedGlyphIDs, *shapedAdjusts);
std::u16string shapedstr;
shapedstr.reserve(shapedGlyphIDs.size());
for (auto& glyphID : shapedGlyphIDs) {
shapedstr += glyphID.complex.code;
auto fontStackHash = FontStackHasher()(fontStack);
bool needShape = true;
if (glyphMap.find(fontStackHash) != glyphMap.end()) {
auto& glyphs = glyphMap[fontStackHash];
if (glyphs.find(glyphID) != glyphs.end()) needShape = false;
}
if (needShape) {
auto glyph = glyphManager->getGlyph(fontStack, glyphID);
glyphMap[fontStackHash].emplace(glyph->id, glyph);
}
}
results[fontStack][type][str] = HBShapeResult{shapedstr,
shapedAdjusts}; //.emplace(str, shapedstr, shapedAdjusts);
}
}
}
#endif // MLN_TEXT_SHAPING_HARFBUZZ
worker.self().invoke(&GeometryTileWorker::onGlyphsAvailable, std::move(glyphMap), std::move(results));
}
void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) {