Skip to content

Commit fbc0e3e

Browse files
committed
Fonts & Markers
- Seperated out the Display interface and added a Font interface. This is for future improvements to enable different size font display - It is now possible to provide different font sizes for predefined types, and the main text buffer can be scaled independent of the rest of the UI. - Beginning markdown support: #Heading will show bigger font - Markers now handle their own updates when the buffer changes - Markers are outside the undo system, but flexible enough now for users to update them as needed. I am still working on improving marker abilities and making them flexible enough for various scenarios. - Integrated a simple signal/slot mechanism to make messaging easier. I hope this will be better than the messaging system in the long term, and more flexible. - Fix the bug where you couldn't 'j' down in certain wrapped text buffer cases
1 parent 25a780d commit fbc0e3e

55 files changed

Lines changed: 12601 additions & 580 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

demos/demo_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Zep
44
{
5-
const float DemoFontPtSize = 11.0f;
5+
const float DemoFontPtSize = 14.0f;
66
} // Zep
77

88

demos/demo_imgui/main.cpp

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,16 @@ void main()
101101

102102
std::string startupFile;
103103

104-
Zep::NVec2f GetDisplayScale()
104+
Zep::NVec2f GetPixelScale()
105105
{
106106
float ddpi = 0.0f;
107107
float hdpi = 0.0f;
108108
float vdpi = 0.0f;
109-
auto res = SDL_GetDisplayDPI(0, &ddpi, &hdpi, &vdpi);
109+
110+
auto window = SDL_GL_GetCurrentWindow();
111+
auto index = window ? SDL_GetWindowDisplayIndex(window) : 0;
112+
113+
auto res = SDL_GetDisplayDPI(index, &ddpi, &hdpi, &vdpi);
110114
if (res == 0 && hdpi != 0)
111115
{
112116
return Zep::NVec2f(hdpi, vdpi) / 96.0f;
@@ -153,15 +157,44 @@ bool ReadCommandLine(int argc, char** argv, int& exitCode)
153157
}
154158

155159
// A helper struct to init the editor and handle callbacks
156-
struct ZepContainer : public IZepComponent, public IZepReplProvider
160+
struct ZepContainerImGui : public IZepComponent, public IZepReplProvider
157161
{
158-
ZepContainer(const std::string& startupFilePath, const std::string& configPath)
159-
: spEditor(std::make_unique<ZepEditor_ImGui>(configPath))
162+
ZepContainerImGui(const std::string& startupFilePath, const std::string& configPath)
163+
: spEditor(std::make_unique<ZepEditor_ImGui>(configPath, GetPixelScale()))
160164
{
161165
chibi_init(scheme, SDL_GetBasePath());
162166

167+
// ZepEditor_ImGui will have created the fonts for us; but we need to build
168+
// the font atlas
169+
auto fontPath = std::string(SDL_GetBasePath()) + "Cousine-Regular.ttf";
170+
auto& display = static_cast<ZepDisplay_ImGui&>(spEditor->GetDisplay());
171+
172+
int fontPixelHeight = (int)dpi_pixel_height_from_point_size(DemoFontPtSize, GetPixelScale().y);
173+
174+
auto& io = ImGui::GetIO();
175+
ImVector<ImWchar> ranges;
176+
ImFontGlyphRangesBuilder builder;
177+
builder.AddRanges(io.Fonts->GetGlyphRangesDefault()); // Add one of the default ranges
178+
builder.AddRanges(io.Fonts->GetGlyphRangesCyrillic()); // Add one of the default ranges
179+
builder.AddRanges(greek_range);
180+
builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted)
181+
182+
ImFontConfig cfg;
183+
cfg.OversampleH = 4;
184+
cfg.OversampleV = 4;
185+
186+
auto pImFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(fontPath.c_str(), float(fontPixelHeight), &cfg, ranges.Data);
187+
188+
display.SetFont(ZepTextType::UI, std::make_shared<ZepFont_ImGui>(display, pImFont, fontPixelHeight));
189+
display.SetFont(ZepTextType::Text, std::make_shared<ZepFont_ImGui>(display, pImFont, fontPixelHeight));
190+
display.SetFont(ZepTextType::Heading1, std::make_shared<ZepFont_ImGui>(display, pImFont, int(fontPixelHeight * 1.75)));
191+
display.SetFont(ZepTextType::Heading2, std::make_shared<ZepFont_ImGui>(display, pImFont, int(fontPixelHeight * 1.5)));
192+
display.SetFont(ZepTextType::Heading3, std::make_shared<ZepFont_ImGui>(display, pImFont, int(fontPixelHeight * 1.25)));
193+
194+
unsigned int flags = 0; // ImGuiFreeType::NoHinting;
195+
ImGuiFreeType::BuildFontAtlas(ImGui::GetIO().Fonts, flags);
196+
163197
spEditor->RegisterCallback(this);
164-
spEditor->SetPixelScale(GetDisplayScale());
165198

166199
ZepMode_Orca::Register(*spEditor);
167200

@@ -198,7 +231,7 @@ struct ZepContainer : public IZepComponent, public IZepReplProvider
198231
#endif
199232
}
200233

201-
ZepContainer()
234+
ZepContainerImGui()
202235
{
203236
spEditor->UnRegisterCallback(this);
204237
}
@@ -230,7 +263,7 @@ struct ZepContainer : public IZepComponent, public IZepReplProvider
230263
if (range.first >= range.second)
231264
return "<No Expression>";
232265

233-
const auto& text = buffer.GetGapBuffer();
266+
const auto& text = buffer.GetWorkingBuffer();
234267
auto eval = std::string(text.begin() + range.first.Index(), text.begin() + range.second.Index());
235268

236269
// Flash the evaluated expression
@@ -324,7 +357,7 @@ struct ZepContainer : public IZepComponent, public IZepReplProvider
324357
if (pSyntax->GetSyntaxAt(spTipMsg->location).foreground == ThemeColor::Identifier)
325358
{
326359
auto spMarker = std::make_shared<RangeMarker>(*spTipMsg->pBuffer);
327-
spMarker->description = "This is an identifier";
360+
spMarker->SetDescription("This is an identifier");
328361
spMarker->SetHighlightColor(ThemeColor::Identifier);
329362
spMarker->SetTextColor(ThemeColor::Text);
330363
spTipMsg->spMarker = spMarker;
@@ -333,7 +366,7 @@ struct ZepContainer : public IZepComponent, public IZepReplProvider
333366
else if (pSyntax->GetSyntaxAt(spTipMsg->location).foreground == ThemeColor::Keyword)
334367
{
335368
auto spMarker = std::make_shared<RangeMarker>(*spTipMsg->pBuffer);
336-
spMarker->description = "This is a keyword";
369+
spMarker->SetDescription("This is a keyword");
337370
spMarker->SetHighlightColor(ThemeColor::Keyword);
338371
spMarker->SetTextColor(ThemeColor::Text);
339372
spTipMsg->spMarker = spMarker;
@@ -436,37 +469,17 @@ int main(int argc, char** argv)
436469
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
437470
ImGui_ImplOpenGL3_Init(glsl_version);
438471

472+
// ** Zep specific code, before Initializing font map
473+
ZepContainerImGui zep(startupFile, SDL_GetBasePath());
474+
439475
// Setup style
440476
ImGui::StyleColorsDark();
441477

442-
ImVector<ImWchar> ranges;
443-
ImFontGlyphRangesBuilder builder;
444-
builder.AddRanges(io.Fonts->GetGlyphRangesDefault()); // Add one of the default ranges
445-
builder.AddRanges(io.Fonts->GetGlyphRangesCyrillic()); // Add one of the default ranges
446-
//builder.AddRanges(io.Fonts->GetGlyphRangesThai()); // Add one of the default ranges
447-
ImWchar greek_range[] = { 0x300, 0x52F, 0x1f00, 0x1fff, 0, 0 };
448-
builder.AddRanges(greek_range);
449-
builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted)
450-
451-
ImFontConfig cfg;
452-
cfg.OversampleH = 4;
453-
cfg.OversampleV = 4;
454-
455-
float fontPixelHeight = dpi_pixel_height_from_point_size(DemoFontPtSize, GetDisplayScale().y);
456-
io.Fonts->AddFontFromFileTTF((std::string(SDL_GetBasePath()) + "Cousine-Regular.ttf").c_str(), fontPixelHeight, &cfg, ranges.Data);
457-
458-
ZLOG(INFO, "DPI Scale: " << MUtils::NVec2f(GetDisplayScale().x, GetDisplayScale().y));
459-
ZLOG(INFO, "Font Pixel Size: " << fontPixelHeight);
460-
461-
unsigned int flags = 0; // ImGuiFreeType::NoHinting;
462-
ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);
478+
ZLOG(INFO, "DPI Scale: " << MUtils::NVec2f(GetPixelScale().x, GetPixelScale().y));
463479

464480
bool show_demo_window = false;
465481
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
466482

467-
// ** Zep specific code
468-
ZepContainer zep(startupFile, SDL_GetBasePath());
469-
470483
MUtils::TimeProvider::Instance().StartThread();
471484

472485
// Main loop

demos/demo_qt/mainwindow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ std::string MainWindow::ReplParse(ZepBuffer& buffer, const GlyphIterator& cursor
167167
ZEP_UNUSED(cursorOffset);
168168
ZEP_UNUSED(type);
169169

170-
auto ret = chibi_repl(scheme, NULL, buffer.GetGapBuffer().string());
170+
auto ret = chibi_repl(scheme, NULL, buffer.GetWorkingBuffer().string());
171171
ret = RTrim(ret);
172172
return ret;
173173
}

extensions/orca/orca.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void Orca::ReadFromBuffer(ZepBuffer* pBuffer)
101101
m_size = NVec2i(m_field.width, m_field.height);
102102

103103
// Copy the buffer into the field
104-
auto& text = pBuffer->GetGapBuffer();
104+
auto& text = pBuffer->GetWorkingBuffer();
105105
auto sz = text.size();
106106
for (int y = 0; y < m_field.height; y++)
107107
{
@@ -138,7 +138,7 @@ void Orca::WriteToBuffer(ZepBuffer* pBuffer, ZepWindow& window)
138138
m_lastCursorPos = window.BufferToDisplay();
139139

140140
// Copy the calculated buffer data from the orca buffer
141-
auto& text = pBuffer->GetMutableText();
141+
auto& text = pBuffer->GetMutableWorkingBuffer();
142142
for (int y = 0; y < m_field.height; y++)
143143
{
144144
for (int x = 0; x < m_field.width; x++)

extensions/orca/syntax_orca.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ SyntaxResult ZepSyntax_Orca::GetSyntaxAt(const GlyphIterator& itr) const
4949

5050
void ZepSyntax_Orca::UpdateSyntax()
5151
{
52-
auto& buffer = m_buffer.GetGapBuffer();
52+
auto& buffer = m_buffer.GetWorkingBuffer();
5353

5454
// We don't do anything in orca mode, we get dynamically because Orca tells us the colors
5555
m_targetChar = long(0);

extensions/repl/mode_repl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ bool ZepReplExCommand::AddKeyPress(uint32_t key, uint32_t modifiers)
147147
{
148148
ChangeRecord record;
149149
auto& buffer = m_pReplWindow->GetBuffer();
150-
std::string str = std::string(buffer.GetGapBuffer().begin() + m_startLocation.Index(), buffer.GetGapBuffer().end());
150+
std::string str = std::string(buffer.GetWorkingBuffer().begin() + m_startLocation.Index(), buffer.GetWorkingBuffer().end());
151151
if (str.size() <= 1)
152152
{
153153
MoveToEnd();

include/zep/buffer.h

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "zep/mcommon/file/path.h"
77
#include "zep/mcommon/string/stringutils.h"
88
#include "zep/mcommon/logger.h"
9+
#include "zep/mcommon/signals.h"
910

1011
#include "zep/glyph_iterator.h"
1112

@@ -92,37 +93,16 @@ enum class ReplaceRangeMode
9293
Replace,
9394
};
9495

95-
struct MarkerMove
96-
{
97-
MarkerMove(ByteIndex markerFrom, ByteIndex markerTo, const std::shared_ptr<RangeMarker> spMarker)
98-
: from(markerFrom),
99-
to(markerTo),
100-
marker(spMarker)
101-
{
102-
103-
}
104-
105-
ByteIndex from;
106-
ByteIndex to;
107-
std::shared_ptr<RangeMarker> marker;
108-
};
109-
110-
using tMarkerMoves = std::vector<MarkerMove>;
111-
using tMarkers = std::vector<std::shared_ptr<RangeMarker>>;
11296
struct ChangeRecord
11397
{
11498
std::string strDeleted;
11599
std::string strInserted;
116-
tMarkerMoves markerMoves;
117-
tMarkers markerDeletes;
118100
GlyphIterator itrStart;
119101
GlyphIterator itrEnd;
120102

121103
void Clear()
122104
{
123105
strDeleted.clear();
124-
markerMoves.clear();
125-
markerDeletes.clear();
126106
itrStart.Invalidate();
127107
itrEnd.Invalidate();
128108
}
@@ -180,14 +160,16 @@ class ZepBuffer : public ZepComponent
180160
GlyphIterator End() const;
181161
GlyphIterator Begin() const;
182162

183-
const GapBuffer<uint8_t>& GetGapBuffer() const
163+
const GapBuffer<uint8_t>& GetWorkingBuffer() const
184164
{
185-
return m_gapBuffer;
165+
return m_workingBuffer;
186166
}
187-
GapBuffer<uint8_t>& GetMutableText()
167+
168+
GapBuffer<uint8_t>& GetMutableWorkingBuffer()
188169
{
189-
return m_gapBuffer;
170+
return m_workingBuffer;
190171
}
172+
191173
const std::vector<ByteIndex> GetLineEnds() const
192174
{
193175
return m_lineEnds;
@@ -247,7 +229,6 @@ class ZepBuffer : public ZepComponent
247229

248230
void ForEachMarker(uint32_t types, Direction dir, const GlyphIterator& begin, const GlyphIterator& end, std::function<bool(const std::shared_ptr<RangeMarker>&)> fnCB) const;
249231
std::shared_ptr<RangeMarker> FindNextMarker(GlyphIterator start, Direction dir, uint32_t markerType);
250-
void ApplyMarkerChanges(ChangeRecord& record, Direction direction);
251232

252233
void SetBufferType(BufferType type);
253234
BufferType GetBufferType() const;
@@ -287,15 +268,16 @@ class ZepBuffer : public ZepComponent
287268
uint64_t ToHandle() const;
288269
static ZepBuffer* FromHandle(ZepEditor& editor, uint64_t handle);
289270

271+
Zep::signal<void(ZepBuffer& buffer, const GlyphIterator&, const std::string&)> sigPreInsert;
272+
Zep::signal<void(ZepBuffer& buffer, const GlyphIterator&, const GlyphIterator&)> sigPreDelete;
273+
290274
private:
291275
void MarkUpdate();
292276

293-
void UpdateForInsert(const GlyphIterator& startOffset, const GlyphIterator& endOffset, ChangeRecord& changeRecord);
294-
void UpdateForDelete(const GlyphIterator& startOffset, const GlyphIterator& endOffset, ChangeRecord& changeRecord);
295-
296277
private:
297278
// Buffer & record of the line end locations
298-
GapBuffer<uint8_t> m_gapBuffer;
279+
GapBuffer<uint8_t> m_workingBuffer;
280+
299281
std::vector<ByteIndex> m_lineEnds;
300282

301283
// File and modification info

0 commit comments

Comments
 (0)