-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimrichtextutils.h
197 lines (163 loc) · 7.33 KB
/
imrichtextutils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#pragma once
#include <string_view>
#include <optional>
#include "imgui.h"
#ifndef IM_RICHTEXT_MAX_COLORSTOPS
#define IM_RICHTEXT_MAX_COLORSTOPS 4
#endif
#ifdef IM_RICHTEXT_NO_IMGUI
#define IM_COL32_BLACK ImRichText::ToRGBA(0, 0, 0, 255)
#define IM_COL32_BLACK_TRANS ImRichText::ToRGBA(0, 0, 0, 0)
struct ImVec2
{
float x = 0.f, y = 0.f;
};
enum ImGuiDir : int
{
ImGuiDir_None = -1,
ImGuiDir_Left = 0,
ImGuiDir_Right = 1,
ImGuiDir_Up = 2,
ImGuiDir_Down = 3,
ImGuiDir_COUNT
};
#endif
#if !defined(IMGUI_DEFINE_MATH_OPERATORS) || defined(IM_RICHTEXT_NO_IMGUI)
[[nodiscard]] ImVec2 operator+(ImVec2 lhs, ImVec2 rhs) { return ImVec2{ lhs.x + rhs.x, lhs.y + rhs.y }; }
[[nodiscard]] ImVec2 operator*(ImVec2 lhs, float rhs) { return ImVec2{ lhs.x * rhs, lhs.y * rhs }; }
[[nodiscard]] ImVec2 operator-(ImVec2 lhs, ImVec2 rhs) { return ImVec2{ lhs.x - rhs.x, lhs.y - rhs.y }; }
#endif
namespace ImRichText
{
enum class BulletType
{
Circle,
FilledCircle,
Disk = FilledCircle,
Square,
Triangle,
Arrow,
CheckMark,
CheckBox, // Needs fixing
Concentric,
Custom
};
struct BoundedBox
{
float top = 0.f, left = 0.f;
float width = 0.f, height = 0.f;
ImVec2 start(ImVec2 origin) const { return ImVec2{ left, top } + origin; }
ImVec2 end(ImVec2 origin) const { return ImVec2{ left + width, top + height } + origin; }
ImVec2 center(ImVec2 origin) const { return ImVec2{ left + (0.5f * width), top + (0.5f * height) } + origin; }
};
// Implement this to draw primitives in your favorite graphics API
struct IRenderer
{
void* UserData = nullptr;
virtual void DrawLine(ImVec2 startpos, ImVec2 endpos, uint32_t color, float thickness = 1.f) = 0;
virtual void DrawPolyline(ImVec2* points, int sz, uint32_t color, float thickness) = 0;
virtual void DrawTriangle(ImVec2 pos1, ImVec2 pos2, ImVec2 pos3, uint32_t color, bool filled, bool thickness = 1.f) = 0;
virtual void DrawRect(ImVec2 startpos, ImVec2 endpos, uint32_t color, bool filled, float thickness = 1.f, float radius = 0.f, int corners = 0) = 0;
virtual void DrawRectGradient(ImVec2 startpos, ImVec2 endpos, uint32_t topleftcolor, uint32_t toprightcolor, uint32_t bottomrightcolor, uint32_t bottomleftcolor) = 0;
virtual void DrawPolygon(ImVec2* points, int sz, uint32_t color, bool filled, float thickness = 1.f) = 0;
virtual void DrawPolyGradient(ImVec2* points, uint32_t* colors, int sz) = 0;
virtual void DrawCircle(ImVec2 center, float radius, uint32_t color, bool filled, bool thickness = 1.f) = 0;
virtual void DrawBullet(ImVec2 startpos, ImVec2 endpos, uint32_t color, int index, int depth) {};
virtual void DrawText(std::string_view text, ImVec2 pos, uint32_t color) = 0;
virtual void DrawText(std::string_view text, std::string_view family, ImVec2 pos, float sz, uint32_t color, bool bold = false, bool italics = false, bool light = false) = 0;
void DrawDefaultBullet(BulletType type, ImVec2 initpos, const BoundedBox& bounds, uint32_t color, float bulletsz);
};
// Implement this interface to handle parsed rich text
struct ITagVisitor
{
virtual bool TagStart(std::string_view tag) = 0;
virtual bool Attribute(std::string_view name, std::optional<std::string_view> value) = 0;
virtual bool TagStartDone() = 0;
virtual bool Content(std::string_view content) = 0;
virtual bool PreFormattedContent(std::string_view content) = 0;
virtual bool TagEnd(std::string_view tag, bool selfTerminating) = 0;
virtual void Finalize() = 0;
virtual void Error(std::string_view tag) = 0;
virtual bool IsSelfTerminating(std::string_view tag) const = 0;
virtual bool IsPreformattedContent(std::string_view tag) const = 0;
};
struct IPlatform
{
virtual ImVec2 GetCurrentMousePos() = 0;
virtual bool IsMouseClicked() = 0;
virtual void HandleHyperlink(std::string_view) = 0;
virtual void RequestFrame() = 0;
virtual void HandleHover(bool) = 0;
};
struct IntOrFloat
{
float value = 0.f;
bool isFloat = false;
};
struct ColorStop
{
uint32_t from, to;
float pos = -1.f;
};
struct ColorGradient
{
ColorStop colorStops[IM_RICHTEXT_MAX_COLORSTOPS];
int totalStops = 0;
float angleDegrees = 0.f;
ImGuiDir dir = ImGuiDir::ImGuiDir_Down;
};
struct FourSidedMeasure
{
float top = 0.f, left = 0.f, right = 0.f, bottom = 0.f;
float h() const { return left + right; }
float v() const { return top + bottom; }
};
enum class LineType
{
Solid, Dashed, Dotted, DashDot
};
struct Border
{
uint32_t color = IM_COL32_BLACK_TRANS;
float thickness = 0.f;
LineType lineType = LineType::Solid; // Unused for rendering
};
enum BoxCorner
{
TopLeftCorner = 1,
TopRightCorner = 2,
BottomRightCorner = 4,
BottomLeftCorner = 8,
AllCorners = TopLeftCorner | TopRightCorner | BottomRightCorner | BottomLeftCorner
};
struct FourSidedBorder
{
Border top, left, bottom, right;
float radius = 0.f;
int rounding = BoxCorner::AllCorners;
float h() const { return left.thickness + right.thickness; }
float v() const { return top.thickness + bottom.thickness; }
};
// Generic string helpers, case-insensitive matches
[[nodiscard]] bool AreSame(const std::string_view lhs, const char* rhs);
[[nodiscard]] bool AreSame(const std::string_view lhs, const std::string_view rhs);
[[nodiscard]] bool StartsWith(const std::string_view lhs, const char* rhs);
[[nodiscard]] int SkipDigits(const std::string_view text, int from = 0);
[[nodiscard]] int SkipFDigits(const std::string_view text, int from = 0);
[[nodiscard]] int SkipSpace(const std::string_view text, int from = 0);
[[nodiscard]] int SkipSpace(const char* text, int idx, int end);
[[nodiscard]] std::optional<std::string_view> GetQuotedString(const char* text, int& idx, int end);
[[nodiscard]] int ExtractInt(std::string_view input, int defaultVal);
[[nodiscard]] int ExtractIntFromHex(std::string_view input, int defaultVal);
[[nodiscard]] IntOrFloat ExtractNumber(std::string_view input, float defaultVal);
[[nodiscard]] float ExtractFloatWithUnit(std::string_view input, float defaultVal, float ems, float parent, float scale);
[[nodiscard]] uint32_t ToRGBA(int r, int g, int b, int a = 255);
[[nodiscard]] uint32_t ToRGBA(float r, float g, float b, float a = 1.f);
[[nodiscard]] uint32_t ExtractColor(std::string_view stylePropVal, uint32_t(*NamedColor)(const char*, void*), void* userData);
[[nodiscard]] ColorGradient ExtractLinearGradient(std::string_view input, uint32_t(*NamedColor)(const char*, void*), void* userData);
[[nodiscard]] uint32_t GetColor(const char* name, void*);
[[nodiscard]] Border ExtractBorder(std::string_view input, float ems, float percent,
uint32_t(*NamedColor)(const char*, void*), void* userData);
// Parse rich text and invoke appropriate visitor methods
void ParseRichText(const char* text, const char* textend, char TagStart, char TagEnd, ITagVisitor& visitor);
}