20using namespace render;
37 bool isNull()
const {
return m_face ==
nullptr; }
145 float ascent()
const {
return m_ascent; }
147 float height()
const {
return m_ascent - m_descent; }
169 std::vector<GlyphBox>
glyphBoxes(
const std::u32string_view&
text)
const;
172 float size()
const {
return m_size; }
179 float m_ascent = 0.f;
180 float m_descent = 0.f;
181 float m_lineGap = 0.f;
232 : m_face(face.release())
255 std::swap(m_face, face.m_face);
260 return std::exchange(m_face,
nullptr);
313 std::vector<char32_t> result;
317 static_cast<std::vector<char32_t>*
>(closure)->push_back(
static_cast<char32_t>(codepoint));
340 static const struct {
342 const char* fallback;
343 } generic_fallbacks[] = {
344#if defined(__linux__)
345 {
"sans-serif",
"DejaVu Sans"},
346 {
"serif",
"DejaVu Serif"},
347 {
"monospace",
"DejaVu Sans Mono"},
349 {
"sans-serif",
"Arial"},
350 {
"serif",
"Times New Roman"},
351 {
"monospace",
"Courier New"},
353 {
"cursive",
"Comic Sans MS"},
354 {
"fantasy",
"Impact"}
357 for(
auto value : generic_fallbacks) {
358 if(value.generic == family || family.empty()) {
377 static const char*
const sans[] = {
"Arial",
"Liberation Sans",
"Arimo",
"Nimbus Sans",
"Nimbus Sans L",
"FreeSans",
nullptr};
378 static const char*
const serif[] = {
"Times New Roman",
"Liberation Serif",
"Tinos",
"Nimbus Roman",
"Nimbus Roman No9 L",
"FreeSerif",
nullptr};
379 static const char*
const mono[] = {
"Courier New",
"Liberation Mono",
"Cousine",
"Nimbus Mono PS",
"Nimbus Mono",
"FreeMono",
nullptr};
380 static const char*
const calibri[] = {
"Carlito",
nullptr};
381 static const char*
const cambria[] = {
"Caladea",
nullptr};
382 static const char*
const georgia[] = {
"Gelasio",
nullptr};
383 static const struct {
385 const char*
const* substitutes;
387 {
"Arial", sans}, {
"Helvetica", sans}, {
"Helvetica Neue", sans},
388 {
"Times New Roman", serif}, {
"Times", serif},
389 {
"Courier New", mono}, {
"Courier", mono},
390 {
"Calibri", calibri}, {
"Cambria", cambria}, {
"Georgia", georgia},
393 std::string_view input(familyStack);
394 while(!input.empty()) {
395 auto family = input.substr(0, input.find(
','));
396 input.remove_prefix(family.length());
397 if(!input.empty() && input.front() ==
',')
398 input.remove_prefix(1);
400 if(!family.empty() && (family.front() ==
'\'' || family.front() ==
'"')) {
401 auto quote = family.front();
402 family.remove_prefix(1);
403 if(!family.empty() && family.back() == quote)
404 family.remove_suffix(1);
410 std::string name(family);
414 std::string lower(name);
415 for(
auto& ch : lower)
416 ch =
static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
418 for(
const auto& alias : aliases) {
419 std::string key(alias.family);
421 ch =
static_cast<char>(std::tolower(
static_cast<unsigned char>(ch)));
426 for(
auto substitute = alias.substitutes; *substitute; ++substitute) {
444#ifndef NOVASVG_DISABLE_LOAD_SYSTEM_FONTS
456 : m_face(face), m_size(size)
458 if(m_size > 0.f && !m_face.
isNull()) {
466 if(m_size > 0.f && !m_face.
isNull())
473 if(m_size > 0.f && !m_face.
isNull())
479 std::vector<GlyphBox> boxes;
480 if(m_size <= 0.f || m_face.
isNull())
488 bool hasPrevious =
false;
494 previous = codepoint;
500 if(extents.
w > 0.f || extents.
h > 0.f)
501 boxes.push_back({pen, extents.
x, extents.
x + extents.
w, extents.
y, extents.
y + extents.
h});
friend FontFaceCache * fontFaceCache()
bool addFontFace(const std::string &family, bool bold, bool italic, const FontFace &face)
FontFace getFontFace(const std::string &family, bool bold, bool italic) const
FontFace getFontFaceLocal(const std::string &family, bool bold, bool italic) const
FontFace getFontFaceForFamilyStack(const std::string &familyStack, bool bold, bool italic) const
void swap(FontFace &face)
float ascentUnits() const
float descentUnits() const
float notdefAdvanceWidthUnits() const
font_face_t * get() const
float kernAdvanceUnits(char32_t first, char32_t second) const
std::vector< char32_t > codepoints() const
float advanceWidthUnits(char32_t codepoint) const
FontFace & operator=(const FontFace &face)
float measureText(const std::u32string_view &text) const
const FontFace & face() const
std::vector< GlyphBox > glyphBoxes(const std::u32string_view &text) const
NOVASVG_INLINE codepoint_t font_face_apply_ligature(font_face_t *face, text_iterator_t *it, codepoint_t codepoint)
NOVASVG_INLINE void font_face_cache_add(font_face_cache_t *cache, const char *family, bool bold, bool italic, font_face_t *face)
Add a font face to the cache with the specified family and style.
NOVASVG_INLINE float font_face_text_extents(font_face_t *face, float size, const void *text, int length, text_encoding_t encoding, rect_t *extents)
Computes the bounding box of a text string and its advance width.
NOVASVG_INLINE float font_face_get_units_per_em(const font_face_t *face)
NOVASVG_INLINE void font_face_destroy(font_face_t *face)
Decrements the reference count and potentially destroys the font face.
unsigned int codepoint_t
Represents a Unicode code point.
NOVASVG_INLINE font_face_t * font_face_load_from_data(const void *data, unsigned int length, int ttcindex, destroy_func_t destroy_func, void *closure)
Loads a font face from memory.
NOVASVG_INLINE font_face_t * font_face_load_from_file(const char *filename, int ttcindex)
Loads a font face from a file.
NOVASVG_INLINE void font_face_get_glyph_metrics(font_face_t *face, float size, codepoint_t codepoint, float *advance_width, float *left_side_bearing, rect_t *extents)
Retrieves metrics for a specified glyph at a given size.
NOVASVG_INLINE font_face_t * font_face_cache_get(font_face_cache_t *cache, const char *family, bool bold, bool italic)
Retrieve a font face from the cache by family and style.
void(* destroy_func_t)(void *closure)
A function pointer type for a cleanup callback.
NOVASVG_INLINE float font_face_get_kern_advance(font_face_t *face, float size, codepoint_t ch1, codepoint_t ch2)
NOVASVG_INLINE void font_face_enumerate_codepoints(const font_face_t *face, void(*callback)(uint32_t codepoint, void *closure), void *closure)
NOVASVG_INLINE codepoint_t text_iterator_next(text_iterator_t *it)
Retrieves the next code point and advances the iterator.
@ NOVASVG_TEXT_ENCODING_UTF32
UTF-32 encoding.
NOVASVG_INLINE void font_face_get_metrics(const font_face_t *face, float size, float *ascent, float *descent, float *line_gap, rect_t *extents)
Retrieves metrics for a font face at a specified size.
NOVASVG_INLINE bool text_iterator_has_next(const text_iterator_t *it)
Checks if there are more code points to iterate.
NOVASVG_INLINE int font_face_cache_load_sys(font_face_cache_t *cache)
Load all available system font faces and add them to the cache.
NOVASVG_INLINE void text_iterator_init(text_iterator_t *it, const void *text, int length, text_encoding_t encoding)
Initializes a text iterator.
NOVASVG_INLINE font_face_t * font_face_reference(font_face_t *face)
Increments the reference count of a font face.
NOVASVG_INLINE font_face_cache_t * font_face_cache_create(void)
Create a new, empty font‐face cache.
Main namespace for the NovaSVG library.
FontFace embeddedFallbackFont(bool bold=false, bool italic=false)
FontFaceCache * fontFaceCache()
constexpr void stripLeadingAndTrailingSpaces(std::string_view &input)
bool addFontFaceFromFile(const char *family, bool bold, bool italic, const char *filename)
Add a font face from a file to the cache.
bool addFontFaceFromData(const char *family, bool bold, bool italic, const void *data, size_t length, novasvg_destroy_func_t destroy_func, void *closure)
Add a font face from memory to the cache.
void(* novasvg_destroy_func_t)(void *closure)
Callback for cleaning up resources.
A structure representing a rectangle in 2D space.
float x
The x-coordinate of the top-left corner of the rectangle.
float w
The width of the rectangle.
float h
The height of the rectangle.
float y
The y-coordinate of the top-left corner of the rectangle.
Iterator for traversing code points in text data.
std::string text
UTF-8; ' ' marks a forced line break ( ,.