void Font::generateAsciiMap() { GlyphAtlas atlas; for (int i = 0; i < 128; i++) { atlas.addGlyphData(getGlyphDataFromChar(i)); } atlas.generate(); atlas.test(); }
void run(const std::string& url, const FontStack& fontStack, const GlyphRangeSet& glyphRanges) { // Squelch logging. Log::setObserver(std::make_unique<Log::NullObserver>()); glyphAtlas.setObserver(&observer); glyphAtlas.setURL(url); glyphAtlas.hasGlyphRanges(fontStack, glyphRanges); loop.run(); }
void TileParser::addGlyph(uint64_t tileid, const std::string stackname, const std::u32string &string, const FontStack &fontStack, GlyphAtlas &glyphAtlas, GlyphPositions &face) { const std::map<uint32_t, SDFGlyph> &sdfs = fontStack.getSDFs(); // Loop through all characters and add glyph to atlas, positions. for (uint32_t chr : string) { auto sdf_it = sdfs.find(chr); if (sdf_it != sdfs.end()) { const SDFGlyph& sdf = sdf_it->second; const Rect<uint16_t> rect = glyphAtlas.addGlyph(tileid, stackname, sdf); face.emplace(chr, Glyph{rect, sdf.metrics}); } } }
void SymbolBucket::addFeatures(const GeometryTileLayer& layer, const FilterExpression& filter, uintptr_t tileUID, SpriteAtlas& spriteAtlas, Sprite& sprite, GlyphAtlas& glyphAtlas, GlyphStore& glyphStore) { const std::vector<SymbolFeature> features = processFeatures(layer, filter, glyphStore); // Stop if we still need glyphs because the // bucket will be discarded. if (needsGlyphs()) { return; } float horizontalAlign = 0.5; float verticalAlign = 0.5; switch (layout.text.anchor) { case TextAnchorType::Top: case TextAnchorType::Bottom: case TextAnchorType::Center: break; case TextAnchorType::Right: case TextAnchorType::TopRight: case TextAnchorType::BottomRight: horizontalAlign = 1; break; case TextAnchorType::Left: case TextAnchorType::TopLeft: case TextAnchorType::BottomLeft: horizontalAlign = 0; break; } switch (layout.text.anchor) { case TextAnchorType::Left: case TextAnchorType::Right: case TextAnchorType::Center: break; case TextAnchorType::Bottom: case TextAnchorType::BottomLeft: case TextAnchorType::BottomRight: verticalAlign = 1; break; case TextAnchorType::Top: case TextAnchorType::TopLeft: case TextAnchorType::TopRight: verticalAlign = 0; break; } float justify = 0.5; if (layout.text.justify == TextJustifyType::Right) justify = 1; else if (layout.text.justify == TextJustifyType::Left) justify = 0; auto* fontStack = glyphStore.getFontStack(layout.text.font); for (const auto& feature : features) { if (!feature.geometry.size()) continue; Shaping shaping; Rect<uint16_t> image; GlyphPositions face; // if feature has text, shape the text if (feature.label.length()) { shaping = fontStack->getShaping( /* string */ feature.label, /* maxWidth: ems */ layout.placement != PlacementType::Line ? layout.text.max_width * 24 : 0, /* lineHeight: ems */ layout.text.line_height * 24, /* horizontalAlign */ horizontalAlign, /* verticalAlign */ verticalAlign, /* justify */ justify, /* spacing: ems */ layout.text.letter_spacing * 24, /* translate */ vec2<float>(layout.text.offset[0], layout.text.offset[1])); // Add the glyphs we need for this label to the glyph atlas. if (shaping.size()) { glyphAtlas.addGlyphs(tileUID, feature.label, layout.text.font, *fontStack, face); } } // if feature has icon, get sprite atlas position if (feature.sprite.length()) { image = spriteAtlas.getImage(feature.sprite, false); if (sprite.getSpritePosition(feature.sprite).sdf) { sdfIcons = true; } } // if either shaping or icon position is present, add the feature if (shaping.size() || image.hasArea()) { for (const auto& line : feature.geometry) { if (line.size()) { addFeature(line, shaping, face, image); } } } } }
void SymbolBucket::addFeatures(uintptr_t tileUID, SpriteAtlas& spriteAtlas, GlyphAtlas& glyphAtlas, GlyphStore& glyphStore) { float horizontalAlign = 0.5; float verticalAlign = 0.5; switch (layout.text.anchor) { case TextAnchorType::Top: case TextAnchorType::Bottom: case TextAnchorType::Center: break; case TextAnchorType::Right: case TextAnchorType::TopRight: case TextAnchorType::BottomRight: horizontalAlign = 1; break; case TextAnchorType::Left: case TextAnchorType::TopLeft: case TextAnchorType::BottomLeft: horizontalAlign = 0; break; } switch (layout.text.anchor) { case TextAnchorType::Left: case TextAnchorType::Right: case TextAnchorType::Center: break; case TextAnchorType::Bottom: case TextAnchorType::BottomLeft: case TextAnchorType::BottomRight: verticalAlign = 1; break; case TextAnchorType::Top: case TextAnchorType::TopLeft: case TextAnchorType::TopRight: verticalAlign = 0; break; } const float justify = layout.text.justify == TextJustifyType::Right ? 1 : layout.text.justify == TextJustifyType::Left ? 0 : 0.5; auto fontStack = glyphStore.getFontStack(layout.text.font); for (const auto& feature : features) { if (feature.geometry.empty()) continue; Shaping shapedText; PositionedIcon shapedIcon; GlyphPositions face; // if feature has text, shape the text if (feature.label.length()) { shapedText = fontStack->getShaping( /* string */ feature.label, /* maxWidth: ems */ layout.placement != PlacementType::Line ? layout.text.maxWidth * 24 : 0, /* lineHeight: ems */ layout.text.lineHeight * 24, /* horizontalAlign */ horizontalAlign, /* verticalAlign */ verticalAlign, /* justify */ justify, /* spacing: ems */ layout.text.letterSpacing * 24, /* translate */ vec2<float>(layout.text.offset.value[0], layout.text.offset.value[1])); // Add the glyphs we need for this label to the glyph atlas. if (shapedText) { glyphAtlas.addGlyphs(tileUID, feature.label, layout.text.font, **fontStack, face); } } // if feature has icon, get sprite atlas position if (feature.sprite.length()) { auto image = spriteAtlas.getImage(feature.sprite, false); if (image) { shapedIcon = shapeIcon(*image, layout); assert((*image).spriteImage); if ((*image).spriteImage->sdf) { sdfIcons = true; } if ((*image).relativePixelRatio != 1.0f) { iconsNeedLinear = true; } } } // if either shapedText or icon position is present, add the feature if (shapedText || shapedIcon) { addFeature(feature.geometry, shapedText, shapedIcon, face); } } features.clear(); }
void Glyph::CopyToAtlas(GlyphAtlas &atlas) { atlas.AddGlyph(mBuffer, mSize, mMinTexCoord, mMaxTexCoord); }