Merge branch 'master' into vulkan
This commit is contained in:
@@ -22,6 +22,8 @@ namespace Nz
|
||||
{
|
||||
public:
|
||||
AbstractAtlas() = default;
|
||||
AbstractAtlas(const AbstractAtlas&) = delete;
|
||||
AbstractAtlas(AbstractAtlas&&) noexcept = default;
|
||||
virtual ~AbstractAtlas();
|
||||
|
||||
virtual void Clear() = 0;
|
||||
@@ -31,6 +33,9 @@ namespace Nz
|
||||
virtual UInt32 GetStorage() const = 0;
|
||||
virtual bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) = 0;
|
||||
|
||||
AbstractAtlas& operator=(const AbstractAtlas&) = delete;
|
||||
AbstractAtlas& operator=(AbstractAtlas&&) noexcept = default;
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnAtlasCleared, const AbstractAtlas* /*atlas*/);
|
||||
NazaraSignal(OnAtlasLayerChange, const AbstractAtlas* /*atlas*/, AbstractImage* /*oldLayer*/, AbstractImage* /*newLayer*/);
|
||||
|
||||
@@ -27,7 +27,9 @@ namespace Nz
|
||||
AbstractTextDrawer() = default;
|
||||
virtual ~AbstractTextDrawer();
|
||||
|
||||
virtual const Recti& GetBounds() const = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
virtual const Rectf& GetBounds() const = 0;
|
||||
virtual Font* GetFont(std::size_t index) const = 0;
|
||||
virtual std::size_t GetFontCount() const = 0;
|
||||
virtual const Glyph& GetGlyph(std::size_t index) const = 0;
|
||||
@@ -35,6 +37,9 @@ namespace Nz
|
||||
virtual const Line& GetLine(std::size_t index) const = 0;
|
||||
virtual std::size_t GetLineCount() const = 0;
|
||||
inline std::size_t GetLineGlyphCount(std::size_t index) const;
|
||||
virtual float GetMaxLineWidth() const = 0;
|
||||
|
||||
virtual void SetMaxLineWidth(float lineWidth) = 0;
|
||||
|
||||
struct Glyph
|
||||
{
|
||||
@@ -44,6 +49,7 @@ namespace Nz
|
||||
Vector2f corners[4];
|
||||
AbstractImage* atlas;
|
||||
bool flipped;
|
||||
int renderOrder;
|
||||
};
|
||||
|
||||
struct Line
|
||||
|
||||
@@ -83,15 +83,15 @@ namespace Nz
|
||||
bool IsLoopPointInterpolationEnabled() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const String& filePath, const AnimationParams& params = AnimationParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params = AnimationParams());
|
||||
bool LoadFromStream(Stream& stream, const AnimationParams& params = AnimationParams());
|
||||
|
||||
void RemoveSequence(const String& sequenceName);
|
||||
void RemoveSequence(UInt32 index);
|
||||
|
||||
template<typename... Args> static AnimationRef New(Args&&... args);
|
||||
|
||||
static AnimationRef LoadFromFile(const String& filePath, const AnimationParams& params = AnimationParams());
|
||||
static AnimationRef LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params = AnimationParams());
|
||||
static AnimationRef LoadFromStream(Stream& stream, const AnimationParams& params = AnimationParams());
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnAnimationDestroy, const Animation* /*animation*/);
|
||||
NazaraSignal(OnAnimationRelease, const Animation* /*animation*/);
|
||||
|
||||
@@ -330,18 +330,26 @@ namespace Nz
|
||||
TextAlign_Max = TextAlign_Right
|
||||
};
|
||||
|
||||
enum TextStyleFlags
|
||||
enum TextStyle
|
||||
{
|
||||
TextStyle_Regular = 0x0,
|
||||
TextStyle_Bold,
|
||||
TextStyle_Italic,
|
||||
TextStyle_StrikeThrough,
|
||||
TextStyle_Underlined,
|
||||
|
||||
TextStyle_Bold = 0x1,
|
||||
TextStyle_Italic = 0x2,
|
||||
TextStyle_StrikeThrough = 0x4,
|
||||
TextStyle_Underlined = 0x8,
|
||||
|
||||
TextStyle_Max = TextStyle_Underlined*2-1
|
||||
TextStyle_Max = TextStyle_Underlined
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumAsFlags<TextStyle>
|
||||
{
|
||||
static constexpr TextStyle max = TextStyle_Max;
|
||||
};
|
||||
|
||||
using TextStyleFlags = Flags<TextStyle>;
|
||||
|
||||
constexpr TextStyleFlags TextStyle_Regular = 0;
|
||||
|
||||
enum VertexComponent
|
||||
{
|
||||
VertexComponent_Unused = -1,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
#include <Nazara/Utility/AbstractAtlas.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -58,14 +59,14 @@ namespace Nz
|
||||
bool Create(FontData* data);
|
||||
void Destroy();
|
||||
|
||||
bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* glyph) const;
|
||||
bool ExtractGlyph(unsigned int characterSize, char32_t character, TextStyleFlags style, float outlineThickness, FontGlyph* glyph) const;
|
||||
|
||||
const std::shared_ptr<AbstractAtlas>& GetAtlas() const;
|
||||
std::size_t GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const;
|
||||
std::size_t GetCachedGlyphCount(unsigned int characterSize, TextStyleFlags style, float outlineThickness) const;
|
||||
std::size_t GetCachedGlyphCount() const;
|
||||
String GetFamilyName() const;
|
||||
int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const;
|
||||
const Glyph& GetGlyph(unsigned int characterSize, UInt32 style, char32_t character) const;
|
||||
const Glyph& GetGlyph(unsigned int characterSize, TextStyleFlags style, float outlineThickness, char32_t character) const;
|
||||
unsigned int GetGlyphBorder() const;
|
||||
unsigned int GetMinimumStepSize() const;
|
||||
const SizeInfo& GetSizeInfo(unsigned int characterSize) const;
|
||||
@@ -73,13 +74,8 @@ namespace Nz
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
bool Precache(unsigned int characterSize, UInt32 style, char32_t character) const;
|
||||
bool Precache(unsigned int characterSize, UInt32 style, const String& characterSet) const;
|
||||
|
||||
// Open
|
||||
bool OpenFromFile(const String& filePath, const FontParams& params = FontParams());
|
||||
bool OpenFromMemory(const void* data, std::size_t size, const FontParams& params = FontParams());
|
||||
bool OpenFromStream(Stream& stream, const FontParams& params = FontParams());
|
||||
bool Precache(unsigned int characterSize, TextStyleFlags style, float outlineThickness, char32_t character) const;
|
||||
bool Precache(unsigned int characterSize, TextStyleFlags style, float outlineThickness, const String& characterSet) const;
|
||||
|
||||
void SetAtlas(const std::shared_ptr<AbstractAtlas>& atlas);
|
||||
void SetGlyphBorder(unsigned int borderSize);
|
||||
@@ -93,6 +89,10 @@ namespace Nz
|
||||
static unsigned int GetDefaultGlyphBorder();
|
||||
static unsigned int GetDefaultMinimumStepSize();
|
||||
|
||||
static FontRef OpenFromFile(const String& filePath, const FontParams& params = FontParams());
|
||||
static FontRef OpenFromMemory(const void* data, std::size_t size, const FontParams& params = FontParams());
|
||||
static FontRef OpenFromStream(Stream& stream, const FontParams& params = FontParams());
|
||||
|
||||
template<typename... Args> static FontRef New(Args&&... args);
|
||||
|
||||
static void SetDefaultAtlas(const std::shared_ptr<AbstractAtlas>& atlas);
|
||||
@@ -107,6 +107,7 @@ namespace Nz
|
||||
bool requireFauxItalic;
|
||||
bool flipped;
|
||||
bool valid;
|
||||
float fauxOutlineThickness;
|
||||
int advance;
|
||||
unsigned int layerIndex;
|
||||
};
|
||||
@@ -131,11 +132,11 @@ namespace Nz
|
||||
private:
|
||||
using GlyphMap = std::unordered_map<char32_t, Glyph>;
|
||||
|
||||
UInt64 ComputeKey(unsigned int characterSize, UInt32 style) const;
|
||||
UInt64 ComputeKey(unsigned int characterSize, TextStyleFlags style, float outlineThickness) const;
|
||||
void OnAtlasCleared(const AbstractAtlas* atlas);
|
||||
void OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer);
|
||||
void OnAtlasRelease(const AbstractAtlas* atlas);
|
||||
const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, UInt32 style, char32_t character) const;
|
||||
const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, TextStyleFlags style, float outlineThickness, char32_t character) const;
|
||||
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -21,7 +22,7 @@ namespace Nz
|
||||
FontData() = default;
|
||||
virtual ~FontData();
|
||||
|
||||
virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* dst) = 0;
|
||||
virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, TextStyleFlags style, float outlineThickness, FontGlyph* dst) = 0;
|
||||
|
||||
virtual String GetFamilyName() const = 0;
|
||||
virtual String GetStyleName() const = 0;
|
||||
@@ -35,7 +36,8 @@ namespace Nz
|
||||
virtual float QueryUnderlinePosition(unsigned int characterSize) const = 0;
|
||||
virtual float QueryUnderlineThickness(unsigned int characterSize) const = 0;
|
||||
|
||||
virtual bool SupportsStyle(UInt32 style) const = 0;
|
||||
virtual bool SupportsOutline(float outlineThickness) const = 0;
|
||||
virtual bool SupportsStyle(TextStyleFlags style) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,9 @@ namespace Nz
|
||||
{
|
||||
public:
|
||||
GuillotineImageAtlas();
|
||||
virtual ~GuillotineImageAtlas();
|
||||
GuillotineImageAtlas(const GuillotineImageAtlas&) = delete;
|
||||
GuillotineImageAtlas(GuillotineImageAtlas&&) noexcept = default;
|
||||
~GuillotineImageAtlas() = default;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
@@ -38,6 +40,9 @@ namespace Nz
|
||||
void SetRectChoiceHeuristic(GuillotineBinPack::FreeRectChoiceHeuristic heuristic);
|
||||
void SetRectSplitHeuristic(GuillotineBinPack::GuillotineSplitHeuristic heuristic);
|
||||
|
||||
GuillotineImageAtlas& operator=(const GuillotineImageAtlas&) = delete;
|
||||
GuillotineImageAtlas& operator=(GuillotineImageAtlas&&) noexcept = default;
|
||||
|
||||
protected:
|
||||
struct Layer;
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Nz
|
||||
|
||||
bool Convert(PixelFormatType format);
|
||||
|
||||
void Copy(const Image& source, const Boxui& srcBox, const Vector3ui& dstPos);
|
||||
void Copy(const Image* source, const Boxui& srcBox, const Vector3ui& dstPos);
|
||||
|
||||
bool Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1);
|
||||
void Destroy();
|
||||
@@ -93,23 +93,6 @@ namespace Nz
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
// Load
|
||||
bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams());
|
||||
bool LoadFromStream(Stream& stream, const ImageParams& params = ImageParams());
|
||||
|
||||
// LoadArray
|
||||
bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
bool LoadArrayFromImage(const Image& image, const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
bool LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
|
||||
// LoadCubemap
|
||||
bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams());
|
||||
bool LoadCubemapFromImage(const Image& image, const CubemapParams& params = CubemapParams());
|
||||
bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams());
|
||||
bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams());
|
||||
|
||||
// LoadFace
|
||||
bool LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params = ImageParams());
|
||||
bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams());
|
||||
@@ -133,6 +116,24 @@ namespace Nz
|
||||
static void Copy(UInt8* destination, const UInt8* source, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, unsigned int dstWidth = 0, unsigned int dstHeight = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0);
|
||||
static UInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1);
|
||||
static UInt8 GetMaxLevel(ImageType type, unsigned int width, unsigned int height, unsigned int depth = 1);
|
||||
|
||||
// Load
|
||||
static ImageRef LoadFromFile(const String& filePath, const ImageParams& params = ImageParams());
|
||||
static ImageRef LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams());
|
||||
static ImageRef LoadFromStream(Stream& stream, const ImageParams& params = ImageParams());
|
||||
|
||||
// LoadArray
|
||||
static ImageRef LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
static ImageRef LoadArrayFromImage(const Image* image, const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
static ImageRef LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
static ImageRef LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2));
|
||||
|
||||
// LoadCubemap
|
||||
static ImageRef LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams());
|
||||
static ImageRef LoadCubemapFromImage(const Image* image, const CubemapParams& params = CubemapParams());
|
||||
static ImageRef LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams());
|
||||
static ImageRef LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams());
|
||||
|
||||
template<typename... Args> static ImageRef New(Args&&... args);
|
||||
|
||||
struct SharedImage
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace Nz
|
||||
static constexpr const char* StencilTest = "MatStencilTest";
|
||||
static constexpr const char* StencilZFail = "MatStencilZFail";
|
||||
static constexpr const char* Transform = "MatTransform";
|
||||
static constexpr const char* VertexColor = "MatVertexColor";
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -128,10 +128,6 @@ namespace Nz
|
||||
bool IsAnimable() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const String& filePath, const MeshParams& params = MeshParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams());
|
||||
bool LoadFromStream(Stream& stream, const MeshParams& params = MeshParams());
|
||||
|
||||
void Recenter();
|
||||
|
||||
void RemoveSubMesh(const String& identifier);
|
||||
@@ -149,6 +145,10 @@ namespace Nz
|
||||
Mesh& operator=(const Mesh&) = delete;
|
||||
Mesh& operator=(Mesh&&) = delete;
|
||||
|
||||
static MeshRef LoadFromFile(const String& filePath, const MeshParams& params = MeshParams());
|
||||
static MeshRef LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams());
|
||||
static MeshRef LoadFromStream(Stream& stream, const MeshParams& params = MeshParams());
|
||||
|
||||
template<typename... Args> static MeshRef New(Args&&... args);
|
||||
|
||||
// Signals:
|
||||
|
||||
@@ -41,10 +41,10 @@ namespace Nz
|
||||
virtual Vector3f GetLeft() const;
|
||||
virtual NodeType GetNodeType() const;
|
||||
const Node* GetParent() const;
|
||||
Vector3f GetPosition(CoordSys coordSys = CoordSys_Global) const;
|
||||
Vector3f GetPosition(CoordSys coordSys = CoordSys_Local) const;
|
||||
virtual Vector3f GetRight() const;
|
||||
Quaternionf GetRotation(CoordSys coordSys = CoordSys_Global) const;
|
||||
Vector3f GetScale(CoordSys coordSys = CoordSys_Global) const;
|
||||
Quaternionf GetRotation(CoordSys coordSys = CoordSys_Local) const;
|
||||
Vector3f GetScale(CoordSys coordSys = CoordSys_Local) const;
|
||||
const Matrix4f& GetTransformMatrix() const;
|
||||
virtual Vector3f GetUp() const;
|
||||
|
||||
@@ -75,6 +75,7 @@ namespace Nz
|
||||
void SetPosition(const Vector3f& translation, CoordSys coordSys = CoordSys_Local);
|
||||
void SetPosition(float translationX, float translationY, float translationZ = 0.f, CoordSys coordSys = CoordSys_Local);
|
||||
void SetRotation(const Quaternionf& quat, CoordSys coordSys = CoordSys_Local);
|
||||
void SetScale(const Vector2f& scale, CoordSys coordSys = CoordSys_Local);
|
||||
void SetScale(const Vector3f& scale, CoordSys coordSys = CoordSys_Local);
|
||||
void SetScale(float scale, CoordSys coordSys = CoordSys_Local);
|
||||
void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, CoordSys coordSys = CoordSys_Local);
|
||||
@@ -105,6 +106,8 @@ namespace Nz
|
||||
virtual void UpdateDerived() const;
|
||||
virtual void UpdateTransformMatrix() const;
|
||||
|
||||
static Quaternionf ScaleQuaternion(const Vector3f& scale, Quaternionf quaternion);
|
||||
|
||||
mutable std::vector<Node*> m_childs;
|
||||
mutable Matrix4f m_transformMatrix;
|
||||
mutable Quaternionf m_derivedRotation;
|
||||
|
||||
212
include/Nazara/Utility/RichTextDrawer.hpp
Normal file
212
include/Nazara/Utility/RichTextDrawer.hpp
Normal file
@@ -0,0 +1,212 @@
|
||||
// Copyright (C) 2016 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RICHTEXTDRAWER_HPP
|
||||
#define NAZARA_RICHTEXTDRAWER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/AbstractTextDrawer.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <Nazara/Utility/Font.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_UTILITY_API RichTextDrawer : public AbstractTextDrawer
|
||||
{
|
||||
public:
|
||||
class BlockRef;
|
||||
|
||||
RichTextDrawer();
|
||||
RichTextDrawer(const RichTextDrawer& drawer);
|
||||
RichTextDrawer(RichTextDrawer&& drawer);
|
||||
~RichTextDrawer();
|
||||
|
||||
BlockRef AppendText(const String& str, bool forceNewBlock = false);
|
||||
|
||||
void Clear() override;
|
||||
|
||||
inline std::size_t FindBlock(std::size_t glyphIndex) const;
|
||||
|
||||
inline unsigned int GetBlockCharacterSize(std::size_t index) const;
|
||||
inline float GetBlockCharacterSpacingOffset(std::size_t index) const;
|
||||
inline const Color& GetBlockColor(std::size_t index) const;
|
||||
inline std::size_t GetBlockCount() const;
|
||||
inline std::size_t GetBlockFirstGlyphIndex(std::size_t index) const;
|
||||
inline const FontRef& GetBlockFont(std::size_t index) const;
|
||||
inline float GetBlockLineHeight(std::size_t index) const;
|
||||
inline float GetBlockLineSpacingOffset(std::size_t index) const;
|
||||
inline const Color& GetBlockOutlineColor(std::size_t index) const;
|
||||
inline float GetBlockOutlineThickness(std::size_t index) const;
|
||||
inline TextStyleFlags GetBlockStyle(std::size_t index) const;
|
||||
inline const String& GetBlockText(std::size_t index) const;
|
||||
|
||||
inline BlockRef GetBlock(std::size_t index);
|
||||
const Rectf& GetBounds() const override;
|
||||
inline unsigned int GetDefaultCharacterSize() const;
|
||||
inline float GetDefaultCharacterSpacingOffset() const;
|
||||
inline const Color& GetDefaultColor() const;
|
||||
inline const FontRef& GetDefaultFont() const;
|
||||
inline float GetDefaultLineSpacingOffset() const;
|
||||
inline const Color& GetDefaultOutlineColor() const;
|
||||
inline float GetDefaultOutlineThickness() const;
|
||||
inline TextStyleFlags GetDefaultStyle() const;
|
||||
Font* GetFont(std::size_t index) const override;
|
||||
std::size_t GetFontCount() const override;
|
||||
const Glyph& GetGlyph(std::size_t index) const override;
|
||||
std::size_t GetGlyphCount() const override;
|
||||
const Line& GetLine(std::size_t index) const override;
|
||||
std::size_t GetLineCount() const override;
|
||||
float GetMaxLineWidth() const override;
|
||||
|
||||
inline bool HasBlocks() const;
|
||||
|
||||
void MergeBlocks();
|
||||
|
||||
void RemoveBlock(std::size_t index);
|
||||
|
||||
inline void SetBlockCharacterSize(std::size_t index, unsigned int characterSize);
|
||||
inline void SetBlockCharacterSpacingOffset(std::size_t index, float offset);
|
||||
inline void SetBlockColor(std::size_t index, const Color& color);
|
||||
inline void SetBlockFont(std::size_t index, FontRef font);
|
||||
inline void SetBlockLineSpacingOffset(std::size_t index, float offset);
|
||||
inline void SetBlockOutlineColor(std::size_t index, const Color& color);
|
||||
inline void SetBlockOutlineThickness(std::size_t index, float thickness);
|
||||
inline void SetBlockStyle(std::size_t index, TextStyleFlags style);
|
||||
inline void SetBlockText(std::size_t index, String str);
|
||||
|
||||
inline void SetDefaultCharacterSize(unsigned int characterSize);
|
||||
inline void SetDefaultCharacterSpacingOffset(float offset);
|
||||
inline void SetDefaultColor(const Color& color);
|
||||
inline void SetDefaultFont(const FontRef& font);
|
||||
inline void SetDefaultLineSpacingOffset(float offset);
|
||||
inline void SetDefaultOutlineColor(const Color& color);
|
||||
inline void SetDefaultOutlineThickness(float thickness);
|
||||
inline void SetDefaultStyle(TextStyleFlags style);
|
||||
|
||||
void SetMaxLineWidth(float lineWidth) override;
|
||||
|
||||
RichTextDrawer& operator=(const RichTextDrawer& drawer);
|
||||
RichTextDrawer& operator=(RichTextDrawer&& drawer);
|
||||
|
||||
static constexpr std::size_t InvalidBlockIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
private:
|
||||
struct Block;
|
||||
|
||||
inline void AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset) const;
|
||||
void AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset, std::size_t glyphIndex, float glyphPosition) const;
|
||||
inline void ClearGlyphs() const;
|
||||
inline void ConnectFontSlots();
|
||||
inline void DisconnectFontSlots();
|
||||
bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, const Font* font, const Color& color, TextStyleFlags style, float lineSpacingOffset, unsigned int characterSize, int renderOrder, int* advance) const;
|
||||
void GenerateGlyphs(const Font* font, const Color& color, TextStyleFlags style, unsigned int characterSize, const Color& outlineColor, float characterSpacingOffset, float lineSpacingOffset, float outlineThickness, const String& text) const;
|
||||
inline float GetLineHeight(const Block& block) const;
|
||||
inline float GetLineHeight(float lineSpacingOffset, const Font::SizeInfo& sizeInfo) const;
|
||||
inline std::size_t HandleFontAddition(const FontRef& font);
|
||||
inline void InvalidateGlyphs();
|
||||
inline void ReleaseFont(std::size_t fontIndex);
|
||||
inline bool ShouldLineWrap(float size) const;
|
||||
|
||||
void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer);
|
||||
void OnFontInvalidated(const Font* font);
|
||||
void OnFontRelease(const Font* object);
|
||||
|
||||
void UpdateGlyphs() const;
|
||||
|
||||
static constexpr std::size_t InvalidGlyph = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct Block
|
||||
{
|
||||
std::size_t fontIndex;
|
||||
std::size_t glyphIndex;
|
||||
Color color;
|
||||
Color outlineColor;
|
||||
String text;
|
||||
TextStyleFlags style;
|
||||
float characterSpacingOffset;
|
||||
float lineSpacingOffset;
|
||||
float outlineThickness;
|
||||
unsigned int characterSize;
|
||||
};
|
||||
|
||||
struct FontData
|
||||
{
|
||||
FontRef font;
|
||||
std::size_t useCount = 0;
|
||||
|
||||
NazaraSlot(Font, OnFontAtlasChanged, atlasChangedSlot);
|
||||
NazaraSlot(Font, OnFontAtlasLayerChanged, atlasLayerChangedSlot);
|
||||
NazaraSlot(Font, OnFontGlyphCacheCleared, glyphCacheClearedSlot);
|
||||
NazaraSlot(Font, OnFontRelease, fontReleaseSlot);
|
||||
};
|
||||
|
||||
Color m_defaultColor;
|
||||
Color m_defaultOutlineColor;
|
||||
TextStyleFlags m_defaultStyle;
|
||||
FontRef m_defaultFont;
|
||||
mutable std::size_t m_lastSeparatorGlyph;
|
||||
std::unordered_map<FontRef, std::size_t> m_fontIndexes;
|
||||
std::vector<Block> m_blocks;
|
||||
std::vector<FontData> m_fonts;
|
||||
mutable std::vector<Glyph> m_glyphs;
|
||||
mutable std::vector<Line> m_lines;
|
||||
mutable Rectf m_bounds;
|
||||
mutable Vector2f m_drawPos;
|
||||
mutable bool m_glyphUpdated;
|
||||
float m_defaultCharacterSpacingOffset;
|
||||
float m_defaultLineSpacingOffset;
|
||||
float m_defaultOutlineThickness;
|
||||
float m_maxLineWidth;
|
||||
unsigned int m_defaultCharacterSize;
|
||||
mutable float m_lastSeparatorPosition;
|
||||
};
|
||||
|
||||
class RichTextDrawer::BlockRef
|
||||
{
|
||||
friend RichTextDrawer;
|
||||
|
||||
public:
|
||||
BlockRef(const BlockRef&) = default;
|
||||
BlockRef(BlockRef&&) = default;
|
||||
~BlockRef() = default;
|
||||
|
||||
inline float GetCharacterSpacingOffset() const;
|
||||
inline unsigned int GetCharacterSize() const;
|
||||
inline Color GetColor() const;
|
||||
inline std::size_t GetFirstGlyphIndex() const;
|
||||
inline const FontRef& GetFont() const;
|
||||
inline float GetLineSpacingOffset() const;
|
||||
inline Color GetOutlineColor() const;
|
||||
inline float GetOutlineThickness() const;
|
||||
inline TextStyleFlags GetStyle() const;
|
||||
inline const String& GetText() const;
|
||||
|
||||
inline void SetCharacterSpacingOffset(float offset);
|
||||
inline void SetCharacterSize(unsigned int size);
|
||||
inline void SetColor(Color color);
|
||||
inline void SetFont(FontRef font);
|
||||
inline void SetLineSpacingOffset(float offset);
|
||||
inline void SetOutlineColor(Color color);
|
||||
inline void SetOutlineThickness(float thickness);
|
||||
inline void SetStyle(TextStyleFlags style);
|
||||
inline void SetText(const String& text);
|
||||
|
||||
BlockRef& operator=(const BlockRef&) = default;
|
||||
BlockRef& operator=(BlockRef&&) = default;
|
||||
|
||||
private:
|
||||
inline BlockRef(RichTextDrawer& drawer, std::size_t index);
|
||||
|
||||
std::size_t m_blockIndex;
|
||||
RichTextDrawer& m_drawer;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/RichTextDrawer.inl>
|
||||
|
||||
#endif // NAZARA_RICHTEXTDRAWER_HPP
|
||||
631
include/Nazara/Utility/RichTextDrawer.inl
Normal file
631
include/Nazara/Utility/RichTextDrawer.inl
Normal file
@@ -0,0 +1,631 @@
|
||||
// Copyright (C) 2016 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/RichTextDrawer.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::size_t RichTextDrawer::FindBlock(std::size_t glyphIndex) const
|
||||
{
|
||||
auto it = m_blocks.begin();
|
||||
for (; it != m_blocks.end(); ++it)
|
||||
{
|
||||
if (it->glyphIndex > glyphIndex)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(it != m_blocks.begin());
|
||||
return std::distance(m_blocks.begin(), it) - 1;
|
||||
/*
|
||||
// Binary search
|
||||
std::size_t count = m_blocks.size();
|
||||
std::size_t step;
|
||||
|
||||
std::size_t i = InvalidBlockIndex;
|
||||
std::size_t first = 0;
|
||||
std::size_t last = count;
|
||||
while (count > 0)
|
||||
{
|
||||
i = first;
|
||||
step = count / 2;
|
||||
|
||||
i += step;
|
||||
|
||||
if (m_blocks[i].glyphIndex < glyphIndex)
|
||||
{
|
||||
first = ++i;
|
||||
count -= step + 1;
|
||||
}
|
||||
else
|
||||
count = step;
|
||||
}
|
||||
|
||||
return i;*/
|
||||
}
|
||||
|
||||
inline auto RichTextDrawer::GetBlock(std::size_t index) -> BlockRef
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return BlockRef(*this, index);
|
||||
}
|
||||
|
||||
inline unsigned int RichTextDrawer::GetBlockCharacterSize(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].characterSize;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetBlockCharacterSpacingOffset(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].characterSpacingOffset;
|
||||
}
|
||||
|
||||
inline const Color& RichTextDrawer::GetBlockColor(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].color;
|
||||
}
|
||||
|
||||
inline std::size_t RichTextDrawer::GetBlockCount() const
|
||||
{
|
||||
return m_blocks.size();
|
||||
}
|
||||
|
||||
inline std::size_t RichTextDrawer::GetBlockFirstGlyphIndex(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].glyphIndex;
|
||||
}
|
||||
|
||||
inline const FontRef& RichTextDrawer::GetBlockFont(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
std::size_t fontIndex = m_blocks[index].fontIndex;
|
||||
assert(fontIndex < m_fonts.size());
|
||||
return m_fonts[fontIndex].font;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetBlockLineHeight(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].lineSpacingOffset;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetBlockLineSpacingOffset(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].lineSpacingOffset;
|
||||
}
|
||||
|
||||
inline const Color& RichTextDrawer::GetBlockOutlineColor(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].outlineColor;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetBlockOutlineThickness(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].outlineThickness;
|
||||
}
|
||||
|
||||
inline TextStyleFlags RichTextDrawer::GetBlockStyle(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].style;
|
||||
}
|
||||
|
||||
inline const String& RichTextDrawer::GetBlockText(std::size_t index) const
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
return m_blocks[index].text;
|
||||
}
|
||||
|
||||
inline unsigned int RichTextDrawer::GetDefaultCharacterSize() const
|
||||
{
|
||||
return m_defaultCharacterSize;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetDefaultCharacterSpacingOffset() const
|
||||
{
|
||||
return m_defaultCharacterSpacingOffset;
|
||||
}
|
||||
|
||||
inline const Color& RichTextDrawer::GetDefaultColor() const
|
||||
{
|
||||
return m_defaultColor;
|
||||
}
|
||||
|
||||
inline const FontRef& RichTextDrawer::GetDefaultFont() const
|
||||
{
|
||||
return m_defaultFont;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetDefaultLineSpacingOffset() const
|
||||
{
|
||||
return m_defaultLineSpacingOffset;
|
||||
}
|
||||
|
||||
inline const Color& RichTextDrawer::GetDefaultOutlineColor() const
|
||||
{
|
||||
return m_defaultOutlineColor;
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetDefaultOutlineThickness() const
|
||||
{
|
||||
return m_defaultOutlineThickness;
|
||||
}
|
||||
|
||||
inline TextStyleFlags RichTextDrawer::GetDefaultStyle() const
|
||||
{
|
||||
return m_defaultStyle;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::AppendNewLine(const Font* font, unsigned int characterSize, float lineSpacingOffset) const
|
||||
{
|
||||
AppendNewLine(font, characterSize, lineSpacingOffset, InvalidGlyph, 0);
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::ClearGlyphs() const
|
||||
{
|
||||
m_bounds.MakeZero();
|
||||
m_lastSeparatorGlyph = InvalidGlyph;
|
||||
m_lines.clear();
|
||||
m_glyphs.clear();
|
||||
m_glyphUpdated = true;
|
||||
m_bounds.MakeZero(); //< Compute bounds as float to speedup bounds computation (as casting between floats and integers is costly)
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::ConnectFontSlots()
|
||||
{
|
||||
for (auto& fontData : m_fonts)
|
||||
{
|
||||
fontData.atlasChangedSlot.Connect(fontData.font->OnFontAtlasChanged, this, &RichTextDrawer::OnFontInvalidated);
|
||||
fontData.atlasLayerChangedSlot.Connect(fontData.font->OnFontAtlasLayerChanged, this, &RichTextDrawer::OnFontAtlasLayerChanged);
|
||||
fontData.fontReleaseSlot.Connect(fontData.font->OnFontDestroy, this, &RichTextDrawer::OnFontRelease);
|
||||
fontData.glyphCacheClearedSlot.Connect(fontData.font->OnFontGlyphCacheCleared, this, &RichTextDrawer::OnFontInvalidated);
|
||||
}
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::DisconnectFontSlots()
|
||||
{
|
||||
for (auto& fontData : m_fonts)
|
||||
{
|
||||
fontData.atlasChangedSlot.Disconnect();
|
||||
fontData.atlasLayerChangedSlot.Disconnect();
|
||||
fontData.fontReleaseSlot.Disconnect();
|
||||
fontData.glyphCacheClearedSlot.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetLineHeight(const Block& block) const
|
||||
{
|
||||
assert(block.fontIndex < m_fonts.size());
|
||||
const FontData& fontData = m_fonts[block.fontIndex];
|
||||
|
||||
return GetLineHeight(block.lineSpacingOffset, fontData.font->GetSizeInfo(block.characterSize));
|
||||
}
|
||||
|
||||
inline float RichTextDrawer::GetLineHeight(float lineSpacingOffset, const Font::SizeInfo& sizeInfo) const
|
||||
{
|
||||
return float(sizeInfo.lineHeight) + lineSpacingOffset;
|
||||
}
|
||||
|
||||
inline std::size_t RichTextDrawer::HandleFontAddition(const FontRef& font)
|
||||
{
|
||||
auto it = m_fontIndexes.find(font);
|
||||
if (it == m_fontIndexes.end())
|
||||
{
|
||||
std::size_t fontIndex = m_fonts.size();
|
||||
m_fonts.emplace_back();
|
||||
auto& fontData = m_fonts.back();
|
||||
fontData.font = font;
|
||||
fontData.atlasChangedSlot.Connect(font->OnFontAtlasChanged, this, &RichTextDrawer::OnFontInvalidated);
|
||||
fontData.atlasLayerChangedSlot.Connect(font->OnFontAtlasLayerChanged, this, &RichTextDrawer::OnFontAtlasLayerChanged);
|
||||
fontData.fontReleaseSlot.Connect(font->OnFontDestroy, this, &RichTextDrawer::OnFontRelease);
|
||||
fontData.glyphCacheClearedSlot.Connect(font->OnFontGlyphCacheCleared, this, &RichTextDrawer::OnFontInvalidated);
|
||||
|
||||
it = m_fontIndexes.emplace(font, fontIndex).first;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::ReleaseFont(std::size_t fontIndex)
|
||||
{
|
||||
assert(fontIndex < m_fonts.size());
|
||||
|
||||
FontData& fontData = m_fonts[fontIndex];
|
||||
assert(fontData.useCount > 0);
|
||||
|
||||
if (--fontData.useCount == 0)
|
||||
{
|
||||
// Shift font indexes
|
||||
m_fontIndexes.erase(fontData.font);
|
||||
for (auto& fontIndexe : m_fontIndexes)
|
||||
{
|
||||
if (fontIndexe.second > fontIndex)
|
||||
fontIndexe.second--;
|
||||
}
|
||||
|
||||
m_fonts.erase(m_fonts.begin() + fontIndex);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool RichTextDrawer::ShouldLineWrap(float size) const
|
||||
{
|
||||
if (m_lines.back().glyphIndex > m_glyphs.size())
|
||||
return false;
|
||||
|
||||
return m_lines.back().bounds.GetMaximum().x + size > m_maxLineWidth;
|
||||
}
|
||||
|
||||
inline bool RichTextDrawer::HasBlocks() const
|
||||
{
|
||||
return !m_blocks.empty();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockCharacterSize(std::size_t index, unsigned int characterSize)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].characterSize = characterSize;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockCharacterSpacingOffset(std::size_t index, float offset)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].characterSpacingOffset = offset;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockColor(std::size_t index, const Color& color)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].color = color;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockFont(std::size_t index, FontRef font)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
std::size_t fontIndex = HandleFontAddition(font);
|
||||
std::size_t oldFontIndex = m_blocks[index].fontIndex;
|
||||
|
||||
if (oldFontIndex != fontIndex)
|
||||
{
|
||||
ReleaseFont(oldFontIndex);
|
||||
|
||||
m_fonts[fontIndex].useCount++;
|
||||
m_blocks[index].fontIndex = fontIndex;
|
||||
}
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockLineSpacingOffset(std::size_t index, float offset)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].lineSpacingOffset = offset;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockOutlineColor(std::size_t index, const Color& color)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].outlineColor = color;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockOutlineThickness(std::size_t index, float thickness)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].outlineThickness = thickness;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockStyle(std::size_t index, TextStyleFlags style)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
m_blocks[index].style = style;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetBlockText(std::size_t index, String str)
|
||||
{
|
||||
NazaraAssert(index < m_blocks.size(), "Invalid block index");
|
||||
|
||||
std::size_t previousLength = m_blocks[index].text.GetLength();
|
||||
|
||||
m_blocks[index].text = std::move(str);
|
||||
|
||||
std::size_t newLength = m_blocks[index].text.GetLength();
|
||||
if (newLength != previousLength)
|
||||
{
|
||||
std::size_t delta = newLength - previousLength; //< Underflow allowed
|
||||
for (std::size_t i = index + 1; i < m_blocks.size(); ++i)
|
||||
m_blocks[i].glyphIndex += delta;
|
||||
}
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultCharacterSize(unsigned int characterSize)
|
||||
{
|
||||
m_defaultCharacterSize = characterSize;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultCharacterSpacingOffset(float offset)
|
||||
{
|
||||
m_defaultCharacterSpacingOffset = offset;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultColor(const Color& color)
|
||||
{
|
||||
m_defaultColor = color;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultFont(const FontRef& font)
|
||||
{
|
||||
m_defaultFont = font;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultLineSpacingOffset(float offset)
|
||||
{
|
||||
m_defaultLineSpacingOffset = offset;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultOutlineColor(const Color& color)
|
||||
{
|
||||
m_defaultOutlineColor = color;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultOutlineThickness(float thickness)
|
||||
{
|
||||
m_defaultOutlineThickness = thickness;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::SetDefaultStyle(TextStyleFlags style)
|
||||
{
|
||||
m_defaultStyle = style;
|
||||
}
|
||||
|
||||
inline void RichTextDrawer::InvalidateGlyphs()
|
||||
{
|
||||
m_glyphUpdated = false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \class Nz::RichTextDrawer::BlockRef
|
||||
* \brief Helper class representing a block inside a RichTextDrawer, allowing easier access.
|
||||
*
|
||||
* \warning This class is meant for temporary use, moving or destroying the RichTextDrawer or one of its blocks invalidates all BlockRef
|
||||
*/
|
||||
|
||||
inline RichTextDrawer::BlockRef::BlockRef(RichTextDrawer& drawer, std::size_t index) :
|
||||
m_blockIndex(index),
|
||||
m_drawer(drawer)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the character spacing offset used for the characters of the referenced block
|
||||
* \return The referenced block character size
|
||||
*
|
||||
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
|
||||
*/
|
||||
inline float RichTextDrawer::BlockRef::GetCharacterSpacingOffset() const
|
||||
{
|
||||
return m_drawer.GetBlockCharacterSpacingOffset(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the character size used for the characters of the referenced block
|
||||
* \return The referenced block character size
|
||||
*
|
||||
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
|
||||
*/
|
||||
inline unsigned int RichTextDrawer::BlockRef::GetCharacterSize() const
|
||||
{
|
||||
return m_drawer.GetBlockCharacterSize(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the color used for the characters of the referenced block
|
||||
* \return The referenced block color
|
||||
*
|
||||
* \see GetCharacterSize, GetFont, GetStyle, GetText, SetColor
|
||||
*/
|
||||
inline Color RichTextDrawer::BlockRef::GetColor() const
|
||||
{
|
||||
return m_drawer.GetBlockColor(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the font used for the characters of the referenced block
|
||||
* \return A reference on the referenced block font
|
||||
*
|
||||
* \see GetCharacterSize, GetColor, GetStyle, GetText, SetFont
|
||||
*/
|
||||
inline const FontRef& RichTextDrawer::BlockRef::GetFont() const
|
||||
{
|
||||
return m_drawer.GetBlockFont(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the line spacing offset used for the characters of the referenced block
|
||||
* \return The referenced block character size
|
||||
*
|
||||
* \see GetColor, GetFont, GetStyle, GetText, SetCharacterSize
|
||||
*/
|
||||
inline float RichTextDrawer::BlockRef::GetLineSpacingOffset() const
|
||||
{
|
||||
return m_drawer.GetBlockLineSpacingOffset(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the outline color used for the characters of the referenced block
|
||||
* \return The referenced block outline color
|
||||
*
|
||||
* \see GetCharacterSize, GetColor, GetStyle, GetText, SetFont
|
||||
*/
|
||||
inline Color RichTextDrawer::BlockRef::GetOutlineColor() const
|
||||
{
|
||||
return m_drawer.GetBlockOutlineColor(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the outline thickness used for the characters of the referenced block
|
||||
* \return The referenced block outline thickness
|
||||
*
|
||||
* \see GetCharacterSize, GetColor, GetStyle, GetText, SetFont
|
||||
*/
|
||||
inline float RichTextDrawer::BlockRef::GetOutlineThickness() const
|
||||
{
|
||||
return m_drawer.GetBlockOutlineThickness(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the style flags used for the characters of the referenced block
|
||||
* \return The referenced block style flags (see TextStyleFlags)
|
||||
*
|
||||
* \see GetCharacterSize, GetColor, GetFont, GetText, SetStyle
|
||||
*/
|
||||
inline TextStyleFlags RichTextDrawer::BlockRef::GetStyle() const
|
||||
{
|
||||
return m_drawer.GetBlockStyle(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the first glyph index at which starts the referenced block
|
||||
* \return The first glyph index concerned by this block
|
||||
*
|
||||
* \see GetText
|
||||
*/
|
||||
inline std::size_t RichTextDrawer::BlockRef::GetFirstGlyphIndex() const
|
||||
{
|
||||
return m_drawer.GetBlockFirstGlyphIndex(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the text of the referenced block
|
||||
* \return The referenced block text
|
||||
*
|
||||
* \see GetCharacterSize, GetColor, GetFont, GetStyle, SetText
|
||||
*/
|
||||
inline const String& RichTextDrawer::BlockRef::GetText() const
|
||||
{
|
||||
return m_drawer.GetBlockText(m_blockIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the character spacing offset of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetCharacterSpacingOffset, SetColor, SetFont, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetCharacterSpacingOffset(float offset)
|
||||
{
|
||||
m_drawer.SetBlockCharacterSpacingOffset(m_blockIndex, offset);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the character size of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetCharacterSize, SetColor, SetFont, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetCharacterSize(unsigned int size)
|
||||
{
|
||||
m_drawer.SetBlockCharacterSize(m_blockIndex, size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the color of the referenced block characters
|
||||
* \remark This is the only property that can be changed without forcing a glyph regeneration
|
||||
*
|
||||
* \see GetColor, SetCharacterSize, SetFont, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetColor(Color color)
|
||||
{
|
||||
m_drawer.SetBlockColor(m_blockIndex, color);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the font of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetCharacterSize, SetCharacterSize, SetColor, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetFont(FontRef font)
|
||||
{
|
||||
m_drawer.SetBlockFont(m_blockIndex, std::move(font));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the line spacing offset of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetLineSpacingOffset, SetColor, SetFont, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetLineSpacingOffset(float offset)
|
||||
{
|
||||
m_drawer.SetBlockLineSpacingOffset(m_blockIndex, offset);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the outline color of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetCharacterSize, SetCharacterSize, SetColor, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetOutlineColor(Color color)
|
||||
{
|
||||
m_drawer.SetBlockOutlineColor(m_blockIndex, std::move(color));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the outline thickness of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetCharacterSize, SetCharacterSize, SetColor, SetStyle, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetOutlineThickness(float thickness)
|
||||
{
|
||||
m_drawer.SetBlockOutlineThickness(m_blockIndex, thickness);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the style flags of the referenced block characters
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetStyle, SetCharacterSize, SetColor, SetFont, SetText
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetStyle(TextStyleFlags style)
|
||||
{
|
||||
m_drawer.SetBlockStyle(m_blockIndex, style);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Changes the text of the referenced block
|
||||
* \remark This invalidates the drawer and will force a (complete or partial, depending on the block index) glyph regeneration to occur.
|
||||
*
|
||||
* \see GetText, SetCharacterSize, SetColor, SetFont, SetStyle
|
||||
*/
|
||||
inline void RichTextDrawer::BlockRef::SetText(const String& text)
|
||||
{
|
||||
m_drawer.SetBlockText(m_blockIndex, text);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/DebugOff.hpp>
|
||||
@@ -19,70 +19,108 @@ namespace Nz
|
||||
class NAZARA_UTILITY_API SimpleTextDrawer : public AbstractTextDrawer
|
||||
{
|
||||
public:
|
||||
SimpleTextDrawer();
|
||||
SimpleTextDrawer(const SimpleTextDrawer& drawer);
|
||||
SimpleTextDrawer(SimpleTextDrawer&& drawer);
|
||||
virtual ~SimpleTextDrawer();
|
||||
inline SimpleTextDrawer();
|
||||
inline SimpleTextDrawer(const SimpleTextDrawer& drawer);
|
||||
inline SimpleTextDrawer(SimpleTextDrawer&& drawer);
|
||||
~SimpleTextDrawer() = default;
|
||||
|
||||
void AppendText(const String& str);
|
||||
inline void AppendText(const String& str);
|
||||
|
||||
void Clear();
|
||||
void Clear() override;
|
||||
|
||||
const Recti& GetBounds() const override;
|
||||
unsigned int GetCharacterSize() const;
|
||||
const Color& GetColor() const;
|
||||
Font* GetFont() const;
|
||||
const Rectf& GetBounds() const override;
|
||||
inline float GetCharacterSpacingOffset() const;
|
||||
inline unsigned int GetCharacterSize() const;
|
||||
inline const Color& GetColor() const;
|
||||
inline Font* GetFont() const;
|
||||
Font* GetFont(std::size_t index) const override;
|
||||
std::size_t GetFontCount() const override;
|
||||
const Glyph& GetGlyph(std::size_t index) const override;
|
||||
std::size_t GetGlyphCount() const override;
|
||||
const Line& GetLine(std::size_t index) const override;
|
||||
std::size_t GetLineCount() const override;
|
||||
UInt32 GetStyle() const;
|
||||
const String& GetText() const;
|
||||
inline float GetLineHeight() const;
|
||||
inline float GetLineSpacingOffset() const;
|
||||
float GetMaxLineWidth() const override;
|
||||
inline const Color& GetOutlineColor() const;
|
||||
inline float GetOutlineThickness() const;
|
||||
inline TextStyleFlags GetStyle() const;
|
||||
inline const String& GetText() const;
|
||||
|
||||
void SetCharacterSize(unsigned int characterSize);
|
||||
void SetColor(const Color& color);
|
||||
void SetFont(Font* font);
|
||||
void SetStyle(UInt32 style);
|
||||
void SetText(const String& str);
|
||||
inline void SetCharacterSpacingOffset(float offset);
|
||||
inline void SetCharacterSize(unsigned int characterSize);
|
||||
inline void SetColor(const Color& color);
|
||||
inline void SetFont(Font* font);
|
||||
inline void SetLineSpacingOffset(float offset);
|
||||
inline void SetMaxLineWidth(float lineWidth) override;
|
||||
inline void SetOutlineColor(const Color& color);
|
||||
inline void SetOutlineThickness(float thickness);
|
||||
inline void SetStyle(TextStyleFlags style);
|
||||
inline void SetText(const String& str);
|
||||
|
||||
SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer);
|
||||
SimpleTextDrawer& operator=(SimpleTextDrawer&& drawer);
|
||||
inline SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer);
|
||||
inline SimpleTextDrawer& operator=(SimpleTextDrawer&& drawer);
|
||||
|
||||
static SimpleTextDrawer Draw(const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White);
|
||||
static SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White);
|
||||
static inline SimpleTextDrawer Draw(const String& str, unsigned int characterSize, TextStyleFlags style = TextStyle_Regular, const Color& color = Color::White);
|
||||
static inline SimpleTextDrawer Draw(const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor);
|
||||
static inline SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style = TextStyle_Regular, const Color& color = Color::White);
|
||||
static inline SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor);
|
||||
|
||||
private:
|
||||
inline void AppendNewLine() const;
|
||||
void AppendNewLine(std::size_t glyphIndex, float glyphPosition) const;
|
||||
|
||||
void ClearGlyphs() const;
|
||||
void ConnectFontSlots();
|
||||
void DisconnectFontSlots();
|
||||
|
||||
inline void ConnectFontSlots();
|
||||
inline void DisconnectFontSlots();
|
||||
|
||||
bool GenerateGlyph(Glyph& glyph, char32_t character, float outlineThickness, bool lineWrap, Nz::Color color, int renderOrder, int* advance) const;
|
||||
void GenerateGlyphs(const String& text) const;
|
||||
|
||||
inline float GetLineHeight(const Font::SizeInfo& sizeInfo) const;
|
||||
|
||||
inline void InvalidateColor();
|
||||
inline void InvalidateGlyphs();
|
||||
|
||||
void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer);
|
||||
void OnFontInvalidated(const Font* font);
|
||||
void OnFontRelease(const Font* object);
|
||||
void UpdateGlyphColor() const;
|
||||
void UpdateGlyphs() const;
|
||||
|
||||
inline bool ShouldLineWrap(float size) const;
|
||||
|
||||
inline void UpdateGlyphColor() const;
|
||||
inline void UpdateGlyphs() const;
|
||||
|
||||
static constexpr std::size_t InvalidGlyph = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
NazaraSlot(Font, OnFontAtlasChanged, m_atlasChangedSlot);
|
||||
NazaraSlot(Font, OnFontAtlasLayerChanged, m_atlasLayerChangedSlot);
|
||||
NazaraSlot(Font, OnFontGlyphCacheCleared, m_glyphCacheClearedSlot);
|
||||
NazaraSlot(Font, OnFontRelease, m_fontReleaseSlot);
|
||||
|
||||
mutable std::size_t m_lastSeparatorGlyph;
|
||||
mutable std::vector<Glyph> m_glyphs;
|
||||
mutable std::vector<Line> m_lines;
|
||||
Color m_color;
|
||||
Color m_outlineColor;
|
||||
FontRef m_font;
|
||||
mutable Rectf m_workingBounds;
|
||||
mutable Recti m_bounds;
|
||||
mutable Rectf m_bounds;
|
||||
String m_text;
|
||||
TextStyleFlags m_style;
|
||||
mutable UInt32 m_previousCharacter;
|
||||
UInt32 m_style;
|
||||
mutable Vector2ui m_drawPos;
|
||||
mutable Vector2f m_drawPos;
|
||||
mutable bool m_colorUpdated;
|
||||
mutable bool m_glyphUpdated;
|
||||
mutable float m_lastSeparatorPosition;
|
||||
float m_characterSpacingOffset;
|
||||
float m_lineSpacingOffset;
|
||||
float m_maxLineWidth;
|
||||
float m_outlineThickness;
|
||||
unsigned int m_characterSize;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/SimpleTextDrawer.inl>
|
||||
|
||||
#endif // NAZARA_SIMPLETEXTDRAWER_HPP
|
||||
|
||||
385
include/Nazara/Utility/SimpleTextDrawer.inl
Normal file
385
include/Nazara/Utility/SimpleTextDrawer.inl
Normal file
@@ -0,0 +1,385 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/SimpleTextDrawer.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline SimpleTextDrawer::SimpleTextDrawer() :
|
||||
m_color(Color::White),
|
||||
m_outlineColor(Color::Black),
|
||||
m_style(TextStyle_Regular),
|
||||
m_colorUpdated(true),
|
||||
m_glyphUpdated(true),
|
||||
m_characterSpacingOffset(0.f),
|
||||
m_lineSpacingOffset(0.f),
|
||||
m_maxLineWidth(std::numeric_limits<float>::infinity()),
|
||||
m_outlineThickness(0.f),
|
||||
m_characterSize(24)
|
||||
{
|
||||
SetFont(Font::GetDefault());
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer::SimpleTextDrawer(const SimpleTextDrawer& drawer) :
|
||||
m_color(drawer.m_color),
|
||||
m_text(drawer.m_text),
|
||||
m_style(drawer.m_style),
|
||||
m_colorUpdated(false),
|
||||
m_glyphUpdated(false),
|
||||
m_outlineColor(drawer.m_outlineColor),
|
||||
m_characterSpacingOffset(drawer.m_characterSpacingOffset),
|
||||
m_lineSpacingOffset(drawer.m_lineSpacingOffset),
|
||||
m_maxLineWidth(drawer.m_maxLineWidth),
|
||||
m_outlineThickness(drawer.m_outlineThickness),
|
||||
m_characterSize(drawer.m_characterSize)
|
||||
{
|
||||
SetFont(drawer.m_font);
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer::SimpleTextDrawer(SimpleTextDrawer&& drawer)
|
||||
{
|
||||
operator=(std::move(drawer));
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::AppendText(const String& str)
|
||||
{
|
||||
m_text.Append(str);
|
||||
if (m_glyphUpdated)
|
||||
GenerateGlyphs(str);
|
||||
}
|
||||
|
||||
inline float SimpleTextDrawer::GetCharacterSpacingOffset() const
|
||||
{
|
||||
return m_characterSpacingOffset;
|
||||
}
|
||||
|
||||
inline unsigned int SimpleTextDrawer::GetCharacterSize() const
|
||||
{
|
||||
return m_characterSize;
|
||||
}
|
||||
|
||||
inline const Color& SimpleTextDrawer::GetColor() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
inline Font* SimpleTextDrawer::GetFont() const
|
||||
{
|
||||
return m_font;
|
||||
}
|
||||
|
||||
inline float SimpleTextDrawer::GetLineHeight() const
|
||||
{
|
||||
NazaraAssert(m_font, "SimpleTextDrawer has no font");
|
||||
return GetLineHeight(m_font->GetSizeInfo(m_characterSize));
|
||||
}
|
||||
|
||||
inline float SimpleTextDrawer::GetLineSpacingOffset() const
|
||||
{
|
||||
return m_lineSpacingOffset;
|
||||
}
|
||||
|
||||
inline const Color& SimpleTextDrawer::GetOutlineColor() const
|
||||
{
|
||||
return m_outlineColor;
|
||||
}
|
||||
|
||||
inline float SimpleTextDrawer::GetOutlineThickness() const
|
||||
{
|
||||
return m_outlineThickness;
|
||||
}
|
||||
|
||||
inline TextStyleFlags SimpleTextDrawer::GetStyle() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
|
||||
inline const String& SimpleTextDrawer::GetText() const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetCharacterSpacingOffset(float offset)
|
||||
{
|
||||
if (m_characterSpacingOffset != offset)
|
||||
{
|
||||
m_characterSpacingOffset = offset;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetCharacterSize(unsigned int characterSize)
|
||||
{
|
||||
if (m_characterSize != characterSize)
|
||||
{
|
||||
m_characterSize = characterSize;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetColor(const Color& color)
|
||||
{
|
||||
if (m_color != color)
|
||||
{
|
||||
m_color = color;
|
||||
|
||||
InvalidateColor();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetFont(Font* font)
|
||||
{
|
||||
if (m_font != font)
|
||||
{
|
||||
m_font = font;
|
||||
|
||||
if (m_font)
|
||||
ConnectFontSlots();
|
||||
else
|
||||
DisconnectFontSlots();
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetLineSpacingOffset(float offset)
|
||||
{
|
||||
if (m_lineSpacingOffset != offset)
|
||||
{
|
||||
m_lineSpacingOffset = offset;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetMaxLineWidth(float lineWidth)
|
||||
{
|
||||
if (m_maxLineWidth != lineWidth)
|
||||
{
|
||||
NazaraAssert(lineWidth > 0.f, "Max line width must be positive");
|
||||
|
||||
m_maxLineWidth = lineWidth;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetOutlineColor(const Color& color)
|
||||
{
|
||||
if (m_outlineColor != color)
|
||||
{
|
||||
m_outlineColor = color;
|
||||
|
||||
InvalidateColor();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetOutlineThickness(float thickness)
|
||||
{
|
||||
if (m_outlineThickness != thickness)
|
||||
{
|
||||
NazaraAssert(thickness >= 0.f, "Thickness must be zero or positive");
|
||||
|
||||
m_outlineThickness = thickness;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetStyle(TextStyleFlags style)
|
||||
{
|
||||
if (m_style != style)
|
||||
{
|
||||
m_style = style;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::SetText(const String& str)
|
||||
{
|
||||
if (m_text != str)
|
||||
{
|
||||
m_text = str;
|
||||
|
||||
InvalidateGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer& SimpleTextDrawer::operator=(const SimpleTextDrawer& drawer)
|
||||
{
|
||||
m_characterSize = drawer.m_characterSize;
|
||||
m_characterSpacingOffset = drawer.m_characterSpacingOffset;
|
||||
m_color = drawer.m_color;
|
||||
m_lineSpacingOffset = drawer.m_lineSpacingOffset;
|
||||
m_maxLineWidth = drawer.m_maxLineWidth;
|
||||
m_outlineColor = drawer.m_outlineColor;
|
||||
m_outlineThickness = drawer.m_outlineThickness;
|
||||
m_style = drawer.m_style;
|
||||
m_text = drawer.m_text;
|
||||
|
||||
SetFont(drawer.m_font);
|
||||
InvalidateGlyphs();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer& SimpleTextDrawer::operator=(SimpleTextDrawer&& drawer)
|
||||
{
|
||||
DisconnectFontSlots();
|
||||
|
||||
m_bounds = std::move(drawer.m_bounds);
|
||||
m_colorUpdated = std::move(drawer.m_colorUpdated);
|
||||
m_characterSize = std::move(drawer.m_characterSize);
|
||||
m_characterSpacingOffset = drawer.m_characterSpacingOffset;
|
||||
m_color = std::move(drawer.m_color);
|
||||
m_glyphs = std::move(drawer.m_glyphs);
|
||||
m_glyphUpdated = std::move(drawer.m_glyphUpdated);
|
||||
m_font = std::move(drawer.m_font);
|
||||
m_lineSpacingOffset = drawer.m_lineSpacingOffset;
|
||||
m_maxLineWidth = drawer.m_maxLineWidth;
|
||||
m_outlineColor = std::move(drawer.m_outlineColor);
|
||||
m_outlineThickness = std::move(drawer.m_outlineThickness);
|
||||
m_style = std::move(drawer.m_style);
|
||||
m_text = std::move(drawer.m_text);
|
||||
|
||||
// Update slot pointers (TODO: Improve the way of doing this)
|
||||
if (m_font)
|
||||
{
|
||||
drawer.DisconnectFontSlots();
|
||||
ConnectFontSlots();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer SimpleTextDrawer::Draw(const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color)
|
||||
{
|
||||
SimpleTextDrawer drawer;
|
||||
drawer.SetCharacterSize(characterSize);
|
||||
drawer.SetColor(color);
|
||||
drawer.SetStyle(style);
|
||||
drawer.SetText(str);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer SimpleTextDrawer::Draw(const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor)
|
||||
{
|
||||
SimpleTextDrawer drawer;
|
||||
drawer.SetCharacterSize(characterSize);
|
||||
drawer.SetColor(color);
|
||||
drawer.SetOutlineColor(outlineColor);
|
||||
drawer.SetOutlineThickness(outlineThickness);
|
||||
drawer.SetStyle(style);
|
||||
drawer.SetText(str);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer SimpleTextDrawer::Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color)
|
||||
{
|
||||
SimpleTextDrawer drawer;
|
||||
drawer.SetCharacterSize(characterSize);
|
||||
drawer.SetColor(color);
|
||||
drawer.SetFont(font);
|
||||
drawer.SetStyle(style);
|
||||
drawer.SetText(str);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
inline SimpleTextDrawer SimpleTextDrawer::Draw(Font* font, const String& str, unsigned int characterSize, TextStyleFlags style, const Color& color, float outlineThickness, const Color& outlineColor)
|
||||
{
|
||||
SimpleTextDrawer drawer;
|
||||
drawer.SetCharacterSize(characterSize);
|
||||
drawer.SetColor(color);
|
||||
drawer.SetFont(font);
|
||||
drawer.SetOutlineColor(outlineColor);
|
||||
drawer.SetOutlineThickness(outlineThickness);
|
||||
drawer.SetStyle(style);
|
||||
drawer.SetText(str);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::AppendNewLine() const
|
||||
{
|
||||
AppendNewLine(InvalidGlyph, 0);
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::ConnectFontSlots()
|
||||
{
|
||||
m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &SimpleTextDrawer::OnFontInvalidated);
|
||||
m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &SimpleTextDrawer::OnFontAtlasLayerChanged);
|
||||
m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &SimpleTextDrawer::OnFontRelease);
|
||||
m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &SimpleTextDrawer::OnFontInvalidated);
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::DisconnectFontSlots()
|
||||
{
|
||||
m_atlasChangedSlot.Disconnect();
|
||||
m_atlasLayerChangedSlot.Disconnect();
|
||||
m_fontReleaseSlot.Disconnect();
|
||||
m_glyphCacheClearedSlot.Disconnect();
|
||||
}
|
||||
|
||||
inline float SimpleTextDrawer::GetLineHeight(const Font::SizeInfo& sizeInfo) const
|
||||
{
|
||||
return float(sizeInfo.lineHeight) + m_lineSpacingOffset;
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::InvalidateColor()
|
||||
{
|
||||
m_colorUpdated = false;
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::InvalidateGlyphs()
|
||||
{
|
||||
m_glyphUpdated = false;
|
||||
}
|
||||
|
||||
inline bool SimpleTextDrawer::ShouldLineWrap(float size) const
|
||||
{
|
||||
if (m_lines.back().glyphIndex > m_glyphs.size())
|
||||
return false;
|
||||
|
||||
return m_lines.back().bounds.GetMaximum().x + size > m_maxLineWidth;
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::UpdateGlyphColor() const
|
||||
{
|
||||
if (m_outlineThickness > 0.f)
|
||||
{
|
||||
for (std::size_t glyphIndex = 0; glyphIndex < m_glyphs.size(); ++glyphIndex)
|
||||
{
|
||||
Glyph& glyph = m_glyphs[glyphIndex];
|
||||
if (glyphIndex % 2 == 0)
|
||||
glyph.color = m_outlineColor;
|
||||
else
|
||||
glyph.color = m_color;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Glyph& glyph : m_glyphs)
|
||||
glyph.color = m_color;
|
||||
}
|
||||
|
||||
m_colorUpdated = true;
|
||||
}
|
||||
|
||||
inline void SimpleTextDrawer::UpdateGlyphs() const
|
||||
{
|
||||
NazaraAssert(m_font && m_font->IsValid(), "Invalid font");
|
||||
|
||||
ClearGlyphs();
|
||||
GenerateGlyphs(m_text);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/DebugOff.hpp>
|
||||
Reference in New Issue
Block a user