- Add three proportional serif fonts: Crimson Pro, ET Book, Spectral - Fix text rendering for variable-width fonts: selection, cursor, mouse click mapping, search highlights, and syntax-colored text now use pixel-accurate measurement via ImGui::CalcTextSize() - Add per-buffer edit mode (code/writing) with auto-detection from file extension (.txt, .md, .rst, .org, .tex default to writing) - Add C-k m keybinding and :mode command to toggle edit modes - Switch config format from INI to TOML (kge.toml), with legacy INI fallback; vendor toml++ v3.4.0 - New config keys: font.code and font.writing for per-mode defaults - Add font tab completion for ImGui builds - Add tab completion for :mode command - Update help text, themes.md, and add CONFIG.md - Bump version to 1.10.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
138 lines
2.9 KiB
C++
138 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "Font.h"
|
|
|
|
namespace kte::Fonts {
|
|
class FontRegistry {
|
|
public:
|
|
// Get the global instance
|
|
static FontRegistry &Instance()
|
|
{
|
|
static FontRegistry instance;
|
|
return instance;
|
|
}
|
|
|
|
|
|
// Register a font (usually done at startup or static initialization)
|
|
void Register(std::unique_ptr<Font> font)
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
auto name = font->Name();
|
|
assert(fonts_.find(name) == fonts_.end() && "Font already registered!");
|
|
fonts_[std::move(name)] = std::move(font);
|
|
}
|
|
|
|
|
|
// Get a font by name (const access)
|
|
const Font *Get(const std::string &name) const
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
const auto it = fonts_.find(name);
|
|
return it != fonts_.end() ? it->second.get() : nullptr;
|
|
}
|
|
|
|
|
|
// Convenience: load a font by name and size
|
|
bool LoadFont(const std::string &name, const float size)
|
|
{
|
|
if (auto *font = Get(name)) {
|
|
font->Load(size);
|
|
// Track current selection
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
current_name_ = name;
|
|
current_size_ = size;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
// Request font load to be applied at a safe time (e.g., before starting a new frame)
|
|
// Thread-safe. Frontend should call ConsumePendingFontRequest() and then LoadFont().
|
|
void RequestLoadFont(const std::string &name, float size)
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
pending_name_ = name;
|
|
pending_size_ = size;
|
|
has_pending_ = true;
|
|
}
|
|
|
|
|
|
// Retrieve and clear a pending font request. Returns true if there was one.
|
|
bool ConsumePendingFontRequest(std::string &name, float &size)
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
if (!has_pending_)
|
|
return false;
|
|
name = pending_name_;
|
|
size = pending_size_;
|
|
has_pending_ = false;
|
|
return true;
|
|
}
|
|
|
|
|
|
// Check if font exists
|
|
bool HasFont(const std::string &name) const
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
return fonts_.count(name) > 0;
|
|
}
|
|
|
|
|
|
// Return all registered font names (sorted)
|
|
std::vector<std::string> FontNames() const
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
std::vector<std::string> names;
|
|
names.reserve(fonts_.size());
|
|
for (const auto &[name, _] : fonts_)
|
|
names.push_back(name);
|
|
std::sort(names.begin(), names.end());
|
|
return names;
|
|
}
|
|
|
|
|
|
// Current font name/size as last successfully loaded via LoadFont()
|
|
std::string CurrentFontName() const
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
return current_name_;
|
|
}
|
|
|
|
|
|
float CurrentFontSize() const
|
|
{
|
|
std::lock_guard lock(mutex_);
|
|
return current_size_;
|
|
}
|
|
|
|
private:
|
|
FontRegistry() = default;
|
|
|
|
mutable std::mutex mutex_;
|
|
std::unordered_map<std::string, std::unique_ptr<Font> > fonts_;
|
|
|
|
// Pending font change request (applied by frontend between frames)
|
|
bool has_pending_ = false;
|
|
std::string pending_name_;
|
|
float pending_size_ = 0.0f;
|
|
|
|
// Track last applied font
|
|
std::string current_name_;
|
|
float current_size_ = 0.0f;
|
|
};
|
|
|
|
|
|
void InstallDefaultFonts();
|
|
}
|