mirror of https://github.com/AxioDL/metaforce.git
Text system updates
This commit is contained in:
parent
4ede0d6858
commit
b4ffb13903
|
@ -34,7 +34,9 @@ list(APPEND SPECTER_HEADERS
|
|||
include/Specter/ViewSystem.hpp
|
||||
include/Specter/View.hpp
|
||||
include/Specter/RootView.hpp
|
||||
include/Specter/ScrollView.hpp
|
||||
include/Specter/TextView.hpp
|
||||
include/Specter/MultiLineTextView.hpp
|
||||
include/Specter/Space.hpp
|
||||
include/Specter/Table.hpp
|
||||
include/Specter/Outliner.hpp
|
||||
|
@ -54,7 +56,9 @@ list(APPEND SPECTER_SOURCES
|
|||
lib/Specter.cpp
|
||||
lib/View.cpp
|
||||
lib/RootView.cpp
|
||||
lib/ScrollView.cpp
|
||||
lib/TextView.cpp
|
||||
lib/MultiLineTextView.cpp
|
||||
lib/Space.cpp
|
||||
lib/Table.cpp
|
||||
lib/Outliner.cpp
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f075c38a4cb65ce4d1e812a308de45b41cb88eb8
|
||||
Subproject commit 9885d34420ec70ba52d8270b4e0a9ddc22663dea
|
|
@ -62,6 +62,8 @@ class FontAtlas
|
|||
uint32_t m_dpi;
|
||||
FT_Fixed m_ftXscale;
|
||||
FT_UShort m_ftXPpem;
|
||||
FT_Pos m_lineHeight;
|
||||
bool m_subpixel;
|
||||
|
||||
public:
|
||||
struct Glyph
|
||||
|
@ -120,7 +122,9 @@ public:
|
|||
uint32_t dpi() const {return m_dpi;}
|
||||
FT_Fixed FT_Xscale() const {return m_ftXscale;}
|
||||
FT_UShort FT_XPPem() const {return m_ftXPpem;}
|
||||
FT_Pos FT_LineHeight() const {return m_lineHeight;}
|
||||
boo::ITexture* texture() const {return m_tex;}
|
||||
bool subpixel() const {return m_subpixel;}
|
||||
|
||||
const Glyph* lookupGlyph(atUint32 charcode) const
|
||||
{
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef SPECTER_MULTILINETEXTVIEW_HPP
|
||||
#define SPECTER_MULTILINETEXTVIEW_HPP
|
||||
|
||||
#include "View.hpp"
|
||||
#include "TextView.hpp"
|
||||
#include "FontCache.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
|
||||
class MultiLineTextView : public View
|
||||
{
|
||||
ViewSystem& m_viewSystem;
|
||||
std::vector<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);
|
||||
|
||||
void typesetGlyphs(const std::string& str,
|
||||
const Zeus::CColor& defaultColor=Zeus::CColor::skWhite);
|
||||
void typesetGlyphs(const std::wstring& str,
|
||||
const Zeus::CColor& defaultColor=Zeus::CColor::skWhite);
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_MULTILINETEXTVIEW_HPP
|
|
@ -2,7 +2,7 @@
|
|||
#define SPECTER_ROOTVIEW_HPP
|
||||
|
||||
#include "View.hpp"
|
||||
#include "TextView.hpp"
|
||||
#include "MultiLineTextView.hpp"
|
||||
#include "FontCache.hpp"
|
||||
#include <boo/boo.hpp>
|
||||
|
||||
|
@ -14,7 +14,7 @@ class RootView : public View, public boo::IWindowCallback
|
|||
{
|
||||
boo::IWindow* m_window = nullptr;
|
||||
boo::ITextureR* m_renderTex = nullptr;
|
||||
TextView m_textView;
|
||||
MultiLineTextView m_textView;
|
||||
boo::SWindowRect m_rootRect;
|
||||
bool m_resizeRTDirty = false;
|
||||
bool m_destroyed = false;
|
||||
|
@ -46,6 +46,8 @@ public:
|
|||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
RootView(ViewSystem& system, boo::IWindow* window);
|
||||
|
||||
const boo::SWindowRect& rootRect() const {return m_rootRect;}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef SPECTER_SCROLLVIEW_HPP
|
||||
#define SPECTER_SCROLLVIEW_HPP
|
||||
|
||||
#include "View.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
class ViewSystem;
|
||||
|
||||
class ScrollView : public View
|
||||
{
|
||||
View& m_contentView;
|
||||
public:
|
||||
ScrollView(ViewSystem& system, View& parentView, View& contentView);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_SCROLLVIEW_HPP
|
|
@ -26,6 +26,7 @@ public:
|
|||
{
|
||||
friend class ViewSystem;
|
||||
friend class TextView;
|
||||
friend class MultiLineTextView;
|
||||
FontCache* m_fcache = nullptr;
|
||||
boo::IShaderPipeline* m_regular = nullptr;
|
||||
boo::IShaderPipeline* m_subpixel = nullptr;
|
||||
|
@ -39,7 +40,8 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
TextView(ViewSystem& system, FontTag font, size_t capacity=256);
|
||||
TextView(ViewSystem& system, View& parentView, const FontAtlas& font, size_t capacity=256);
|
||||
TextView(ViewSystem& system, View& parentView, FontTag font, size_t capacity=256);
|
||||
|
||||
struct RenderGlyph
|
||||
{
|
||||
|
|
|
@ -14,9 +14,13 @@
|
|||
namespace Specter
|
||||
{
|
||||
class ViewSystem;
|
||||
class RootView;
|
||||
|
||||
class View
|
||||
{
|
||||
RootView& m_rootView;
|
||||
View& m_parentView;
|
||||
boo::SWindowRect m_subRect;
|
||||
boo::IGraphicsBufferD* m_bgVertBuf;
|
||||
boo::IGraphicsBufferD* m_bgInstBuf;
|
||||
boo::IVertexFormat* m_bgVtxFmt = nullptr; /* OpenGL only */
|
||||
|
@ -25,6 +29,10 @@ class View
|
|||
Zeus::CColor m_bgColor;
|
||||
int m_bgValidSlots = 0;
|
||||
|
||||
friend class RootView;
|
||||
void buildResources(ViewSystem& system);
|
||||
View(ViewSystem& system, RootView& parentView);
|
||||
|
||||
protected:
|
||||
struct VertexBlock
|
||||
{
|
||||
|
@ -71,10 +79,15 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
View(ViewSystem& system);
|
||||
View(ViewSystem& system, View& parentView);
|
||||
|
||||
public:
|
||||
View() = delete;
|
||||
|
||||
View& parent() {return m_parentView;}
|
||||
RootView& root() {return m_rootView;}
|
||||
void updateSize();
|
||||
|
||||
void setBackground(Zeus::CColor color) {m_bgColor = color; m_bgValidSlots = 0;}
|
||||
virtual void resized(const boo::SWindowRect &root, const boo::SWindowRect& sub);
|
||||
virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
|
|
@ -221,7 +221,9 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
|
|||
bool subpixel, FCharFilter& filter, Athena::io::FileWriter& writer)
|
||||
: m_dpi(dpi),
|
||||
m_ftXscale(face->size->metrics.x_scale),
|
||||
m_ftXPpem(face->size->metrics.x_ppem)
|
||||
m_ftXPpem(face->size->metrics.x_ppem),
|
||||
m_lineHeight(face->size->metrics.height),
|
||||
m_subpixel(subpixel)
|
||||
{
|
||||
FT_Int32 baseFlags = FT_LOAD_NO_BITMAP;
|
||||
if (subpixel)
|
||||
|
@ -433,7 +435,9 @@ FontAtlas::FontAtlas(boo::IGraphicsDataFactory* gf, FT_Face face, uint32_t dpi,
|
|||
bool subpixel, FCharFilter& filter, Athena::io::FileReader& reader)
|
||||
: m_dpi(dpi),
|
||||
m_ftXscale(face->size->metrics.x_scale),
|
||||
m_ftXPpem(face->size->metrics.x_ppem)
|
||||
m_ftXPpem(face->size->metrics.x_ppem),
|
||||
m_lineHeight(face->size->metrics.height),
|
||||
m_subpixel(subpixel)
|
||||
{
|
||||
FT_Int32 baseFlags = FT_LOAD_NO_BITMAP;
|
||||
if (subpixel)
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#include "Specter/MultiLineTextView.hpp"
|
||||
#include "Specter/ViewSystem.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
static LogVisor::LogModule Log("Specter::MultiLineTextView");
|
||||
|
||||
MultiLineTextView::MultiLineTextView(ViewSystem& system,
|
||||
View& parentView,
|
||||
const FontAtlas& font,
|
||||
size_t lineCapacity,
|
||||
float lineHeight)
|
||||
: View(system, parentView),
|
||||
m_viewSystem(system),
|
||||
m_fontAtlas(font),
|
||||
m_lineCapacity(lineCapacity),
|
||||
m_lineHeight(lineHeight) {}
|
||||
|
||||
MultiLineTextView::MultiLineTextView(ViewSystem& system,
|
||||
View& parentView,
|
||||
FontTag font,
|
||||
size_t lineCapacity,
|
||||
float lineHeight)
|
||||
: MultiLineTextView(system,
|
||||
parentView,
|
||||
system.m_textSystem.m_fcache->lookupAtlas(font),
|
||||
lineCapacity,
|
||||
lineHeight) {}
|
||||
|
||||
void MultiLineTextView::typesetGlyphs(const std::string& str,
|
||||
const Zeus::CColor& defaultColor)
|
||||
{
|
||||
m_lines.clear();
|
||||
size_t rem = str.size() + 1;
|
||||
const utf8proc_uint8_t* it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
|
||||
size_t lineCount = 0;
|
||||
while (rem)
|
||||
{
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (sz < 0)
|
||||
Log.report(LogVisor::FatalError, "invalid UTF-8 char");
|
||||
if (ch == '\n' || ch == '\0')
|
||||
++lineCount;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
}
|
||||
|
||||
m_lines.reserve(lineCount);
|
||||
rem = str.size() + 1;
|
||||
it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
const utf8proc_uint8_t* beginIt = it;
|
||||
|
||||
while (rem)
|
||||
{
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (ch == '\n' || ch == '\0')
|
||||
{
|
||||
m_lines.emplace_back(m_viewSystem, *this, m_fontAtlas, m_lineCapacity);
|
||||
m_lines.back().typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor);
|
||||
beginIt = it + 1;
|
||||
}
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
}
|
||||
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void MultiLineTextView::typesetGlyphs(const std::wstring& str,
|
||||
const Zeus::CColor& defaultColor)
|
||||
{
|
||||
m_lines.clear();
|
||||
size_t rem = str.size() + 1;
|
||||
auto it = str.cbegin();
|
||||
|
||||
size_t lineCount = 0;
|
||||
while (rem)
|
||||
{
|
||||
if (*it == L'\n' || *it == L'\0')
|
||||
++lineCount;
|
||||
--rem;
|
||||
++it;
|
||||
}
|
||||
|
||||
m_lines.reserve(lineCount);
|
||||
rem = str.size() + 1;
|
||||
it = str.cbegin();
|
||||
auto beginIt = it;
|
||||
|
||||
while (rem)
|
||||
{
|
||||
if (*it == L'\n' || *it == L'\0')
|
||||
{
|
||||
m_lines.emplace_back(m_viewSystem, *this, m_fontAtlas, m_lineCapacity);
|
||||
m_lines.back().typesetGlyphs(std::wstring(beginIt, it), defaultColor);
|
||||
beginIt = it + 1;
|
||||
}
|
||||
--rem;
|
||||
++it;
|
||||
}
|
||||
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void MultiLineTextView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
unsigned lHeight = unsigned(m_lineHeight * m_fontAtlas.FT_LineHeight()) >> 6;
|
||||
unsigned decumHeight = lHeight * m_lines.size();
|
||||
boo::SWindowRect tsub = sub;
|
||||
tsub.location[1] += decumHeight;
|
||||
tsub.size[1] = 10;
|
||||
for (TextView& tv : m_lines)
|
||||
{
|
||||
tsub.location[1] -= lHeight;
|
||||
tv.resized(root, tsub);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiLineTextView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
for (TextView& tv : m_lines)
|
||||
tv.draw(gfxQ);
|
||||
}
|
||||
|
||||
}
|
|
@ -5,17 +5,17 @@ namespace Specter
|
|||
{
|
||||
|
||||
RootView::RootView(ViewSystem& system, boo::IWindow* window)
|
||||
: View(system), m_window(window), m_textView(system, system.m_mainFont)
|
||||
: View(system, *this), m_window(window), m_textView(system, *this, system.m_mainFont)
|
||||
{
|
||||
window->setCallback(this);
|
||||
boo::SWindowRect rect = window->getWindowFrame();
|
||||
m_renderTex = system.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1);
|
||||
system.m_factory->commit();
|
||||
resized(rect);
|
||||
m_textView.typesetGlyphs("Hello, World! — こんにちは世界!", Zeus::CColor::skGreen);
|
||||
m_textView.typesetGlyphs("Hello, World!\nこんにちは世界!\n\n", Zeus::CColor::skWhite);
|
||||
Zeus::CColor transBlack(0.f, 0.f, 0.f, 0.5f);
|
||||
m_textView.setBackground(transBlack);
|
||||
setBackground(Zeus::CColor::skBlue);
|
||||
setBackground(Zeus::CColor::skGrey);
|
||||
}
|
||||
|
||||
void RootView::destroyed()
|
||||
|
@ -34,14 +34,16 @@ void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&)
|
|||
m_rootRect.location[0] = 0;
|
||||
m_rootRect.location[1] = 0;
|
||||
View::resized(m_rootRect, m_rootRect);
|
||||
|
||||
boo::SWindowRect textRect = m_rootRect;
|
||||
textRect.location[0] = 10;
|
||||
textRect.location[1] = 10;
|
||||
textRect.size[0] -= 20;
|
||||
if (textRect.size[0] < 0)
|
||||
textRect.size[0] = 0;
|
||||
textRect.size[1] = 10;
|
||||
textRect.size[1] = 100;
|
||||
m_textView.resized(m_rootRect, textRect);
|
||||
|
||||
m_resizeRTDirty = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#include "Specter/ScrollView.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
|
||||
ScrollView::ScrollView(ViewSystem& system, View& parentView, View& contentView)
|
||||
: View(system, parentView), m_contentView(contentView)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -259,15 +259,21 @@ void TextView::System::init(boo::MetalDataFactory* factory, FontCache* fcache)
|
|||
|
||||
#endif
|
||||
|
||||
TextView::TextView(ViewSystem& system, FontTag font, size_t capacity)
|
||||
: View(system),
|
||||
TextView::TextView(ViewSystem& system, View& parentView, const FontAtlas& font, size_t capacity)
|
||||
: View(system, parentView),
|
||||
m_capacity(capacity),
|
||||
m_fontAtlas(system.m_textSystem.m_fcache->lookupAtlas(font))
|
||||
m_fontAtlas(font)
|
||||
{
|
||||
m_glyphBuf =
|
||||
system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex,
|
||||
sizeof(RenderGlyph), capacity);
|
||||
|
||||
boo::IShaderPipeline* shader;
|
||||
if (font.subpixel())
|
||||
shader = system.m_textSystem.m_subpixel;
|
||||
else
|
||||
shader = system.m_textSystem.m_regular;
|
||||
|
||||
if (!system.m_textSystem.m_vtxFmt)
|
||||
{
|
||||
boo::VertexElementDescriptor vdescs[] =
|
||||
|
@ -288,7 +294,7 @@ TextView::TextView(ViewSystem& system, FontTag font, size_t capacity)
|
|||
};
|
||||
m_vtxFmt = system.m_factory->newVertexFormat(13, vdescs);
|
||||
boo::ITexture* texs[] = {m_fontAtlas.texture()};
|
||||
m_shaderBinding = system.m_factory->newShaderDataBinding(system.m_textSystem.m_regular, m_vtxFmt,
|
||||
m_shaderBinding = system.m_factory->newShaderDataBinding(shader, m_vtxFmt,
|
||||
nullptr, m_glyphBuf, nullptr, 1,
|
||||
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
|
||||
1, texs);
|
||||
|
@ -296,7 +302,7 @@ TextView::TextView(ViewSystem& system, FontTag font, size_t capacity)
|
|||
else
|
||||
{
|
||||
boo::ITexture* texs[] = {m_fontAtlas.texture()};
|
||||
m_shaderBinding = system.m_factory->newShaderDataBinding(system.m_textSystem.m_regular, system.m_textSystem.m_vtxFmt,
|
||||
m_shaderBinding = system.m_factory->newShaderDataBinding(shader, system.m_textSystem.m_vtxFmt,
|
||||
nullptr, m_glyphBuf, nullptr, 1,
|
||||
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
|
||||
1, texs);
|
||||
|
@ -305,6 +311,9 @@ TextView::TextView(ViewSystem& system, FontTag font, size_t capacity)
|
|||
m_glyphs.reserve(capacity);
|
||||
}
|
||||
|
||||
TextView::TextView(ViewSystem& system, View& parentView, FontTag font, size_t capacity)
|
||||
: TextView(system, parentView, system.m_textSystem.m_fcache->lookupAtlas(font), capacity) {}
|
||||
|
||||
TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor)
|
||||
{
|
||||
m_pos[0].assign(adv + glyph.m_leftPadding, glyph.m_verticalOffset + glyph.m_height, 0.f);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Specter/View.hpp"
|
||||
#include "Specter/ViewSystem.hpp"
|
||||
#include "Specter/RootView.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
|
@ -145,8 +146,10 @@ void View::System::init(boo::MetalDataFactory* factory)
|
|||
|
||||
#endif
|
||||
|
||||
View::View(ViewSystem& system)
|
||||
void View::buildResources(ViewSystem& system)
|
||||
{
|
||||
m_bgColor = Zeus::CColor::skClear;
|
||||
|
||||
m_bgVertBuf =
|
||||
system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex,
|
||||
sizeof(Zeus::CVector3f), 4);
|
||||
|
@ -181,11 +184,30 @@ View::View(ViewSystem& system)
|
|||
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
|
||||
0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
View::View(ViewSystem& system, RootView& rootView)
|
||||
: m_rootView(rootView),
|
||||
m_parentView(rootView)
|
||||
{
|
||||
buildResources(system);
|
||||
}
|
||||
|
||||
View::View(ViewSystem& system, View& parentView)
|
||||
: m_rootView(parentView.root()),
|
||||
m_parentView(parentView)
|
||||
{
|
||||
buildResources(system);
|
||||
}
|
||||
|
||||
void View::updateSize()
|
||||
{
|
||||
resized(m_rootView.rootRect(), m_subRect);
|
||||
}
|
||||
|
||||
void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
m_subRect = sub;
|
||||
m_viewVertBlock.setViewRect(root, sub);
|
||||
m_bgRect[0].assign(0.f, sub.size[1], 0.f);
|
||||
m_bgRect[1].assign(0.f, 0.f, 0.f);
|
||||
|
|
Loading…
Reference in New Issue