Skip to content

Commit

Permalink
[Code Health] Font and TextBatch Code Cleanup (#204)
Browse files Browse the repository at this point in the history
* clean up fonts - but they're broken right now

* minor adjustments

* fix up fonts and textbatches

* make sure wii u builds

* fix points on 3ds
  • Loading branch information
TurtleP authored Sep 10, 2023
1 parent 2d37b3b commit fe7b804
Show file tree
Hide file tree
Showing 44 changed files with 1,027 additions and 3,457 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ target_sources(${PROJECT_NAME} PRIVATE
source/objects/file/file.cpp
source/objects/file/physfs/file.cpp
source/objects/file/wrap_file.cpp
source/objects/font/font.cpp
source/objects/font/wrap_font.cpp
source/objects/glyphdata/glyphdata.cpp
source/objects/glyphdata/wrap_glyphdata.cpp
Expand All @@ -426,6 +427,7 @@ target_sources(${PROJECT_NAME} PRIVATE
source/objects/source/wrap_source.cpp
source/objects/spritebatch/spritebatch.cpp
source/objects/spritebatch/wrap_spritebatch.cpp
source/objects/textbatch/textbatch.cpp
source/objects/textbatch/wrap_textbatch.cpp
source/objects/texture/wrap_texture.cpp
source/objects/thread/luathread.cpp
Expand Down
2 changes: 0 additions & 2 deletions include/modules/font/wrap_fontmodule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#include <common/luax.hpp>

#include <objects/rasterizer/wrap_rasterizer.hpp>

namespace Wrap_FontModule
{
int NewRasterizer(lua_State* L);
Expand Down
33 changes: 23 additions & 10 deletions include/modules/graphics/graphics.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
#include <modules/math/math.hpp>
#include <modules/window/window.tcc>

#include <objects/font/font.tcc>
#include <objects/shader/shader.tcc>
#include <objects/textbatch/textbatch.tcc>
#include <objects/texture/texture.tcc>

#include <objects/font/font.hpp>
#include <objects/mesh/mesh.hpp>
#include <objects/quad/quad.hpp>
#include <objects/spritebatch/spritebatch.hpp>
#include <objects/textbatch/textbatch.hpp>

#include <utilities/driver/renderer/drawcommand.tcc>

Expand Down Expand Up @@ -210,7 +210,7 @@ namespace love
RenderState::BlendState blendState = RenderState::ComputeBlendState(
RenderState::BLEND_ALPHA, RenderState::BLENDALPHA_MULTIPLY);

StrongReference<Font<Console::Which>> font;
StrongReference<Font> font;
StrongReference<Shader<Console::Which>> shader;
RenderTargetsStrongReference renderTargets;

Expand Down Expand Up @@ -386,17 +386,17 @@ namespace love

/* objects */

Font<Console::Which>* NewFont(Rasterizer<Console::Which>* data) const
Font* NewFont(Rasterizer<Console::Which>* data) const
{
return new Font<Console::Which>(data, this->states.back().defaultSamplerState);
return new Font(data, this->states.back().defaultSamplerState);
}

void SetFont(Font<Console::Which>* font)
void SetFont(Font* font)
{
this->states.back().font = font;
}

Font<Console::Which>* GetFont()
Font* GetFont()
{
return this->states.back().font;
}
Expand All @@ -406,6 +406,11 @@ namespace love
return new SpriteBatch(texture, size);
}

TextBatch* NewTextBatch(Font* font, const Font::ColoredStrings& text = {}) const
{
return new TextBatch(font, text);
}

Mesh* NewMesh(int vertexCount, vertex::PrimitiveType mode) const
{
return new Mesh(vertexCount, mode);
Expand Down Expand Up @@ -695,7 +700,7 @@ namespace love

stats.drawCalls = Renderer<>::drawCalls;
stats.textures = Texture<>::textureCount;
stats.fonts = Font<>::fontCount;
stats.fonts = Font::fontCount;
stats.shaderSwitches = Shader<>::shaderSwitches;
stats.textureMemory = Texture<>::totalGraphicsMemory;
stats.drawCallsBatched = Renderer<>::drawCallsBatched;
Expand Down Expand Up @@ -1308,10 +1313,18 @@ namespace love

void Points(std::span<Vector2> points, std::span<Color> colors)
{
if (Console::Is(Console::CTR))
{
for (const auto& point : points)
this->Circle(DRAW_FILL, point.x, point.y, this->states.back().pointSize);

return;
}

const auto& transform = this->GetTransform();
bool is2D = transform.IsAffine2DTransform();

DrawCommand<Console::Which> command(points.size(), vertex::PRIMITIVE_TRIANGLE_FAN);
DrawCommand<Console::Which> command(points.size(), vertex::PRIMITIVE_POINTS);

if (is2D)
transform.TransformXY(command.Positions().get(), points.data(), points.size());
Expand Down Expand Up @@ -1453,6 +1466,6 @@ namespace love

int renderTargetSwitchCount;

StrongReference<Font<Console::Which>> defaultFont;
StrongReference<Font> defaultFont;
};
} // namespace love
258 changes: 258 additions & 0 deletions include/objects/font/font.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
#pragma once

#include <common/color.hpp>
#include <common/console.hpp>
#include <common/exception.hpp>
#include <common/math.hpp>
#include <common/strongreference.hpp>

#include <utilities/bidirectionalmap/bidirectionalmap.hpp>

#include <utilities/driver/renderer/renderstate.hpp>
#include <utilities/driver/renderer/samplerstate.hpp>
#include <utilities/driver/renderer/vertex.hpp>

#include <objects/rasterizer_ext.hpp>
#include <objects/texture/texture.tcc>

#include <vector>

#if defined(__3DS__)
#include <citro3d.h>
using TextureHandle = C3D_Tex;
#else
using TextureHandle = love::Texture<love::Console::Which>;
#endif

namespace love
{
using StrongRasterizer = StrongReference<Rasterizer<Console::Which>>;

class Font : public Object
{
public:
static inline Type type = Type("Font", &Object::type);

using Codepoints = std::vector<uint32_t>;

enum AlignMode
{
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT,
ALIGN_JUSTIFY,
ALIGN_MAX_ENUM
};

struct ColoredString
{
std::string string;
Color color;
};

using ColoredStrings = std::vector<ColoredString>;

struct IndexedColor
{
Color color;
int index;
};

struct ColoredCodepoints
{
std::vector<uint32_t> codepoints;
std::vector<IndexedColor> colors;
};

struct TextInfo
{
int width;
int height;
};

struct Glyph
{
TextureHandle* texture;
int spacing;
std::array<vertex::Vertex, 0x06> vertices;

int sheet;
};

struct DrawCommand
{
TextureHandle* texture;
int start;
int count;

int sheet;
};

static inline int fontCount = 0;

Font(Rasterizer<Console::Which>* rasterizer, const SamplerState& state);

virtual ~Font()
{
Font::fontCount--;
}

int GetWidth(std::string_view text);

int GetWidth(uint32_t glyph);

bool HasGlyphs(std::string_view text) const;

bool HasGlyph(uint32_t glyph) const;

float GetKerning(uint32_t left, uint32_t right);

float GetKerning(std::string_view left, std::string_view right);

static void GetCodepointsFromString(std::string_view text, Codepoints& codepoints);

static void GetCodepointsFromString(const ColoredStrings& strings,
ColoredCodepoints& codepoints);

void GetWrap(const std::vector<ColoredString>& text, float wraplimit,
std::vector<std::string>& lines, std::vector<int>* line_widths = nullptr);

void GetWrap(const ColoredCodepoints& codepoints, float wraplimit,
std::vector<ColoredCodepoints>& lines, std::vector<int>* linewidths = nullptr);

void SetFallbacks(const std::vector<Font*>& fallbacks)
{}

void Print(Graphics<Console::Which>& graphics, const ColoredStrings& text,
const Matrix4<Console::Which>& localTransform, const Color& color);

void Printf(Graphics<Console::Which>& graphics, const ColoredStrings& text, float wrap,
AlignMode alignment, const Matrix4<Console::Which>& localTransform,
const Color& color);

int GetAscent() const;

int GetDescent() const;

float GetHeight() const
{
return std::floor(this->height / this->dpiScale + 0.5f);
}

uint32_t GetTextureCacheID() const
{
return this->textureCacheID;
}

float GetBaseline() const;

std::vector<DrawCommand> GenerateVertices(const ColoredCodepoints& codepoints,
const Color& color,
std::vector<vertex::Vertex>& vertices,
float extraSpacing = 0.0f, Vector2 offset = {},
TextInfo* info = nullptr);

std::vector<DrawCommand> GenerateVerticesFormatted(const ColoredCodepoints& codepoints,
const Color& color, float wrap,
AlignMode align,
std::vector<vertex::Vertex>& vertices,
TextInfo* info = nullptr);

void SetFont(Font* font);

void SetLineHeight(float height)
{
this->lineHeight = height;
}

float GetLineHeight() const
{
return this->lineHeight;
}

void SetSamplerState(const SamplerState& state);

const SamplerState& GetSamplerState() const
{
return this->samplerState;
}

float GetDPIScale() const
{
return this->dpiScale;
}

// clang-format off
static constexpr BidirectionalMap alignModes = {
"left", ALIGN_LEFT,
"center", ALIGN_CENTER,
"right", ALIGN_RIGHT,
"justify", ALIGN_JUSTIFY
};
// clang-format on

private:
struct TextureSize
{
int width;
int height;
};

static constexpr int MAX_TEXTURE_SIZE = 2048;

bool LoadVolatile();

void UnloadVolatile();

void CreateTexture();

TextureSize GetNextTextureSize() const;

GlyphData* GetRasterizerGlyphData(uint32_t glyph, float& dpiScale);

const Glyph& AddGlyph(uint32_t glyph);

const Glyph& FindGlyph(uint32_t glyph);

void Printv(Graphics<Console::Which>& graphics, const Matrix4<Console::Which>& transform,
const std::vector<DrawCommand>& drawCommands,
const std::vector<vertex::Vertex>& vertices);

int textureX;
int textureY;
int textureWidth;
int textureHeight;

int rowHeight;

uint32_t textureCacheID;

#if defined(__3DS__)
std::vector<C3D_Tex> textures;
#else
std::vector<StrongReference<Texture<Console::Which>>> textures;
#endif

std::unordered_map<uint32_t, Glyph> glyphs;
std::unordered_map<uint64_t, float> kernings;
std::vector<StrongRasterizer> rasterizers;

static constexpr auto SPACES_PER_TAB = 0x04;
static constexpr uint32_t TAB_GLYPH = 9;
static constexpr uint32_t SPACE_GLYPH = 32;

static constexpr uint32_t NEWLINE_GLYPH = 10;
static constexpr uint32_t CARRIAGE_GLYPH = 13;

static constexpr int TEXTURE_PADDING = 2;

float lineHeight;
float height;

SamplerState samplerState;
float dpiScale;
bool useSpacesAsTab;

PixelFormat format;
};
} // namespace love
Loading

0 comments on commit fe7b804

Please sign in to comment.