| 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 |  | 
|---|