1 | |
2 | #include "render-sdf.h" |
3 | |
4 | #include "arithmetics.hpp" |
5 | #include "pixel-conversion.hpp" |
6 | #include "bitmap-interpolation.hpp" |
7 | |
8 | namespace msdfgen { |
9 | |
10 | static float distVal(float dist, double pxRange, float midValue) { |
11 | if (!pxRange) |
12 | return (float) (dist > midValue); |
13 | return (float) clamp((dist-midValue)*pxRange+.5); |
14 | } |
15 | |
16 | void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 1> &sdf, double pxRange, float midValue) { |
17 | Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height); |
18 | pxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height); |
19 | for (int y = 0; y < output.height; ++y) |
20 | for (int x = 0; x < output.width; ++x) { |
21 | float sd; |
22 | interpolate(&sd, sdf, scale*Point2(x+.5, y+.5)); |
23 | *output(x, y) = distVal(sd, pxRange, midValue); |
24 | } |
25 | } |
26 | |
27 | void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 1> &sdf, double pxRange, float midValue) { |
28 | Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height); |
29 | pxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height); |
30 | for (int y = 0; y < output.height; ++y) |
31 | for (int x = 0; x < output.width; ++x) { |
32 | float sd; |
33 | interpolate(&sd, sdf, scale*Point2(x+.5, y+.5)); |
34 | float v = distVal(sd, pxRange, midValue); |
35 | output(x, y)[0] = v; |
36 | output(x, y)[1] = v; |
37 | output(x, y)[2] = v; |
38 | } |
39 | } |
40 | |
41 | void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 3> &sdf, double pxRange, float midValue) { |
42 | Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height); |
43 | pxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height); |
44 | for (int y = 0; y < output.height; ++y) |
45 | for (int x = 0; x < output.width; ++x) { |
46 | float sd[3]; |
47 | interpolate(sd, sdf, scale*Point2(x+.5, y+.5)); |
48 | *output(x, y) = distVal(median(sd[0], sd[1], sd[2]), pxRange, midValue); |
49 | } |
50 | } |
51 | |
52 | void renderSDF(const BitmapRef<float, 3> &output, const BitmapConstRef<float, 3> &sdf, double pxRange, float midValue) { |
53 | Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height); |
54 | pxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height); |
55 | for (int y = 0; y < output.height; ++y) |
56 | for (int x = 0; x < output.width; ++x) { |
57 | float sd[3]; |
58 | interpolate(sd, sdf, scale*Point2(x+.5, y+.5)); |
59 | output(x, y)[0] = distVal(sd[0], pxRange, midValue); |
60 | output(x, y)[1] = distVal(sd[1], pxRange, midValue); |
61 | output(x, y)[2] = distVal(sd[2], pxRange, midValue); |
62 | } |
63 | } |
64 | |
65 | void renderSDF(const BitmapRef<float, 1> &output, const BitmapConstRef<float, 4> &sdf, double pxRange, float midValue) { |
66 | Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height); |
67 | pxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height); |
68 | for (int y = 0; y < output.height; ++y) |
69 | for (int x = 0; x < output.width; ++x) { |
70 | float sd[4]; |
71 | interpolate(sd, sdf, scale*Point2(x+.5, y+.5)); |
72 | *output(x, y) = distVal(median(sd[0], sd[1], sd[2]), pxRange, midValue); |
73 | } |
74 | } |
75 | |
76 | void renderSDF(const BitmapRef<float, 4> &output, const BitmapConstRef<float, 4> &sdf, double pxRange, float midValue) { |
77 | Vector2 scale((double) sdf.width/output.width, (double) sdf.height/output.height); |
78 | pxRange *= (double) (output.width+output.height)/(sdf.width+sdf.height); |
79 | for (int y = 0; y < output.height; ++y) |
80 | for (int x = 0; x < output.width; ++x) { |
81 | float sd[4]; |
82 | interpolate(sd, sdf, scale*Point2(x+.5, y+.5)); |
83 | output(x, y)[0] = distVal(sd[0], pxRange, midValue); |
84 | output(x, y)[1] = distVal(sd[1], pxRange, midValue); |
85 | output(x, y)[2] = distVal(sd[2], pxRange, midValue); |
86 | output(x, y)[3] = distVal(sd[3], pxRange, midValue); |
87 | } |
88 | } |
89 | |
90 | void simulate8bit(const BitmapRef<float, 1> &bitmap) { |
91 | const float *end = bitmap.pixels+1*bitmap.width*bitmap.height; |
92 | for (float *p = bitmap.pixels; p < end; ++p) |
93 | *p = pixelByteToFloat(pixelFloatToByte(*p)); |
94 | } |
95 | |
96 | void simulate8bit(const BitmapRef<float, 3> &bitmap) { |
97 | const float *end = bitmap.pixels+3*bitmap.width*bitmap.height; |
98 | for (float *p = bitmap.pixels; p < end; ++p) |
99 | *p = pixelByteToFloat(pixelFloatToByte(*p)); |
100 | } |
101 | |
102 | void simulate8bit(const BitmapRef<float, 4> &bitmap) { |
103 | const float *end = bitmap.pixels+4*bitmap.width*bitmap.height; |
104 | for (float *p = bitmap.pixels; p < end; ++p) |
105 | *p = pixelByteToFloat(pixelFloatToByte(*p)); |
106 | } |
107 | |
108 | } |
109 | |