Add cairo interface.

This commit is contained in:
jmsgrogan 2021-04-17 13:57:14 +01:00
parent a03eb9599f
commit 9bcc0ae88e
63 changed files with 1247 additions and 450 deletions

View file

@ -1,8 +1,46 @@
list(APPEND graphics_LIB_INCLUDES OpenGlInterface.cpp)
list(APPEND graphics_HEADERS OpenGlInterface.h)
list(APPEND graphics_LIB_INCLUDES
DrawingContext.cpp
DrawingManager.cpp
DrawingSurface.cpp
opengl/OpenGlInterface.cpp
cairo/CairoInterface.cpp
cairo/CairoDrawingSurface.cpp
cairo/CairoDrawingContext.cpp)
list(APPEND graphics_HEADERS
opengl/OpenGlInterface.h
cairo/CairoInterface.h
INativeDrawingSurface.h
INativeDrawingContext.h)
add_library(graphics SHARED ${graphics_LIB_INCLUDES} ${graphics_HEADERS})
find_package(PkgConfig)
PKG_CHECK_MODULES(PC_CAIRO cairo)
FIND_PATH(CAIRO_INCLUDE_DIRS
NAMES cairo.h
HINTS ${PC_CAIRO_INCLUDEDIR}
${PC_CAIRO_INCLUDE_DIRS}
PATH_SUFFIXES cairo
)
FIND_LIBRARY(CAIRO_LIBRARIES
NAMES cairo
HINTS ${PC_CAIRO_LIBDIR}
${PC_CAIRO_LIBRARY_DIRS}
)
add_library(graphics SHARED
${graphics_LIB_INCLUDES}
${graphics_HEADERS})
target_include_directories(graphics PUBLIC
${CAIRO_INCLUDE_DIRS}
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/cairo"
"${CMAKE_CURRENT_SOURCE_DIR}/opengl"
"${PROJECT_SOURCE_DIR}/src/geometry/"
"${PROJECT_SOURCE_DIR}/src/visual_elements/"
)
target_link_libraries(graphics PUBLIC GL)
target_link_libraries(graphics PUBLIC visual_elements GL ${CAIRO_LIBRARIES})
set_property(TARGET graphics PROPERTY FOLDER src)

View file

@ -0,0 +1,18 @@
#include "DrawingContext.h"
#include "INativeDrawingContext.h"
std::unique_ptr<DrawingContext> DrawingContext::Create()
{
return std::make_unique<DrawingContext>();
}
void DrawingContext::SetNativeContext(std::unique_ptr<INativeDrawingContext> context)
{
mNativeDrawingContext = std::move(context);
}
INativeDrawingContext* DrawingContext::GetNativeContext()
{
return mNativeDrawingContext.get();
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <memory>
class INativeDrawingContext;
class DrawingContext
{
public:
DrawingContext() = default;
static std::unique_ptr<DrawingContext> Create();
void SetNativeContext(std::unique_ptr<INativeDrawingContext> context);
INativeDrawingContext* GetNativeContext();
private:
std::unique_ptr<INativeDrawingContext> mNativeDrawingContext;
};
using DrawingContextPtr = std::unique_ptr<DrawingContext>;

View file

@ -0,0 +1,63 @@
#include "DrawingManager.h"
#include "INativeDrawingContext.h"
#include "DrawingSurface.h"
#include "DrawingContext.h"
#include "CairoInterface.h"
DrawingManager::DrawingManager()
{
mCairoInterface = CairoInterface::Create();
}
std::unique_ptr<DrawingManager> DrawingManager::Create()
{
return std::make_unique<DrawingManager>();
}
void DrawingManager::InitalizeSurface(unsigned width, unsigned height)
{
mDrawingSurface = DrawingSurface::Create();
mDrawingSurface->SetSize(width, height);
if (mCairoInterface)
{
mCairoInterface->InitializeSurface(mDrawingSurface.get());
}
}
void DrawingManager::InitializeContext()
{
mDrawingContext = DrawingContext::Create();
if (mCairoInterface && mDrawingSurface)
{
mCairoInterface->InitializeContext(mDrawingContext.get(), mDrawingSurface.get());
}
}
void DrawingManager::AddText(TextElement* text)
{
if (!mDrawingContext)
{
InitializeContext();
}
if (!mDrawingContext)
{
return;
}
if (mCairoInterface)
{
mCairoInterface->AddText(text, mDrawingContext.get());
}
}
void DrawingManager::RenderToFile(const std::string& path)
{
if (mDrawingSurface && mCairoInterface)
{
mCairoInterface->RenderToFile(mDrawingSurface.get(), path);
}
}

View file

@ -0,0 +1,31 @@
#pragma once
#include <memory>
#include "INativeDrawingContext.h"
#include "INativeDrawingSurface.h"
#include "CairoInterface.h"
class TextElement;
class DrawingSurface;
using DrawingSurfacePtr = std::unique_ptr<DrawingSurface>;
class DrawingContext;
using DrawingContextPtr = std::unique_ptr<DrawingContext>;
class DrawingManager
{
public:
DrawingManager();
static std::unique_ptr<DrawingManager> Create();
void InitalizeSurface(unsigned width, unsigned height);
void InitializeContext();
void AddText(TextElement* text);
void RenderToFile(const std::string& path);
private:
DrawingSurfacePtr mDrawingSurface {nullptr};
DrawingContextPtr mDrawingContext {nullptr};
CairoInterfacePtr mCairoInterface {nullptr};
};
using DrawingManagerPtr = std::unique_ptr<DrawingManager>;

View file

@ -0,0 +1,40 @@
#include "DrawingSurface.h"
std::unique_ptr<DrawingSurface> DrawingSurface::Create()
{
return std::make_unique<DrawingSurface>();
}
INativeDrawingSurface* DrawingSurface::GetNativeSurface()
{
if (mNativeDrawingSurface)
{
return mNativeDrawingSurface.get();
}
else
{
return nullptr;
}
}
void DrawingSurface::SetNativeSurface(std::unique_ptr<INativeDrawingSurface> surface)
{
mNativeDrawingSurface = std::move(surface);
}
void DrawingSurface::SetSize(unsigned width, unsigned height)
{
mWidth = width;
mHeight = height;
}
unsigned DrawingSurface::GetWidth() const
{
return mWidth;
}
unsigned DrawingSurface::GetHeight() const
{
return mHeight;
}

View file

@ -0,0 +1,29 @@
#pragma once
#include <memory>
#include "INativeDrawingSurface.h"
class DrawingSurface
{
public:
DrawingSurface() = default;
static std::unique_ptr<DrawingSurface> Create();
INativeDrawingSurface* GetNativeSurface();
void SetNativeSurface(std::unique_ptr<INativeDrawingSurface> surface);
void SetSize(unsigned width, unsigned height);
unsigned GetWidth() const;
unsigned GetHeight() const;
private:
unsigned mWidth = 0;
unsigned mHeight = 0;
std::unique_ptr<INativeDrawingSurface> mNativeDrawingSurface;
};

View file

@ -0,0 +1,8 @@
#pragma once
class INativeDrawingContext
{
public:
virtual ~INativeDrawingContext() = default;
};

View file

@ -0,0 +1,9 @@
#pragma once
class INativeDrawingSurface
{
public:
virtual ~INativeDrawingSurface() = default;
virtual void DestroyNativeSurface() = 0;
};

View file

@ -0,0 +1,31 @@
#include "CairoDrawingContext.h"
cairo_t* CairoDrawingContext::GetNativeContext()
{
return mNativeContext;
}
CairoDrawingContext::CairoDrawingContext(cairo_t* context)
: mNativeContext(context)
{
}
CairoDrawingContext::~CairoDrawingContext()
{
DestroyNativeContext();
}
std::unique_ptr<CairoDrawingContext> CairoDrawingContext::Create(cairo_t* context)
{
return std::make_unique<CairoDrawingContext>(context);
}
void CairoDrawingContext::DestroyNativeContext()
{
if (mNativeContext)
{
cairo_destroy (mNativeContext);
mNativeContext = nullptr;
}
}

View file

@ -0,0 +1,27 @@
#pragma once
#include "INativeDrawingContext.h"
#include <memory>
#include <cairo.h>
class CairoDrawingContext : public INativeDrawingContext
{
public:
CairoDrawingContext(cairo_t* context);
virtual ~CairoDrawingContext();
static std::unique_ptr<CairoDrawingContext> Create(cairo_t* context);
cairo_t* GetNativeContext();
void DestroyNativeContext();
private:
cairo_t* mNativeContext;
};
using CairoDrawingContextPtr = std::unique_ptr<CairoDrawingContext>;

View file

@ -0,0 +1,31 @@
#include "CairoDrawingSurface.h"
CairoDrawingSurface::CairoDrawingSurface(cairo_surface_t* surface)
: mNativeSurface(surface)
{
}
CairoDrawingSurface::~CairoDrawingSurface()
{
DestroyNativeSurface();
}
std::unique_ptr<CairoDrawingSurface> CairoDrawingSurface::Create(cairo_surface_t* surface)
{
return std::make_unique<CairoDrawingSurface>(surface);
}
cairo_surface_t* CairoDrawingSurface::GetNativeSurface()
{
return mNativeSurface;
}
void CairoDrawingSurface::DestroyNativeSurface()
{
if (mNativeSurface)
{
cairo_surface_destroy (mNativeSurface);
mNativeSurface = nullptr;
}
}

View file

@ -0,0 +1,27 @@
#pragma once
#include "INativeDrawingSurface.h"
#include <cairo.h>
#include <memory>
class CairoDrawingSurface : public INativeDrawingSurface
{
public:
CairoDrawingSurface(cairo_surface_t* surface);
virtual ~CairoDrawingSurface();
static std::unique_ptr<CairoDrawingSurface> Create(cairo_surface_t* surface);
cairo_surface_t* GetNativeSurface();
void DestroyNativeSurface() override;
private:
cairo_surface_t* mNativeSurface;
};
using CairoDrawingSurfacePtr = std::unique_ptr<CairoDrawingSurface>;

View file

@ -0,0 +1,51 @@
#include "CairoInterface.h"
#include "DrawingSurface.h"
#include "DrawingContext.h"
#include "CairoDrawingSurface.h"
#include "CairoDrawingContext.h"
#include "TextElement.h"
#include <cairo.h>
std::unique_ptr<CairoInterface> CairoInterface::Create()
{
return std::make_unique<CairoInterface>();
}
void CairoInterface::InitializeSurface(DrawingSurface* surface)
{
auto native_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
surface->GetWidth(), surface->GetHeight());
auto cairo_surface = CairoDrawingSurface::Create(native_surface);
surface->SetNativeSurface(std::move(cairo_surface));
}
void CairoInterface::InitializeContext(DrawingContext* context, DrawingSurface* surface)
{
auto cairo_surface = dynamic_cast<CairoDrawingSurface*>(surface->GetNativeSurface());
auto native_context = cairo_create(cairo_surface->GetNativeSurface());
auto cairo_context = CairoDrawingContext::Create(native_context);
context->SetNativeContext(std::move(cairo_context));
}
void CairoInterface::RenderToFile(DrawingSurface* surface, const std::string& path)
{
auto cairo_surface = dynamic_cast<CairoDrawingSurface*>(surface->GetNativeSurface());
cairo_surface_write_to_png (cairo_surface->GetNativeSurface(), path.c_str());
}
void CairoInterface::AddText(TextElement* text, DrawingContext* context)
{
auto cairo_context = dynamic_cast<CairoDrawingContext*>(context->GetNativeContext());
auto native_context = cairo_context->GetNativeContext();
cairo_select_font_face (native_context, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (native_context, 32.0);
cairo_set_source_rgb (native_context, 0.0, 0.0, 1.0);
cairo_move_to(native_context, 10.0, 50.0);
cairo_show_text(native_context, text->GetContent().c_str());
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <memory>
#include <string>
class DrawingSurface;
class DrawingContext;
class TextElement;
class CairoInterface
{
public:
CairoInterface() = default;
static std::unique_ptr<CairoInterface> Create();
void InitializeSurface(DrawingSurface* surface);
void InitializeContext(DrawingContext* context, DrawingSurface* surface);
void AddText(TextElement* text, DrawingContext* context);
void RenderToFile(DrawingSurface* surface, const std::string& path);
};
using CairoInterfacePtr = std::unique_ptr<CairoInterface>;