/** \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());
 }