Crafter.Graphics/interfaces/Crafter.Graphics-Font.cppm

74 lines
2.7 KiB
Text
Raw Normal View History

2025-11-17 00:44:45 +01:00
/*
Crafter®.Graphics
2026-03-09 20:10:19 +01:00
Copyright (C) 2026 Catcrafts®
2025-11-17 00:44:45 +01:00
Catcrafts.net
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
module;
2026-05-18 02:07:48 +02:00
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
2025-11-17 00:44:45 +01:00
#include "../lib/stb_truetype.h"
2026-05-18 02:07:48 +02:00
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM
2025-11-17 00:44:45 +01:00
export module Crafter.Graphics:Font;
2026-05-18 02:07:48 +02:00
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
2025-11-17 00:44:45 +01:00
import std;
namespace Crafter {
2026-05-01 23:35:37 +02:00
// Decode the UTF-8 codepoint at `text[i]` and advance `i` past it.
// Returns 0 once `i` reaches the end. Malformed sequences yield U+FFFD
// and the index is moved past one byte to keep iteration finite.
export inline std::uint32_t DecodeUtf8(std::string_view text, std::size_t& i) {
if (i >= text.size()) return 0;
std::uint8_t b0 = static_cast<std::uint8_t>(text[i]);
// Single-byte ASCII is the common path.
if (b0 < 0x80) { ++i; return b0; }
int extra;
std::uint32_t cp;
if ((b0 & 0xE0) == 0xC0) { extra = 1; cp = b0 & 0x1F; }
else if ((b0 & 0xF0) == 0xE0) { extra = 2; cp = b0 & 0x0F; }
else if ((b0 & 0xF8) == 0xF0) { extra = 3; cp = b0 & 0x07; }
else { ++i; return 0xFFFD; } // continuation byte at start, or 5+-byte leader
++i;
for (int k = 0; k < extra; ++k) {
if (i >= text.size()) return 0xFFFD;
std::uint8_t b = static_cast<std::uint8_t>(text[i]);
if ((b & 0xC0) != 0x80) return 0xFFFD; // missing continuation
cp = (cp << 6) | (b & 0x3Fu);
++i;
}
return cp;
}
2025-11-17 00:44:45 +01:00
export class Font {
public:
std::vector<unsigned char> fontBuffer;
2026-05-01 23:35:37 +02:00
std::int_fast32_t ascent;
std::int_fast32_t descent;
2025-11-17 00:44:45 +01:00
std::int_fast32_t lineGap;
stbtt_fontinfo font;
2026-04-16 23:03:24 +02:00
Font(const std::filesystem::path& font);
std::uint32_t GetLineWidth(const std::string_view text, float size);
2026-05-01 23:35:37 +02:00
float LineHeight(float size);
float AscentPx(float size); // baseline offset from line-top
float ScaleForSize(float size); // stb's pixel-units-per-em factor
2025-11-17 00:44:45 +01:00
};
2026-05-18 02:07:48 +02:00
}
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM