<commit_before>#include "fontContext.h"
#define FONTSTASH_IMPLEMENTATION
#include "fontstash.h"

namespace Tangram {

#define INVALID_FONT -2
#define ATLAS_SIZE 512

FontContext::FontContext() : FontContext(ATLAS_SIZE) {}

FontContext::FontContext(int _atlasSize) {
    initFontContext(_atlasSize);
}

FontContext::~FontContext() {
    fonsDeleteInternal(m_fsContext);
}

void FontContext::bindAtlas(GLuint _textureUnit) {
    {
        std::lock_guard<std::mutex> lock(m_atlasMutex);
        m_atlas->update(_textureUnit);
    }
    m_atlas->bind(_textureUnit);
}

void FontContext::clearState() {
    fonsClearState(m_fsContext);
}

bool FontContext::lock() {
    try {
        m_contextMutex.lock();
    } catch (std::system_error& e) {
        LOGW("Dead lock: aborting");
        return false;
    }
    return true;
}

void FontContext::unlock() {
    m_contextMutex.unlock();
}

FontID FontContext::addFont(const std::string& _family, const std::string& _weight,
                            const std::string& _style, bool _tryFallback) {

    unsigned int dataSize = 0;
    unsigned char* data = nullptr;
    int font = FONS_INVALID;

    std::string fontKey = _family + "_" + _weight + "_" + _style;

    auto it = m_fonts.find(fontKey);
    if (it != m_fonts.end()) {
        if (it->second < 0) {
            goto fallback;
        }
        return it->second;
    }

    {
        // Assuming bundled ttf file follows this convention
        auto bundledFontPath = "fonts/" + _family + "-" + _weight + _style + ".ttf";
        if (!(data = bytesFromFile(bundledFontPath.c_str(), PathType::resource, &dataSize)) &&
            !(data = bytesFromFile(bundledFontPath.c_str(), PathType::internal, &dataSize))) {
            const std::string sysFontPath = systemFontPath(_family, _weight, _style);
            if ( !(data = bytesFromFile(sysFontPath.c_str(), PathType::absolute, &dataSize)) ) {
                
                LOGE("Could not load font file %s", fontKey.c_str());
                m_fonts.emplace(std::move(fontKey), INVALID_FONT);
                goto fallback;
            }
        }
    }
    font = fonsAddFont(m_fsContext, fontKey.c_str(), data, dataSize);

    if (font == FONS_INVALID) {
        LOGE("Could not load font %s", fontKey.c_str());
        m_fonts.emplace(std::move(fontKey), INVALID_FONT);
        goto fallback;
    }

    m_fonts.emplace(std::move(fontKey), font);

    return font;

fallback:
    if (_tryFallback && m_fonts.size() > 0) {
        return 0;
    }
    return INVALID_FONT;
}

void FontContext::setFont(const std::string& _key, int size) {
    FontID id = getFontID(_key);

    if (id >= 0) {
        fonsSetSize(m_fsContext, size);
        fonsSetFont(m_fsContext, id);
    } else {
        LOGW("Could not find font %s", _key.c_str());
    }
}

FontID FontContext::getFontID(const std::string& _key) {
    auto it = m_fonts.find(_key);

    if (it != m_fonts.end()) {
        return it->second;
    }

    if (m_fonts.size() > 0) {
        // sceneLoader makes sure that first loaded font is the default bundled font
        LOGW("Using default font for '%s'.", _key.c_str());
        m_fonts.emplace(_key, 0);
        return 0;
    } else {
        LOGE("No default font loaded.");
        return -1;
    }
}

std::vector<FONSquad>& FontContext::rasterize(const std::string& _text, FontID _fontID,
                                              float _fontSize, float _sdf) {

    m_quadBuffer.clear();

    fonsSetSize(m_fsContext, _fontSize);
    fonsSetFont(m_fsContext, _fontID);

    if (_sdf > 0){
        fonsSetBlur(m_fsContext, _sdf);
        fonsSetBlurType(m_fsContext, FONS_EFFECT_DISTANCE_FIELD);
    } else {
        fonsSetBlurType(m_fsContext, FONS_EFFECT_NONE);
    }

    float advance = fonsDrawText(m_fsContext, 0, 0, _text.c_str(), nullptr, 0);
    if (advance < 0) {
        m_quadBuffer.clear();
        return m_quadBuffer;
    }

    return m_quadBuffer;
}

void FontContext::pushQuad(void* _userPtr, const FONSquad* _quad) {
    FontContext* fontContext = static_cast<FontContext*>(_userPtr);
    fontContext->m_quadBuffer.emplace_back(*_quad);
}
<commit_msg>use known text length<commit_after>#include "fontContext.h"
#define FONTSTASH_IMPLEMENTATION
#include "fontstash.h"

namespace Tangram {

#define INVALID_FONT -2
#define ATLAS_SIZE 512

FontContext::FontContext() : FontContext(ATLAS_SIZE) {}

FontContext::FontContext(int _atlasSize) {
    initFontContext(_atlasSize);
}

FontContext::~FontContext() {
    fonsDeleteInternal(m_fsContext);
}

void FontContext::bindAtlas(GLuint _textureUnit) {
    {
        std::lock_guard<std::mutex> lock(m_atlasMutex);
        m_atlas->update(_textureUnit);
    }
    m_atlas->bind(_textureUnit);
}

void FontContext::clearState() {
    fonsClearState(m_fsContext);
}

bool FontContext::lock() {
    try {
        m_contextMutex.lock();
    } catch (std::system_error& e) {
        LOGW("Dead lock: aborting");
        return false;
    }
    return true;
}

void FontContext::unlock() {
    m_contextMutex.unlock();
}

FontID FontContext::addFont(const std::string& _family, const std::string& _weight,
                            const std::string& _style, bool _tryFallback) {

    unsigned int dataSize = 0;
    unsigned char* data = nullptr;
    int font = FONS_INVALID;

    std::string fontKey = _family + "_" + _weight + "_" + _style;

    auto it = m_fonts.find(fontKey);
    if (it != m_fonts.end()) {
        if (it->second < 0) {
            goto fallback;
        }
        return it->second;
    }

    {
        // Assuming bundled ttf file follows this convention
        auto bundledFontPath = "fonts/" + _family + "-" + _weight + _style + ".ttf";
        if (!(data = bytesFromFile(bundledFontPath.c_str(), PathType::resource, &dataSize)) &&
            !(data = bytesFromFile(bundledFontPath.c_str(), PathType::internal, &dataSize))) {
            const std::string sysFontPath = systemFontPath(_family, _weight, _style);
            if ( !(data = bytesFromFile(sysFontPath.c_str(), PathType::absolute, &dataSize)) ) {
                
                LOGE("Could not load font file %s", fontKey.c_str());
                m_fonts.emplace(std::move(fontKey), INVALID_FONT);
                goto fallback;
            }
        }
    }
    font = fonsAddFont(m_fsContext, fontKey.c_str(), data, dataSize);

    if (font == FONS_INVALID) {
        LOGE("Could not load font %s", fontKey.c_str());
        m_fonts.emplace(std::move(fontKey), INVALID_FONT);
        goto fallback;
    }

    m_fonts.emplace(std::move(fontKey), font);

    return font;

fallback:
    if (_tryFallback && m_fonts.size() > 0) {
        return 0;
    }
    return INVALID_FONT;
}

void FontContext::setFont(const std::string& _key, int size) {
    FontID id = getFontID(_key);

    if (id >= 0) {
        fonsSetSize(m_fsContext, size);
        fonsSetFont(m_fsContext, id);
    } else {
        LOGW("Could not find font %s", _key.c_str());
    }
}

FontID FontContext::getFontID(const std::string& _key) {
    auto it = m_fonts.find(_key);

    if (it != m_fonts.end()) {
        return it->second;
    }

    if (m_fonts.size() > 0) {
        // sceneLoader makes sure that first loaded font is the default bundled font
        LOGW("Using default font for '%s'.", _key.c_str());
        m_fonts.emplace(_key, 0);
        return 0;
    } else {
        LOGE("No default font loaded.");
        return -1;
    }
}

std::vector<FONSquad>& FontContext::rasterize(const std::string& _text, FontID _fontID,
                                              float _fontSize, float _sdf) {

    m_quadBuffer.clear();

    fonsSetSize(m_fsContext, _fontSize);
    fonsSetFont(m_fsContext, _fontID);

    if (_sdf > 0){
        fonsSetBlur(m_fsContext, _sdf);
        fonsSetBlurType(m_fsContext, FONS_EFFECT_DISTANCE_FIELD);
    } else {
        fonsSetBlurType(m_fsContext, FONS_EFFECT_NONE);
    }

    float advance = fonsDrawText(m_fsContext, 0, 0,
                                 _text.c_str(), _text.c_str() + _text.length(),
                                 0);
    if (advance < 0) {
        m_quadBuffer.clear();
        return m_quadBuffer;
    }

    return m_quadBuffer;
}

void FontContext::pushQuad(void* _userPtr, const FONSquad* _quad) {
    FontContext* fontContext = static_cast<FontContext*>(_userPtr);
    fontContext->m_quadBuffer.emplace_back(*_quad);
}

{'fraction_non_alphanumeric': 0.12891322461611712, 'fraction_numerical': 0.004285204142364004, 'mean_word_length': 2.678633975481611, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4201320', 'n_tokens_mistral': 2875, 'n_tokens_neox': 2764, 'n_words': 570}