Moved poker code to main dawn code.
This commit is contained in:
9
src/dawn/display/font/CMakeLists.txt
Normal file
9
src/dawn/display/font/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
TrueTypeTexture.cpp
|
||||
)
|
16
src/dawn/display/font/TrueTypeCharacter.hpp
Normal file
16
src/dawn/display/font/TrueTypeCharacter.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct TrueTypeCharacter {
|
||||
glm::vec2 advance;
|
||||
glm::vec2 size;
|
||||
glm::vec2 offset;
|
||||
glm::vec4 quad;
|
||||
};
|
||||
}
|
198
src/dawn/display/font/TrueTypeTexture.cpp
Normal file
198
src/dawn/display/font/TrueTypeTexture.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TrueTypeTexture.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "util/Math.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TrueTypeTexture::TrueTypeTexture(const uint32_t fontSize) :
|
||||
fontSize(fontSize)
|
||||
{
|
||||
assertTrue(fontSize > 0, "Font size cannot be zero");
|
||||
texture = std::make_shared<Texture>();
|
||||
}
|
||||
|
||||
void TrueTypeTexture::setFace(const FT_Face face) {
|
||||
this->face = face;
|
||||
assertTrue(fontSize < 256, "Font size cannot be greater than 256");
|
||||
|
||||
// Set freetype font size prior to baking.
|
||||
auto ret = FT_Set_Pixel_Sizes(face, 0, fontSize);
|
||||
if(ret != 0) {
|
||||
assertUnreachable("Failed to set font size %i", ret);
|
||||
}
|
||||
|
||||
// Set the texture size
|
||||
texture->setSize(
|
||||
fontSize * 24,
|
||||
fontSize * 24,
|
||||
TextureFormat::R,
|
||||
TextureDataFormat::UNSIGNED_BYTE
|
||||
);
|
||||
|
||||
// Texture buffer
|
||||
uint8_t *buffer = new uint8_t[texture->getWidth() * texture->getHeight()];
|
||||
// Fill with zeros
|
||||
std::memset(buffer, 0, texture->getWidth() * texture->getHeight());
|
||||
|
||||
size_t offset = 0;
|
||||
struct TrueTypeCharacter info;
|
||||
int32_t textureX = 0, textureY = 0;
|
||||
int32_t rowHeight = 0;
|
||||
|
||||
// Character sets
|
||||
std::vector<wchar_t> characterBlocks;
|
||||
// Latin
|
||||
for(wchar_t c = 0x0020; c < 0x007F; c++) characterBlocks.push_back(c);
|
||||
// Latin-1 Supplement
|
||||
for(wchar_t c = 0x00A0; c < 0x00FF; c++) characterBlocks.push_back(c);
|
||||
// Latin Extended-A
|
||||
for(wchar_t c = 0x0100; c < 0x017F; c++) characterBlocks.push_back(c);
|
||||
// Latin Extended-B
|
||||
for(wchar_t c = 0x0180; c < 0x024F; c++) characterBlocks.push_back(c);
|
||||
// Hiragana
|
||||
for(wchar_t c = 0x3040; c < 0x309F; c++) characterBlocks.push_back(c);
|
||||
// Katakana
|
||||
for(wchar_t c = 0x30A0; c < 0x30FF; c++) characterBlocks.push_back(c);
|
||||
|
||||
// For each character in the character set
|
||||
for(wchar_t c : characterBlocks) {
|
||||
// Load the character
|
||||
if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
|
||||
assertUnreachable("Failed to load character (1)");
|
||||
}
|
||||
|
||||
// Store the character information
|
||||
info.advance.x = (float_t)(face->glyph->advance.x >> 6);
|
||||
info.advance.y = (float_t)(face->glyph->advance.y >> 6);
|
||||
info.size = glm::vec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||
|
||||
// Determine the texture position
|
||||
if(textureX + face->glyph->bitmap.width >= texture->getWidth()) {
|
||||
textureX = 0;
|
||||
textureY += rowHeight + 2;// Tiny gap between rows
|
||||
rowHeight = face->glyph->bitmap.rows;
|
||||
} else {
|
||||
rowHeight = Math::max<int32_t>(rowHeight, face->glyph->bitmap.rows);
|
||||
}
|
||||
|
||||
// Set the quad positions
|
||||
info.offset = glm::vec2(
|
||||
face->glyph->bitmap_left,
|
||||
-face->glyph->bitmap_top
|
||||
);
|
||||
info.quad = glm::vec4(
|
||||
textureX,
|
||||
textureY,
|
||||
textureX + face->glyph->bitmap.width,
|
||||
textureY + face->glyph->bitmap.rows
|
||||
) / glm::vec4(
|
||||
texture->getWidth(),
|
||||
texture->getHeight(),
|
||||
texture->getWidth(),
|
||||
texture->getHeight()
|
||||
);
|
||||
|
||||
// Store the cached character data.
|
||||
this->characterData[c] = info;
|
||||
|
||||
// Determine pixel offset.
|
||||
offset = textureX + (textureY * texture->getWidth());
|
||||
assertTrue(
|
||||
offset + (face->glyph->bitmap.rows * texture->getWidth()) <=
|
||||
texture->getWidth() * texture->getHeight(),
|
||||
"Font texture buffer overflow will occur."
|
||||
);
|
||||
|
||||
// Buffer pixels, we have to do this one row at a time due to the
|
||||
// differences in width between the glyph and the texture.
|
||||
const size_t countPerRow = face->glyph->bitmap.width;
|
||||
int32_t i = 0;
|
||||
while(i != face->glyph->bitmap.rows) {
|
||||
std::memcpy(
|
||||
buffer + offset + (i * texture->getWidth()),
|
||||
face->glyph->bitmap.buffer + (i * countPerRow),
|
||||
countPerRow
|
||||
);
|
||||
i++;
|
||||
}
|
||||
|
||||
// Increment textureX
|
||||
textureX += face->glyph->bitmap.width + 2;// I add a tiny gap between chars
|
||||
}
|
||||
|
||||
this->texture->buffer(buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
struct TrueTypeCharacter TrueTypeTexture::getCharacterData(wchar_t c) {
|
||||
return this->characterData[c];
|
||||
}
|
||||
|
||||
glm::vec2 TrueTypeTexture::bufferStringToMesh(
|
||||
std::shared_ptr<Mesh> mesh,
|
||||
const std::wstring text,
|
||||
glm::vec2 &position,
|
||||
bool_t flipY
|
||||
) {
|
||||
assertNotNull(mesh, "Mesh must be supplied and not null");
|
||||
assertTrue(text.size() > 0, "Text must be at least one character long.");
|
||||
|
||||
// Create mesh buffers
|
||||
mesh->createBuffers(
|
||||
text.length() * QUAD_VERTICE_COUNT,
|
||||
text.length() * QUAD_INDICE_COUNT
|
||||
);
|
||||
|
||||
// Foreach char
|
||||
size_t i = 0;
|
||||
glm::vec2 size = { 0, 0 };
|
||||
for(wchar_t c : text) {
|
||||
// Get the character data
|
||||
auto info = this->getCharacterData(c);
|
||||
|
||||
// Buffer the quad
|
||||
glm::vec4 quad = glm::vec4(
|
||||
position.x,
|
||||
position.y,
|
||||
position.x + info.size.x,
|
||||
position.y + info.size.y
|
||||
);
|
||||
if(flipY) {
|
||||
QuadMesh::buffer(
|
||||
mesh,
|
||||
quad,
|
||||
glm::vec4(
|
||||
info.quad.x,
|
||||
info.quad.w,
|
||||
info.quad.z,
|
||||
info.quad.y
|
||||
),
|
||||
i * QUAD_VERTICE_COUNT,
|
||||
i * QUAD_INDICE_COUNT
|
||||
);
|
||||
} else {
|
||||
QuadMesh::buffer(
|
||||
mesh,
|
||||
quad,
|
||||
info.quad,
|
||||
i * QUAD_VERTICE_COUNT,
|
||||
i * QUAD_INDICE_COUNT
|
||||
);
|
||||
}
|
||||
position += info.advance;
|
||||
size += info.advance;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
TrueTypeTexture::~TrueTypeTexture() {
|
||||
}
|
66
src/dawn/display/font/TrueTypeTexture.hpp
Normal file
66
src/dawn/display/font/TrueTypeTexture.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Texture.hpp"
|
||||
#include "TrueTypeCharacter.hpp"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
namespace Dawn {
|
||||
class TrueTypeTexture final {
|
||||
private:
|
||||
FT_Face face;
|
||||
|
||||
public:
|
||||
uint32_t fontSize;
|
||||
std::shared_ptr<Texture> texture;
|
||||
std::unordered_map<wchar_t, struct TrueTypeCharacter> characterData;
|
||||
|
||||
/**
|
||||
* Construct a new New True Type Face Texture object
|
||||
*
|
||||
* @param fontSize Size of the font.
|
||||
*/
|
||||
TrueTypeTexture(const uint32_t fontSize);
|
||||
|
||||
/**
|
||||
* Sets the face for this texture.
|
||||
*
|
||||
* @param face Face to set.
|
||||
*/
|
||||
void setFace(const FT_Face face);
|
||||
|
||||
/**
|
||||
* Returns the character data for the given character.
|
||||
*
|
||||
* @param c Character to get data for.
|
||||
* @return The Character data for the given character.
|
||||
*/
|
||||
struct TrueTypeCharacter getCharacterData(wchar_t c);
|
||||
|
||||
/**
|
||||
* Buffers a string to the given mesh.
|
||||
*
|
||||
* @param mesh Mesh to buffer to.
|
||||
* @param text Text to buffer.
|
||||
* @param position Position to buffer to.
|
||||
* @param flipY Whether or not to flip the Y axis.
|
||||
* @return The size of the string.
|
||||
*/
|
||||
glm::vec2 bufferStringToMesh(
|
||||
std::shared_ptr<Mesh> mesh,
|
||||
const std::wstring text,
|
||||
glm::vec2 &position,
|
||||
bool_t flipY = false
|
||||
);
|
||||
|
||||
/**
|
||||
* Destroys this true type face texture.
|
||||
*/
|
||||
~TrueTypeTexture();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user