Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/msdfgen/core/rasterization.cpp
9903 views
1
2
#include "rasterization.h"
3
4
#include <vector>
5
#include "arithmetics.hpp"
6
7
namespace msdfgen {
8
9
void rasterize(const BitmapRef<float, 1> &output, const Shape &shape, const Projection &projection, FillRule fillRule) {
10
Scanline scanline;
11
for (int y = 0; y < output.height; ++y) {
12
int row = shape.inverseYAxis ? output.height-y-1 : y;
13
shape.scanline(scanline, projection.unprojectY(y+.5));
14
for (int x = 0; x < output.width; ++x)
15
*output(x, row) = (float) scanline.filled(projection.unprojectX(x+.5), fillRule);
16
}
17
}
18
19
void distanceSignCorrection(const BitmapRef<float, 1> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
20
Scanline scanline;
21
for (int y = 0; y < sdf.height; ++y) {
22
int row = shape.inverseYAxis ? sdf.height-y-1 : y;
23
shape.scanline(scanline, projection.unprojectY(y+.5));
24
for (int x = 0; x < sdf.width; ++x) {
25
bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
26
float &sd = *sdf(x, row);
27
if ((sd > .5f) != fill)
28
sd = 1.f-sd;
29
}
30
}
31
}
32
33
template <int N>
34
static void multiDistanceSignCorrection(const BitmapRef<float, N> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
35
int w = sdf.width, h = sdf.height;
36
if (!(w && h))
37
return;
38
Scanline scanline;
39
bool ambiguous = false;
40
std::vector<char> matchMap;
41
matchMap.resize(w*h);
42
char *match = &matchMap[0];
43
for (int y = 0; y < h; ++y) {
44
int row = shape.inverseYAxis ? h-y-1 : y;
45
shape.scanline(scanline, projection.unprojectY(y+.5));
46
for (int x = 0; x < w; ++x) {
47
bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
48
float *msd = sdf(x, row);
49
float sd = median(msd[0], msd[1], msd[2]);
50
if (sd == .5f)
51
ambiguous = true;
52
else if ((sd > .5f) != fill) {
53
msd[0] = 1.f-msd[0];
54
msd[1] = 1.f-msd[1];
55
msd[2] = 1.f-msd[2];
56
*match = -1;
57
} else
58
*match = 1;
59
if (N >= 4 && (msd[3] > .5f) != fill)
60
msd[3] = 1.f-msd[3];
61
++match;
62
}
63
}
64
// This step is necessary to avoid artifacts when whole shape is inverted
65
if (ambiguous) {
66
match = &matchMap[0];
67
for (int y = 0; y < h; ++y) {
68
int row = shape.inverseYAxis ? h-y-1 : y;
69
for (int x = 0; x < w; ++x) {
70
if (!*match) {
71
int neighborMatch = 0;
72
if (x > 0) neighborMatch += *(match-1);
73
if (x < w-1) neighborMatch += *(match+1);
74
if (y > 0) neighborMatch += *(match-w);
75
if (y < h-1) neighborMatch += *(match+w);
76
if (neighborMatch < 0) {
77
float *msd = sdf(x, row);
78
msd[0] = 1.f-msd[0];
79
msd[1] = 1.f-msd[1];
80
msd[2] = 1.f-msd[2];
81
}
82
}
83
++match;
84
}
85
}
86
}
87
}
88
89
void distanceSignCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
90
multiDistanceSignCorrection(sdf, shape, projection, fillRule);
91
}
92
93
void distanceSignCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
94
multiDistanceSignCorrection(sdf, shape, projection, fillRule);
95
}
96
97
// Legacy API
98
99
void rasterize(const BitmapRef<float, 1> &output, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
100
rasterize(output, shape, Projection(scale, translate), fillRule);
101
}
102
103
void distanceSignCorrection(const BitmapRef<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
104
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
105
}
106
107
void distanceSignCorrection(const BitmapRef<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
108
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
109
}
110
111
void distanceSignCorrection(const BitmapRef<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
112
distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
113
}
114
115
}
116
117