From 81af56102812e3e9f7f41672108a674f8deb17f5 Mon Sep 17 00:00:00 2001 From: TurtleP Date: Tue, 28 Nov 2023 18:15:14 -0500 Subject: [PATCH] rendering improvements and stuff Co-authored-by: Chris Feger --- .gitignore | 2 +- CMakeLists.txt | 1 + include/modules/graphics/graphics.tcc | 7 +- .../bmfontrasterizer/bmfontrasterizer.hpp | 4 +- include/objects/font/font.hpp | 79 +++++- .../imagerasterizer/imagerasterizer.hpp | 4 +- include/objects/rasterizer/rasterizer.hpp | 2 + .../truetyperasterizer/truetyperasterizer.tcc | 5 + .../{drawcommand.tcc => drawcommand.hpp} | 62 ++--- include/utilities/shaper/genericshaper.hpp | 5 +- include/utilities/shaper/textshaper.hpp | 22 +- include/utilities/temptransform.hpp | 13 +- .../include/utilities/driver/renderer_ext.hpp | 2 +- .../include/utilities/driver/renderer_ext.hpp | 11 +- .../include/utilities/driver/vertex_ext.hpp | 16 +- platform/ctr/source/objects/texture_ext.cpp | 6 +- .../source/objects/truetyperasterizer_ext.cpp | 11 + .../driver/renderer/renderer_ext.cpp | 8 +- .../include/utilities/driver/renderer_ext.hpp | 2 +- .../bmfontrasterizer/bmfontrasterizer.cpp | 9 + source/objects/font/font.cpp | 230 ++++++++++-------- .../imagerasterizer/imagerasterizer.cpp | 11 +- source/objects/mesh/mesh.cpp | 4 +- source/objects/spritebatch/spritebatch.cpp | 3 +- source/objects/textbatch/textbatch.cpp | 20 +- .../truetyperasterizer/truetyperasterizer.cpp | 4 +- .../utilities/driver/renderer/drawcommand.cpp | 11 + .../driver/renderer/polyline/polyline.cpp | 3 +- source/utilities/shaper/genericshaper.cpp | 13 +- source/utilities/shaper/textshaper.cpp | 71 ++++-- 30 files changed, 418 insertions(+), 223 deletions(-) rename include/utilities/driver/renderer/{drawcommand.tcc => drawcommand.hpp} (70%) create mode 100644 source/utilities/driver/renderer/drawcommand.cpp diff --git a/.gitignore b/.gitignore index 2f983583..bec105db 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,4 @@ test *.wuhb *.zip -debug.py \ No newline at end of file +debug.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 59cd028a..171b8022 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -510,6 +510,7 @@ target_sources(${PROJECT_NAME} PRIVATE source/utilities/decoder/types/mp3decoder.cpp source/utilities/decoder/types/vorbisdecoder.cpp source/utilities/decoder/types/wavedecoder.cpp + source/utilities/driver/renderer/drawcommand.cpp source/utilities/driver/renderer/polyline/polyline.cpp source/utilities/driver/renderer/polyline/types/beveljoin.cpp source/utilities/driver/renderer/polyline/types/miterjoin.cpp diff --git a/include/modules/graphics/graphics.tcc b/include/modules/graphics/graphics.tcc index 2fd1f722..47f7153b 100644 --- a/include/modules/graphics/graphics.tcc +++ b/include/modules/graphics/graphics.tcc @@ -22,7 +22,7 @@ #include #include -#include +#include #include @@ -1169,8 +1169,7 @@ namespace love DrawCommand command(count, vertex::PRIMITIVE_TRIANGLE_FAN); if (is2D) - transform.TransformXY(std::span(command.Positions().get(), command.count), - points); + transform.TransformXY(std::span(*command.Positions()), points); command.FillVertices(this->GetColor()); @@ -1401,7 +1400,7 @@ namespace love DrawCommand command(points.size(), vertex::PRIMITIVE_POINTS); if (is2D) - transform.TransformXY(std::span(command.Positions().get(), points.size()), points); + transform.TransformXY(std::span(*command.Positions()), points); if (colors.size() > 1) command.FillVertices(colors); diff --git a/include/objects/bmfontrasterizer/bmfontrasterizer.hpp b/include/objects/bmfontrasterizer/bmfontrasterizer.hpp index 128c0829..6ea4b92b 100644 --- a/include/objects/bmfontrasterizer/bmfontrasterizer.hpp +++ b/include/objects/bmfontrasterizer/bmfontrasterizer.hpp @@ -22,6 +22,8 @@ namespace love int GetGlyphSpacing(uint32_t glyph) const override; + int GetGlyphWidth(uint32_t glyph) const override; + int GetGlyphIndex(uint32_t glyph) const override; GlyphData* GetGlyphDataForIndex(int index) const override; @@ -62,4 +64,4 @@ namespace love bool unicode; int lineHeight; }; -} // namespace love \ No newline at end of file +} // namespace love diff --git a/include/objects/font/font.hpp b/include/objects/font/font.hpp index 131da4d5..0e37d989 100644 --- a/include/objects/font/font.hpp +++ b/include/objects/font/font.hpp @@ -54,7 +54,7 @@ namespace love int spacing; std::array vertices; - int sheet; + bool requiresDraw; }; struct DrawCommand @@ -62,8 +62,6 @@ namespace love TextureHandle* texture; int start; int count; - - int sheet; }; static inline int fontCount = 0; @@ -115,17 +113,43 @@ namespace love float GetBaseline() const; + std::vector GenerateVertices(const ColoredCodepoints& codepoints, Range range, + const Color& color, + std::span& vertices, + float extraSpacing = 0.0f, Vector2 offset = {}, + TextShaper::TextInfo* info = nullptr) + { + return RealGenerateVertices(codepoints, range, color, vertices, extraSpacing, offset, + info); + } + + std::vector GenerateVerticesFormatted(const ColoredCodepoints& codepoints, + const Color& color, float wrap, + AlignMode align, + std::span& vertices, + TextShaper::TextInfo* info = nullptr) + { + return RealGenerateVerticesFormatted(codepoints, color, wrap, align, vertices, info); + } + std::vector GenerateVertices(const ColoredCodepoints& codepoints, Range range, const Color& color, std::vector& vertices, float extraSpacing = 0.0f, Vector2 offset = {}, - TextShaper::TextInfo* info = nullptr); + TextShaper::TextInfo* info = nullptr) + { + return RealGenerateVertices(codepoints, range, color, vertices, extraSpacing, offset, + info); + } std::vector GenerateVerticesFormatted(const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, std::vector& vertices, - TextShaper::TextInfo* info = nullptr); + TextShaper::TextInfo* info = nullptr) + { + return RealGenerateVerticesFormatted(codepoints, color, wrap, align, vertices, info); + } void SetLineHeight(float height); @@ -161,6 +185,10 @@ namespace love static constexpr int MAX_TEXTURE_SIZE = 2048; + void AllocateVertices(std::span& vertices, size_t count); + + void AllocateVertices(std::vector& vertices, size_t count); + bool LoadVolatile(); void UnloadVolatile(); @@ -177,7 +205,24 @@ namespace love void Render(Graphics& graphics, const Matrix4& transform, const std::vector& drawCommands, - const std::vector& vertices); + const std::span& vertices); + + template + requires std::same_as> || + std::same_as> + std::vector RealGenerateVertices(const ColoredCodepoints& codepoints, + Range range, const Color& color, + Container& vertices, + float extraSpacing = 0.0f, + Vector2 offset = {}, + TextShaper::TextInfo* info = nullptr); + + template + requires std::same_as> || + std::same_as> + std::vector RealGenerateVerticesFormatted( + const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, + Container& vertices, TextShaper::TextInfo* info = nullptr); int textureX; int textureY; @@ -191,12 +236,12 @@ namespace love #if defined(__3DS__) std::vector textures; #else - std::vector > > textures; + std::vector>> textures; #endif StrongReference shaper; - std::map glyphs; + std::unordered_map glyphs; std::unordered_map kernings; static constexpr auto SPACES_PER_TAB = 0x04; @@ -214,4 +259,22 @@ namespace love PixelFormat format; }; + + extern template std::vector Font::RealGenerateVertices( + const ColoredCodepoints& codepoints, Range range, const Color& color, + std::span& vertices, float extraSpacing = 0.0f, Vector2 offset = {}, + TextShaper::TextInfo* info = nullptr); + + extern template std::vector Font::RealGenerateVertices( + const ColoredCodepoints& codepoints, Range range, const Color& color, + std::vector& vertices, float extraSpacing = 0.0f, Vector2 offset = {}, + TextShaper::TextInfo* info = nullptr); + + extern template std::vector Font::RealGenerateVerticesFormatted( + const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, + std::span& vertices, TextShaper::TextInfo* info = nullptr); + + extern template std::vector Font::RealGenerateVerticesFormatted( + const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, + std::vector& vertices, TextShaper::TextInfo* info = nullptr); } // namespace love diff --git a/include/objects/imagerasterizer/imagerasterizer.hpp b/include/objects/imagerasterizer/imagerasterizer.hpp index a6abf338..95c935ee 100644 --- a/include/objects/imagerasterizer/imagerasterizer.hpp +++ b/include/objects/imagerasterizer/imagerasterizer.hpp @@ -22,6 +22,8 @@ namespace love int GetGlyphSpacing(uint32_t glyph) const override; + int GetGlyphWidth(uint32_t glyph) const override; + int GetGlyphIndex(uint32_t glyph) const override; GlyphData* GetGlyphDataForIndex(int index) const override; @@ -54,4 +56,4 @@ namespace love Color32 spacer; }; -} // namespace love \ No newline at end of file +} // namespace love diff --git a/include/objects/rasterizer/rasterizer.hpp b/include/objects/rasterizer/rasterizer.hpp index 9aaef090..e0751a85 100644 --- a/include/objects/rasterizer/rasterizer.hpp +++ b/include/objects/rasterizer/rasterizer.hpp @@ -55,6 +55,8 @@ namespace love virtual int GetGlyphSpacing(uint32_t glyph) const = 0; + virtual int GetGlyphWidth(uint32_t glyph) const = 0; + virtual int GetGlyphIndex(uint32_t glyph) const = 0; GlyphData* GetGlyphData(uint32_t glyph) const; diff --git a/include/objects/truetyperasterizer/truetyperasterizer.tcc b/include/objects/truetyperasterizer/truetyperasterizer.tcc index 78d2aa6a..95ec66ff 100644 --- a/include/objects/truetyperasterizer/truetyperasterizer.tcc +++ b/include/objects/truetyperasterizer/truetyperasterizer.tcc @@ -49,6 +49,11 @@ namespace love int GetGlyphSpacing(uint32_t glyph) const override; + int GetGlyphWidth(uint32_t glyph) const override + { + return GetGlyphSpacing(glyph); + } + int GetGlyphIndex(uint32_t glyph) const override; GlyphData* GetGlyphDataForIndex(int index) const override; diff --git a/include/utilities/driver/renderer/drawcommand.tcc b/include/utilities/driver/renderer/drawcommand.hpp similarity index 70% rename from include/utilities/driver/renderer/drawcommand.tcc rename to include/utilities/driver/renderer/drawcommand.hpp index 3723a7fd..a06a5cbe 100644 --- a/include/utilities/driver/renderer/drawcommand.tcc +++ b/include/utilities/driver/renderer/drawcommand.hpp @@ -15,6 +15,7 @@ namespace love using namespace vertex; #if defined(__3DS__) + #include using Handle = C3D_Tex; #else using Handle = Texture; @@ -25,6 +26,8 @@ namespace love DrawCommand() {} + std::span AllocateVertices(size_t count); + DrawCommand(size_t count, PrimitiveType type = PRIMITIVE_TRIANGLES, Shader<>::StandardShader shader = Shader<>::STANDARD_DEFAULT) : positions {}, @@ -39,8 +42,8 @@ namespace love try { - this->positions = std::make_unique(count); - this->vertices = std::make_unique(count); + this->positions = std::vector(count); + this->vertices = AllocateVertices(count); } catch (std::bad_alloc&) { @@ -59,7 +62,7 @@ namespace love try { - this->vertices = std::make_unique(count); + this->vertices = AllocateVertices(count); } catch (std::bad_alloc&) { @@ -67,39 +70,42 @@ namespace love } } - DrawCommand Clone() + DrawCommand(std::span vertices, PrimitiveType type, + Shader<>::StandardShader shader, CommonFormat format) : + vertices(vertices), + count(vertices.size()), + size(count * VERTEX_SIZE), + format(format), + type(type), + shader(shader) { - /* init count, size, shader, and type */ - DrawCommand clone(this->count, this->type, this->shader); - clone.format = this->format; - clone.handles = this->handles; - - if (this->positions) - std::copy_n(this->Positions().get(), this->count, clone.Positions().get()); - - std::copy_n(this->Vertices().get(), this->count, clone.Vertices().get()); + if (this->count == 0) + throw love::Exception("Vertex count cannot be zero."); + } - return clone; + std::optional>& Positions() + { + return this->positions; } - const std::unique_ptr& Positions() const + const std::optional>& Positions() const { return this->positions; } - const std::span GetPositions() const + std::span GetPositions() const { - return std::span(this->positions.get(), this->count); + return this->positions ? *this->positions : std::span {}; } - const std::unique_ptr& Vertices() const + std::span Vertices() const { - return this->vertices; + return std::span(this->vertices.data(), this->vertices.size()); } - const std::span GetVertices() const + std::span Vertices() { - return std::span(this->vertices.get(), this->count); + return this->vertices; } /* primitive */ @@ -110,7 +116,7 @@ namespace love // clang-format off this->vertices[index] = { - .position = { this->positions[index].x, this->positions[index].y, 0 }, + .position = { (*this->positions)[index].x, (*this->positions)[index].y, 0 }, .color = color.array(), .texcoord = { 0.0f, 0.0f } }; @@ -126,7 +132,7 @@ namespace love // clang-format off this->vertices[index] = { - .position = { this->positions[index].x, this->positions[index].y, 0 }, + .position = { (*this->positions)[index].x, (*this->positions)[index].y, 0 }, .color = colors[index].array(), .texcoord = { 0, 0 } }; @@ -142,7 +148,7 @@ namespace love // clang-format off this->vertices[index] = { - .position = { this->positions[index].x, this->positions[index].y, 0 }, + .position = { (*this->positions)[index].x, (*this->positions)[index].y, 0 }, .color = colors[index].array(), .texcoord = { 0, 0 } }; @@ -158,7 +164,7 @@ namespace love // clang-format off this->vertices[index] = { - .position = { this->positions[index].x, this->positions[index].y, 0 }, + .position = { (*this->positions)[index].x, (*this->positions)[index].y, 0 }, .color = color.array(), .texcoord = { textureCoords[index].x, textureCoords[index].y } }; @@ -174,7 +180,7 @@ namespace love // clang-format off this->vertices[index] = { - .position = { this->positions[index].x, this->positions[index].y, 0 }, + .position = { (*this->positions)[index].x, (*this->positions)[index].y, 0 }, .color = source[index].color, .texcoord = source[index].texcoord }; @@ -183,8 +189,8 @@ namespace love } public: - std::unique_ptr positions; - std::unique_ptr vertices; + std::optional> positions; + std::span vertices; size_t count; size_t size; diff --git a/include/utilities/shaper/genericshaper.hpp b/include/utilities/shaper/genericshaper.hpp index c7aabfd6..8ca5834a 100644 --- a/include/utilities/shaper/genericshaper.hpp +++ b/include/utilities/shaper/genericshaper.hpp @@ -14,9 +14,10 @@ namespace love void ComputeGlyphPositions(const ColoredCodepoints& codepoints, Range range, Vector2 offset, float extraspacing, std::vector* positions, - std::vector* colors, TextInfo* info) override; + std::vector* colors, TextInfo* info, + size_t* drawnGlyphs) override; int ComputeWordWrapIndex(const ColoredCodepoints& codepoints, Range range, float wraplimit, float* width) override; }; -} // namespace love \ No newline at end of file +} // namespace love diff --git a/include/utilities/shaper/textshaper.hpp b/include/utilities/shaper/textshaper.hpp index 5e9270b3..bfec3d9f 100644 --- a/include/utilities/shaper/textshaper.hpp +++ b/include/utilities/shaper/textshaper.hpp @@ -107,7 +107,11 @@ namespace love float GetKerning(const std::string& left, const std::string& right); - int GetGlyphAdvance(uint32_t glyph, GlyphIndex* index = nullptr); + int GetGlyphAdvance(uint32_t glyph); + + int GetGlyphWidth(uint32_t glyph); + + GlyphIndex GetGlyphIndex(uint32_t glyph); int GetWidth(const std::string& string); @@ -122,7 +126,8 @@ namespace love virtual void ComputeGlyphPositions(const ColoredCodepoints& codepoints, Range range, Vector2 offset, float extraSpacing, std::vector* positions, - std::vector* colors, TextInfo* info) = 0; + std::vector* colors, TextInfo* info, + size_t* drawnGlyphs) = 0; virtual int ComputeWordWrapIndex(const ColoredCodepoints& codepoints, Range range, float wrapLimit, float* width) = 0; @@ -153,7 +158,16 @@ namespace love float lineHeight; bool useSpacesForTab; - std::unordered_map> glyphAdvances; + struct CachedGlyphData + { + int advance; + int width; + GlyphIndex index; + }; + + CachedGlyphData& CalcGlyphInfo(uint32_t glyph); + + std::unordered_map cachedGlyphs; std::unordered_map kernings; }; -} // namespace love \ No newline at end of file +} // namespace love diff --git a/include/utilities/temptransform.hpp b/include/utilities/temptransform.hpp index ef1a56a6..15429c6b 100644 --- a/include/utilities/temptransform.hpp +++ b/include/utilities/temptransform.hpp @@ -7,12 +7,12 @@ namespace love class TempTransform { public: - TempTransform(Graphics& graphics) : graphics(&graphics) + TempTransform(Graphics& graphics) : graphics(&graphics) { this->graphics->PushTransform(); } - TempTransform(Graphics& graphics, const Matrix4& transform) : + TempTransform(Graphics& graphics, const Matrix4& transform) : TempTransform(graphics) { this->graphics->PushTransform(); @@ -26,19 +26,12 @@ namespace love std::forward(src)); } - template - void TransformXYPure(vDst&& dst, vSrc&& src) - { - this->graphics->GetTransform().TransformXY(std::forward(dst), - std::forward(src)); - } - ~TempTransform() { this->graphics->PopTransform(); } private: - Graphics* graphics; + Graphics* graphics; }; } // namespace love diff --git a/platform/cafe/include/utilities/driver/renderer_ext.hpp b/platform/cafe/include/utilities/driver/renderer_ext.hpp index 46d3309b..d0fbad30 100644 --- a/platform/cafe/include/utilities/driver/renderer_ext.hpp +++ b/platform/cafe/include/utilities/driver/renderer_ext.hpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include #include diff --git a/platform/ctr/include/utilities/driver/renderer_ext.hpp b/platform/ctr/include/utilities/driver/renderer_ext.hpp index a684c8f2..33e6a6ef 100644 --- a/platform/ctr/include/utilities/driver/renderer_ext.hpp +++ b/platform/ctr/include/utilities/driver/renderer_ext.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include @@ -15,7 +15,7 @@ #include #include <3ds.h> -#include +#include namespace love { @@ -47,6 +47,13 @@ namespace love static void FlushVertices(); + static std::span AllocateVertices(size_t count) + { + std::span ret = std::span(m_vertices + m_vertexOffset, count); + m_vertexOffset += count; + return ret; + } + Info GetRendererInfo(); void DestroyFramebuffers(); diff --git a/platform/ctr/include/utilities/driver/vertex_ext.hpp b/platform/ctr/include/utilities/driver/vertex_ext.hpp index fc39aec5..e94f2ba8 100644 --- a/platform/ctr/include/utilities/driver/vertex_ext.hpp +++ b/platform/ctr/include/utilities/driver/vertex_ext.hpp @@ -10,17 +10,7 @@ namespace love { namespace attributes { - typedef void (*AttributeSetFunction)(void); - - enum TEXENV_MODE - { - TEXENV_MODE_PRIMITIVE, - TEXENV_MODE_TEXTURE, - TEXENV_MODE_TEXT, - TEXENV_MODE_MAX_ENUM - }; - - void SetPrimitiveAttribute() + inline void SetPrimitiveAttribute() { C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvInit(env); @@ -30,7 +20,7 @@ namespace love C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); } - void SetTextureAttribute() + inline void SetTextureAttribute() { C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvInit(env); @@ -39,7 +29,7 @@ namespace love C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); } - void SetFontAttribute() + inline void SetFontAttribute() { C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvInit(env); diff --git a/platform/ctr/source/objects/texture_ext.cpp b/platform/ctr/source/objects/texture_ext.cpp index 6d01d84a..2d45077b 100644 --- a/platform/ctr/source/objects/texture_ext.cpp +++ b/platform/ctr/source/objects/texture_ext.cpp @@ -270,8 +270,7 @@ void Texture::ReplacePixels(const void* data, size_t size, int sli C3D_TexFlush(this->texture); } -void Texture::Draw(Graphics& graphics, - const Matrix4& matrix) +void Texture::Draw(Graphics& graphics, const Matrix4& matrix) { this->Draw(graphics, this->quad, matrix); } @@ -340,7 +339,8 @@ void Texture::Draw(Graphics& graphics, Quad* quad, command.format = CommonFormat::TEXTURE; if (is2D) - translated.TransformXY(std::span(command.Positions().get(), command.count), std::span(quad->GetVertexPositions(), command.count)); + translated.TransformXY(std::span(*command.Positions()), + std::span(quad->GetVertexPositions(), command.count)); const auto* coords = quad->GetVertexTextureCoords(); command.FillVertices(graphics.GetColor(), coords); diff --git a/platform/ctr/source/objects/truetyperasterizer_ext.cpp b/platform/ctr/source/objects/truetyperasterizer_ext.cpp index d1511fa6..355d6518 100644 --- a/platform/ctr/source/objects/truetyperasterizer_ext.cpp +++ b/platform/ctr/source/objects/truetyperasterizer_ext.cpp @@ -82,6 +82,17 @@ int TrueTypeRasterizer::GetGlyphSpacing(uint32_t glyph) const return out.xAdvance; } +template<> +int TrueTypeRasterizer::GetGlyphWidth(uint32_t glyph) const +{ + fontGlyphPos_s out {}; + + int index = fontGlyphIndexFromCodePoint(this->face, glyph); + fontCalcGlyphPos(&out, this->face, index, GLYPH_POS_CALC_VTXCOORD, this->scale, this->scale); + + return out.width; +} + template<> int TrueTypeRasterizer::GetGlyphIndex(uint32_t glyph) const { diff --git a/platform/ctr/source/utilities/driver/renderer/renderer_ext.cpp b/platform/ctr/source/utilities/driver/renderer/renderer_ext.cpp index 8a705523..83f9052c 100644 --- a/platform/ctr/source/utilities/driver/renderer/renderer_ext.cpp +++ b/platform/ctr/source/utilities/driver/renderer/renderer_ext.cpp @@ -147,7 +147,6 @@ void Renderer::FlushVertices() for (const auto& command : m_commands) { - std::memcpy(m_vertices + m_vertexOffset, command.Vertices().get(), command.size); SetTexEnvFunction(command.format); if (s_primitiveType != command.type) @@ -159,8 +158,7 @@ void Renderer::FlushVertices() } ++drawCallsBatched; - C3D_DrawArrays(*s_primitive, m_vertexOffset, command.count); - m_vertexOffset += command.count; + C3D_DrawArrays(*s_primitive, command.vertices.data() - m_vertices, command.count); } m_commands.clear(); @@ -174,7 +172,7 @@ bool Renderer::Render(DrawCommand& command) if (command.handles.empty() || (this->currentTexture == command.handles.back())) { ++drawCalls; - m_commands.push_back(command.Clone()); + m_commands.push_back(std::move(command)); return true; } else @@ -190,7 +188,7 @@ bool Renderer::Render(DrawCommand& command) } ++drawCalls; - m_commands.push_back(command.Clone()); + m_commands.push_back(std::move(command)); return true; } diff --git a/platform/hac/include/utilities/driver/renderer_ext.hpp b/platform/hac/include/utilities/driver/renderer_ext.hpp index e015d35a..15b1b8ff 100644 --- a/platform/hac/include/utilities/driver/renderer_ext.hpp +++ b/platform/hac/include/utilities/driver/renderer_ext.hpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include #include diff --git a/source/objects/bmfontrasterizer/bmfontrasterizer.cpp b/source/objects/bmfontrasterizer/bmfontrasterizer.cpp index 2d0c398e..ce4ed58b 100644 --- a/source/objects/bmfontrasterizer/bmfontrasterizer.cpp +++ b/source/objects/bmfontrasterizer/bmfontrasterizer.cpp @@ -254,6 +254,15 @@ int BMFontRasterizer::GetGlyphSpacing(uint32_t glyph) const return this->characters[iterator->second].metrics.advance; } +int BMFontRasterizer::GetGlyphWidth(uint32_t glyph) const +{ + const auto iterator = this->characterIndices.find(glyph); + if (iterator == this->characterIndices.end()) + return 0; + + return this->characters[iterator->second].metrics.width; +} + int BMFontRasterizer::GetGlyphIndex(uint32_t glyph) const { const auto iterator = this->characterIndices.find(glyph); diff --git a/source/objects/font/font.cpp b/source/objects/font/font.cpp index 0305abb9..5e813310 100644 --- a/source/objects/font/font.cpp +++ b/source/objects/font/font.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -265,7 +266,8 @@ const Font::Glyph& Font::AddGlyph(TextShaper::GlyphIndex glyphIndex) float top = 0.0f; Glyph _glyph {}; - _glyph.texture = nullptr; + _glyph.texture = nullptr; + _glyph.requiresDraw = (width != 0); std::fill_n(_glyph.vertices.data(), 6, Vertex {}); @@ -350,8 +352,7 @@ const Font::Glyph& Font::AddGlyph(TextShaper::GlyphIndex glyphIndex) { const auto& sheetInfo = data->GetGlyphSheetInfo(); - _glyph.sheet = sheetInfo.index; - _glyph.texture = &this->textures[_glyph.sheet]; + _glyph.texture = &this->textures[sheetInfo.index]; left = sheetInfo.left; top = sheetInfo.top; @@ -423,8 +424,8 @@ float Font::GetKerning(const std::string& left, const std::string& right) struct PositionedGlyph { - const TextShaper::GlyphPosition* position; - const Font::Glyph* glyph; + TextShaper::GlyphPosition position; + Font::Glyph glyph; Color color; }; @@ -432,35 +433,44 @@ static bool sortGlyphs(const PositionedGlyph& left, const PositionedGlyph& right { if (Console::Is(Console::CTR)) { - const auto result = left.glyph->texture - right.glyph->texture; + const auto result = left.glyph.texture - right.glyph.texture; return result < 0; } - return left.glyph->texture < right.glyph->texture; + return left.glyph.texture < right.glyph.texture; } static inline bool isSimilarCommand(const Font::DrawCommand& previous, std::vector::iterator current) { - if (Console::Is(Console::CTR)) - return previous.sheet == current->sheet; - return previous.texture == current->texture; } -std::vector Font::GenerateVertices(const ColoredCodepoints& codepoints, - Range range, const Color& color, - std::vector& vertices, - float extraSpacing, Vector2 offset, - TextShaper::TextInfo* info) +void Font::AllocateVertices(std::span& vertices, size_t count) +{ + vertices = Renderer::AllocateVertices(count); +} + +void Font::AllocateVertices(std::vector& vertices, size_t count) +{ + vertices.clear(); + vertices.resize(count); +} +template +requires std::same_as> || std::same_as> +std::vector Font::RealGenerateVertices(const ColoredCodepoints& codepoints, + Range range, const Color& color, + Container& allVertices, + float extraSpacing, Vector2 offset, + TextShaper::TextInfo* info) { std::vector positions {}; std::vector colors {}; - this->shaper->ComputeGlyphPositions(codepoints, range, offset, extraSpacing, &positions, - &colors, info); + size_t drawnGlyphs = 0; - size_t vertexStartSize = vertices.size(); + this->shaper->ComputeGlyphPositions(codepoints, range, offset, extraSpacing, &positions, + &colors, info, &drawnGlyphs); const auto linearColor = Graphics<>::GammaCorrectColor(color); auto currentColor = linearColor; @@ -469,7 +479,7 @@ std::vector Font::GenerateVertices(const ColoredCodepoints& c int colorCount = colors.size(); std::vector glyphs {}; - glyphs.reserve(positions.size()); + glyphs.reserve(drawnGlyphs); for (int index = 0; index < (int)positions.size(); index++) { @@ -478,83 +488,82 @@ std::vector Font::GenerateVertices(const ColoredCodepoints& c const auto& glyph = this->FindGlyph(info.glyphIndex); - if (cacheId != this->textureCacheID) + if (glyph.requiresDraw) { - index = -1; - glyphs.clear(); - vertices.resize(vertexStartSize); - currentColorIndex = 0; - currentColor = color; - continue; - } + if (cacheId != this->textureCacheID) + { + index = -1; + glyphs.clear(); + currentColorIndex = 0; + currentColor = color; + continue; + } - if (currentColorIndex < colorCount && colors[currentColorIndex].index == index) - { - auto newColor = colors[currentColorIndex].color; + if (currentColorIndex < colorCount && colors[currentColorIndex].index == index) + { + auto newColor = colors[currentColorIndex].color; - newColor.r = std::clamp(newColor.r, 0.0f, 1.0f); - newColor.g = std::clamp(newColor.g, 0.0f, 1.0f); - newColor.b = std::clamp(newColor.b, 0.0f, 1.0f); - newColor.a = std::clamp(newColor.a, 0.0f, 1.0f); + newColor.r = std::clamp(newColor.r, 0.0f, 1.0f); + newColor.g = std::clamp(newColor.g, 0.0f, 1.0f); + newColor.b = std::clamp(newColor.b, 0.0f, 1.0f); + newColor.a = std::clamp(newColor.a, 0.0f, 1.0f); - Graphics<>::GammaCorrectColor(newColor); - newColor *= linearColor; - Graphics<>::UnGammaCorrectColor(newColor); + Graphics<>::GammaCorrectColor(newColor); + newColor *= linearColor; + Graphics<>::UnGammaCorrectColor(newColor); - currentColor = newColor; - currentColorIndex++; - } + currentColor = newColor; + currentColorIndex++; + } - glyphs.emplace_back(&info, &glyph, currentColor); + glyphs.emplace_back(info, glyph, currentColor); + } } std::sort(glyphs.begin(), glyphs.end(), sortGlyphs); std::vector commands {}; + if (!glyphs.empty()) + this->AllocateVertices(allVertices, glyphs.size() * glyphs[0].glyph.vertices.size()); + for (int index = 0; index < (int)glyphs.size(); index++) { - const auto& info = *glyphs[index].position; - - const auto& glyph = *glyphs[index].glyph; + const auto& info = glyphs[index].position; + const auto& glyph = glyphs[index].glyph; const auto& color = glyphs[index].color; if (glyph.texture != nullptr) { for (int j = 0; j < (int)glyph.vertices.size(); j++) { - vertices.push_back(glyph.vertices[j]); - vertices.back().position[0] += info.position.x; - vertices.back().position[1] += info.position.y; - vertices.back().color = color.array(); + allVertices[index * glyph.vertices.size() + j] = glyph.vertices[j]; + allVertices[index * glyph.vertices.size() + j].position.x += info.position.x; + allVertices[index * glyph.vertices.size() + j].position.y += info.position.y; + allVertices[index * glyph.vertices.size() + j].color = color.array(); } - // check if a glyph texture or sheet has changed since last iteration if (commands.empty() || commands.back().texture != glyph.texture) - { - DrawCommand& command = commands.emplace_back(); - command.start = (int)vertices.size() - 0x06; - command.count = 0x0; - command.texture = glyph.texture; - } + commands.emplace_back(glyph.texture, index * glyph.vertices.size(), 0); - commands.back().count += 0x06; + commands.back().count += glyph.vertices.size(); } } return commands; } -std::vector Font::GenerateVerticesFormatted( +template +requires std::same_as> || std::same_as> +std::vector Font::RealGenerateVerticesFormatted( const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, - std::vector& vertices, TextShaper::TextInfo* info) + Container& allVertices, TextShaper::TextInfo* info) { wrap = std::max(wrap, 0.0f); uint32_t cacheId = this->textureCacheID; std::vector drawCommands {}; - vertices.reserve(codepoints.cps.size() * 6); std::vector ranges {}; std::vector widths {}; @@ -612,27 +621,28 @@ std::vector Font::GenerateVerticesFormatted( } auto newCommands = - this->GenerateVertices(codepoints, range, color, vertices, extraSpacing, offset); + this->RealGenerateVertices(codepoints, range, color, allVertices, extraSpacing, offset); - if (!newCommands.empty()) - { - auto firstCommand = newCommands.begin(); + // Probably useless? + // if (!newCommands.empty()) + // { + // auto firstCommand = newCommands.begin(); - if (!drawCommands.empty()) - { - auto prevCommand = drawCommands.back(); - bool isSimilar = isSimilarCommand(prevCommand, firstCommand); + // if (!drawCommands.empty()) + // { + // auto prevCommand = drawCommands.back(); + // bool isSimilar = isSimilarCommand(prevCommand, firstCommand); - if (isSimilar && (prevCommand.start + prevCommand.count) == firstCommand->start) - { - drawCommands.back().count += firstCommand->count; - ++firstCommand; - } - } + // if (isSimilar && (prevCommand.start + prevCommand.count) == firstCommand->start) + // { + // drawCommands.back().count += firstCommand->count; + // ++firstCommand; + // } + // } - /* append new commands to the built list */ - drawCommands.insert(drawCommands.end(), firstCommand, newCommands.end()); - } + // /* append new commands to the built list */ + // drawCommands.insert(drawCommands.end(), firstCommand, newCommands.end()); + // } y += this->GetHeight() * this->GetLineHeight(); } @@ -643,45 +653,50 @@ std::vector Font::GenerateVerticesFormatted( info->height = y; } - if (cacheId != this->textureCacheID) - { - vertices.clear(); - drawCommands = this->GenerateVerticesFormatted(codepoints, color, wrap, align, vertices); - } + // Doesn't seem necessary? + // if (cacheId != this->textureCacheID) + // { + // // vertices.clear(); + // drawCommands = this->GenerateVerticesFormatted(codepoints, color, wrap, align, + // vertices); + // } return drawCommands; } -void Font::Render(Graphics<>& graphics, const Matrix4& transform, - const std::vector& drawCommands, const std::vector& vertices) +void Font::Render(Graphics<>& graphics, const Matrix4& matrix, + const std::vector& drawCommands, const std::span& vertices) { if (vertices.empty() || drawCommands.empty()) return; - Matrix4 matrix(graphics.GetTransform(), transform); + TempTransform transform(graphics, matrix); for (const auto& command : drawCommands) { /* total vertices for the quads */ - CommonFormat format = CommonFormat::TEXTURE; - if (Console::Is(Console::CTR)) - format = CommonFormat::FONT; + CommonFormat format; + Shader<>::StandardShader shader; - auto shader = Shader<>::STANDARD_TEXTURE; - if (Console::Is(Console::CTR)) + if (!Console::Is(Console::CTR)) + { + shader = Shader<>::STANDARD_TEXTURE; + format = CommonFormat::TEXTURE; + } + else + { shader = Shader<>::STANDARD_DEFAULT; + format = CommonFormat::FONT; + } - love::DrawCommand drawCommand(command.count, shader, format); - drawCommand.type = PrimitiveType::PRIMITIVE_TRIANGLES; + auto drawVertices = vertices.subspan(command.start, command.count); + love::DrawCommand drawCommand(drawVertices, PrimitiveType::PRIMITIVE_TRIANGLES, shader, + format); /* texture to use - single texture */ drawCommand.handles = { command.texture }; - const auto start = command.start; - const auto count = command.count; - - std::memcpy(drawCommand.Vertices().get(), &vertices[start], drawCommand.size); - matrix.TransformXY(drawCommand.GetVertices(), std::span(&vertices[start], count)); + transform.TransformXY(drawCommand.Vertices(), drawCommand.Vertices()); Renderer::Instance().Render(drawCommand); } @@ -693,7 +708,8 @@ void Font::Print(Graphics<>& graphics, const ColoredStrings& text, const Matrix4 ColoredCodepoints codepoints {}; love::GetCodepointsFromString(text, codepoints); - std::vector vertices {}; + std::span vertices; + auto commands = this->GenerateVertices(codepoints, Range(), color, vertices); this->Render(graphics, matrix, commands, vertices); @@ -705,7 +721,7 @@ void Font::Printf(Graphics<>& graphics, const ColoredStrings& text, float wrap, ColoredCodepoints codepoints {}; love::GetCodepointsFromString(text, codepoints); - std::vector vertices {}; + std::span vertices; auto commands = this->GenerateVerticesFormatted(codepoints, color, wrap, alignment, vertices); this->Render(graphics, matrix, commands, vertices); @@ -756,3 +772,21 @@ void Font::GetWrap(const ColoredCodepoints& codepoints, float wraplimit, std::ve { this->shaper->GetWrap(codepoints, wraplimit, ranges, linewidths); } + +template std::vector Font::RealGenerateVertices( + const ColoredCodepoints& codepoints, Range range, const Color& color, + std::span& vertices, float extraSpacing = 0.0f, Vector2 offset = {}, + TextShaper::TextInfo* info = nullptr); + +template std::vector Font::RealGenerateVertices( + const ColoredCodepoints& codepoints, Range range, const Color& color, + std::vector& vertices, float extraSpacing = 0.0f, Vector2 offset = {}, + TextShaper::TextInfo* info = nullptr); + +template std::vector Font::RealGenerateVerticesFormatted( + const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, + std::span& vertices, TextShaper::TextInfo* info = nullptr); + +template std::vector Font::RealGenerateVerticesFormatted( + const ColoredCodepoints& codepoints, const Color& color, float wrap, AlignMode align, + std::vector& vertices, TextShaper::TextInfo* info = nullptr); diff --git a/source/objects/imagerasterizer/imagerasterizer.cpp b/source/objects/imagerasterizer/imagerasterizer.cpp index 44924748..e8a28277 100644 --- a/source/objects/imagerasterizer/imagerasterizer.cpp +++ b/source/objects/imagerasterizer/imagerasterizer.cpp @@ -38,6 +38,15 @@ int ImageRasterizer::GetGlyphSpacing(uint32_t glyph) const return this->imageGlyphs[it->second].width + this->extraSpacing; } +int ImageRasterizer::GetGlyphWidth(uint32_t glyph) const +{ + auto it = this->glyphIndicies.find(glyph); + if (it == this->glyphIndicies.end()) + return 0; + + return this->imageGlyphs[it->second].width; +} + int ImageRasterizer::GetGlyphIndex(uint32_t glyph) const { auto it = this->glyphIndicies.find(glyph); @@ -156,4 +165,4 @@ Rasterizer::DataType ImageRasterizer::GetDataType() const TextShaper* ImageRasterizer::NewTextShaper() { return new GenericShaper(this); -} \ No newline at end of file +} diff --git a/source/objects/mesh/mesh.cpp b/source/objects/mesh/mesh.cpp index c59bee90..ccd62a62 100644 --- a/source/objects/mesh/mesh.cpp +++ b/source/objects/mesh/mesh.cpp @@ -206,8 +206,8 @@ void Mesh::DrawInternal(Graphics& graphics, const Matrix4& matri DrawCommand command(_range.getSize(), this->mode); command.FillVertices(this->buffer.data()); - transform.TransformXYPure(std::span(command.vertices.get(), command.count), - std::span(&this->buffer[_range.getOffset()], command.count)); + transform.TransformXY(command.Vertices(), + std::span(&this->buffer[_range.getOffset()], command.count)); if (this->texture.Get()) { diff --git a/source/objects/spritebatch/spritebatch.cpp b/source/objects/spritebatch/spritebatch.cpp index faaf1d67..293c6ca3 100644 --- a/source/objects/spritebatch/spritebatch.cpp +++ b/source/objects/spritebatch/spritebatch.cpp @@ -254,8 +254,7 @@ void SpriteBatch::Draw(Graphics& graphics, const Matrix4& matrix command.handles = { this->texture }; #endif - transform.TransformXYPure(std::span(command.vertices.get(), command.count), - std::span(&this->buffer[start], command.count)); + transform.TransformXY(command.Vertices(), std::span(&this->buffer[start], command.count)); for (size_t index = 0; index < command.count; index++) { command.vertices[index].texcoord = this->buffer[start * 0x06 + index].texcoord; diff --git a/source/objects/textbatch/textbatch.cpp b/source/objects/textbatch/textbatch.cpp index b6e347d3..4ec11c3c 100644 --- a/source/objects/textbatch/textbatch.cpp +++ b/source/objects/textbatch/textbatch.cpp @@ -200,17 +200,9 @@ void TextBatch::Draw(Graphics& graphics, const Matrix4& matrix) if (Shader::IsDefaultActive()) Shader::AttachDefault(Shader<>::STANDARD_DEFAULT); - TextureHandle* firstTexture = nullptr; - if (!this->drawCommands.empty()) - firstTexture = this->drawCommands[0].texture; - if (this->font->GetTextureCacheID() != this->textureCacheId) this->RegenerateVertices(); - int totalVertices = 0; - for (const auto& command : drawCommands) - totalVertices = std::max(command.start + command.count, totalVertices); - TempTransform transform(graphics, matrix); for (const auto& command : drawCommands) @@ -227,10 +219,16 @@ void TextBatch::Draw(Graphics& graphics, const Matrix4& matrix) drawCommand.handles = { command.texture }; - transform.TransformXY(std::span(drawCommand.Positions().get(), command.count), - std::span(&this->buffer[command.start], command.count)); + std::copy(this->buffer.begin() + command.start, + this->buffer.begin() + command.start + command.count, + drawCommand.Vertices().begin()); + + transform.TransformXY(drawCommand.Vertices(), drawCommand.Vertices()); + + // transform.TransformXY(std::span(*drawCommand.Positions()), + // std::span(&this->buffer[command.start], command.count)); - drawCommand.FillVertices(&this->buffer[command.start]); + // drawCommand.FillVertices(&this->buffer[command.start]); Renderer::Instance().Render(drawCommand); } } diff --git a/source/objects/truetyperasterizer/truetyperasterizer.cpp b/source/objects/truetyperasterizer/truetyperasterizer.cpp index 99a82962..2fc16ebc 100644 --- a/source/objects/truetyperasterizer/truetyperasterizer.cpp +++ b/source/objects/truetyperasterizer/truetyperasterizer.cpp @@ -9,7 +9,7 @@ using namespace love; // clang-format off -static constexpr BidirectionalMap loadOptions = +static constexpr BidirectionalMap loadOptions = { TrueTypeRasterizer<>::HINTING_NORMAL, FT_LOAD_TARGET_NORMAL, TrueTypeRasterizer<>::HINTING_LIGHT, FT_LOAD_TARGET_LIGHT, @@ -234,4 +234,4 @@ bool TrueTypeRasterizer::Accepts(FT_Library library, Data* data) FT_Long fsize = (FT_Long)data->GetSize(); return FT_New_Memory_Face(library, fbase, fsize, -1, nullptr) == 0; -} \ No newline at end of file +} diff --git a/source/utilities/driver/renderer/drawcommand.cpp b/source/utilities/driver/renderer/drawcommand.cpp new file mode 100644 index 00000000..7d4372bd --- /dev/null +++ b/source/utilities/driver/renderer/drawcommand.cpp @@ -0,0 +1,11 @@ +#include + +#include + +namespace love +{ + std::span DrawCommand::AllocateVertices(size_t count) + { + return Renderer::AllocateVertices(count); + } +} // namespace love diff --git a/source/utilities/driver/renderer/polyline/polyline.cpp b/source/utilities/driver/renderer/polyline/polyline.cpp index 4e08c2da..ab6b4a18 100644 --- a/source/utilities/driver/renderer/polyline/polyline.cpp +++ b/source/utilities/driver/renderer/polyline/polyline.cpp @@ -195,8 +195,7 @@ void Polyline::draw(Graphics* gfx) DrawCommand command(totalVertices, mode); if (is2D) - t.TransformXY(std::span(command.Positions().get(), totalVertices), - std::span(verts, totalVertices)); + t.TransformXY(std::span(*command.Positions()), std::span(verts, totalVertices)); Color colordata[totalVertices] {}; diff --git a/source/utilities/shaper/genericshaper.cpp b/source/utilities/shaper/genericshaper.cpp index 82635f23..e74cd0aa 100644 --- a/source/utilities/shaper/genericshaper.cpp +++ b/source/utilities/shaper/genericshaper.cpp @@ -12,7 +12,8 @@ GenericShaper::GenericShaper(Rasterizer* rasterizer) : TextShaper(rasterizer) void GenericShaper::ComputeGlyphPositions(const ColoredCodepoints& codepoints, Range range, Vector2 offset, float spacing, std::vector* positions, - std::vector* colors, TextInfo* info) + std::vector* colors, TextInfo* info, + size_t* drawnGlyphs) { if (!range.isValid()) range = Range(0, codepoints.cps.size()); @@ -84,8 +85,14 @@ void GenericShaper::ComputeGlyphPositions(const ColoredCodepoints& codepoints, R currentPosition.x += this->GetKerning(previousGlyph, glyph); - GlyphIndex glyphIndex {}; - int advance = this->GetGlyphAdvance(glyph, &glyphIndex); + int advance = this->GetGlyphAdvance(glyph); + int width = this->GetGlyphWidth(glyph); + GlyphIndex glyphIndex = this->GetGlyphIndex(glyph); + + if (width != 0 && drawnGlyphs) + { + (*drawnGlyphs)++; + } if (positions) { diff --git a/source/utilities/shaper/textshaper.cpp b/source/utilities/shaper/textshaper.cpp index 501286fa..cb11b2e8 100644 --- a/source/utilities/shaper/textshaper.cpp +++ b/source/utilities/shaper/textshaper.cpp @@ -188,18 +188,8 @@ float TextShaper::GetKerning(const std::string& left, const std::string& right) return this->GetKerning(leftGlyph, rightGlyph); } -int TextShaper::GetGlyphAdvance(uint32_t glyph, GlyphIndex* glyphIndex) +TextShaper::CachedGlyphData& TextShaper::CalcGlyphInfo(uint32_t glyph) { - const auto iterator = this->glyphAdvances.find(glyph); - - if (iterator != this->glyphAdvances.end()) - { - if (glyphIndex) - *glyphIndex = iterator->second.second; - - return iterator->second.first; - } - int rasterizerIndex = 0; uint32_t realGlyph = glyph; @@ -217,19 +207,64 @@ int TextShaper::GetGlyphAdvance(uint32_t glyph, GlyphIndex* glyphIndex) const auto& rasterizer = this->rasterizers[rasterizerIndex]; const auto spacing = rasterizer->GetGlyphSpacing(realGlyph); + const auto rawWidth = rasterizer->GetGlyphWidth(realGlyph); int advance = std::floor(spacing / rasterizer->GetDPIScale() + 0.5f); + int width = std::floor(width / rasterizer->GetDPIScale() + 0.5f); if (glyph == '\t' && realGlyph == ' ') advance *= TextShaper::SPACES_PER_TAB; - GlyphIndex _glyphIndex = { rasterizer->GetGlyphIndex(realGlyph), rasterizerIndex }; - this->glyphAdvances[glyph] = std::make_pair(advance, _glyphIndex); + return this->cachedGlyphs + .emplace(glyph, + CachedGlyphData { + .advance = advance, + .width = width, + .index = {rasterizer->GetGlyphIndex(realGlyph), rasterizerIndex} + }) + .first->second; +} + +int TextShaper::GetGlyphAdvance(uint32_t glyph) +{ + const auto iterator = this->cachedGlyphs.find(glyph); + + if (iterator != this->cachedGlyphs.end()) + { + return iterator->second.advance; + } + else + { + return CalcGlyphInfo(glyph).advance; + } +} + +int TextShaper::GetGlyphWidth(uint32_t glyph) +{ + const auto iterator = this->cachedGlyphs.find(glyph); - if (glyphIndex) - *glyphIndex = _glyphIndex; + if (iterator != this->cachedGlyphs.end()) + { + return iterator->second.width; + } + else + { + return CalcGlyphInfo(glyph).width; + } +} - return advance; +TextShaper::GlyphIndex TextShaper::GetGlyphIndex(uint32_t glyph) +{ + const auto iterator = this->cachedGlyphs.find(glyph); + + if (iterator != this->cachedGlyphs.end()) + { + return iterator->second.index; + } + else + { + return CalcGlyphInfo(glyph).index; + } } int TextShaper::GetWidth(const std::string& string) @@ -242,7 +277,7 @@ int TextShaper::GetWidth(const std::string& string) TextInfo info {}; this->ComputeGlyphPositions(codepoints, Range(), Vector2(0.0f, 0.0f), 0.0f, nullptr, nullptr, - &info); + &info, nullptr); return info.width; } @@ -346,7 +381,7 @@ void TextShaper::SetFallbacks(const std::vector& fallbacks) throw love::Exception("Font fallbacks must be of the same font type."); this->kernings.clear(); - this->glyphAdvances.clear(); + this->cachedGlyphs.clear(); this->rasterizers.resize(1); this->dpiScales.resize(1);