Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
msdf_atlas.hpp
Go to the documentation of this file.
1#pragma once
2
3// Multi-Channel Signed Distance Field (MSDF) glyph atlas.
4//
5// An MSDF encodes three independent distance signals into the R, G, B
6// channels of each texel. At sample time the shader reconstructs the
7// true distance via `median(r, g, b)`, which preserves sharp corners
8// at arbitrary scales — something single-channel SDF cannot do without
9// becoming a path-rendered fallback.
10//
11// Algorithm reference:
12// Chlumský, V. (2015) — "Shape decomposition for multi-channel
13// distance fields." MSc thesis, Charles University.
14// https://github.com/Chlumsky/msdfgen (BSD-2-Clause)
15//
16// `MsdfAtlas` mirrors the `SdfAtlas` API so call-sites can switch
17// between single and multi-channel rendering with only a shader
18// swap. The underlying pixel buffer is RGB8 (3 bytes per texel).
19
20#include <cstdint>
21#include <memory>
22#include <string>
23#include <vector>
24
25namespace pulp::canvas {
26
27struct MsdfGlyph {
28 char32_t codepoint = 0;
29 int atlas_x = 0;
30 int atlas_y = 0;
31 int width = 0;
32 int height = 0;
33 float bearing_x = 0.0f;
34 float bearing_y = 0.0f;
35 float advance = 0.0f;
36};
37
38class MsdfAtlas {
39public:
42
43 MsdfAtlas(const MsdfAtlas&) = delete;
44 MsdfAtlas& operator=(const MsdfAtlas&) = delete;
45 MsdfAtlas(MsdfAtlas&&) noexcept;
46 MsdfAtlas& operator=(MsdfAtlas&&) noexcept;
47
48 // Build the atlas for `chars` at `base_size` with `padding` texels of
49 // SDF spread around each glyph. Returns false if the font cannot be
50 // resolved or the resulting atlas would exceed `max_atlas_size`.
51 //
52 // When `include_alpha` is true the output is RGBA8 where A holds a
53 // true single-channel SDF (same encoding as `SdfAtlas`). Shaders
54 // can median(r,g,b) for sharp corners and fall back to .a where
55 // MSDF artifacts would otherwise appear (thin strokes, discontinuities
56 // in the channel decomposition). When `include_alpha` is false the
57 // output is RGB8.
58 bool build(const std::string& font_family,
59 const std::vector<char32_t>& chars,
60 int base_size = 48,
61 int padding = 8,
62 int max_atlas_size = 2048,
63 bool include_alpha = false);
64
65 const MsdfGlyph* glyph(char32_t codepoint) const;
66
67 // Atlas image: width() * height() * channels() bytes, row-major.
68 const std::uint8_t* pixels() const;
69 int width() const;
70 int height() const;
71 // 3 for RGB8, 4 for RGBA8 (hybrid-alpha).
72 int channels() const;
73 std::size_t glyph_count() const;
74 int base_size() const;
75
76private:
77 struct Impl;
78 std::unique_ptr<Impl> impl_;
79};
80
81} // namespace pulp::canvas
MsdfAtlas & operator=(const MsdfAtlas &)=delete
bool build(const std::string &font_family, const std::vector< char32_t > &chars, int base_size=48, int padding=8, int max_atlas_size=2048, bool include_alpha=false)
MsdfAtlas(MsdfAtlas &&) noexcept
std::size_t glyph_count() const
const MsdfGlyph * glyph(char32_t codepoint) const
MsdfAtlas(const MsdfAtlas &)=delete
const std::uint8_t * pixels() const
Definition affine_transform.hpp:24
STL namespace.
Definition msdf_atlas.hpp:27
char32_t codepoint
Definition msdf_atlas.hpp:28
int atlas_y
Definition msdf_atlas.hpp:30
float advance
Definition msdf_atlas.hpp:35
int atlas_x
Definition msdf_atlas.hpp:29
float bearing_x
Definition msdf_atlas.hpp:33
int height
Definition msdf_atlas.hpp:32
float bearing_y
Definition msdf_atlas.hpp:34
int width
Definition msdf_atlas.hpp:31