More text changes
This commit is contained in:
@@ -51,6 +51,7 @@ find_package(glm CONFIG REQUIRED)
|
|||||||
find_package(Ktx CONFIG REQUIRED)
|
find_package(Ktx CONFIG REQUIRED)
|
||||||
find_package(nlohmann_json CONFIG REQUIRED)
|
find_package(nlohmann_json CONFIG REQUIRED)
|
||||||
find_package(fmt CONFIG REQUIRED)
|
find_package(fmt CONFIG REQUIRED)
|
||||||
|
find_package(unofficial-lunasvg CONFIG REQUIRED)
|
||||||
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
|
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
@@ -75,7 +76,9 @@ target_link_libraries(Engine PUBLIC KTX::ktx)
|
|||||||
target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
|
target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
|
||||||
target_link_libraries(Engine PUBLIC crcpp)
|
target_link_libraries(Engine PUBLIC crcpp)
|
||||||
target_link_libraries(Engine PUBLIC fmt::fmt)
|
target_link_libraries(Engine PUBLIC fmt::fmt)
|
||||||
|
target_link_libraries(Engine PUBLIC unofficial::lunasvg::lunasvg)
|
||||||
target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator)
|
target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator)
|
||||||
|
|
||||||
target_link_libraries(Engine PUBLIC slang)
|
target_link_libraries(Engine PUBLIC slang)
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(Engine PUBLIC metal)
|
target_link_libraries(Engine PUBLIC metal)
|
||||||
|
|||||||
+3
-3
@@ -60,10 +60,10 @@
|
|||||||
<ExpandedItem>object</ExpandedItem>
|
<ExpandedItem>object</ExpandedItem>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
<Type Name="Seele::UniquePtr<*>">
|
<Type Name="Seele::OwningPtr<*>">
|
||||||
<DisplayString>UniquePtr {*handle}</DisplayString>
|
<DisplayString>OwningPtr {*pointer}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<ExpandedItem>handle</ExpandedItem>
|
<ExpandedItem>pointer</ExpandedItem>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
</AutoVisualizer>
|
</AutoVisualizer>
|
||||||
|
|||||||
@@ -8,5 +8,7 @@ target_sources(Editor
|
|||||||
MaterialLoader.cpp
|
MaterialLoader.cpp
|
||||||
MeshLoader.h
|
MeshLoader.h
|
||||||
MeshLoader.cpp
|
MeshLoader.cpp
|
||||||
|
SVGLoader.h
|
||||||
|
SVGLoader.cpp
|
||||||
TextureLoader.h
|
TextureLoader.h
|
||||||
TextureLoader.cpp "../../../tests/Engine/UI/Element.cpp")
|
TextureLoader.cpp)
|
||||||
@@ -31,45 +31,13 @@ void FontLoader::importAsset(FontImportArgs args) {
|
|||||||
// in case of the space character there is no bitmap
|
// in case of the space character there is no bitmap
|
||||||
// so we create a single pixel empty texture
|
// so we create a single pixel empty texture
|
||||||
void FontLoader::import(FontImportArgs args, PFontAsset asset) {
|
void FontLoader::import(FontImportArgs args, PFontAsset asset) {
|
||||||
FT_Library ft;
|
std::ifstream stream(args.filePath.c_str(), std::ios::binary | std::ios::ate);
|
||||||
FT_Error error = FT_Init_FreeType(&ft);
|
Array<uint8> ttfFile(stream.tellg());
|
||||||
assert(!error);
|
stream.seekg(0);
|
||||||
FT_Face face;
|
stream.read((char*)ttfFile.data(), ttfFile.size());
|
||||||
error = FT_New_Face(ft, args.filePath.string().c_str(), 0, &face);
|
asset->ttfFile = std::move(ttfFile);
|
||||||
assert(!error);
|
asset->graphics = graphics;
|
||||||
FT_Set_Pixel_Sizes(face, 0, 48);
|
asset->loadFace();
|
||||||
for (uint32 c = 0; c < 256; ++c) {
|
|
||||||
if (FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_COLOR)) {
|
|
||||||
std::cout << "error loading " << (char)c << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
FontAsset::Glyph& glyph = asset->glyphs[c];
|
|
||||||
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
|
||||||
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
|
||||||
glyph.advance = face->glyph->advance.x;
|
|
||||||
glyph.textureData.resize(glyph.size.x * glyph.size.y);
|
|
||||||
if (glyph.textureData.size() == 0) {
|
|
||||||
glyph.size.x = 1;
|
|
||||||
glyph.size.y = 1;
|
|
||||||
glyph.textureData.add(0);
|
|
||||||
// load a single transparent pixel, so that we dont have to handle empty textures later
|
|
||||||
} else {
|
|
||||||
std::memcpy(glyph.textureData.data(), face->glyph->bitmap.buffer, glyph.textureData.size());
|
|
||||||
}
|
|
||||||
glyph.texture = graphics->createTexture2D(TextureCreateInfo{
|
|
||||||
.sourceData =
|
|
||||||
{
|
|
||||||
.size = glyph.textureData.size(),
|
|
||||||
.data = glyph.textureData.data(),
|
|
||||||
},
|
|
||||||
.format = Gfx::SE_FORMAT_R8_UNORM,
|
|
||||||
.width = glyph.size.x,
|
|
||||||
.height = glyph.size.y,
|
|
||||||
.name = "FontGlyph",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
FT_Done_Face(face);
|
|
||||||
FT_Done_FreeType(ft);
|
|
||||||
|
|
||||||
AssetRegistry::saveAsset(asset, FontAsset::IDENTIFIER, asset->getFolderPath(), asset->getName());
|
AssetRegistry::saveAsset(asset, FontAsset::IDENTIFIER, asset->getFolderPath(), asset->getName());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include "SVGLoader.h"
|
||||||
|
#include "Asset/SVGAsset.h"
|
||||||
|
#include "Asset/AssetRegistry.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
SVGLoader::SVGLoader(Gfx::PGraphics graphic) {}
|
||||||
|
|
||||||
|
SVGLoader::~SVGLoader() {}
|
||||||
|
|
||||||
|
void SVGLoader::importAsset(SVGImportArgs args) {
|
||||||
|
std::filesystem::path assetPath = args.filePath.filename();
|
||||||
|
assetPath.replace_extension("asset");
|
||||||
|
OSVGAsset asset = new SVGAsset(args.importPath, assetPath.stem().string());
|
||||||
|
asset->setStatus(Asset::Status::Loading);
|
||||||
|
// the registry takes ownership, but we need to edit the reference
|
||||||
|
PSVGAsset ref = asset;
|
||||||
|
AssetRegistry::get().registerSVG(std::move(asset));
|
||||||
|
import(args, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVGLoader::import(SVGImportArgs args, PSVGAsset asset) {
|
||||||
|
std::ifstream stream(args.filePath.c_str(), std::ios::binary | std::ios::ate);
|
||||||
|
Array<char> svgFile(stream.tellg());
|
||||||
|
stream.seekg(0);
|
||||||
|
stream.read((char*)svgFile.data(), svgFile.size());
|
||||||
|
asset->document = lunasvg::Document::loadFromData(svgFile.data());
|
||||||
|
asset->data = std::move(svgFile);
|
||||||
|
asset->graphics = graphics;
|
||||||
|
|
||||||
|
AssetRegistry::saveAsset(asset, SVGAsset::IDENTIFIER, asset->getFolderPath(), asset->getName());
|
||||||
|
|
||||||
|
asset->setStatus(Asset::Status::Ready);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Containers/List.h"
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace Seele {
|
||||||
|
DECLARE_REF(SVGAsset)
|
||||||
|
DECLARE_NAME_REF(Gfx, Graphics)
|
||||||
|
struct SVGImportArgs {
|
||||||
|
std::filesystem::path filePath;
|
||||||
|
std::string importPath;
|
||||||
|
};
|
||||||
|
class SVGLoader {
|
||||||
|
public:
|
||||||
|
SVGLoader(Gfx::PGraphics graphic);
|
||||||
|
~SVGLoader();
|
||||||
|
void importAsset(SVGImportArgs args);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void import(SVGImportArgs args, PSVGAsset asset);
|
||||||
|
Gfx::PGraphics graphics;
|
||||||
|
};
|
||||||
|
DECLARE_REF(SVGLoader)
|
||||||
|
} // namespace Seele
|
||||||
@@ -11,8 +11,14 @@ using namespace Seele::Editor;
|
|||||||
|
|
||||||
InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo)
|
InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo)
|
||||||
: View(graphics, window, createInfo, "InspectorView"),
|
: View(graphics, window, createInfo, "InspectorView"),
|
||||||
uiSystem(new UI::System(new UI::Div(
|
uiSystem(new UI::System(
|
||||||
UI::Attributes{}, {new UI::Div<W_Full, BG_Red>({}, {new UI::Text<Font_Arial>("OtherTest")}), new UI::Text<Font_Arial>("Test")}))) {
|
new UI::Div<M_8>(UI::Attributes{}, {
|
||||||
|
new UI::Div<BG_Red, Inline>({},
|
||||||
|
{
|
||||||
|
new UI::Text<Font_Arial, Text_9XL>("OtherTestT"),
|
||||||
|
}),
|
||||||
|
new UI::Text<Font_Arial>("Test"),
|
||||||
|
}))) {
|
||||||
renderGraph.addPass(new UIPass(graphics, uiSystem));
|
renderGraph.addPass(new UIPass(graphics, uiSystem));
|
||||||
renderGraph.setViewport(viewport);
|
renderGraph.setViewport(viewport);
|
||||||
renderGraph.createRenderPass();
|
renderGraph.createRenderPass();
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ int main() {
|
|||||||
AssetImporter::importFont(FontImportArgs{
|
AssetImporter::importFont(FontImportArgs{
|
||||||
.filePath = "./fonts/arial.ttf",
|
.filePath = "./fonts/arial.ttf",
|
||||||
});
|
});
|
||||||
|
AssetImporter::importFont(FontImportArgs{
|
||||||
|
.filePath = "C:\\Windows\\Fonts\\Calibri.ttf",
|
||||||
|
});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "import/models/cube.fbx",
|
.filePath = sourcePath / "import/models/cube.fbx",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "MaterialAsset.h"
|
#include "MaterialAsset.h"
|
||||||
#include "MaterialInstanceAsset.h"
|
#include "MaterialInstanceAsset.h"
|
||||||
#include "MeshAsset.h"
|
#include "MeshAsset.h"
|
||||||
|
#include "SVGAsset.h"
|
||||||
#include "TextureAsset.h"
|
#include "TextureAsset.h"
|
||||||
#include "Window/WindowManager.h"
|
#include "Window/WindowManager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -46,6 +47,15 @@ PFontAsset AssetRegistry::findFont(std::string_view folderPath, std::string_view
|
|||||||
return folder->fonts.at(std::string(filePath));
|
return folder->fonts.at(std::string(filePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PSVGAsset AssetRegistry::findSVG(std::string_view folderPath, std::string_view filePath) {
|
||||||
|
std::unique_lock l(get().assetLock);
|
||||||
|
AssetFolder* folder = get().assetRoot;
|
||||||
|
if (!folderPath.empty()) {
|
||||||
|
folder = get().getOrCreateFolder(folderPath);
|
||||||
|
}
|
||||||
|
return folder->svgs.at(std::string(filePath));
|
||||||
|
}
|
||||||
|
|
||||||
PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) {
|
PMaterialAsset AssetRegistry::findMaterial(std::string_view folderPath, std::string_view filePath) {
|
||||||
std::unique_lock l(get().assetLock);
|
std::unique_lock l(get().assetLock);
|
||||||
AssetFolder* folder = get().assetRoot;
|
AssetFolder* folder = get().assetRoot;
|
||||||
@@ -79,6 +89,11 @@ void AssetRegistry::registerFont(OFontAsset font) {
|
|||||||
get().registerFontInternal(std::move(font));
|
get().registerFontInternal(std::move(font));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetRegistry::registerSVG(OSVGAsset svg) {
|
||||||
|
std::unique_lock l(get().assetLock);
|
||||||
|
get().registerSVGInternal(std::move(svg));
|
||||||
|
}
|
||||||
|
|
||||||
void AssetRegistry::registerMaterial(OMaterialAsset material) {
|
void AssetRegistry::registerMaterial(OMaterialAsset material) {
|
||||||
std::unique_lock l(get().assetLock);
|
std::unique_lock l(get().assetLock);
|
||||||
get().registerMaterialInternal(std::move(material));
|
get().registerMaterialInternal(std::move(material));
|
||||||
@@ -128,6 +143,9 @@ void AssetRegistry::loadAsset(ArchiveBuffer& buffer) {
|
|||||||
case FontAsset::IDENTIFIER:
|
case FontAsset::IDENTIFIER:
|
||||||
asset = PFontAsset(folder->fonts.at(name));
|
asset = PFontAsset(folder->fonts.at(name));
|
||||||
break;
|
break;
|
||||||
|
case SVGAsset::IDENTIFIER:
|
||||||
|
asset = PSVGAsset(folder->svgs.at(name));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new std::logic_error("Unknown Identifier");
|
throw new std::logic_error("Unknown Identifier");
|
||||||
}
|
}
|
||||||
@@ -273,6 +291,10 @@ Pair<PAsset, ArchiveBuffer> AssetRegistry::peekAsset(ArchiveBuffer& buffer) {
|
|||||||
folder->fonts[name] = new FontAsset(folderPath, name);
|
folder->fonts[name] = new FontAsset(folderPath, name);
|
||||||
asset = PFontAsset(folder->fonts[name]);
|
asset = PFontAsset(folder->fonts[name]);
|
||||||
break;
|
break;
|
||||||
|
case SVGAsset::IDENTIFIER:
|
||||||
|
folder->svgs[name] = new SVGAsset(folderPath, name);
|
||||||
|
asset = PSVGAsset(folder->svgs[name]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new std::logic_error("Unknown Identifier");
|
throw new std::logic_error("Unknown Identifier");
|
||||||
}
|
}
|
||||||
@@ -299,6 +321,9 @@ void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFol
|
|||||||
for (const auto& [name, font] : folder->fonts) {
|
for (const auto& [name, font] : folder->fonts) {
|
||||||
saveAsset(PFontAsset(font), FontAsset::IDENTIFIER, folderPath, name);
|
saveAsset(PFontAsset(font), FontAsset::IDENTIFIER, folderPath, name);
|
||||||
}
|
}
|
||||||
|
for (const auto& [name, svg] : folder->svgs) {
|
||||||
|
saveAsset(PSVGAsset(svg), SVGAsset::IDENTIFIER, folderPath, name);
|
||||||
|
}
|
||||||
for (auto& [name, child] : folder->children) {
|
for (auto& [name, child] : folder->children) {
|
||||||
saveFolder(folderPath / name, child);
|
saveFolder(folderPath / name, child);
|
||||||
}
|
}
|
||||||
@@ -321,6 +346,11 @@ void AssetRegistry::registerFontInternal(OFontAsset font) {
|
|||||||
folder->fonts[font->getName()] = std::move(font);
|
folder->fonts[font->getName()] = std::move(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetRegistry::registerSVGInternal(OSVGAsset svg) {
|
||||||
|
AssetFolder* folder = getOrCreateFolder(svg->getFolderPath());
|
||||||
|
folder->svgs[svg->getName()] = std::move(svg);
|
||||||
|
}
|
||||||
|
|
||||||
void AssetRegistry::registerMaterialInternal(OMaterialAsset material) {
|
void AssetRegistry::registerMaterialInternal(OMaterialAsset material) {
|
||||||
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
|
||||||
folder->materials[material->getName()] = std::move(material);
|
folder->materials[material->getName()] = std::move(material);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
namespace Seele {
|
namespace Seele {
|
||||||
DECLARE_REF(TextureAsset)
|
DECLARE_REF(TextureAsset)
|
||||||
DECLARE_REF(FontAsset)
|
DECLARE_REF(FontAsset)
|
||||||
|
DECLARE_REF(SVGAsset)
|
||||||
DECLARE_REF(MeshAsset)
|
DECLARE_REF(MeshAsset)
|
||||||
DECLARE_REF(MaterialAsset)
|
DECLARE_REF(MaterialAsset)
|
||||||
DECLARE_REF(MaterialInstanceAsset)
|
DECLARE_REF(MaterialInstanceAsset)
|
||||||
@@ -24,12 +25,14 @@ class AssetRegistry {
|
|||||||
static PMeshAsset findMesh(std::string_view folderPath, std::string_view filePath);
|
static PMeshAsset findMesh(std::string_view folderPath, std::string_view filePath);
|
||||||
static PTextureAsset findTexture(std::string_view folderPath, std::string_view filePath);
|
static PTextureAsset findTexture(std::string_view folderPath, std::string_view filePath);
|
||||||
static PFontAsset findFont(std::string_view folderPath, std::string_view name);
|
static PFontAsset findFont(std::string_view folderPath, std::string_view name);
|
||||||
|
static PSVGAsset findSVG(std::string_view folderPath, std::string_view name);
|
||||||
static PMaterialAsset findMaterial(std::string_view folderPath, std::string_view filePath);
|
static PMaterialAsset findMaterial(std::string_view folderPath, std::string_view filePath);
|
||||||
static PMaterialInstanceAsset findMaterialInstance(std::string_view folderPath, std::string_view filePath);
|
static PMaterialInstanceAsset findMaterialInstance(std::string_view folderPath, std::string_view filePath);
|
||||||
|
|
||||||
static void registerMesh(OMeshAsset mesh);
|
static void registerMesh(OMeshAsset mesh);
|
||||||
static void registerTexture(OTextureAsset texture);
|
static void registerTexture(OTextureAsset texture);
|
||||||
static void registerFont(OFontAsset font);
|
static void registerFont(OFontAsset font);
|
||||||
|
static void registerSVG(OSVGAsset svg);
|
||||||
static void registerMaterial(OMaterialAsset material);
|
static void registerMaterial(OMaterialAsset material);
|
||||||
static void registerMaterialInstance(OMaterialInstanceAsset instance);
|
static void registerMaterialInstance(OMaterialInstanceAsset instance);
|
||||||
|
|
||||||
@@ -48,6 +51,7 @@ class AssetRegistry {
|
|||||||
Map<std::string, AssetFolder*> children;
|
Map<std::string, AssetFolder*> children;
|
||||||
Map<std::string, OTextureAsset> textures;
|
Map<std::string, OTextureAsset> textures;
|
||||||
Map<std::string, OFontAsset> fonts;
|
Map<std::string, OFontAsset> fonts;
|
||||||
|
Map<std::string, OSVGAsset> svgs;
|
||||||
Map<std::string, OMeshAsset> meshes;
|
Map<std::string, OMeshAsset> meshes;
|
||||||
Map<std::string, OMaterialAsset> materials;
|
Map<std::string, OMaterialAsset> materials;
|
||||||
Map<std::string, OMaterialInstanceAsset> instances;
|
Map<std::string, OMaterialInstanceAsset> instances;
|
||||||
@@ -70,6 +74,7 @@ class AssetRegistry {
|
|||||||
void registerMeshInternal(OMeshAsset mesh);
|
void registerMeshInternal(OMeshAsset mesh);
|
||||||
void registerTextureInternal(OTextureAsset texture);
|
void registerTextureInternal(OTextureAsset texture);
|
||||||
void registerFontInternal(OFontAsset font);
|
void registerFontInternal(OFontAsset font);
|
||||||
|
void registerSVGInternal(OSVGAsset svg);
|
||||||
void registerMaterialInternal(OMaterialAsset material);
|
void registerMaterialInternal(OMaterialAsset material);
|
||||||
void registerMaterialInstanceInternal(OMaterialInstanceAsset instance);
|
void registerMaterialInstanceInternal(OMaterialInstanceAsset instance);
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ target_sources(Engine
|
|||||||
MaterialInstanceAsset.cpp
|
MaterialInstanceAsset.cpp
|
||||||
MeshAsset.h
|
MeshAsset.h
|
||||||
MeshAsset.cpp
|
MeshAsset.cpp
|
||||||
|
SVGAsset.h
|
||||||
|
SVGAsset.cpp
|
||||||
TextureAsset.h
|
TextureAsset.h
|
||||||
TextureAsset.cpp)
|
TextureAsset.cpp)
|
||||||
|
|
||||||
|
|||||||
@@ -6,35 +6,61 @@ using namespace Seele;
|
|||||||
|
|
||||||
FontAsset::FontAsset() {}
|
FontAsset::FontAsset() {}
|
||||||
|
|
||||||
FontAsset::FontAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
FontAsset::FontAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {
|
||||||
|
FT_Error error = FT_Init_FreeType(&ft);
|
||||||
FontAsset::~FontAsset() {}
|
assert(!error);
|
||||||
|
|
||||||
void FontAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, glyphs); }
|
|
||||||
|
|
||||||
void FontAsset::load(ArchiveBuffer& buffer) { Serialization::load(buffer, glyphs); }
|
|
||||||
|
|
||||||
void FontAsset::Glyph::save(ArchiveBuffer& buffer) const {
|
|
||||||
Serialization::save(buffer, size);
|
|
||||||
Serialization::save(buffer, bearing);
|
|
||||||
Serialization::save(buffer, advance);
|
|
||||||
Serialization::save(buffer, textureData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontAsset::Glyph::load(ArchiveBuffer& buffer) {
|
FontAsset::~FontAsset() {
|
||||||
Serialization::load(buffer, size);
|
FT_Done_Face(face);
|
||||||
Serialization::load(buffer, bearing);
|
FT_Done_FreeType(ft);
|
||||||
Serialization::load(buffer, advance);
|
|
||||||
Serialization::load(buffer, textureData);
|
|
||||||
texture = buffer.getGraphics()->createTexture2D(TextureCreateInfo{
|
|
||||||
.sourceData =
|
|
||||||
{
|
|
||||||
.size = textureData.size(),
|
|
||||||
.data = textureData.data(),
|
|
||||||
},
|
|
||||||
.format = Gfx::SE_FORMAT_R8_UNORM,
|
|
||||||
.width = size.x,
|
|
||||||
.height = size.y,
|
|
||||||
.name = "FontGlyph",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FontAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, ttfFile); }
|
||||||
|
|
||||||
|
void FontAsset::load(ArchiveBuffer& buffer) {
|
||||||
|
Serialization::load(buffer, ttfFile);
|
||||||
|
graphics = buffer.getGraphics();
|
||||||
|
loadFace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontAsset::loadFace() {
|
||||||
|
FT_Error error = FT_New_Memory_Face(ft, ttfFile.data(), ttfFile.size(), 0, &face);
|
||||||
|
assert(!error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontAsset::loadFontSize(uint32 fontSize) {
|
||||||
|
FT_Set_Pixel_Sizes(face, 0, fontSize);
|
||||||
|
fontSizes[fontSize].ascent = face->ascender;
|
||||||
|
fontSizes[fontSize].descent = face->descender;
|
||||||
|
fontSizes[fontSize].linegap = 0;
|
||||||
|
for (uint32 c = 0; c < 256; ++c) {
|
||||||
|
if (FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_COLOR)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FontAsset::Glyph& glyph = fontSizes[fontSize].glyphs[c];
|
||||||
|
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||||
|
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||||
|
glyph.advance = face->glyph->advance.x;
|
||||||
|
glyph.textureData.resize(glyph.size.x * glyph.size.y);
|
||||||
|
if (glyph.textureData.size() == 0) {
|
||||||
|
glyph.size.x = 1;
|
||||||
|
glyph.size.y = 1;
|
||||||
|
glyph.textureData.add(0);
|
||||||
|
// load a single transparent pixel, so that we dont have to handle empty textures later
|
||||||
|
} else {
|
||||||
|
std::memcpy(glyph.textureData.data(), face->glyph->bitmap.buffer, glyph.textureData.size());
|
||||||
|
}
|
||||||
|
glyph.texture = graphics->createTexture2D(TextureCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = glyph.textureData.size(),
|
||||||
|
.data = glyph.textureData.data(),
|
||||||
|
},
|
||||||
|
.format = Gfx::SE_FORMAT_R8_UNORM,
|
||||||
|
.width = glyph.size.x,
|
||||||
|
.height = glyph.size.y,
|
||||||
|
.name = "FontGlyph",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Asset.h"
|
#include "Asset.h"
|
||||||
#include "Containers/Map.h"
|
#include "Containers/Map.h"
|
||||||
|
#include "Graphics/Texture.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include <freetype/freetype.h>
|
#include <freetype/freetype.h>
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
|
||||||
class FontAsset : public Asset {
|
class FontAsset : public Asset {
|
||||||
public:
|
public:
|
||||||
static constexpr uint64 IDENTIFIER = 0x10;
|
static constexpr uint64 IDENTIFIER = 0x10;
|
||||||
@@ -24,10 +24,27 @@ class FontAsset : public Asset {
|
|||||||
void save(ArchiveBuffer& buffer) const;
|
void save(ArchiveBuffer& buffer) const;
|
||||||
void load(ArchiveBuffer& buffer);
|
void load(ArchiveBuffer& buffer);
|
||||||
};
|
};
|
||||||
const Glyph& getGlyphData(char c) const { return glyphs[c]; }
|
struct FontData {
|
||||||
|
int32 ascent;
|
||||||
|
int32 descent;
|
||||||
|
int32 linegap;
|
||||||
|
Map<uint32, Glyph> glyphs;
|
||||||
|
};
|
||||||
|
const Glyph& getGlyphData(char c, uint32 fontSize) {
|
||||||
|
if (!fontSizes.contains(fontSize))
|
||||||
|
loadFontSize(fontSize);
|
||||||
|
return fontSizes[fontSize].glyphs[c];
|
||||||
|
}
|
||||||
|
const FontData& getFontData(uint32 fontSize) { return fontSizes[fontSize]; }
|
||||||
|
void loadFace();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Map<uint32, Glyph> glyphs;
|
void loadFontSize(uint32 fontSize);
|
||||||
|
Gfx::PGraphics graphics;
|
||||||
|
FT_Library ft;
|
||||||
|
FT_Face face;
|
||||||
|
Array<uint8> ttfFile;
|
||||||
|
Map<uint32, FontData> fontSizes;
|
||||||
friend class FontLoader;
|
friend class FontLoader;
|
||||||
};
|
};
|
||||||
DECLARE_REF(FontAsset)
|
DECLARE_REF(FontAsset)
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include "SVGAsset.h"
|
||||||
|
#include "Graphics/Graphics.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
SVGAsset::SVGAsset() {}
|
||||||
|
|
||||||
|
SVGAsset::SVGAsset(std::string_view folderPath, std::string_view name) : Asset(folderPath, name) {}
|
||||||
|
|
||||||
|
SVGAsset::~SVGAsset() {}
|
||||||
|
|
||||||
|
void SVGAsset::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, data); }
|
||||||
|
|
||||||
|
void SVGAsset::load(ArchiveBuffer& buffer) {
|
||||||
|
Serialization::load(buffer, data);
|
||||||
|
document = lunasvg::Document::loadFromData(data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
Gfx::PTexture2D SVGAsset::getTexture(UVector2 dimensions) {
|
||||||
|
auto viewbox = ViewBox{
|
||||||
|
.width = dimensions.x,
|
||||||
|
.height = dimensions.y,
|
||||||
|
};
|
||||||
|
if (!cachedTextures.contains(viewbox)) {
|
||||||
|
auto bitmap = document->renderToBitmap(viewbox.width, viewbox.height);
|
||||||
|
bitmap.convertToRGBA();
|
||||||
|
cachedTextures[viewbox] = graphics->createTexture2D(TextureCreateInfo{
|
||||||
|
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||||
|
.width = viewbox.width,
|
||||||
|
.height = viewbox.height,
|
||||||
|
.name = "SVGTexture",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cachedTextures[viewbox];
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Asset.h"
|
||||||
|
#include "Containers/Map.h"
|
||||||
|
#include "Graphics/Texture.h"
|
||||||
|
#include "Math/Math.h"
|
||||||
|
#include <lunasvg.h>
|
||||||
|
|
||||||
|
namespace Seele {
|
||||||
|
class SVGAsset : public Asset {
|
||||||
|
public:
|
||||||
|
static constexpr uint64 IDENTIFIER = 0x20;
|
||||||
|
SVGAsset();
|
||||||
|
SVGAsset(std::string_view folderPath, std::string_view name);
|
||||||
|
virtual ~SVGAsset();
|
||||||
|
virtual void save(ArchiveBuffer& buffer) const override;
|
||||||
|
virtual void load(ArchiveBuffer& buffer) override;
|
||||||
|
|
||||||
|
Gfx::PTexture2D getTexture(UVector2 viewbox);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// workaround to make vector a map key, could be solved by either implementing
|
||||||
|
// comparison operators for vectors, or implementing a hash map
|
||||||
|
struct ViewBox {
|
||||||
|
uint32 width;
|
||||||
|
uint32 height;
|
||||||
|
constexpr std::strong_ordering operator<=>(const ViewBox& other) const = default;
|
||||||
|
};
|
||||||
|
Array<char> data;
|
||||||
|
Gfx::PGraphics graphics;
|
||||||
|
std::unique_ptr<lunasvg::Document> document;
|
||||||
|
Map<ViewBox, Gfx::OTexture2D> cachedTextures;
|
||||||
|
friend class SVGLoader;
|
||||||
|
};
|
||||||
|
} // namespace Seele
|
||||||
@@ -55,7 +55,7 @@ void UIPass::beginFrame(const Component::Camera& cam) {
|
|||||||
RenderPass::beginFrame(cam);
|
RenderPass::beginFrame(cam);
|
||||||
glyphs.clear();
|
glyphs.clear();
|
||||||
usedTextures.clear();
|
usedTextures.clear();
|
||||||
for (const auto& render : renderElements) {
|
for (auto& render : renderElements) {
|
||||||
float x = render.position.x;
|
float x = render.position.x;
|
||||||
float y = render.position.y;
|
float y = render.position.y;
|
||||||
if (render.text.empty()) {
|
if (render.text.empty()) {
|
||||||
@@ -69,9 +69,9 @@ void UIPass::beginFrame(const Component::Camera& cam) {
|
|||||||
.z = render.level / 100.f,
|
.z = render.level / 100.f,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
y = y + render.fontSize;
|
y = y + render.baseline;
|
||||||
for (uint32 c : render.text) {
|
for (uint32 c : render.text) {
|
||||||
const FontAsset::Glyph& glyph = render.font->getGlyphData(c);
|
const FontAsset::Glyph& glyph = render.font->getGlyphData(c, render.fontSize);
|
||||||
Vector2 bearing = Vector2(glyph.bearing);
|
Vector2 bearing = Vector2(glyph.bearing);
|
||||||
Vector2 size = Vector2(glyph.size);
|
Vector2 size = Vector2(glyph.size);
|
||||||
float xpos = x + glyph.bearing.x;
|
float xpos = x + glyph.bearing.x;
|
||||||
@@ -160,7 +160,33 @@ void UIPass::createRenderPass() {
|
|||||||
.colorAttachments = {colorAttachment},
|
.colorAttachments = {colorAttachment},
|
||||||
.depthAttachment = depthAttachment,
|
.depthAttachment = depthAttachment,
|
||||||
};
|
};
|
||||||
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport, "TextPass");
|
Array<Gfx::SubPassDependency> dependency = {
|
||||||
|
{
|
||||||
|
.srcSubpass = ~0U,
|
||||||
|
.dstSubpass = 0,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport, "TextPass");
|
||||||
|
|
||||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
.name = "TextVertex",
|
.name = "TextVertex",
|
||||||
|
|||||||
@@ -45,4 +45,4 @@ void from_json(nlohmann::json& j, Vector& vec);
|
|||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
|
||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Vector& vector);
|
||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Vector4& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Vector4& vector);
|
||||||
std::ostream& operator<<(std::ostream& stream, const Seele::Quaternion& vector);
|
std::ostream& operator<<(std::ostream& stream, const Seele::Quaternion& vector);
|
||||||
@@ -14,6 +14,7 @@ struct UIRender {
|
|||||||
Vector backgroundColor;
|
Vector backgroundColor;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
Vector2 dimensions;
|
Vector2 dimensions;
|
||||||
|
uint32 baseline;
|
||||||
uint32 z;
|
uint32 z;
|
||||||
uint32 level;
|
uint32 level;
|
||||||
};
|
};
|
||||||
@@ -45,14 +46,14 @@ class Element {
|
|||||||
dimensions.x = parentSize.x * style.width / 100.0f;
|
dimensions.x = parentSize.x * style.width / 100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& child : children) {
|
||||||
|
child->layout(maxDimensions - Vector2(style.marginLeft + style.marginRight, style.marginTop + style.marginBottom));
|
||||||
|
}
|
||||||
if (style.heightType == DimensionType::Pixel) {
|
if (style.heightType == DimensionType::Pixel) {
|
||||||
dimensions.y = style.height;
|
dimensions.y = style.height;
|
||||||
} else if (style.heightType == DimensionType::Percent) {
|
} else if (style.heightType == DimensionType::Percent) {
|
||||||
dimensions.y = parentSize.y * style.height / 100.0f;
|
dimensions.y = parentSize.y * style.height / 100.0f;
|
||||||
}
|
}
|
||||||
for (auto& child : children) {
|
|
||||||
child->layout(maxDimensions);
|
|
||||||
}
|
|
||||||
switch (style.innerDisplay) {
|
switch (style.innerDisplay) {
|
||||||
case InnerDisplayType::Flow:
|
case InnerDisplayType::Flow:
|
||||||
flowLayout();
|
flowLayout();
|
||||||
@@ -71,15 +72,15 @@ class Element {
|
|||||||
if (child->style.position == PositionType::Static || child->style.position == PositionType::Relative) {
|
if (child->style.position == PositionType::Static || child->style.position == PositionType::Relative) {
|
||||||
// create a new line in case the element doesnt fit on the current one anymore,
|
// create a new line in case the element doesnt fit on the current one anymore,
|
||||||
// but keep in current line in case we are still at the start, as a new line wouldnt help here
|
// but keep in current line in case we are still at the start, as a new line wouldnt help here
|
||||||
if (cursor.x + child->dimensions.x > dimensions.x - child->style.left && cursor.x != 0) {
|
if (cursor.x + child->dimensions.x > maxDimensions.x - child->style.left && cursor.x != 0) {
|
||||||
cursor.x = 0;
|
cursor.x = 0;
|
||||||
cursor.y += lineHeight;
|
cursor.y += lineHeight;
|
||||||
|
lineHeight = 0;
|
||||||
}
|
}
|
||||||
// todo: border
|
// todo: border
|
||||||
child->position.x = cursor.x + child->style.marginLeft;
|
child->position.x = cursor.x + child->style.marginLeft;
|
||||||
child->position.y = cursor.y + child->style.marginTop;
|
child->position.y = cursor.y + child->style.marginTop;
|
||||||
cursor.x = child->position.x + child->dimensions.x;
|
cursor.x = child->position.x + child->dimensions.x;
|
||||||
cursor.y = child->position.y + child->dimensions.y;
|
|
||||||
// apply offsets after updating the cursor for relative elements
|
// apply offsets after updating the cursor for relative elements
|
||||||
if (child->style.position == PositionType::Relative) {
|
if (child->style.position == PositionType::Relative) {
|
||||||
child->position.x += child->style.left;
|
child->position.x += child->style.left;
|
||||||
@@ -108,7 +109,7 @@ class Element {
|
|||||||
dimensions.x = cursor.x + style.paddingRight;
|
dimensions.x = cursor.x + style.paddingRight;
|
||||||
}
|
}
|
||||||
if (style.heightType == DimensionType::Auto) {
|
if (style.heightType == DimensionType::Auto) {
|
||||||
dimensions.y = cursor.y + style.paddingBottom;
|
dimensions.y = lineHeight + cursor.y + style.paddingBottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual Array<UIRender> render(Vector2 anchor, uint32 level) {
|
virtual Array<UIRender> render(Vector2 anchor, uint32 level) {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ class Div : public Element {
|
|||||||
virtual void applyStyle(Style parentStyle) override {
|
virtual void applyStyle(Style parentStyle) override {
|
||||||
style = parentStyle;
|
style = parentStyle;
|
||||||
style.outerDisplay = OuterDisplayType::Block;
|
style.outerDisplay = OuterDisplayType::Block;
|
||||||
style.widthType = DimensionType::Percent;
|
|
||||||
style.width = 100;
|
|
||||||
(classes::apply(style), ...);
|
(classes::apply(style), ...);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ template <StyleClass... classes> class Text : public Element {
|
|||||||
virtual void layout(UVector2 parentSize) override {
|
virtual void layout(UVector2 parentSize) override {
|
||||||
size_t cursor = 0;
|
size_t cursor = 0;
|
||||||
for (uint32 i = 0; i < text.size() - 1; ++i) {
|
for (uint32 i = 0; i < text.size() - 1; ++i) {
|
||||||
dimensions.x += style.fontFamily->getGlyphData(text[i]).advance / 64.0f;
|
dimensions.x += style.fontFamily->getGlyphData(text[i], style.fontSize).advance / 64.0f;
|
||||||
}
|
}
|
||||||
dimensions.x += style.fontFamily->getGlyphData(text[text.size() - 1]).size.x;
|
dimensions.x += style.fontFamily->getGlyphData(text[text.size() - 1], style.fontSize).size.x;
|
||||||
dimensions.y = style.fontSize;
|
dimensions.y = style.fontSize;
|
||||||
}
|
}
|
||||||
virtual Array<UIRender> render(Vector2 anchor, uint32 level) override {
|
virtual Array<UIRender> render(Vector2 anchor, uint32 level) override {
|
||||||
@@ -28,6 +28,7 @@ template <StyleClass... classes> class Text : public Element {
|
|||||||
.fontSize = style.fontSize,
|
.fontSize = style.fontSize,
|
||||||
.position = position + anchor,
|
.position = position + anchor,
|
||||||
.dimensions = dimensions,
|
.dimensions = dimensions,
|
||||||
|
.baseline = style.fontSize * 3 / 4, // TODO: improve
|
||||||
.z = style.z,
|
.z = style.z,
|
||||||
.level = level,
|
.level = level,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Asset/AssetRegistry.h"
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
template <typename C>
|
template <typename C>
|
||||||
@@ -36,10 +36,73 @@ template <StringLiteral lit> struct FontClass {
|
|||||||
};
|
};
|
||||||
|
|
||||||
using Font_Arial = FontClass<"arial">;
|
using Font_Arial = FontClass<"arial">;
|
||||||
|
using Font_Calibri = FontClass<"Calibri">;
|
||||||
|
|
||||||
|
template <uint32 fontSize, uint32 lineHeight> struct FontSizeClass {
|
||||||
|
static void apply(UI::Style& s) {
|
||||||
|
s.fontSize = fontSize;
|
||||||
|
s.lineHeight = lineHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using Text_XS = FontSizeClass<12, 16>;
|
||||||
|
using Text_SM = FontSizeClass<14, 20>;
|
||||||
|
using Text_Base = FontSizeClass<16, 24>;
|
||||||
|
using Text_LG = FontSizeClass<18, 28>;
|
||||||
|
using Text_XL = FontSizeClass<20, 28>;
|
||||||
|
using Text_2XL = FontSizeClass<24, 32>;
|
||||||
|
using Text_3XL = FontSizeClass<30, 36>;
|
||||||
|
using Text_4XL = FontSizeClass<36, 40>;
|
||||||
|
using Text_5XL = FontSizeClass<48, 48>;
|
||||||
|
using Text_6XL = FontSizeClass<60, 60>;
|
||||||
|
using Text_7XL = FontSizeClass<72, 72>;
|
||||||
|
using Text_8XL = FontSizeClass<96, 96>;
|
||||||
|
using Text_9XL = FontSizeClass<128, 128>;
|
||||||
|
|
||||||
template <Vector backgroundColor> struct BackgroundColorClass {
|
template <Vector backgroundColor> struct BackgroundColorClass {
|
||||||
static void apply(UI::Style& s) { s.backgroundColor = backgroundColor; }
|
static void apply(UI::Style& s) { s.backgroundColor = backgroundColor; }
|
||||||
};
|
};
|
||||||
|
|
||||||
using BG_Red = BackgroundColorClass<Vector(1, 0, 0)>;
|
using BG_Red = BackgroundColorClass<Vector(1, 0, 0)>;
|
||||||
|
|
||||||
|
template <uint32 ml, uint32 mr, uint32 mt, uint32 mb> struct MarginClass {
|
||||||
|
static void apply(UI::Style& s) {
|
||||||
|
if (ml != -1)
|
||||||
|
s.marginLeft = ml;
|
||||||
|
if (mr != -1)
|
||||||
|
s.marginRight = mr;
|
||||||
|
if (mt != -1)
|
||||||
|
s.marginTop = mt;
|
||||||
|
if (mb != -1)
|
||||||
|
s.marginBottom = mb;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#define DECLARE_MARGIN_CLASSES(x) \
|
||||||
|
using M_##x = MarginClass<x, x, x, x>; \
|
||||||
|
using M_X##x = MarginClass<x, x, -1, -1>; \
|
||||||
|
using M_Y##x = MarginClass<-1, -1, x, x>; \
|
||||||
|
using M_L##x = MarginClass<x, -1, -1, -1>; \
|
||||||
|
using M_R##x = MarginClass<-1, x, -1, -1>; \
|
||||||
|
using M_T##x = MarginClass<-1, -1, x, -1>; \
|
||||||
|
using M_B##x = MarginClass<-1, -1, -1, x>;
|
||||||
|
|
||||||
|
DECLARE_MARGIN_CLASSES(0)
|
||||||
|
DECLARE_MARGIN_CLASSES(1)
|
||||||
|
DECLARE_MARGIN_CLASSES(2)
|
||||||
|
DECLARE_MARGIN_CLASSES(3)
|
||||||
|
DECLARE_MARGIN_CLASSES(4)
|
||||||
|
DECLARE_MARGIN_CLASSES(5)
|
||||||
|
DECLARE_MARGIN_CLASSES(6)
|
||||||
|
DECLARE_MARGIN_CLASSES(7)
|
||||||
|
DECLARE_MARGIN_CLASSES(8)
|
||||||
|
DECLARE_MARGIN_CLASSES(9)
|
||||||
|
DECLARE_MARGIN_CLASSES(10)
|
||||||
|
DECLARE_MARGIN_CLASSES(11)
|
||||||
|
DECLARE_MARGIN_CLASSES(12)
|
||||||
|
DECLARE_MARGIN_CLASSES(14)
|
||||||
|
DECLARE_MARGIN_CLASSES(16)
|
||||||
|
DECLARE_MARGIN_CLASSES(20)
|
||||||
|
DECLARE_MARGIN_CLASSES(24)
|
||||||
|
|
||||||
|
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -39,10 +39,10 @@ struct Style {
|
|||||||
Vector backgroundColor = Vector(1, 1, 1);
|
Vector backgroundColor = Vector(1, 1, 1);
|
||||||
OuterDisplayType outerDisplay = OuterDisplayType::Inline;
|
OuterDisplayType outerDisplay = OuterDisplayType::Inline;
|
||||||
InnerDisplayType innerDisplay = InnerDisplayType::Flow;
|
InnerDisplayType innerDisplay = InnerDisplayType::Flow;
|
||||||
PositionType position = PositionType::Relative;
|
PositionType position = PositionType::Static;
|
||||||
PFontAsset fontFamily;
|
PFontAsset fontFamily;
|
||||||
uint32 lineHeight = 48;
|
uint32 lineHeight = 12;
|
||||||
uint32 fontSize = 48;
|
uint32 fontSize = 12;
|
||||||
uint32 fontWeight = 0;
|
uint32 fontWeight = 0;
|
||||||
uint32 paddingTop = 0;
|
uint32 paddingTop = 0;
|
||||||
uint32 paddingBottom = 0;
|
uint32 paddingBottom = 0;
|
||||||
|
|||||||
+15
-14
@@ -1,16 +1,17 @@
|
|||||||
{
|
{
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"assimp",
|
"assimp",
|
||||||
"entt",
|
"entt",
|
||||||
"stb",
|
"stb",
|
||||||
"entt",
|
"entt",
|
||||||
"freetype",
|
"freetype",
|
||||||
"glfw3",
|
"glfw3",
|
||||||
"glm",
|
"glm",
|
||||||
"ktx",
|
"ktx",
|
||||||
"nlohmann-json",
|
"nlohmann-json",
|
||||||
"fmt",
|
"fmt",
|
||||||
"gtest",
|
"gtest",
|
||||||
"vulkan-memory-allocator"
|
"vulkan-memory-allocator",
|
||||||
]
|
"lunasvg"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user