/** \brief Accessor. * * This function is NOT checked. To check for the existence of a glyph, * use hasGlyph(wchar_t). * * \param idx Index to get (code). * \return Glyph specified by index or NULL. */ const Glyph& getGlyph(wchar_t idx) const { GlyphMap::const_iterator iter = m_glyphs.find(idx); if(m_glyphs.end() == iter) { // Unknown glyphs are represented by unicode symbol 'WHITE VERTICAL RECTANGLE'. return m_glyphs.find(0x25af)->second; } return iter->second; }
void SymbolLayout::prepare(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, const ImageMap& imageMap, const ImagePositions& imagePositions, const OverscaledTileID& tileID, const std::string& sourceID) { const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && layout.get<SymbolPlacement>() == SymbolPlacementType::Line; auto glyphMapIt = glyphMap.find(layout.get<TextFont>()); const Glyphs& glyphs = glyphMapIt != glyphMap.end() ? glyphMapIt->second : Glyphs(); auto glyphPositionsIt = glyphPositions.find(layout.get<TextFont>()); const GlyphPositionMap& glyphPositionMap = glyphPositionsIt != glyphPositions.end() ? glyphPositionsIt->second : GlyphPositionMap(); for (auto it = features.begin(); it != features.end(); ++it) { auto& feature = *it; if (feature.geometry.empty()) continue; std::pair<Shaping, Shaping> shapedTextOrientations; optional<PositionedIcon> shapedIcon; // if feature has text, shape the text if (feature.text) { auto applyShaping = [&] (const std::u16string& text, WritingModeType writingMode) { const float oneEm = 24.0f; const Shaping result = getShaping( /* string */ text, /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ? layout.evaluate<TextMaxWidth>(zoom, feature) * oneEm : 0, /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm, /* anchor */ layout.evaluate<TextAnchor>(zoom, feature), /* justify */ layout.evaluate<TextJustify>(zoom, feature), /* spacing: ems */ util::i18n::allowsLetterSpacing(*feature.text) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * oneEm : 0.0f, /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm), /* verticalHeight */ oneEm, /* writingMode */ writingMode, /* bidirectional algorithm object */ bidi, /* glyphs */ glyphs); return result; }; shapedTextOrientations.first = applyShaping(*feature.text, WritingModeType::Horizontal); if (util::i18n::allowsVerticalWritingMode(*feature.text) && textAlongLine) { shapedTextOrientations.second = applyShaping(util::i18n::verticalizePunctuation(*feature.text), WritingModeType::Vertical); } } // if feature has icon, get sprite atlas position if (feature.icon) { auto image = imageMap.find(*feature.icon); if (image != imageMap.end()) { shapedIcon = PositionedIcon::shapeIcon( imagePositions.at(*feature.icon), layout.evaluate<IconOffset>(zoom, feature), layout.evaluate<IconAnchor>(zoom, feature), layout.evaluate<IconRotate>(zoom, feature) * util::DEG2RAD); if (image->second->sdf) { sdfIcons = true; } if (image->second->pixelRatio != pixelRatio) { iconsNeedLinear = true; } else if (layout.get<IconRotate>().constantOr(1) != 0) { iconsNeedLinear = true; } } } // if either shapedText or icon position is present, add the feature if (shapedTextOrientations.first || shapedIcon) { addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositionMap, tileID, sourceID); } feature.geometry.clear(); } compareText.clear(); }
/** \brief Tell if this has a glyph. * * \param idx Index to get (code). * \return True if yes, false if no. */ bool hasGlyph(wchar_t idx) const { return (m_glyphs.find(idx) != m_glyphs.end()); }