From 72123bc333dc9141def9c690ccd40612d6f21f2e Mon Sep 17 00:00:00 2001 From: James Grogan Date: Tue, 15 Nov 2022 09:32:28 +0000 Subject: [PATCH] Basic Font integration. --- src/client/GuiApplication.cpp | 1 + src/console/MainApplication.cpp | 3 +- src/fonts/BasicFontEngine.h | 14 +++ src/fonts/CMakeLists.txt | 5 +- src/fonts/FontsManager.cpp | 23 +++++ src/fonts/FontsManager.h | 20 +++++ src/fonts/FreeTypeFontEngine.cpp | 87 +++++++++++++++++++ src/fonts/FreeTypeFontEngine.h | 85 ++---------------- src/fonts/IFontEngine.h | 12 +++ src/graphics/CMakeLists.txt | 3 +- src/graphics/DrawingContext.cpp | 11 +-- src/graphics/DrawingContext.h | 7 +- src/graphics/DrawingManager.cpp | 49 ----------- src/graphics/DrawingManager.h | 28 ------ src/ui_elements/desktop_elements/Window.cpp | 6 +- src/ui_elements/desktop_elements/Window.h | 4 +- src/visual_elements/AbstractVisualNode.h | 19 ++++ src/visual_elements/CMakeLists.txt | 2 +- src/visual_elements/RectangleNode.cpp | 5 ++ src/visual_elements/RectangleNode.h | 3 +- src/visual_elements/Scene.cpp | 19 +++- src/visual_elements/Scene.h | 6 +- src/visual_elements/TextNode.cpp | 41 +++++++++ src/visual_elements/TextNode.h | 5 ++ .../ui_interfaces/AbstractUiInterface.h | 12 ++- .../ui_interfaces/UiInterfaceFactory.cpp | 8 +- .../wayland/WaylandInterface.cpp | 7 +- .../ui_interfaces/wayland/WaylandInterface.h | 2 +- .../ui_interfaces/wayland/WaylandSurface.cpp | 8 +- .../ui_interfaces/wayland/WaylandSurface.h | 4 +- .../ui_interfaces/x11/XcbInterface.cpp | 7 +- src/windows/ui_interfaces/x11/XcbInterface.h | 2 +- src/windows/ui_interfaces/x11/XcbWindow.cpp | 6 +- src/windows/ui_interfaces/x11/XcbWindow.h | 5 +- test/fonts/TestFreeTypeFontEngine.cpp | 1 + test/graphics/TestRasterizer.cpp | 3 +- 36 files changed, 325 insertions(+), 198 deletions(-) create mode 100644 src/fonts/FontsManager.cpp create mode 100644 src/fonts/FontsManager.h delete mode 100644 src/graphics/DrawingManager.cpp delete mode 100644 src/graphics/DrawingManager.h diff --git a/src/client/GuiApplication.cpp b/src/client/GuiApplication.cpp index f871ada..0f02d7a 100644 --- a/src/client/GuiApplication.cpp +++ b/src/client/GuiApplication.cpp @@ -4,6 +4,7 @@ #include "Window.h" #include "WindowManager.h" #include "DesktopManager.h" +#include "FontsManager.h" #include "MainApplication.h" #include "AbstractUiInterface.h" diff --git a/src/console/MainApplication.cpp b/src/console/MainApplication.cpp index e13ed86..51f98f4 100644 --- a/src/console/MainApplication.cpp +++ b/src/console/MainApplication.cpp @@ -3,7 +3,6 @@ #include "MidiReader.h" #include "File.h" #include "DocumentConverter.h" -#include "DrawingManager.h" #include "DrawingSurface.h" #include "DrawingContext.h" #include "Grid.h" @@ -97,12 +96,14 @@ void MainApplication::run() } else if(program_type == "-draw") { + /* auto drawing_manager = DrawingManager::Create(); drawing_manager->InitalizeSurface(400, 400); auto text = TextNode::Create("Hello World", DiscretePoint(20, 20)); drawing_manager->AddText(text.get()); drawing_manager->RenderToFile("test.png"); + */ } else { diff --git a/src/fonts/BasicFontEngine.h b/src/fonts/BasicFontEngine.h index e69de29..0938245 100644 --- a/src/fonts/BasicFontEngine.h +++ b/src/fonts/BasicFontEngine.h @@ -0,0 +1,14 @@ +#pragma once + +#include "IFontEngine.h" + +#include "Image.h" + +class BasicFontEngine : public IFontEngine +{ + virtual void initialize(){}; + + virtual void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16){}; + + virtual std::unique_ptr > loadGlyph(unsigned charCode){return nullptr;}; +}; diff --git a/src/fonts/CMakeLists.txt b/src/fonts/CMakeLists.txt index 857443c..b29fe49 100644 --- a/src/fonts/CMakeLists.txt +++ b/src/fonts/CMakeLists.txt @@ -4,12 +4,13 @@ set(fonts_LIB_DEPENDS "") list(APPEND fonts_LIB_INCLUDES FontReader.cpp TrueTypeFont.cpp + FontsManager.cpp ) if(UNIX) find_package(Freetype QUIET) if(Freetype_FOUND) - list(APPEND font_LIB_INCLUDES + list(APPEND fonts_LIB_INCLUDES FreeTypeFontEngine.cpp ) @@ -27,6 +28,6 @@ target_include_directories(fonts PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" ) -target_link_libraries(fonts PUBLIC core ${fonts_LIB_DEPENDS}) +target_link_libraries(fonts PUBLIC core image ${fonts_LIB_DEPENDS}) set_property(TARGET fonts PROPERTY FOLDER src) set_target_properties( fonts PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) \ No newline at end of file diff --git a/src/fonts/FontsManager.cpp b/src/fonts/FontsManager.cpp new file mode 100644 index 0000000..9621802 --- /dev/null +++ b/src/fonts/FontsManager.cpp @@ -0,0 +1,23 @@ +#include "FontsManager.h" + +#include "FreeTypeFontEngine.h" +#include "BasicFontEngine.h" + + +FontsManager::FontsManager() + : mFontEngine(std::make_unique()) +{ + mFontEngine->initialize(); +} + +std::unique_ptr FontsManager::Create() +{ + return std::make_unique(); +} + +IFontEngine* FontsManager::getFontEngine() const +{ + return mFontEngine.get(); +} + + diff --git a/src/fonts/FontsManager.h b/src/fonts/FontsManager.h new file mode 100644 index 0000000..a539a80 --- /dev/null +++ b/src/fonts/FontsManager.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +class IFontEngine; + +class FontsManager +{ +public: + FontsManager(); + static std::unique_ptr Create(); + + IFontEngine* getFontEngine() const; + +private: + std::unique_ptr mFontEngine; +}; + +using FontsManagerPtr = std::unique_ptr; diff --git a/src/fonts/FreeTypeFontEngine.cpp b/src/fonts/FreeTypeFontEngine.cpp index e69de29..5cf100b 100644 --- a/src/fonts/FreeTypeFontEngine.cpp +++ b/src/fonts/FreeTypeFontEngine.cpp @@ -0,0 +1,87 @@ +#include "FreeTypeFontEngine.h" + +#include "Image.h" +#include "FileLogger.h" + +void FreeTypeFontEngine::initialize() +{ + if (mLibrary) + { + return; + } + + const auto error = FT_Init_FreeType(&mLibrary); + if (error) + { + MLOG_ERROR("Error initializing FreeType. Code " << static_cast(error)); + } +} + +void FreeTypeFontEngine::loadFontFace(const std::filesystem::path& fontFile, int penSize) +{ + if (!mLibrary) + { + initialize(); + } + + const auto full_path = mSystemFontLocation / fontFile; + const auto error = FT_New_Face(mLibrary, full_path.c_str(), 0, &mWorkingFontFace ); + if ( error == FT_Err_Unknown_File_Format ) + { + MLOG_ERROR("Found file but format not supported. Code " << static_cast(error)); + } + else if ( error ) + { + MLOG_ERROR("Failed to find or open file. Code " << static_cast(error)); + } + FT_Set_Pixel_Sizes(mWorkingFontFace, penSize, 0); +} + +std::unique_ptr > FreeTypeFontEngine::loadGlyph(unsigned charCode) +{ + auto glyph_index = FT_Get_Char_Index( mWorkingFontFace, 65 ); + if (glyph_index == 0) + { + MLOG_ERROR("Got the null glyph"); + return nullptr; + } + + auto error = FT_Load_Glyph(mWorkingFontFace, glyph_index, FT_LOAD_DEFAULT ); + if (error == FT_Err_Invalid_Argument) + { + MLOG_ERROR("Error loading glyph - bad arg. Code " << static_cast(error)); + return nullptr; + } + else if(error) + { + MLOG_ERROR("Error loading glyph. Code " << static_cast(error)); + return nullptr; + } + + if (mWorkingFontFace->glyph->format != FT_GLYPH_FORMAT_BITMAP) + { + error = FT_Render_Glyph( mWorkingFontFace->glyph, FT_RENDER_MODE_NORMAL ); + } + if (error) + { + MLOG_ERROR("Error rendering glyph. Code " << static_cast(error)); + return nullptr; + } + + auto rows = mWorkingFontFace->glyph->bitmap.rows; + auto columns = mWorkingFontFace->glyph->bitmap.width; + auto image = std::make_unique> (columns, rows); + + unsigned counter = 0; + std::vector data(rows*columns, 0); + for (unsigned idx=0; idxglyph->bitmap.buffer[counter]; + counter++; + } + } + image->setData(data); + return image; +} diff --git a/src/fonts/FreeTypeFontEngine.h b/src/fonts/FreeTypeFontEngine.h index 9bbf3b5..51049a8 100644 --- a/src/fonts/FreeTypeFontEngine.h +++ b/src/fonts/FreeTypeFontEngine.h @@ -4,8 +4,8 @@ #include "Image.h" -#include -#include +template +class Image; #include #include FT_FREETYPE_H @@ -15,86 +15,11 @@ class FreeTypeFontEngine : public IFontEngine public: FreeTypeFontEngine() = default; - void initialize() - { - if (mLibrary) - { - return; - } + void initialize() override; - const auto error = FT_Init_FreeType(&mLibrary); - if (error) - { - std::cout << "Error initializing FreeType" << std::endl; - } - } + void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16) override; - void loadFontFace(const std::filesystem::path& fontFile) - { - const auto full_path = mSystemFontLocation / fontFile; - const auto error = FT_New_Face(mLibrary, full_path.c_str(), 0, &mWorkingFontFace ); - if ( error == FT_Err_Unknown_File_Format ) - { - std::cout << "Found file but format not supported" << std::endl; - } - else if ( error ) - { - std::cout << "Failed to find or open file" << std::endl; - } - - int pensize = 16; - FT_Set_Pixel_Sizes(mWorkingFontFace, pensize, 0); - } - - std::unique_ptr > loadGlyph(unsigned charCode) - { - auto glyph_index = FT_Get_Char_Index( mWorkingFontFace, charCode ); - if (glyph_index == 0) - { - std::cout << "Got the null glyph" << std::endl; - return nullptr; - } - - auto error = FT_Load_Glyph(mWorkingFontFace, glyph_index, FT_LOAD_DEFAULT ); - if (error == FT_Err_Invalid_Argument) - { - std::cout << "Error loading glyph - bad arg" << std::endl; - return nullptr; - } - else if(error) - { - auto code = static_cast(error); - std::cout << "Error loading glyph - somethign else " << code << std::endl; - return nullptr; - } - - if (mWorkingFontFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) - { - std::cout << "It is bitmap format" << std::endl; - } - else - { - error = FT_Render_Glyph( mWorkingFontFace->glyph, FT_RENDER_MODE_NORMAL ); - } - - auto rows = mWorkingFontFace->glyph->bitmap.rows; - auto columns = mWorkingFontFace->glyph->bitmap.width; - std::cout << "We have a bitmap with rows " << rows << " and columns " << columns << std::endl; - - auto image = std::make_unique> (columns, rows); - - unsigned counter = 0; - std::vector data(rows*columns); - for (unsigned idx=0; idxglyph->bitmap.buffer[counter]; - } - } - image->setData(data); - return image; - } + std::unique_ptr > loadGlyph(unsigned charCode) override; private: std::filesystem::path mSystemFontLocation{"/usr/share/fonts/"}; diff --git a/src/fonts/IFontEngine.h b/src/fonts/IFontEngine.h index 0a0ef90..82b410a 100644 --- a/src/fonts/IFontEngine.h +++ b/src/fonts/IFontEngine.h @@ -1,8 +1,20 @@ #pragma once +#include +#include + +template +class Image; + class IFontEngine { public: IFontEngine() = default; virtual ~IFontEngine() = default; + + virtual void initialize(){}; + + virtual void loadFontFace(const std::filesystem::path& fontFile, int penSize = 16) = 0; + + virtual std::unique_ptr > loadGlyph(unsigned charCode) = 0; }; diff --git a/src/graphics/CMakeLists.txt b/src/graphics/CMakeLists.txt index 9a1b3a6..0b5526e 100644 --- a/src/graphics/CMakeLists.txt +++ b/src/graphics/CMakeLists.txt @@ -5,7 +5,6 @@ set(platform_LIBS "") list(APPEND graphics_LIB_INCLUDES DrawingContext.cpp - DrawingManager.cpp DrawingSurface.cpp RasterPainter.cpp ${platform_LIB_INCLUDES} @@ -36,7 +35,7 @@ target_include_directories(graphics PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/opengl" ) -target_link_libraries(graphics PUBLIC visual_elements image ${platform_LIBS}) +target_link_libraries(graphics PUBLIC geometry mesh fonts image visual_elements ${platform_LIBS}) set_property(TARGET graphics PROPERTY FOLDER src) set_target_properties( graphics PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) \ No newline at end of file diff --git a/src/graphics/DrawingContext.cpp b/src/graphics/DrawingContext.cpp index d3cf6d4..495d24d 100644 --- a/src/graphics/DrawingContext.cpp +++ b/src/graphics/DrawingContext.cpp @@ -9,10 +9,11 @@ #include "DrawingSurface.h" #include "Scene.h" -DrawingContext::DrawingContext(DrawingSurface* surface, DrawingMode requestedDrawingMode) +DrawingContext::DrawingContext(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode) : mSurface(surface), mDrawingMode(requestedDrawingMode), - mScene(std::make_unique()) + mScene(std::make_unique()), + mFontsManager(fontsManager) { if (mDrawingMode == DrawingMode::GRAPH) { @@ -24,9 +25,9 @@ DrawingContext::DrawingContext(DrawingSurface* surface, DrawingMode requestedDra } } -std::unique_ptr DrawingContext::Create(DrawingSurface* surface, DrawingMode requestedDrawingMode) +std::unique_ptr DrawingContext::Create(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode) { - return std::make_unique(surface, requestedDrawingMode); + return std::make_unique(surface, fontsManager, requestedDrawingMode); } Scene* DrawingContext::getScene() const @@ -41,6 +42,6 @@ DrawingSurface* DrawingContext::getSurface() const void DrawingContext::paint() { - mScene->update(mDrawingMode == DrawingMode::RASTER ? mSurface->getImage() : nullptr); + mScene->update(mFontsManager, mDrawingMode == DrawingMode::RASTER ? mSurface->getImage() : nullptr); mPainter->paint(this); } diff --git a/src/graphics/DrawingContext.h b/src/graphics/DrawingContext.h index 9c5fcf5..fab6d46 100644 --- a/src/graphics/DrawingContext.h +++ b/src/graphics/DrawingContext.h @@ -6,6 +6,7 @@ class Scene; class AbstractPainter; class DrawingSurface; +class FontsManager; enum class DrawingMode { @@ -16,9 +17,9 @@ enum class DrawingMode class DrawingContext { public: - DrawingContext(DrawingSurface* surface, DrawingMode requestedDrawingMode); + DrawingContext(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode); - static std::unique_ptr Create(DrawingSurface* surface, DrawingMode requestedDrawingMode); + static std::unique_ptr Create(DrawingSurface* surface, FontsManager* fontsManager, DrawingMode requestedDrawingMode); Scene* getScene() const; @@ -28,7 +29,7 @@ public: private: DrawingMode mDrawingMode; - + FontsManager* mFontsManager{nullptr}; DrawingSurface* mSurface{nullptr}; std::unique_ptr mScene; std::unique_ptr mPainter; diff --git a/src/graphics/DrawingManager.cpp b/src/graphics/DrawingManager.cpp deleted file mode 100644 index 329a7d3..0000000 --- a/src/graphics/DrawingManager.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "DrawingManager.h" - -#include "DrawingSurface.h" -#include "DrawingContext.h" -#include "AbstractPainter.h" - -#include "Grid.h" -#include "Image.h" -#include "TriMesh.h" -#include "Scene.h" - -DrawingManager::DrawingManager() -{ - -} - -std::unique_ptr DrawingManager::Create() -{ - return std::make_unique(); -} - -void DrawingManager::InitalizeSurface(unsigned width, unsigned height) -{ - mDrawingSurface = DrawingSurface::Create(); - mDrawingSurface->setSize(width, height); -} - -void DrawingManager::InitializeContext() -{ - //mDrawingContext = DrawingContext::Create(); -} - -void DrawingManager::AddText(TextNode* text) -{ - if (!mDrawingContext) - { - InitializeContext(); - } - - if (!mDrawingContext) - { - return; - } -} - -void DrawingManager::RenderToFile(const std::string& path) -{ - -} diff --git a/src/graphics/DrawingManager.h b/src/graphics/DrawingManager.h deleted file mode 100644 index c3286c1..0000000 --- a/src/graphics/DrawingManager.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -class TextNode; - -class DrawingSurface; -using DrawingSurfacePtr = std::unique_ptr; -class DrawingContext; -using DrawingContextPtr = std::unique_ptr; - -class DrawingManager -{ -public: - DrawingManager(); - static std::unique_ptr Create(); - void InitalizeSurface(unsigned width, unsigned height); - void InitializeContext(); - void AddText(TextNode* text); - void RenderToFile(const std::string& path); - -private: - DrawingSurfacePtr mDrawingSurface {nullptr}; - DrawingContextPtr mDrawingContext {nullptr}; -}; - -using DrawingManagerPtr = std::unique_ptr; diff --git a/src/ui_elements/desktop_elements/Window.cpp b/src/ui_elements/desktop_elements/Window.cpp index 835f01e..f528ce9 100644 --- a/src/ui_elements/desktop_elements/Window.cpp +++ b/src/ui_elements/desktop_elements/Window.cpp @@ -9,7 +9,9 @@ #include "Scene.h" #include "TriMesh.h" #include "AbstractPainter.h" + #include "DrawingContext.h" +#include "FontsManager.h" #include "IPlatformWindow.h" #include "Screen.h" @@ -89,10 +91,10 @@ IPlatformWindow* Window::getPlatformWindow() const return nullptr; } -void Window::setPlatformWindow(IPlatformWindowPtr window, DrawingMode drawingMode) +void Window::setPlatformWindow(IPlatformWindowPtr window, FontsManager* fontsManager, DrawingMode drawingMode) { mPlatformWindow = std::move(window); - mDrawingContext = std::make_unique(this, drawingMode); + mDrawingContext = std::make_unique(this, fontsManager, drawingMode); } void Window::map() diff --git a/src/ui_elements/desktop_elements/Window.h b/src/ui_elements/desktop_elements/Window.h index 8d7e41a..e793d32 100644 --- a/src/ui_elements/desktop_elements/Window.h +++ b/src/ui_elements/desktop_elements/Window.h @@ -11,7 +11,9 @@ class MouseEvent; class KeyboardEvent; class DrawingContext; +class FontsManager; enum class DrawingMode; + class Widget; using WidgetPtr = std::unique_ptr; class IPlatformWindow; @@ -43,7 +45,7 @@ public: IPlatformWindow* getPlatformWindow() const; - void setPlatformWindow(IPlatformWindowPtr window, DrawingMode drawingMode); + void setPlatformWindow(IPlatformWindowPtr window, FontsManager* fontsManager, DrawingMode drawingMode); void map(); diff --git a/src/visual_elements/AbstractVisualNode.h b/src/visual_elements/AbstractVisualNode.h index 9aadedb..1c0fe5c 100644 --- a/src/visual_elements/AbstractVisualNode.h +++ b/src/visual_elements/AbstractVisualNode.h @@ -3,8 +3,11 @@ #include "AbstractMesh.h" #include "Image.h" #include "DiscretePoint.h" + #include +class FontsManager; + class AbstractVisualNode { public: @@ -21,11 +24,21 @@ public: return mMesh.get(); } + virtual void update(FontsManager* fontsManager) + { + + } + virtual void updateMesh() { } + virtual void updateTexture(FontsManager* fontsManager) + { + + } + Image* getImage() const { return mImage.get(); @@ -36,8 +49,14 @@ public: return mLocation; } + Image* getTexture() const + { + return mTexture.get(); + } + protected: DiscretePoint mLocation; std::unique_ptr mMesh; std::unique_ptr > mImage; + std::unique_ptr > mTexture; }; diff --git a/src/visual_elements/CMakeLists.txt b/src/visual_elements/CMakeLists.txt index 16e1aff..cf3ce47 100644 --- a/src/visual_elements/CMakeLists.txt +++ b/src/visual_elements/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(visual_elements PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" ) -target_link_libraries(visual_elements PUBLIC core geometry mesh image) +target_link_libraries(visual_elements PUBLIC core geometry fonts mesh image) set_property(TARGET visual_elements PROPERTY FOLDER src) diff --git a/src/visual_elements/RectangleNode.cpp b/src/visual_elements/RectangleNode.cpp index 5679148..a9415c7 100644 --- a/src/visual_elements/RectangleNode.cpp +++ b/src/visual_elements/RectangleNode.cpp @@ -33,6 +33,11 @@ unsigned RectangleNode::getHeight() const return mHeight; } +void RectangleNode::update(FontsManager* fontsManager) +{ + updateMesh(); +} + void RectangleNode::updateMesh() { const auto rect = Rectangle(mLocation, mWidth, mHeight); diff --git a/src/visual_elements/RectangleNode.h b/src/visual_elements/RectangleNode.h index 0cd30ff..cfe100e 100644 --- a/src/visual_elements/RectangleNode.h +++ b/src/visual_elements/RectangleNode.h @@ -15,9 +15,10 @@ public: unsigned getWidth() const; unsigned getHeight() const; - void updateMesh() override; + void update(FontsManager* fontsManager) override; private: + void updateMesh() override; unsigned mWidth{1}; unsigned mHeight{1}; }; diff --git a/src/visual_elements/Scene.cpp b/src/visual_elements/Scene.cpp index 007f15c..69aa2aa 100644 --- a/src/visual_elements/Scene.cpp +++ b/src/visual_elements/Scene.cpp @@ -3,16 +3,19 @@ #include "VisualLayer.h" #include "GeometryNode.h" #include "RectangleNode.h" +#include "TextNode.h" #include "MeshBuilder.h" #include "TriMesh.h" +#include "Image.h" + void Scene::syncLayers(const std::vector& layers) { mLayers = layers; } -void Scene::update(Image* image) +void Scene::update(FontsManager* fontsManager, Image* image) { if (image) { @@ -28,11 +31,23 @@ void Scene::update(Image* image) auto node = layer->getShapeNode(); if (layer->getIsDirty()) { - node->updateMesh(); + node->update(fontsManager); layer->setIsDirty(false); } mWorkingMeshs.push_back(dynamic_cast(node->getMesh())); + mTextures.push_back(nullptr); + } + else + { + auto node = layer->getTextNode(); + if (layer->getIsDirty()) + { + node->update(fontsManager); + layer->setIsDirty(false); + } + mWorkingMeshs.push_back(dynamic_cast(node->getMesh())); + mTextures.push_back(node->getTexture()); } } } diff --git a/src/visual_elements/Scene.h b/src/visual_elements/Scene.h index fd9faee..c2625f2 100644 --- a/src/visual_elements/Scene.h +++ b/src/visual_elements/Scene.h @@ -5,6 +5,7 @@ class VisualLayer; class TriMesh; +class FontsManager; class RectangleNode; @@ -18,16 +19,19 @@ public: void syncLayers(const std::vector& layers); - void update(Image* image = nullptr); + void update(FontsManager* fontsManager, Image* image = nullptr); unsigned getNumMeshes() const; TriMesh* getMesh(std::size_t idx) const; + Image* getTexture(std::size_t idx) const; + private: void processRectangleNode(RectangleNode* node); std::vector mWorkingMeshs; std::vector mLayers; + std::vector* > mTextures; }; diff --git a/src/visual_elements/TextNode.cpp b/src/visual_elements/TextNode.cpp index 8d782b1..6bd0f72 100644 --- a/src/visual_elements/TextNode.cpp +++ b/src/visual_elements/TextNode.cpp @@ -1,5 +1,10 @@ #include "TextNode.h" +#include "Rectangle.h" +#include "FontsManager.h" +#include "IFontEngine.h" +#include "MeshPrimitives.h" + #include "Color.h" TextNode::TextNode(const std::string& content, const DiscretePoint& loc) @@ -55,3 +60,39 @@ void TextNode::setStrokeColor(const Color& color) { mStrokeColor = color; } + +void TextNode::update(FontsManager* drawingManager) +{ + updateMesh(); + updateTexture(drawingManager); +} + +void TextNode::updateMesh() +{ + double font_height = 16; + double font_width = 16; + + double text_width = mContent.size() * font_width; + + const auto rect = Rectangle(mLocation, text_width, font_height); + + auto mesh = MeshPrimitives::build(rect); + auto color = Color(0, 0, 0, 1.0); + + mesh->addConstantFaceVectorAttribute("Color", color.getAsVectorDouble()); + mMesh = std::move(mesh); +} + +void TextNode::updateTexture(FontsManager* fontsManager) +{ + fontsManager->getFontEngine()->loadFontFace("truetype/msttcorefonts/arial.ttf"); + auto glyph = fontsManager->getFontEngine()->loadGlyph('A'); + + if (!glyph) + { + return; + } + + mTexture = std::make_unique >(glyph->getWidth(), glyph->getHeight()); + mTexture->setData(glyph->getData()); +} diff --git a/src/visual_elements/TextNode.h b/src/visual_elements/TextNode.h index 8d20576..8156038 100644 --- a/src/visual_elements/TextNode.h +++ b/src/visual_elements/TextNode.h @@ -28,7 +28,12 @@ public: void setFillColor(const Color& color); void setStrokeColor(const Color& color); + void update(FontsManager* fontsManager) override; + private: + void updateMesh() override; + void updateTexture(FontsManager* fontsManager) override; + std::string mContent; std::string mFontLabel; Color mFillColor; diff --git a/src/windows/ui_interfaces/AbstractUiInterface.h b/src/windows/ui_interfaces/AbstractUiInterface.h index 8d8fdcd..dd82523 100644 --- a/src/windows/ui_interfaces/AbstractUiInterface.h +++ b/src/windows/ui_interfaces/AbstractUiInterface.h @@ -1,19 +1,25 @@ #pragma once +#include +#include "IFontEngine.h" +#include "FontsManager.h" + namespace mt { class Window; } class DesktopManager; +class FontsManager; class AbstractUIInterface { public: - AbstractUIInterface(DesktopManager* desktopManager, bool useHardware = false) + AbstractUIInterface(DesktopManager* desktopManager, std::unique_ptr fontsManager, bool useHardware = false) : mDesktopManager(desktopManager), - mUseHardwareRendering(useHardware) + mUseHardwareRendering(useHardware), + mFontsManager(std::move(fontsManager)) { } @@ -32,5 +38,7 @@ protected: virtual void initializeHardwareRendering() {}; DesktopManager* mDesktopManager{nullptr}; + std::unique_ptr mFontsManager; + bool mUseHardwareRendering{false}; }; diff --git a/src/windows/ui_interfaces/UiInterfaceFactory.cpp b/src/windows/ui_interfaces/UiInterfaceFactory.cpp index 88479f0..08d6de6 100644 --- a/src/windows/ui_interfaces/UiInterfaceFactory.cpp +++ b/src/windows/ui_interfaces/UiInterfaceFactory.cpp @@ -7,18 +7,22 @@ #include "Win32UiInterface.h" #endif +#include "FontsManager.h" + std::unique_ptr UiInterfaceFactory::create(DesktopManager* desktopManager, Backend backend) { + auto fonts_manager = std::make_unique(); + #ifdef __linux__ if (backend == Backend::UNSET || backend == Backend::X11 || backend == Backend::X11_RASTER) { const bool use_hardware = (backend != Backend::X11_RASTER); - return std::make_unique(desktopManager, use_hardware); + return std::make_unique(desktopManager, std::move(fonts_manager), use_hardware); } else { const bool use_hardware = (backend != Backend::WAYLAND_RASTER); - return std::make_unique(desktopManager, use_hardware); + return std::make_unique(desktopManager, std::move(fonts_manager), use_hardware); } #else return std::make_unique(); diff --git a/src/windows/ui_interfaces/wayland/WaylandInterface.cpp b/src/windows/ui_interfaces/wayland/WaylandInterface.cpp index 5585665..520711e 100644 --- a/src/windows/ui_interfaces/wayland/WaylandInterface.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandInterface.cpp @@ -3,6 +3,7 @@ #include "FileLogger.h" #include "DesktopManager.h" #include "WindowManager.h" +#include "FontsManager.h" #include "WaylandSurface.h" #include "WaylandBuffer.h" @@ -43,8 +44,8 @@ void WaylandInterface::registryHandleGlobalRemoveEvent(void *data, struct wl_reg } -WaylandInterface::WaylandInterface(DesktopManager* desktopManager, bool useHardware) - : AbstractUIInterface(desktopManager, useHardware), +WaylandInterface::WaylandInterface(DesktopManager* desktopManager, std::unique_ptr fontsManager, bool useHardware) + : AbstractUIInterface(desktopManager, std::move(fontsManager), useHardware), mBuffer(std::make_shared()) { mRegistryListener.global = registryHandleGlobalEvent; @@ -129,7 +130,7 @@ void WaylandInterface::doXdgPong(uint32_t serial) void WaylandInterface::addWindow(mt::Window* window) { - WaylandSurface::add(window, mCompositor, mXdgBase, mBuffer, mEglInterface.get()); + WaylandSurface::add(window, mCompositor, mXdgBase, mBuffer, mFontsManager.get(), mEglInterface.get()); } void WaylandInterface::showWindow(mt::Window* window) diff --git a/src/windows/ui_interfaces/wayland/WaylandInterface.h b/src/windows/ui_interfaces/wayland/WaylandInterface.h index 1fdc82a..dfa1159 100644 --- a/src/windows/ui_interfaces/wayland/WaylandInterface.h +++ b/src/windows/ui_interfaces/wayland/WaylandInterface.h @@ -18,7 +18,7 @@ class WaylandInterface : public AbstractUIInterface { public: - WaylandInterface(DesktopManager* desktopManager, bool useHardware = true); + WaylandInterface(DesktopManager* desktopManager, std::unique_ptr fontsManager, bool useHardware = true); ~WaylandInterface(); diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp index 48c4751..2a40199 100644 --- a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp @@ -2,14 +2,16 @@ #include "WaylandEglWindowInterface.h" #include "ImagePrimitives.h" -#include "DrawingContext.h" -void WaylandSurface::add(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer, WaylandEglInterface* eglInterface) +#include "DrawingContext.h" +#include "FontsManager.h" + +void WaylandSurface::add(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer, FontsManager* fontsManager, WaylandEglInterface* eglInterface) { auto wayland_window = std::make_unique(window, compositor, xdg_wm_base, buffer, eglInterface); const auto drawing_mode = eglInterface ? DrawingMode::GRAPH : DrawingMode::RASTER; - window->setPlatformWindow(std::move(wayland_window), drawing_mode); + window->setPlatformWindow(std::move(wayland_window), fontsManager, drawing_mode); } WaylandSurface::WaylandSurface(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer, WaylandEglInterface* eglInterface) diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.h b/src/windows/ui_interfaces/wayland/WaylandSurface.h index 0a3bd58..762e1e4 100644 --- a/src/windows/ui_interfaces/wayland/WaylandSurface.h +++ b/src/windows/ui_interfaces/wayland/WaylandSurface.h @@ -16,11 +16,13 @@ struct xdg_toplevel; class WaylandEglInterface; class WaylandEglWindowInterface; +class FontsManager; + class WaylandSurface : public IPlatformWindow { public: - static void add(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer, WaylandEglInterface* eglInterface); + static void add(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer, FontsManager* fontsManager, WaylandEglInterface* eglInterface); WaylandSurface(mt::Window* window, wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer, WaylandEglInterface* eglInterface); diff --git a/src/windows/ui_interfaces/x11/XcbInterface.cpp b/src/windows/ui_interfaces/x11/XcbInterface.cpp index d2da4b5..6926f01 100644 --- a/src/windows/ui_interfaces/x11/XcbInterface.cpp +++ b/src/windows/ui_interfaces/x11/XcbInterface.cpp @@ -18,12 +18,13 @@ #include "XcbEventInterface.h" #include "XcbGlInterface.h" #include "FileLogger.h" +#include "FontsManager.h" #include -XcbInterface::XcbInterface(DesktopManager* desktopManager, bool useHardware) - : AbstractUIInterface(desktopManager, useHardware), +XcbInterface::XcbInterface(DesktopManager* desktopManager, std::unique_ptr fontsManager, bool useHardware) + : AbstractUIInterface(desktopManager, std::move(fontsManager), useHardware), mEventInterface(XcbEventInterface::Create()) { @@ -151,7 +152,7 @@ uint32_t XcbInterface::getEventMask() void XcbInterface::addWindow(mt::Window* window) { auto screen = mDesktopManager->getDefaultScreen(); - XcbWindow::add(window, mConnection, screen, getEventMask(), mGlInterface.get()); + XcbWindow::add(window, mConnection, screen, getEventMask(), mFontsManager.get(), mGlInterface.get()); } void XcbInterface::onPaint() diff --git a/src/windows/ui_interfaces/x11/XcbInterface.h b/src/windows/ui_interfaces/x11/XcbInterface.h index 1d66f29..3431ea7 100644 --- a/src/windows/ui_interfaces/x11/XcbInterface.h +++ b/src/windows/ui_interfaces/x11/XcbInterface.h @@ -25,7 +25,7 @@ namespace mt class XcbInterface : public AbstractUIInterface { public: - XcbInterface(DesktopManager* desktopManager, bool useHardware = true); + XcbInterface(DesktopManager* desktopManager, std::unique_ptr fontsManager, bool useHardware = true); ~XcbInterface(); diff --git a/src/windows/ui_interfaces/x11/XcbWindow.cpp b/src/windows/ui_interfaces/x11/XcbWindow.cpp index f4d8219..2b771ae 100644 --- a/src/windows/ui_interfaces/x11/XcbWindow.cpp +++ b/src/windows/ui_interfaces/x11/XcbWindow.cpp @@ -7,7 +7,9 @@ #include "Screen.h" #include "ImagePrimitives.h" #include "XcbGlWindowInterface.h" + #include "DrawingContext.h" +#include "FontsManager.h" #include @@ -27,7 +29,7 @@ XcbWindow::~XcbWindow() xcb_destroy_window(mConnection, mHandle); } -void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask, XcbGlInterface* xcbGlInterface) +void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask, FontsManager* fontsManager, XcbGlInterface* xcbGlInterface) { if (!screen) { @@ -52,7 +54,7 @@ void XcbWindow::add(mt::Window* window, xcb_connection_t* connection, mt::Screen auto xcb_window = std::make_unique(window, hwnd, connection, xcbGlInterface); const auto drawing_mode = xcbGlInterface ? DrawingMode::GRAPH : DrawingMode::RASTER; - window->setPlatformWindow(std::move(xcb_window), drawing_mode); + window->setPlatformWindow(std::move(xcb_window), fontsManager, drawing_mode); } int XcbWindow::getHandle() const diff --git a/src/windows/ui_interfaces/x11/XcbWindow.h b/src/windows/ui_interfaces/x11/XcbWindow.h index 0f4fd83..2ffba34 100644 --- a/src/windows/ui_interfaces/x11/XcbWindow.h +++ b/src/windows/ui_interfaces/x11/XcbWindow.h @@ -6,6 +6,9 @@ class XcbImage; class XcbScreen; class XcbGlWindowInterface; class XcbGlInterface; + +class FontsManager; + struct xcb_connection_t; namespace mt @@ -19,7 +22,7 @@ public: XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection, XcbGlInterface* xcbGlInterface); virtual ~XcbWindow(); - static void add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask, XcbGlInterface* xcbGlInterface); + static void add(mt::Window* window, xcb_connection_t* connection, mt::Screen* screen, uint32_t eventMask, FontsManager* fontsManager, XcbGlInterface* xcbGlInterface); int getHandle() const; unsigned getGraphicsContext() const; diff --git a/test/fonts/TestFreeTypeFontEngine.cpp b/test/fonts/TestFreeTypeFontEngine.cpp index 998e7dd..fc6ff4e 100644 --- a/test/fonts/TestFreeTypeFontEngine.cpp +++ b/test/fonts/TestFreeTypeFontEngine.cpp @@ -1,5 +1,6 @@ #include "FreeTypeFontEngine.h" +#include "Image.h" #include diff --git a/test/graphics/TestRasterizer.cpp b/test/graphics/TestRasterizer.cpp index f7d26b3..2309a25 100644 --- a/test/graphics/TestRasterizer.cpp +++ b/test/graphics/TestRasterizer.cpp @@ -1,6 +1,5 @@ #include "Image.h" #include "PngWriter.h" -#include "DrawingManager.h" #include "DrawingSurface.h" #include "DrawingContext.h" #include "Grid.h" @@ -12,11 +11,13 @@ int main() { + /* DrawingManager manager; manager.InitalizeSurface(200, 200); manager.InitializeContext(); auto line = LineSegment::Create(Point(10.0, 10.0), Point(190.0, 190.0)); + */ return 0; }