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
include/Specter/Specter.hpp
include/Specter/ViewSystem.hpp
include/Specter/ViewResources.hpp
include/Specter/View.hpp
include/Specter/RootView.hpp
include/Specter/SplitView.hpp
include/Specter/ScrollView.hpp
include/Specter/TextView.hpp
include/Specter/MultiLineTextView.hpp
@ -56,6 +57,7 @@ list(APPEND SPECTER_SOURCES
lib/Specter.cpp
lib/View.cpp
lib/RootView.cpp
lib/SplitView.cpp
lib/ScrollView.cpp
lib/TextView.cpp
lib/MultiLineTextView.cpp

View File

@ -52,7 +52,7 @@ public:
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
{
@ -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
{
const HECL::Runtime::FileStoreManager& m_fileMgr;
@ -173,17 +185,15 @@ public:
FontCache(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,
FCharFilter filter=DefaultCharFilter, bool subpixel=false,
FCharFilter filter=AllCharFilter, bool subpixel=false,
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)
{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)
{return prepCustomFont(gf, "bmonofont", m_monoFace, filter, subpixel, points, dpi);}

View File

@ -10,14 +10,14 @@ namespace Specter
class MultiLineTextView : public View
{
ViewSystem& m_viewSystem;
ViewResources& m_viewSystem;
std::vector<std::unique_ptr<TextView>> m_lines;
const FontAtlas& m_fontAtlas;
size_t m_lineCapacity;
float m_lineHeight;
public:
MultiLineTextView(ViewSystem& system, 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, const FontAtlas& 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,
const Zeus::CColor& defaultColor=Zeus::CColor::skWhite);

View File

@ -3,12 +3,13 @@
#include "View.hpp"
#include "MultiLineTextView.hpp"
#include "SplitView.hpp"
#include "FontCache.hpp"
#include <boo/boo.hpp>
namespace Specter
{
class ViewSystem;
class ViewResources;
class RootView : public View, public boo::IWindowCallback
{
@ -19,7 +20,7 @@ class RootView : public View, public boo::IWindowCallback
bool m_destroyed = false;
public:
RootView(ViewSystem& system, boo::IWindow* window);
RootView(ViewResources& res, boo::IWindow* window);
void destroyed();
bool isDestroyed() const {return m_destroyed;}
@ -49,82 +50,6 @@ public:
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:
std::unique_ptr<SplitView> m_splitView;
};

View File

@ -5,13 +5,13 @@
namespace Specter
{
class ViewSystem;
class ViewResources;
class ScrollView : public View
{
View& m_contentView;
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 "NodeSocket.hpp"
#include "FontCache.hpp"
#include "ViewSystem.hpp"
#include "ViewResources.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
{
class ViewSystem;
class ViewResources;
class TextView : public View
{
@ -22,9 +22,9 @@ class TextView : public View
int m_validSlots = 0;
public:
class System
class Resources
{
friend class ViewSystem;
friend class ViewResources;
friend class TextView;
friend class MultiLineTextView;
FontCache* m_fcache = nullptr;
@ -40,8 +40,8 @@ public:
#endif
};
TextView(ViewSystem& system, 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, const FontAtlas& font, size_t capacity=256);
TextView(ViewResources& res, View& parentView, FontTag font, size_t capacity=256);
struct RenderGlyph
{

View File

@ -13,7 +13,7 @@
namespace Specter
{
class ViewSystem;
class ViewResources;
class RootView;
class View
@ -31,8 +31,8 @@ class View
std::unique_ptr<boo::IGraphicsData> m_gfxData;
friend class RootView;
void buildResources(ViewSystem& system);
View(ViewSystem& system, RootView& parentView);
void buildResources(ViewResources& res);
View(ViewResources& res, RootView& parentView);
protected:
struct VertexBlock
@ -64,7 +64,7 @@ protected:
boo::IGraphicsBufferD* m_viewVertBlockBuf;
public:
struct System
struct Resources
{
boo::IShaderPipeline* m_solidShader = nullptr;
boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */
@ -81,8 +81,8 @@ public:
};
protected:
View(ViewSystem& system, View& parentView);
void commitResources(ViewSystem& system);
View(ViewResources& res, View& parentView);
void commitResources(ViewResources& res);
public:
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;
while (gindex != 0)
{
if (!filter(charcode))
if (!filter.second(charcode))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue;
@ -313,7 +313,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0;
while (gindex != 0)
{
if (!filter(charcode))
if (!filter.second(charcode))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue;
@ -388,7 +388,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0;
while (gindex != 0)
{
if (!filter(charcode))
if (!filter.second(charcode))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
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);
while (gindex != 0)
{
if (!filter(charcode))
if (!filter.second(charcode))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue;
@ -502,7 +502,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0;
while (gindex != 0)
{
if (!filter(charcode))
if (!filter.second(charcode))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
continue;
@ -579,7 +579,7 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
fullTexmapLayers = 0;
while (gindex != 0)
{
if (!filter(charcode))
if (!filter.second(charcode))
{
charcode = FT_Get_Next_Char(face, charcode, &gindex);
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);
/* 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);
if (search != m_cachedAtlases.end())
return tag;

View File

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

View File

@ -1,11 +1,11 @@
#include "Specter/RootView.hpp"
#include "Specter/ViewSystem.hpp"
#include "Specter/ViewResources.hpp"
namespace Specter
{
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)
{
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);
commitResources(system);
m_splitView.reset(new SplitView(system, *this, SplitView::Axis::Horizontal));
MultiLineTextView* textView1 = new MultiLineTextView(system, *this, system.m_mainFont);
MultiLineTextView* textView2 = new MultiLineTextView(system, *this, system.m_mainFont);
MultiLineTextView* textView1 = new MultiLineTextView(system, *this, system.m_heading18);
MultiLineTextView* textView2 = new MultiLineTextView(system, *this, system.m_heading18);
m_splitView->setContentView(0, std::unique_ptr<MultiLineTextView>(textView1));
m_splitView->setContentView(1, std::unique_ptr<MultiLineTextView>(textView2));
resized(rect);
@ -124,160 +124,4 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
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
{
ScrollView::ScrollView(ViewSystem& system, View& parentView, View& contentView)
ScrollView::ScrollView(ViewResources& system, View& parentView, View& contentView)
: View(system, parentView), m_contentView(contentView)
{
}

View File

@ -1,14 +1,16 @@
#include "Specter/ViewSystem.hpp"
#include "Specter/ViewResources.hpp"
namespace 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_mainFont = fcache->prepMainFont(factory, FontCache::DefaultCharFilter, false, 10.0, 72);
m_monoFont = fcache->prepMonoFont(factory, FontCache::DefaultCharFilter, false, 10.0, 72);
m_mainFont = fcache->prepMainFont(factory, AllCharFilter, false, 10.0, 72 * pixelScale);
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())
{
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());
}
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/ViewSystem.hpp"
#include "Specter/ViewResources.hpp"
#include "utf8proc.h"
#include <freetype/internal/internal.h>
@ -9,7 +9,7 @@ namespace Specter
{
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;
@ -259,7 +259,7 @@ void TextView::System::init(boo::MetalDataFactory* factory, FontCache* fcache)
#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),
m_capacity(capacity),
m_fontAtlas(font)
@ -270,11 +270,11 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font,
boo::IShaderPipeline* shader;
if (font.subpixel())
shader = system.m_textSystem.m_subpixel;
shader = system.m_textRes.m_subpixel;
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[] =
{
@ -302,7 +302,7 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font,
else
{
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,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
1, texs);
@ -312,8 +312,8 @@ TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font,
commitResources(system);
}
TextView::TextView(ViewSystem& system, View& parentView, FontTag font, size_t capacity)
: TextView(system, parentView, system.m_textSystem.m_fcache->lookupAtlas(font), capacity) {}
TextView::TextView(ViewResources& system, View& parentView, FontTag font, size_t 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)
{

View File

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