Changes to diagnose font render buffer issues

This commit is contained in:
Jack Andersen 2015-12-01 15:32:15 -10:00
parent 11dfa963b5
commit 35edc47c91
19 changed files with 371 additions and 340 deletions

View File

@ -31,9 +31,10 @@ include_directories(include ${HECL_INCLUDE_DIR} ${BOO_INCLUDE_DIR}
list(APPEND SPECTER_HEADERS list(APPEND SPECTER_HEADERS
include/Specter/Specter.hpp include/Specter/Specter.hpp
include/Specter/ViewSystem.hpp include/Specter/ViewResources.hpp
include/Specter/View.hpp include/Specter/View.hpp
include/Specter/RootView.hpp include/Specter/RootView.hpp
include/Specter/SplitView.hpp
include/Specter/ScrollView.hpp include/Specter/ScrollView.hpp
include/Specter/TextView.hpp include/Specter/TextView.hpp
include/Specter/MultiLineTextView.hpp include/Specter/MultiLineTextView.hpp
@ -56,6 +57,7 @@ list(APPEND SPECTER_SOURCES
lib/Specter.cpp lib/Specter.cpp
lib/View.cpp lib/View.cpp
lib/RootView.cpp lib/RootView.cpp
lib/SplitView.cpp
lib/ScrollView.cpp lib/ScrollView.cpp
lib/TextView.cpp lib/TextView.cpp
lib/MultiLineTextView.cpp lib/MultiLineTextView.cpp

View File

@ -52,7 +52,7 @@ public:
operator FT_Face() {open(); return m_face;} operator FT_Face() {open(); return m_face;}
}; };
using FCharFilter = std::function<bool(uint32_t)>; using FCharFilter = std::pair<std::string, std::function<bool(uint32_t)>>;
class FontAtlas class FontAtlas
{ {
@ -153,6 +153,18 @@ public:
} }
}; };
static FCharFilter const AllCharFilter =
std::make_pair("all-glyphs", [](uint32_t)->bool
{return true;});
static FCharFilter const LatinCharFilter =
std::make_pair("latin-glyphs", [](uint32_t c)->bool
{return c <= 0xff || ((c - 0x2200) <= (0x23FF - 0x2200));});
static FCharFilter const LatinAndJapaneseCharFilter =
std::make_pair("latin-and-jp-glyphs", [](uint32_t c)->bool
{return LatinCharFilter.second(c) || ((c - 0x2E00) <= (0x30FF - 0x2E00));});
class FontCache class FontCache
{ {
const HECL::Runtime::FileStoreManager& m_fileMgr; const HECL::Runtime::FileStoreManager& m_fileMgr;
@ -173,17 +185,15 @@ public:
FontCache(const FontCache& other) = delete; FontCache(const FontCache& other) = delete;
FontCache& operator=(const FontCache& other) = delete; FontCache& operator=(const FontCache& other) = delete;
static bool DefaultCharFilter(uint32_t ch) {return true;}
FontTag prepCustomFont(boo::IGraphicsDataFactory* gf, const std::string& name, FT_Face face, FontTag prepCustomFont(boo::IGraphicsDataFactory* gf, const std::string& name, FT_Face face,
FCharFilter filter=DefaultCharFilter, bool subpixel=false, FCharFilter filter=AllCharFilter, bool subpixel=false,
float points=10.0, uint32_t dpi=72); float points=10.0, uint32_t dpi=72);
FontTag prepMainFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=DefaultCharFilter, FontTag prepMainFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=AllCharFilter,
bool subpixel=false, float points=10.0, uint32_t dpi=72) bool subpixel=false, float points=10.0, uint32_t dpi=72)
{return prepCustomFont(gf, "droidsans-permissive", m_regFace, filter, subpixel, points, dpi);} {return prepCustomFont(gf, "droidsans-permissive", m_regFace, filter, subpixel, points, dpi);}
FontTag prepMonoFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=DefaultCharFilter, FontTag prepMonoFont(boo::IGraphicsDataFactory* gf, FCharFilter filter=AllCharFilter,
bool subpixel=false, float points=10.0, uint32_t dpi=72) bool subpixel=false, float points=10.0, uint32_t dpi=72)
{return prepCustomFont(gf, "bmonofont", m_monoFace, filter, subpixel, points, dpi);} {return prepCustomFont(gf, "bmonofont", m_monoFace, filter, subpixel, points, dpi);}

View File

@ -10,14 +10,14 @@ namespace Specter
class MultiLineTextView : public View class MultiLineTextView : public View
{ {
ViewSystem& m_viewSystem; ViewResources& m_viewSystem;
std::vector<std::unique_ptr<TextView>> m_lines; std::vector<std::unique_ptr<TextView>> m_lines;
const FontAtlas& m_fontAtlas; const FontAtlas& m_fontAtlas;
size_t m_lineCapacity; size_t m_lineCapacity;
float m_lineHeight; float m_lineHeight;
public: public:
MultiLineTextView(ViewSystem& system, View& parentView, const FontAtlas& font, size_t lineCapacity=256, float lineHeight=1.0); MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font, size_t lineCapacity=256, float lineHeight=1.0);
MultiLineTextView(ViewSystem& system, View& parentView, FontTag font, size_t lineCapacity=256, float lineHeight=1.0); MultiLineTextView(ViewResources& res, View& parentView, FontTag font, size_t lineCapacity=256, float lineHeight=1.0);
void typesetGlyphs(const std::string& str, void typesetGlyphs(const std::string& str,
const Zeus::CColor& defaultColor=Zeus::CColor::skWhite); const Zeus::CColor& defaultColor=Zeus::CColor::skWhite);

View File

@ -3,12 +3,13 @@
#include "View.hpp" #include "View.hpp"
#include "MultiLineTextView.hpp" #include "MultiLineTextView.hpp"
#include "SplitView.hpp"
#include "FontCache.hpp" #include "FontCache.hpp"
#include <boo/boo.hpp> #include <boo/boo.hpp>
namespace Specter namespace Specter
{ {
class ViewSystem; class ViewResources;
class RootView : public View, public boo::IWindowCallback class RootView : public View, public boo::IWindowCallback
{ {
@ -19,7 +20,7 @@ class RootView : public View, public boo::IWindowCallback
bool m_destroyed = false; bool m_destroyed = false;
public: public:
RootView(ViewSystem& system, boo::IWindow* window); RootView(ViewResources& res, boo::IWindow* window);
void destroyed(); void destroyed();
bool isDestroyed() const {return m_destroyed;} bool isDestroyed() const {return m_destroyed;}
@ -49,82 +50,6 @@ public:
boo::IWindow* window() const {return m_window;} boo::IWindow* window() const {return m_window;}
class SplitView : public View
{
public:
class System
{
friend class ViewSystem;
friend class SplitView;
boo::ITextureS* m_shadingTex;
void init(boo::IGraphicsDataFactory* factory);
};
enum class Axis
{
Horizontal,
Vertical
};
private:
Axis m_axis;
float m_slide = 0.5;
bool m_dragging = false;
void setSlide(float slide)
{
m_slide = std::min(std::max(slide, 0.0f), 1.0f);
updateSize();
}
std::unique_ptr<View> m_views[2];
VertexBlock m_splitBlock;
boo::IGraphicsBufferD* m_splitBlockBuf;
struct SplitVert
{
Zeus::CVector3f m_pos;
Zeus::CVector2f m_uv;
} m_splitVerts[4];
void setHorizontalVerts(int width)
{
m_splitVerts[0].m_pos.assign(0, 1, 0);
m_splitVerts[0].m_uv.assign(0, 0);
m_splitVerts[1].m_pos.assign(0, -1, 0);
m_splitVerts[1].m_uv.assign(1, 0);
m_splitVerts[2].m_pos.assign(width, 1, 0);
m_splitVerts[2].m_uv.assign(0, 0);
m_splitVerts[3].m_pos.assign(width, -1, 0);
m_splitVerts[3].m_uv.assign(1, 0);
}
void setVerticalVerts(int height)
{
m_splitVerts[0].m_pos.assign(-1, height, 0);
m_splitVerts[0].m_uv.assign(0, 0);
m_splitVerts[1].m_pos.assign(-1, 0, 0);
m_splitVerts[1].m_uv.assign(0, 0);
m_splitVerts[2].m_pos.assign(1, height, 0);
m_splitVerts[2].m_uv.assign(1, 0);
m_splitVerts[3].m_pos.assign(1, 0, 0);
m_splitVerts[3].m_uv.assign(1, 0);
}
boo::IGraphicsBufferD* m_splitVertsBuf;
boo::IVertexFormat* m_splitVtxFmt; /* OpenGL only */
boo::IShaderDataBinding* m_splitShaderBinding;
int m_splitValidSlots = 0;
public:
SplitView(ViewSystem& system, View& parentView, Axis axis);
void setContentView(int slot, std::unique_ptr<View>&& view);
std::unique_ptr<View> releaseContentView(int slot);
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&);
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ);
};
private: private:
std::unique_ptr<SplitView> m_splitView; std::unique_ptr<SplitView> m_splitView;
}; };

View File

@ -5,13 +5,13 @@
namespace Specter namespace Specter
{ {
class ViewSystem; class ViewResources;
class ScrollView : public View class ScrollView : public View
{ {
View& m_contentView; View& m_contentView;
public: public:
ScrollView(ViewSystem& system, View& parentView, View& contentView); ScrollView(ViewResources& res, View& parentView, View& contentView);
}; };
} }

View File

@ -16,6 +16,6 @@
#include "Node.hpp" #include "Node.hpp"
#include "NodeSocket.hpp" #include "NodeSocket.hpp"
#include "FontCache.hpp" #include "FontCache.hpp"
#include "ViewSystem.hpp" #include "ViewResources.hpp"
#endif // SPECTER_HPP #endif // SPECTER_HPP

View File

@ -0,0 +1,86 @@
#ifndef SPECTER_SPLITVIEW_HPP
#define SPECTER_SPLITVIEW_HPP
#include "Specter/View.hpp"
namespace Specter
{
class SplitView : public View
{
public:
class Resources
{
friend class ViewResources;
friend class SplitView;
boo::ITextureS* m_shadingTex;
void init(boo::IGraphicsDataFactory* factory);
};
enum class Axis
{
Horizontal,
Vertical
};
private:
Axis m_axis;
float m_slide = 0.5;
bool m_dragging = false;
void setSlide(float slide)
{
m_slide = std::min(std::max(slide, 0.0f), 1.0f);
updateSize();
}
std::unique_ptr<View> m_views[2];
VertexBlock m_splitBlock;
boo::IGraphicsBufferD* m_splitBlockBuf;
struct SplitVert
{
Zeus::CVector3f m_pos;
Zeus::CVector2f m_uv;
} m_splitVerts[4];
void setHorizontalVerts(int width)
{
m_splitVerts[0].m_pos.assign(0, 1, 0);
m_splitVerts[0].m_uv.assign(0, 0);
m_splitVerts[1].m_pos.assign(0, -1, 0);
m_splitVerts[1].m_uv.assign(1, 0);
m_splitVerts[2].m_pos.assign(width, 1, 0);
m_splitVerts[2].m_uv.assign(0, 0);
m_splitVerts[3].m_pos.assign(width, -1, 0);
m_splitVerts[3].m_uv.assign(1, 0);
}
void setVerticalVerts(int height)
{
m_splitVerts[0].m_pos.assign(-1, height, 0);
m_splitVerts[0].m_uv.assign(0, 0);
m_splitVerts[1].m_pos.assign(-1, 0, 0);
m_splitVerts[1].m_uv.assign(0, 0);
m_splitVerts[2].m_pos.assign(1, height, 0);
m_splitVerts[2].m_uv.assign(1, 0);
m_splitVerts[3].m_pos.assign(1, 0, 0);
m_splitVerts[3].m_uv.assign(1, 0);
}
boo::IGraphicsBufferD* m_splitVertsBuf;
boo::IVertexFormat* m_splitVtxFmt; /* OpenGL only */
boo::IShaderDataBinding* m_splitShaderBinding;
int m_splitValidSlots = 0;
public:
SplitView(ViewResources& res, View& parentView, Axis axis);
std::unique_ptr<View> setContentView(int slot, std::unique_ptr<View>&& view);
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&);
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ);
};
}
#endif // SPECTER_SPLITVIEW_HPP

View File

@ -10,7 +10,7 @@
namespace Specter namespace Specter
{ {
class ViewSystem; class ViewResources;
class TextView : public View class TextView : public View
{ {
@ -22,9 +22,9 @@ class TextView : public View
int m_validSlots = 0; int m_validSlots = 0;
public: public:
class System class Resources
{ {
friend class ViewSystem; friend class ViewResources;
friend class TextView; friend class TextView;
friend class MultiLineTextView; friend class MultiLineTextView;
FontCache* m_fcache = nullptr; FontCache* m_fcache = nullptr;
@ -40,8 +40,8 @@ public:
#endif #endif
}; };
TextView(ViewSystem& system, View& parentView, const FontAtlas& font, size_t capacity=256); TextView(ViewResources& res, View& parentView, const FontAtlas& font, size_t capacity=256);
TextView(ViewSystem& system, View& parentView, FontTag font, size_t capacity=256); TextView(ViewResources& res, View& parentView, FontTag font, size_t capacity=256);
struct RenderGlyph struct RenderGlyph
{ {

View File

@ -13,7 +13,7 @@
namespace Specter namespace Specter
{ {
class ViewSystem; class ViewResources;
class RootView; class RootView;
class View class View
@ -31,8 +31,8 @@ class View
std::unique_ptr<boo::IGraphicsData> m_gfxData; std::unique_ptr<boo::IGraphicsData> m_gfxData;
friend class RootView; friend class RootView;
void buildResources(ViewSystem& system); void buildResources(ViewResources& res);
View(ViewSystem& system, RootView& parentView); View(ViewResources& res, RootView& parentView);
protected: protected:
struct VertexBlock struct VertexBlock
@ -64,7 +64,7 @@ protected:
boo::IGraphicsBufferD* m_viewVertBlockBuf; boo::IGraphicsBufferD* m_viewVertBlockBuf;
public: public:
struct System struct Resources
{ {
boo::IShaderPipeline* m_solidShader = nullptr; boo::IShaderPipeline* m_solidShader = nullptr;
boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */ boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */
@ -81,8 +81,8 @@ public:
}; };
protected: protected:
View(ViewSystem& system, View& parentView); View(ViewResources& res, View& parentView);
void commitResources(ViewSystem& system); void commitResources(ViewResources& res);
public: public:
virtual ~View() {} virtual ~View() {}

View File

@ -0,0 +1,42 @@
#ifndef SPECTER_VIEWRESOURCES_HPP
#define SPECTER_VIEWRESOURCES_HPP
#include "TextView.hpp"
#include "RootView.hpp"
namespace Specter
{
class ViewResources
{
template <class Factory>
void init(Factory* factory, FontCache* fcache)
{
m_viewRes.init(factory);
m_textRes.init(factory, fcache);
m_splitViewRes.init(factory);
}
public:
boo::IGraphicsDataFactory* m_factory = nullptr;
View::Resources m_viewRes;
TextView::Resources m_textRes;
SplitView::Resources m_splitViewRes;
std::unique_ptr<boo::IGraphicsData> m_resData;
Specter::FontTag m_mainFont;
Specter::FontTag m_monoFont;
Specter::FontTag m_heading14;
Specter::FontTag m_heading18;
ViewResources() = default;
ViewResources(const ViewResources& other) = delete;
ViewResources(ViewResources&& other) = default;
ViewResources& operator=(const ViewResources& other) = delete;
ViewResources& operator=(ViewResources&& other) = default;
void init(boo::IGraphicsDataFactory* factory, FontCache* fcache, float pixelScale);
};
}
#endif // SPECTER_VIEWRESOURCES_HPP

View File

@ -1,39 +0,0 @@
#ifndef SPECTER_VIEWSYSTEM_HPP
#define SPECTER_VIEWSYSTEM_HPP
#include "TextView.hpp"
#include "RootView.hpp"
namespace Specter
{
class ViewSystem
{
template <class Factory>
void init(Factory* factory, FontCache* fcache)
{
m_viewSystem.init(factory);
m_textSystem.init(factory, fcache);
m_splitViewSystem.init(factory);
}
public:
boo::IGraphicsDataFactory* m_factory = nullptr;
View::System m_viewSystem;
TextView::System m_textSystem;
RootView::SplitView::System m_splitViewSystem;
std::unique_ptr<boo::IGraphicsData> m_sysData;
Specter::FontTag m_mainFont;
Specter::FontTag m_monoFont;
ViewSystem() = default;
ViewSystem(const ViewSystem& other) = delete;
ViewSystem(ViewSystem&& other) = default;
ViewSystem& operator=(const ViewSystem& other) = delete;
ViewSystem& operator=(ViewSystem&& other) = default;
void init(boo::IGraphicsDataFactory* factory, FontCache* fcache);
};
}
#endif // SPECTER_VIEWSYSTEM_HPP

View File

@ -248,7 +248,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
unsigned fullTexmapLayers = 0; unsigned fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter(charcode)) if (!filter.second(charcode))
{ {
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue; continue;
@ -313,7 +313,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0; fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter(charcode)) if (!filter.second(charcode))
{ {
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue; continue;
@ -388,7 +388,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0; fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter(charcode)) if (!filter.second(charcode))
{ {
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue; continue;
@ -458,7 +458,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
FT_ULong charcode = FT_Get_First_Char(face, &gindex); FT_ULong charcode = FT_Get_First_Char(face, &gindex);
while (gindex != 0) while (gindex != 0)
{ {
if (!filter(charcode)) if (!filter.second(charcode))
{ {
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue; continue;
@ -502,7 +502,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0; fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter(charcode)) if (!filter.second(charcode))
{ {
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue; continue;
@ -579,7 +579,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0; fullTexmapLayers = 0;
while (gindex != 0) while (gindex != 0)
{ {
if (!filter(charcode)) if (!filter.second(charcode))
{ {
charcode = FT_Get_Next_Char(face, charcode, &gindex); charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue; continue;
@ -665,7 +665,7 @@ FontTag FontCache::prepCustomFont(boo::IGraphicsDataFactory* gf, const std::stri
FT_Set_Char_Size(face, 0, points * 64.0, 0, dpi); FT_Set_Char_Size(face, 0, points * 64.0, 0, dpi);
/* Make tag and search for cached version */ /* Make tag and search for cached version */
FontTag tag(name, subpixel, points, dpi); FontTag tag(name + '_' + filter.first, subpixel, points, dpi);
auto search = m_cachedAtlases.find(tag); auto search = m_cachedAtlases.find(tag);
if (search != m_cachedAtlases.end()) if (search != m_cachedAtlases.end())
return tag; return tag;

View File

@ -1,32 +1,32 @@
#include "Specter/MultiLineTextView.hpp" #include "Specter/MultiLineTextView.hpp"
#include "Specter/ViewSystem.hpp" #include "Specter/ViewResources.hpp"
namespace Specter namespace Specter
{ {
static LogVisor::LogModule Log("Specter::MultiLineTextView"); static LogVisor::LogModule Log("Specter::MultiLineTextView");
MultiLineTextView::MultiLineTextView(ViewSystem& system, MultiLineTextView::MultiLineTextView(ViewResources& res,
View& parentView, View& parentView,
const FontAtlas& font, const FontAtlas& font,
size_t lineCapacity, size_t lineCapacity,
float lineHeight) float lineHeight)
: View(system, parentView), : View(res, parentView),
m_viewSystem(system), m_viewSystem(res),
m_fontAtlas(font), m_fontAtlas(font),
m_lineCapacity(lineCapacity), m_lineCapacity(lineCapacity),
m_lineHeight(lineHeight) m_lineHeight(lineHeight)
{ {
commitResources(system); commitResources(res);
} }
MultiLineTextView::MultiLineTextView(ViewSystem& system, MultiLineTextView::MultiLineTextView(ViewResources& res,
View& parentView, View& parentView,
FontTag font, FontTag font,
size_t lineCapacity, size_t lineCapacity,
float lineHeight) float lineHeight)
: MultiLineTextView(system, : MultiLineTextView(res,
parentView, parentView,
system.m_textSystem.m_fcache->lookupAtlas(font), res.m_textRes.m_fcache->lookupAtlas(font),
lineCapacity, lineCapacity,
lineHeight) {} lineHeight) {}

View File

@ -1,11 +1,11 @@
#include "Specter/RootView.hpp" #include "Specter/RootView.hpp"
#include "Specter/ViewSystem.hpp" #include "Specter/ViewResources.hpp"
namespace Specter namespace Specter
{ {
static LogVisor::LogModule Log("Specter::RootView"); static LogVisor::LogModule Log("Specter::RootView");
RootView::RootView(ViewSystem& system, boo::IWindow* window) RootView::RootView(ViewResources& system, boo::IWindow* window)
: View(system, *this), m_window(window) : View(system, *this), m_window(window)
{ {
window->setCallback(this); window->setCallback(this);
@ -13,8 +13,8 @@ RootView::RootView(ViewSystem& system, boo::IWindow* window)
m_renderTex = system.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1); m_renderTex = system.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1);
commitResources(system); commitResources(system);
m_splitView.reset(new SplitView(system, *this, SplitView::Axis::Horizontal)); m_splitView.reset(new SplitView(system, *this, SplitView::Axis::Horizontal));
MultiLineTextView* textView1 = new MultiLineTextView(system, *this, system.m_mainFont); MultiLineTextView* textView1 = new MultiLineTextView(system, *this, system.m_heading18);
MultiLineTextView* textView2 = new MultiLineTextView(system, *this, system.m_mainFont); MultiLineTextView* textView2 = new MultiLineTextView(system, *this, system.m_heading18);
m_splitView->setContentView(0, std::unique_ptr<MultiLineTextView>(textView1)); m_splitView->setContentView(0, std::unique_ptr<MultiLineTextView>(textView1));
m_splitView->setContentView(1, std::unique_ptr<MultiLineTextView>(textView2)); m_splitView->setContentView(1, std::unique_ptr<MultiLineTextView>(textView2));
resized(rect); resized(rect);
@ -124,160 +124,4 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
gfxQ->resolveDisplay(m_renderTex); gfxQ->resolveDisplay(m_renderTex);
} }
void RootView::SplitView::System::init(boo::IGraphicsDataFactory* factory)
{
static const Zeus::RGBA32 tex[3] =
{
{0,0,0,64},
{0,0,0,255},
{255,255,255,64}
};
m_shadingTex = factory->newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, tex, 12);
}
RootView::SplitView::SplitView(ViewSystem& system, View& parentView, Axis axis)
: View(system, parentView), m_axis(axis)
{
m_splitBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexBlock), 1);
m_splitVertsBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SplitVert), 4);
if (!system.m_viewSystem.m_texVtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{m_splitVertsBuf, nullptr, boo::VertexSemantic::Position4},
{m_splitVertsBuf, nullptr, boo::VertexSemantic::UV4}
};
m_splitVtxFmt = system.m_factory->newVertexFormat(2, vdescs);
boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf};
boo::ITexture* texs[] = {system.m_splitViewSystem.m_shadingTex};
m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewSystem.m_texShader,
m_splitVtxFmt, m_splitVertsBuf, nullptr,
nullptr, 1, bufs, 1, texs);
}
else
{
boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf};
boo::ITexture* texs[] = {system.m_splitViewSystem.m_shadingTex};
m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewSystem.m_texShader,
system.m_viewSystem.m_texVtxFmt,
m_splitVertsBuf, nullptr,
nullptr, 1, bufs, 1, texs);
}
commitResources(system);
}
void RootView::SplitView::setContentView(int slot, std::unique_ptr<View>&& view)
{
if (slot < 0 || slot > 1)
Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::setContentView");
m_views[slot] = std::move(view);
updateSize();
}
std::unique_ptr<View> RootView::SplitView::releaseContentView(int slot)
{
if (slot < 0 || slot > 1)
Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::releaseContentView");
std::unique_ptr<View> ret;
m_views[slot].swap(ret);
updateSize();
return ret;
}
void RootView::SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (button == boo::EMouseButton::Primary)
{
m_dragging = true;
if (m_axis == Axis::Horizontal)
setSlide(coord.pixel[1] / float(subRect().size[1]));
else if (m_axis == Axis::Vertical)
setSlide(coord.pixel[0] / float(subRect().size[0]));
}
}
void RootView::SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (button == boo::EMouseButton::Primary)
m_dragging = false;
}
void RootView::SplitView::mouseMove(const boo::SWindowCoord& coord)
{
if (m_axis == Axis::Horizontal)
{
if (m_dragging)
setSlide(coord.pixel[1] / float(subRect().size[1]));
int slidePx = subRect().size[1] * m_slide;
if (abs(int(coord.pixel[1]) - slidePx) < 4)
root().window()->setCursor(boo::EMouseCursor::VerticalArrow);
else
root().window()->setCursor(boo::EMouseCursor::Pointer);
}
else if (m_axis == Axis::Vertical)
{
if (m_dragging)
setSlide(coord.pixel[0] / float(subRect().size[0]));
int slidePx = subRect().size[0] * m_slide;
if (abs(int(coord.pixel[0]) - slidePx) < 4)
root().window()->setCursor(boo::EMouseCursor::HorizontalArrow);
else
root().window()->setCursor(boo::EMouseCursor::Pointer);
}
}
void RootView::SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
View::resized(root, sub);
if (m_axis == Axis::Horizontal)
{
boo::SWindowRect ssub = sub;
ssub.size[1] *= m_slide;
if (m_views[0])
m_views[0]->resized(root, ssub);
ssub.location[1] += ssub.size[1];
ssub.size[1] = sub.size[1] - ssub.size[1];
if (m_views[1])
m_views[1]->resized(root, ssub);
m_splitBlock.setViewRect(root, ssub);
setHorizontalVerts(ssub.size[0]);
}
else if (m_axis == Axis::Vertical)
{
boo::SWindowRect ssub = sub;
ssub.size[0] *= m_slide;
if (m_views[0])
m_views[0]->resized(root, ssub);
ssub.location[0] += ssub.size[0];
ssub.size[0] = sub.size[0] - ssub.size[0];
if (m_views[1])
m_views[1]->resized(root, ssub);
m_splitBlock.setViewRect(root, ssub);
setVerticalVerts(ssub.size[1]);
}
m_splitValidSlots = 0;
}
void RootView::SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
{
View::draw(gfxQ);
if (m_views[0])
m_views[0]->draw(gfxQ);
if (m_views[1])
m_views[1]->draw(gfxQ);
int pendingSlot = 1 << gfxQ->pendingDynamicSlot();
if ((m_splitValidSlots & pendingSlot) == 0)
{
m_splitBlockBuf->load(&m_splitBlock, sizeof(VertexBlock));
m_splitVertsBuf->load(m_splitVerts, sizeof(SplitVert) * 4);
m_splitValidSlots |= pendingSlot;
}
gfxQ->setShaderDataBinding(m_splitShaderBinding);
gfxQ->draw(0, 4);
}
} }

View File

@ -3,7 +3,7 @@
namespace Specter namespace Specter
{ {
ScrollView::ScrollView(ViewSystem& system, View& parentView, View& contentView) ScrollView::ScrollView(ViewResources& system, View& parentView, View& contentView)
: View(system, parentView), m_contentView(contentView) : View(system, parentView), m_contentView(contentView)
{ {
} }

View File

@ -1,14 +1,16 @@
#include "Specter/ViewSystem.hpp" #include "Specter/ViewResources.hpp"
namespace Specter namespace Specter
{ {
static LogVisor::LogModule Log("Specter"); static LogVisor::LogModule Log("Specter");
void ViewSystem::init(boo::IGraphicsDataFactory* factory, FontCache* fcache) void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, float pixelScale)
{ {
m_factory = factory; m_factory = factory;
m_mainFont = fcache->prepMainFont(factory, FontCache::DefaultCharFilter, false, 10.0, 72); m_mainFont = fcache->prepMainFont(factory, AllCharFilter, false, 10.0, 72 * pixelScale);
m_monoFont = fcache->prepMonoFont(factory, FontCache::DefaultCharFilter, false, 10.0, 72); m_monoFont = fcache->prepMonoFont(factory, AllCharFilter, false, 10.0, 72 * pixelScale);
m_heading14 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 14.0, 72 * pixelScale);
m_heading18 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 18.0, 72 * pixelScale);
switch (factory->platform()) switch (factory->platform())
{ {
case boo::IGraphicsDataFactory::Platform::OGL: case boo::IGraphicsDataFactory::Platform::OGL:
@ -28,7 +30,7 @@ void ViewSystem::init(boo::IGraphicsDataFactory* factory, FontCache* fcache)
Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName()); Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName());
} }
fcache->closeBuiltinFonts(); fcache->closeBuiltinFonts();
m_sysData.reset(factory->commit()); m_resData.reset(factory->commit());
} }
} }

159
specter/lib/SplitView.cpp Normal file
View File

@ -0,0 +1,159 @@
#include <LogVisor/LogVisor.hpp>
#include "Specter/SplitView.hpp"
#include "Specter/ViewResources.hpp"
namespace Specter
{
static LogVisor::LogModule Log("Specter::SplitView");
void SplitView::Resources::init(boo::IGraphicsDataFactory* factory)
{
static const Zeus::RGBA32 tex[3] =
{
{0,0,0,64},
{0,0,0,255},
{255,255,255,64}
};
m_shadingTex = factory->newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, tex, 12);
}
SplitView::SplitView(ViewResources& system, View& parentView, Axis axis)
: View(system, parentView), m_axis(axis)
{
m_splitBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexBlock), 1);
m_splitVertsBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SplitVert), 4);
if (!system.m_viewRes.m_texVtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{m_splitVertsBuf, nullptr, boo::VertexSemantic::Position4},
{m_splitVertsBuf, nullptr, boo::VertexSemantic::UV4}
};
m_splitVtxFmt = system.m_factory->newVertexFormat(2, vdescs);
boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf};
boo::ITexture* texs[] = {system.m_splitViewRes.m_shadingTex};
m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader,
m_splitVtxFmt, m_splitVertsBuf, nullptr,
nullptr, 1, bufs, 1, texs);
}
else
{
boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf};
boo::ITexture* texs[] = {system.m_splitViewRes.m_shadingTex};
m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader,
system.m_viewRes.m_texVtxFmt,
m_splitVertsBuf, nullptr,
nullptr, 1, bufs, 1, texs);
}
commitResources(system);
}
std::unique_ptr<View> SplitView::setContentView(int slot, std::unique_ptr<View>&& view)
{
if (slot < 0 || slot > 1)
Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::setContentView");
std::unique_ptr<View> ret;
m_views[slot].swap(ret);
m_views[slot] = std::move(view);
updateSize();
return ret;
}
void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (button == boo::EMouseButton::Primary)
{
m_dragging = true;
if (m_axis == Axis::Horizontal)
setSlide(coord.pixel[1] / float(subRect().size[1]));
else if (m_axis == Axis::Vertical)
setSlide(coord.pixel[0] / float(subRect().size[0]));
}
}
void SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (button == boo::EMouseButton::Primary)
m_dragging = false;
}
void SplitView::mouseMove(const boo::SWindowCoord& coord)
{
if (m_axis == Axis::Horizontal)
{
if (m_dragging)
setSlide(coord.pixel[1] / float(subRect().size[1]));
int slidePx = subRect().size[1] * m_slide;
if (abs(int(coord.pixel[1]) - slidePx) < 4)
root().window()->setCursor(boo::EMouseCursor::VerticalArrow);
else
root().window()->setCursor(boo::EMouseCursor::Pointer);
}
else if (m_axis == Axis::Vertical)
{
if (m_dragging)
setSlide(coord.pixel[0] / float(subRect().size[0]));
int slidePx = subRect().size[0] * m_slide;
if (abs(int(coord.pixel[0]) - slidePx) < 4)
root().window()->setCursor(boo::EMouseCursor::HorizontalArrow);
else
root().window()->setCursor(boo::EMouseCursor::Pointer);
}
}
void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
View::resized(root, sub);
if (m_axis == Axis::Horizontal)
{
boo::SWindowRect ssub = sub;
ssub.size[1] *= m_slide;
if (m_views[0])
m_views[0]->resized(root, ssub);
ssub.location[1] += ssub.size[1];
ssub.size[1] = sub.size[1] - ssub.size[1];
if (m_views[1])
m_views[1]->resized(root, ssub);
m_splitBlock.setViewRect(root, ssub);
setHorizontalVerts(ssub.size[0]);
}
else if (m_axis == Axis::Vertical)
{
boo::SWindowRect ssub = sub;
ssub.size[0] *= m_slide;
if (m_views[0])
m_views[0]->resized(root, ssub);
ssub.location[0] += ssub.size[0];
ssub.size[0] = sub.size[0] - ssub.size[0];
if (m_views[1])
m_views[1]->resized(root, ssub);
m_splitBlock.setViewRect(root, ssub);
setVerticalVerts(ssub.size[1]);
}
m_splitValidSlots = 0;
}
void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
{
View::draw(gfxQ);
if (m_views[0])
m_views[0]->draw(gfxQ);
if (m_views[1])
m_views[1]->draw(gfxQ);
int pendingSlot = 1 << gfxQ->pendingDynamicSlot();
if ((m_splitValidSlots & pendingSlot) == 0)
{
m_splitBlockBuf->load(&m_splitBlock, sizeof(VertexBlock));
m_splitVertsBuf->load(m_splitVerts, sizeof(SplitVert) * 4);
m_splitValidSlots |= pendingSlot;
}
gfxQ->setShaderDataBinding(m_splitShaderBinding);
gfxQ->draw(0, 4);
}
}

View File

@ -1,5 +1,5 @@
#include "Specter/TextView.hpp" #include "Specter/TextView.hpp"
#include "Specter/ViewSystem.hpp" #include "Specter/ViewResources.hpp"
#include "utf8proc.h" #include "utf8proc.h"
#include <freetype/internal/internal.h> #include <freetype/internal/internal.h>
@ -9,7 +9,7 @@ namespace Specter
{ {
static LogVisor::LogModule Log("Specter::TextView"); static LogVisor::LogModule Log("Specter::TextView");
void TextView::System::init(boo::GLDataFactory* factory, FontCache* fcache) void TextView::Resources::init(boo::GLDataFactory* factory, FontCache* fcache)
{ {
m_fcache = fcache; m_fcache = fcache;
@ -259,7 +259,7 @@ void TextView::System::init(boo::MetalDataFactory* factory, FontCache* fcache)
#endif #endif
TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font, size_t capacity) TextView::TextView(ViewResources& system, View& parentView, const FontAtlas& font, size_t capacity)
: View(system, parentView), : View(system, parentView),
m_capacity(capacity), m_capacity(capacity),
m_fontAtlas(font) m_fontAtlas(font)
@ -270,11 +270,11 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font,
boo::IShaderPipeline* shader; boo::IShaderPipeline* shader;
if (font.subpixel()) if (font.subpixel())
shader = system.m_textSystem.m_subpixel; shader = system.m_textRes.m_subpixel;
else else
shader = system.m_textSystem.m_regular; shader = system.m_textRes.m_regular;
if (!system.m_textSystem.m_vtxFmt) if (!system.m_textRes.m_vtxFmt)
{ {
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor vdescs[] =
{ {
@ -302,7 +302,7 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font,
else else
{ {
boo::ITexture* texs[] = {m_fontAtlas.texture()}; boo::ITexture* texs[] = {m_fontAtlas.texture()};
m_shaderBinding = system.m_factory->newShaderDataBinding(shader, system.m_textSystem.m_vtxFmt, m_shaderBinding = system.m_factory->newShaderDataBinding(shader, system.m_textRes.m_vtxFmt,
nullptr, m_glyphBuf, nullptr, 1, nullptr, m_glyphBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
1, texs); 1, texs);
@ -312,8 +312,8 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font,
commitResources(system); commitResources(system);
} }
TextView::TextView(ViewSystem& system, View& parentView, FontTag font, size_t capacity) TextView::TextView(ViewResources& system, View& parentView, FontTag font, size_t capacity)
: TextView(system, parentView, system.m_textSystem.m_fcache->lookupAtlas(font), capacity) {} : TextView(system, parentView, system.m_textRes.m_fcache->lookupAtlas(font), capacity) {}
TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor) TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor)
{ {

View File

@ -1,11 +1,11 @@
#include "Specter/View.hpp" #include "Specter/View.hpp"
#include "Specter/ViewSystem.hpp" #include "Specter/ViewResources.hpp"
#include "Specter/RootView.hpp" #include "Specter/RootView.hpp"
namespace Specter namespace Specter
{ {
void View::System::init(boo::GLDataFactory* factory) void View::Resources::init(boo::GLDataFactory* factory)
{ {
static const char* SolidVS = static const char* SolidVS =
"#version 330\n" "#version 330\n"
@ -274,7 +274,7 @@ void View::System::init(boo::MetalDataFactory* factory)
#endif #endif
void View::buildResources(ViewSystem& system) void View::buildResources(ViewResources& system)
{ {
m_bgColor = Zeus::CColor::skClear; m_bgColor = Zeus::CColor::skClear;
@ -290,7 +290,7 @@ void View::buildResources(ViewSystem& system)
system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform,
sizeof(VertexBlock), 1); sizeof(VertexBlock), 1);
if (!system.m_viewSystem.m_solidVtxFmt) if (!system.m_viewRes.m_solidVtxFmt)
{ {
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor vdescs[] =
{ {
@ -299,7 +299,7 @@ void View::buildResources(ViewSystem& system)
}; };
m_bgVtxFmt = system.m_factory->newVertexFormat(2, vdescs); m_bgVtxFmt = system.m_factory->newVertexFormat(2, vdescs);
m_bgShaderBinding = m_bgShaderBinding =
system.m_factory->newShaderDataBinding(system.m_viewSystem.m_solidShader, m_bgVtxFmt, system.m_factory->newShaderDataBinding(system.m_viewRes.m_solidShader, m_bgVtxFmt,
m_bgVertBuf, m_bgInstBuf, nullptr, 1, m_bgVertBuf, m_bgInstBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
0, nullptr); 0, nullptr);
@ -307,21 +307,21 @@ void View::buildResources(ViewSystem& system)
else else
{ {
m_bgShaderBinding = m_bgShaderBinding =
system.m_factory->newShaderDataBinding(system.m_viewSystem.m_solidShader, system.m_viewSystem.m_solidVtxFmt, system.m_factory->newShaderDataBinding(system.m_viewRes.m_solidShader, system.m_viewRes.m_solidVtxFmt,
m_bgVertBuf, m_bgInstBuf, nullptr, 1, m_bgVertBuf, m_bgInstBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
0, nullptr); 0, nullptr);
} }
} }
View::View(ViewSystem& system, RootView& rootView) View::View(ViewResources& system, RootView& rootView)
: m_rootView(rootView), : m_rootView(rootView),
m_parentView(rootView) m_parentView(rootView)
{ {
buildResources(system); buildResources(system);
} }
View::View(ViewSystem& system, View& parentView) View::View(ViewResources& system, View& parentView)
: m_rootView(parentView.root()), : m_rootView(parentView.root()),
m_parentView(parentView) m_parentView(parentView)
{ {
@ -359,7 +359,7 @@ void View::draw(boo::IGraphicsCommandQueue* gfxQ)
gfxQ->draw(0, 4); gfxQ->draw(0, 4);
} }
void View::commitResources(ViewSystem& system) void View::commitResources(ViewResources& system)
{ {
m_gfxData.reset(system.m_factory->commit()); m_gfxData.reset(system.m_factory->commit());
} }