26 const std::vector<SdfTextQuad>& quads,
27 std::uint8_t* out,
int out_w,
int out_h,
29 const int aw = atlas.width();
30 const int ah = atlas.height();
31 if (aw <= 0 || ah <= 0)
return;
33 const float edge255 = opts.edge * 255.0f;
35 for (
const auto& q : quads) {
36 const int x0 =
static_cast<int>(std::max(0.0f, std::floor(q.dst_x)));
37 const int y0 =
static_cast<int>(std::max(0.0f, std::floor(q.dst_y)));
38 const int x1 =
static_cast<int>(std::min(
39 static_cast<float>(out_w),
40 std::ceil(q.dst_x + q.dst_w)));
41 const int y1 =
static_cast<int>(std::min(
42 static_cast<float>(out_h),
43 std::ceil(q.dst_y + q.dst_h)));
45 if (q.dst_w <= 0 || q.dst_h <= 0)
continue;
46 const float sx_per_px = q.src_w / q.dst_w;
47 const float sy_per_px = q.src_h / q.dst_h;
49 for (
int y = y0; y < y1; ++y) {
50 for (
int x = x0; x < x1; ++x) {
51 const float sx = q.src_x + (x + 0.5f - q.dst_x) * sx_per_px;
52 const float sy = q.src_y + (y + 0.5f - q.dst_y) * sy_per_px;
53 const int ix =
static_cast<int>(sx);
54 const int iy =
static_cast<int>(sy);
55 if (ix < 0 || iy < 0 || ix >= aw || iy >= ah)
continue;
57 const std::uint8_t d = atlas.pixels()[iy * aw + ix];
59 const float aa = 0.5f * std::max(sx_per_px, sy_per_px) * 255.0f;
60 const float lo = edge255 - aa;
61 const float hi = edge255 + aa;
62 float a = (d - lo) / std::max(1.0f, (hi - lo));
63 if (a < 0.0f) a = 0.0f;
64 else if (a > 1.0f) a = 1.0f;
65 const auto byte =
static_cast<std::uint8_t
>(a * 255.0f);
66 std::uint8_t& dst = out[y * out_w + x];
67 if (
byte > dst) dst = byte;
void render_sdf_text_software(const AtlasT &atlas, const std::vector< SdfTextQuad > &quads, std::uint8_t *out, int out_w, int out_h, const SdfTextOptions &opts={})
Definition sdf_software_renderer.hpp:25
Definition sdf_text.hpp:35