Esempio n. 1
0
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();
    }
Esempio n. 3
0
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);
                }
            }
        }
    }
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
void Glyph::CopyToAtlas(GlyphAtlas &atlas)
{
	atlas.AddGlyph(mBuffer, mSize, mMinTexCoord, mMaxTexCoord);
}