<commit_before>// Copyright 2015-2019 <NAME>. All rights reserved.

#include <cassert>
#include <stdexcept>
#include "TTFont.hpp"
#include "core/Engine.hpp"
#include "utils/Utf8.hpp"
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

namespace ouzel
{
    namespace gui
    {
        TTFont::TTFont(const std::vector<uint8_t>& initData, bool initMipmaps):
            data(initData),
            mipmaps(initMipmaps)
        {
            const int offset = stbtt_GetFontOffsetForIndex(data.data(), 0);

            if (offset == -1)
                throw std::runtime_error("Not a font");

            font = std::make_unique<stbtt_fontinfo>();

            if (!stbtt_InitFont(font.get(), data.data(), offset))
                throw std::runtime_error("Failed to load font");
        }

        Font::RenderData TTFont::getRenderData(const std::string& text,
                                               Color color,
                                               float fontSize,
                                               const Vector2F& anchor) const
        {
            if (!font)
                throw std::runtime_error("Font not loaded");

            static constexpr uint32_t SPACING = 2;

            struct CharDescriptor final
            {
                uint16_t x = 0;
                uint16_t y = 0;
                uint16_t width = 0;
                uint16_t height = 0;
                Vector2F offset;
                float advance = 0;
                std::vector<uint8_t> bitmap;
            };

            std::unordered_map<uint32_t, CharDescriptor> chars;

            const float s = stbtt_ScaleForPixelHeight(font.get(), fontSize);

            const std::u32string utf32Text = utf8::toUtf32(text);

            std::set<char32_t> glyphs;
            for (const char32_t i : utf32Text)
                glyphs.insert(i);

            uint16_t width = 0;
            uint16_t height = 0;

            int ascent;
            int descent;
            int lineGap;
            stbtt_GetFontVMetrics(font.get(), &ascent, &descent, &lineGap);

            for (const char32_t c : glyphs)
            {
                int w;
                int h;
                int xoff;
                int yoff;

                if (const int index = stbtt_FindGlyphIndex(font.get(), static_cast<int>(c)))
                {
                    int advance;
                    int leftBearing;
                    stbtt_GetGlyphHMetrics(font.get(), index, &advance, &leftBearing);

                    CharDescriptor charDesc;

                    if (unsigned char* bitmap = stbtt_GetGlyphBitmapSubpixel(font.get(), s, s, 0.0F, 0.0F, index, &w, &h, &xoff, &yoff))
                    {
                        charDesc.width = static_cast<uint16_t>(w);
                        charDesc.height = static_cast<uint16_t>(h);
                        charDesc.offset.v[0] = static_cast<float>(leftBearing * s);
                        charDesc.offset.v[1] = static_cast<float>(yoff + (ascent - descent) * s);
                        charDesc.bitmap = std::vector<uint8_t>(bitmap, bitmap + h * w);
                        charDesc.x = width;

                        width += static_cast<uint16_t>(w);
                        height = height > static_cast<uint16_t>(h) ? height : static_cast<uint16_t>(h);

                        stbtt_FreeBitmap(bitmap, nullptr);
                    }

                    charDesc.advance = static_cast<float>(advance * s);

                    if (!chars.empty())
                        width += SPACING;

                    chars[c] = charDesc;
                }
            }

            std::vector<uint8_t> textureData(width * height * 4);

            for (uint16_t posX = 0; posX < width; ++posX)
            {
                for (uint16_t posY = 0; posY < height; ++posY)
                {
                    textureData[(posY * width + posX) * 4 + 0] = 255;
                    textureData[(posY * width + posX) * 4 + 1] = 255;
                    textureData[(posY * width + posX) * 4 + 2] = 255;
                    textureData[(posY * width + posX) * 4 + 3] = 0;
                }
            }

            for (const auto& c : chars)
            {
                const CharDescriptor& charDesc = c.second;

                for (uint16_t posX = 0; posX < charDesc.width; ++posX)
                {
                    for (uint16_t posY = 0; posY < charDesc.height; ++posY)
                    {
                        textureData[(posY * width + posX + charDesc.x) * 4 + 0] = 255;
                        textureData[(posY * width + posX + charDesc.x) * 4 + 1] = 255;
                        textureData[(posY * width + posX + charDesc.x) * 4 + 2] = 255;
                        textureData[(posY * width + posX + charDesc.x) * 4 + 3] = charDesc.bitmap[posY * charDesc.width + posX];
                    }
                }
            }

            RenderData result;

            auto texture = std::make_shared<graphics::Texture>(*engine->getRenderer(),
                                                               textureData,
                                                               Size2U(width, height), 0,
                                                               mipmaps ? 0 : 1);

            Vector2F position;

            std::vector<uint16_t> indices;
            std::vector<graphics::Vertex> vertices;
            indices.reserve(utf32Text.size() * 6);
            vertices.reserve(utf32Text.size() * 4);

            Vector2F textCoords[4];

            size_t firstChar = 0;

            for (auto i = utf32Text.begin(); i != utf32Text.end(); ++i)
            {
                auto iter = chars.find(*i);

                if (iter != chars.end())
                {
                    const CharDescriptor& f = iter->second;

                    auto startIndex = static_cast<uint16_t>(vertices.size());
                    indices.push_back(startIndex + 0);
                    indices.push_back(startIndex + 1);
                    indices.push_back(startIndex + 2);

                    indices.push_back(startIndex + 1);
                    indices.push_back(startIndex + 3);
                    indices.push_back(startIndex + 2);

                    Vector2F leftTop(f.x / static_cast<float>(width),
                                     f.y / static_cast<float>(height));

                    Vector2F rightBottom((f.x + f.width) / static_cast<float>(width),
                                         (f.y + f.height) / static_cast<float>(height));

                    textCoords[0] = Vector2F(leftTop.v[0], rightBottom.v[1]);
                    textCoords[1] = Vector2F(rightBottom.v[0], rightBottom.v[1]);
                    textCoords[2] = Vector2F(leftTop.v[0], leftTop.v[1]);
                    textCoords[3] = Vector2F(rightBottom.v[0], leftTop.v[1]);

                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0], -position.v[1] - f.offset.v[1] - f.height, 0.0F},
                                          color, textCoords[0], Vector3F{0.0F, 0.0F, -1.0F});
                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0] + f.width, -position.v[1] - f.offset.v[1] - f.height, 0.0F},
                                          color, textCoords[1], Vector3F{0.0F, 0.0F, -1.0F});
                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0], -position.v[1] - f.offset.v[1], 0.0F},
                                          color, textCoords[2], Vector3F{0.0F, 0.0F, -1.0F});
                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0] + f.width, -position.v[1] - f.offset.v[1], 0.0F},
                                          color, textCoords[3], Vector3F{0.0F, 0.0F, -1.0F});

                    if ((i + 1) != utf32Text.end())
                    {
                        const int kernAdvance = stbtt_GetCodepointKernAdvance(font.get(),
                                                                              static_cast<int>(*i),
                                                                              static_cast<int>(*(i + 1)));
                        position.v[0] += static_cast<float>(kernAdvance) * s;
                    }

                    position.v[0] += f.advance;
                }

                if (*i == static_cast<uint32_t>('\n') || // line feed
                    (i + 1) == utf32Text.end()) // end of string
                {
                    const float lineWidth = position.v[0];
                    position.v[0] = 0.0F;
                    position.v[1] += fontSize + lineGap;

                    for (size_t c = firstChar; c < vertices.size(); ++c)
                        vertices[c].position.v[0] -= lineWidth * anchor.v[0];

                    firstChar = vertices.size();
                }
            }

            const float textHeight = position.v[1];

            for (graphics::Vertex& vertex : vertices)
                vertex.position.v[1] += textHeight * (1.0F - anchor.v[1]);

            return std::make_tuple(std::move(indices), std::move(vertices), std::move(texture));
        }
    } // namespace gui
} // namespace ouzel
<commit_msg>Disable -Wold-style-cast for stb_truetype.h<commit_after>// Copyright 2015-2019 <NAME>. All rights reserved.

#include <cassert>
#include <stdexcept>
#include "TTFont.hpp"
#include "core/Engine.hpp"
#include "utils/Utf8.hpp"

#if defined(__GNUC__)
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wold-style-cast"
#endif

#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

#if defined(__GNUC__)
#  pragma GCC diagnostic pop
#endif

namespace ouzel
{
    namespace gui
    {
        TTFont::TTFont(const std::vector<uint8_t>& initData, bool initMipmaps):
            data(initData),
            mipmaps(initMipmaps)
        {
            const int offset = stbtt_GetFontOffsetForIndex(data.data(), 0);

            if (offset == -1)
                throw std::runtime_error("Not a font");

            font = std::make_unique<stbtt_fontinfo>();

            if (!stbtt_InitFont(font.get(), data.data(), offset))
                throw std::runtime_error("Failed to load font");
        }

        Font::RenderData TTFont::getRenderData(const std::string& text,
                                               Color color,
                                               float fontSize,
                                               const Vector2F& anchor) const
        {
            if (!font)
                throw std::runtime_error("Font not loaded");

            static constexpr uint32_t SPACING = 2;

            struct CharDescriptor final
            {
                uint16_t x = 0;
                uint16_t y = 0;
                uint16_t width = 0;
                uint16_t height = 0;
                Vector2F offset;
                float advance = 0;
                std::vector<uint8_t> bitmap;
            };

            std::unordered_map<uint32_t, CharDescriptor> chars;

            const float s = stbtt_ScaleForPixelHeight(font.get(), fontSize);

            const std::u32string utf32Text = utf8::toUtf32(text);

            std::set<char32_t> glyphs;
            for (const char32_t i : utf32Text)
                glyphs.insert(i);

            uint16_t width = 0;
            uint16_t height = 0;

            int ascent;
            int descent;
            int lineGap;
            stbtt_GetFontVMetrics(font.get(), &ascent, &descent, &lineGap);

            for (const char32_t c : glyphs)
            {
                int w;
                int h;
                int xoff;
                int yoff;

                if (const int index = stbtt_FindGlyphIndex(font.get(), static_cast<int>(c)))
                {
                    int advance;
                    int leftBearing;
                    stbtt_GetGlyphHMetrics(font.get(), index, &advance, &leftBearing);

                    CharDescriptor charDesc;

                    if (unsigned char* bitmap = stbtt_GetGlyphBitmapSubpixel(font.get(), s, s, 0.0F, 0.0F, index, &w, &h, &xoff, &yoff))
                    {
                        charDesc.width = static_cast<uint16_t>(w);
                        charDesc.height = static_cast<uint16_t>(h);
                        charDesc.offset.v[0] = static_cast<float>(leftBearing * s);
                        charDesc.offset.v[1] = static_cast<float>(yoff + (ascent - descent) * s);
                        charDesc.bitmap = std::vector<uint8_t>(bitmap, bitmap + h * w);
                        charDesc.x = width;

                        width += static_cast<uint16_t>(w);
                        height = height > static_cast<uint16_t>(h) ? height : static_cast<uint16_t>(h);

                        stbtt_FreeBitmap(bitmap, nullptr);
                    }

                    charDesc.advance = static_cast<float>(advance * s);

                    if (!chars.empty())
                        width += SPACING;

                    chars[c] = charDesc;
                }
            }

            std::vector<uint8_t> textureData(width * height * 4);

            for (uint16_t posX = 0; posX < width; ++posX)
            {
                for (uint16_t posY = 0; posY < height; ++posY)
                {
                    textureData[(posY * width + posX) * 4 + 0] = 255;
                    textureData[(posY * width + posX) * 4 + 1] = 255;
                    textureData[(posY * width + posX) * 4 + 2] = 255;
                    textureData[(posY * width + posX) * 4 + 3] = 0;
                }
            }

            for (const auto& c : chars)
            {
                const CharDescriptor& charDesc = c.second;

                for (uint16_t posX = 0; posX < charDesc.width; ++posX)
                {
                    for (uint16_t posY = 0; posY < charDesc.height; ++posY)
                    {
                        textureData[(posY * width + posX + charDesc.x) * 4 + 0] = 255;
                        textureData[(posY * width + posX + charDesc.x) * 4 + 1] = 255;
                        textureData[(posY * width + posX + charDesc.x) * 4 + 2] = 255;
                        textureData[(posY * width + posX + charDesc.x) * 4 + 3] = charDesc.bitmap[posY * charDesc.width + posX];
                    }
                }
            }

            RenderData result;

            auto texture = std::make_shared<graphics::Texture>(*engine->getRenderer(),
                                                               textureData,
                                                               Size2U(width, height), 0,
                                                               mipmaps ? 0 : 1);

            Vector2F position;

            std::vector<uint16_t> indices;
            std::vector<graphics::Vertex> vertices;
            indices.reserve(utf32Text.size() * 6);
            vertices.reserve(utf32Text.size() * 4);

            Vector2F textCoords[4];

            size_t firstChar = 0;

            for (auto i = utf32Text.begin(); i != utf32Text.end(); ++i)
            {
                auto iter = chars.find(*i);

                if (iter != chars.end())
                {
                    const CharDescriptor& f = iter->second;

                    auto startIndex = static_cast<uint16_t>(vertices.size());
                    indices.push_back(startIndex + 0);
                    indices.push_back(startIndex + 1);
                    indices.push_back(startIndex + 2);

                    indices.push_back(startIndex + 1);
                    indices.push_back(startIndex + 3);
                    indices.push_back(startIndex + 2);

                    Vector2F leftTop(f.x / static_cast<float>(width),
                                     f.y / static_cast<float>(height));

                    Vector2F rightBottom((f.x + f.width) / static_cast<float>(width),
                                         (f.y + f.height) / static_cast<float>(height));

                    textCoords[0] = Vector2F(leftTop.v[0], rightBottom.v[1]);
                    textCoords[1] = Vector2F(rightBottom.v[0], rightBottom.v[1]);
                    textCoords[2] = Vector2F(leftTop.v[0], leftTop.v[1]);
                    textCoords[3] = Vector2F(rightBottom.v[0], leftTop.v[1]);

                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0], -position.v[1] - f.offset.v[1] - f.height, 0.0F},
                                          color, textCoords[0], Vector3F{0.0F, 0.0F, -1.0F});
                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0] + f.width, -position.v[1] - f.offset.v[1] - f.height, 0.0F},
                                          color, textCoords[1], Vector3F{0.0F, 0.0F, -1.0F});
                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0], -position.v[1] - f.offset.v[1], 0.0F},
                                          color, textCoords[2], Vector3F{0.0F, 0.0F, -1.0F});
                    vertices.emplace_back(Vector3F{position.v[0] + f.offset.v[0] + f.width, -position.v[1] - f.offset.v[1], 0.0F},
                                          color, textCoords[3], Vector3F{0.0F, 0.0F, -1.0F});

                    if ((i + 1) != utf32Text.end())
                    {
                        const int kernAdvance = stbtt_GetCodepointKernAdvance(font.get(),
                                                                              static_cast<int>(*i),
                                                                              static_cast<int>(*(i + 1)));
                        position.v[0] += static_cast<float>(kernAdvance) * s;
                    }

                    position.v[0] += f.advance;
                }

                if (*i == static_cast<uint32_t>('\n') || // line feed
                    (i + 1) == utf32Text.end()) // end of string
                {
                    const float lineWidth = position.v[0];
                    position.v[0] = 0.0F;
                    position.v[1] += fontSize + lineGap;

                    for (size_t c = firstChar; c < vertices.size(); ++c)
                        vertices[c].position.v[0] -= lineWidth * anchor.v[0];

                    firstChar = vertices.size();
                }
            }

            const float textHeight = position.v[1];

            for (graphics::Vertex& vertex : vertices)
                vertex.position.v[1] += textHeight * (1.0F - anchor.v[1]);

            return std::make_tuple(std::move(indices), std::move(vertices), std::move(texture));
        }
    } // namespace gui
} // namespace ouzel

{'fraction_non_alphanumeric': 0.11803841613907072, 'fraction_numerical': 0.02671960510784419, 'mean_word_length': 1.252991659615617, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 60, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6303393', 'n_tokens_mistral': 5652, 'n_tokens_neox': 5142, 'n_words': 1034}