-
-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added -exportsvg, RGBA & FL32 image output
- Loading branch information
Showing
12 changed files
with
328 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
|
||
#include "export-svg.h" | ||
|
||
#include <cstdio> | ||
#include "edge-segments.h" | ||
|
||
namespace msdfgen { | ||
|
||
static void writeSvgCoord(FILE *f, Point2 coord) { | ||
fprintf(f, "%.17g %.17g", coord.x, coord.y); | ||
} | ||
|
||
static void writeSvgPathDef(FILE *f, const Shape &shape) { | ||
bool beginning = true; | ||
for (const Contour &c : shape.contours) { | ||
if (c.edges.empty()) | ||
continue; | ||
if (beginning) | ||
beginning = false; | ||
else | ||
fputc(' ', f); | ||
fputs("M ", f); | ||
writeSvgCoord(f, c.edges[0]->controlPoints()[0]); | ||
for (const EdgeHolder &e : c.edges) { | ||
const Point2 *cp = e->controlPoints(); | ||
switch (e->type()) { | ||
case (int) LinearSegment::EDGE_TYPE: | ||
fputs(" L ", f); | ||
writeSvgCoord(f, cp[1]); | ||
break; | ||
case (int) QuadraticSegment::EDGE_TYPE: | ||
fputs(" Q ", f); | ||
writeSvgCoord(f, cp[1]); | ||
fputc(' ', f); | ||
writeSvgCoord(f, cp[2]); | ||
break; | ||
case (int) CubicSegment::EDGE_TYPE: | ||
fputs(" C ", f); | ||
writeSvgCoord(f, cp[1]); | ||
fputc(' ', f); | ||
writeSvgCoord(f, cp[2]); | ||
fputc(' ', f); | ||
writeSvgCoord(f, cp[3]); | ||
break; | ||
} | ||
} | ||
fputs(" Z", f); | ||
} | ||
} | ||
|
||
bool saveSvgShape(const Shape &shape, const char *filename) { | ||
if (FILE *f = fopen(filename, "w")) { | ||
fputs("<svg xmlns=\"http://www.w3.org/2000/svg\"><path", f); | ||
if (!shape.inverseYAxis) | ||
fputs(" transform=\"scale(1 -1)\"", f); | ||
fputs(" d=\"", f); | ||
writeSvgPathDef(f, shape); | ||
fputs("\"/></svg>\n", f); | ||
fclose(f); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool saveSvgShape(const Shape &shape, const Shape::Bounds &bounds, const char *filename) { | ||
if (FILE *f = fopen(filename, "w")) { | ||
fprintf(f, "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"%.17g %.17g %.17g %.17g\"><path", bounds.l, bounds.b, bounds.r-bounds.l, bounds.t-bounds.b); | ||
if (!shape.inverseYAxis) | ||
fprintf(f, " transform=\"translate(0 %.17g) scale(1 -1)\"", bounds.b+bounds.t); | ||
fputs(" d=\"", f); | ||
writeSvgPathDef(f, shape); | ||
fputs("\"/></svg>\n", f); | ||
fclose(f); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
#pragma once | ||
|
||
#include "Shape.h" | ||
|
||
namespace msdfgen { | ||
|
||
bool saveSvgShape(const Shape &shape, const char *filename); | ||
bool saveSvgShape(const Shape &shape, const Shape::Bounds &bounds, const char *filename); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
|
||
#include "save-fl32.h" | ||
|
||
#include <cstdio> | ||
|
||
namespace msdfgen { | ||
|
||
// Requires byte reversal for floats on big-endian platform | ||
#ifndef __BIG_ENDIAN__ | ||
|
||
template <int N> | ||
bool saveFl32(const BitmapConstRef<float, N> &bitmap, const char *filename) { | ||
if (FILE *f = fopen(filename, "wb")) { | ||
byte header[16] = { byte('F'), byte('L'), byte('3'), byte('2') }; | ||
header[4] = byte(bitmap.height); | ||
header[5] = byte(bitmap.height>>8); | ||
header[6] = byte(bitmap.height>>16); | ||
header[7] = byte(bitmap.height>>24); | ||
header[8] = byte(bitmap.width); | ||
header[9] = byte(bitmap.width>>8); | ||
header[10] = byte(bitmap.width>>16); | ||
header[11] = byte(bitmap.width>>24); | ||
header[12] = byte(N); | ||
fwrite(header, 1, 16, f); | ||
fwrite(bitmap.pixels, sizeof(float), N*bitmap.width*bitmap.height, f); | ||
fclose(f); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
template bool saveFl32(const BitmapConstRef<float, 1> &bitmap, const char *filename); | ||
template bool saveFl32(const BitmapConstRef<float, 2> &bitmap, const char *filename); | ||
template bool saveFl32(const BitmapConstRef<float, 3> &bitmap, const char *filename); | ||
template bool saveFl32(const BitmapConstRef<float, 4> &bitmap, const char *filename); | ||
|
||
#endif | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
#pragma once | ||
|
||
#include "BitmapRef.hpp" | ||
|
||
namespace msdfgen { | ||
|
||
/// Saves the bitmap as an uncompressed floating-point FL32 file, which can be decoded trivially. | ||
template <int N> | ||
bool saveFl32(const BitmapConstRef<float, N> &bitmap, const char *filename); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
|
||
#include "save-rgba.h" | ||
|
||
#include <cstdio> | ||
#include "pixel-conversion.hpp" | ||
|
||
namespace msdfgen { | ||
|
||
class RgbaFileOutput { | ||
FILE *file; | ||
|
||
public: | ||
RgbaFileOutput(const char *filename, unsigned width, unsigned height) { | ||
if ((file = fopen(filename, "wb"))) { | ||
byte header[12] = { byte('R'), byte('G'), byte('B'), byte('A') }; | ||
header[4] = byte(width>>24); | ||
header[5] = byte(width>>16); | ||
header[6] = byte(width>>8); | ||
header[7] = byte(width); | ||
header[8] = byte(height>>24); | ||
header[9] = byte(height>>16); | ||
header[10] = byte(height>>8); | ||
header[11] = byte(height); | ||
fwrite(header, 1, 12, file); | ||
} | ||
} | ||
|
||
~RgbaFileOutput() { | ||
if (file) | ||
fclose(file); | ||
} | ||
|
||
void writePixel(const byte rgba[4]) { | ||
fwrite(rgba, 1, 4, file); | ||
} | ||
|
||
operator FILE *() { | ||
return file; | ||
} | ||
|
||
}; | ||
|
||
bool saveRgba(const BitmapConstRef<byte, 1> &bitmap, const char *filename) { | ||
RgbaFileOutput output(filename, bitmap.width, bitmap.height); | ||
if (output) { | ||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) }; | ||
for (int y = bitmap.height; y--;) { | ||
for (const byte *p = bitmap(0, y), *end = p+bitmap.width; p < end; ++p) { | ||
rgba[0] = rgba[1] = rgba[2] = *p; | ||
output.writePixel(rgba); | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool saveRgba(const BitmapConstRef<byte, 3> &bitmap, const char *filename) { | ||
RgbaFileOutput output(filename, bitmap.width, bitmap.height); | ||
if (output) { | ||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) }; | ||
for (int y = bitmap.height; y--;) { | ||
for (const byte *p = bitmap(0, y), *end = p+3*bitmap.width; p < end; p += 3) { | ||
rgba[0] = p[0], rgba[1] = p[1], rgba[2] = p[2]; | ||
output.writePixel(rgba); | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool saveRgba(const BitmapConstRef<byte, 4> &bitmap, const char *filename) { | ||
RgbaFileOutput output(filename, bitmap.width, bitmap.height); | ||
if (output) { | ||
for (int y = bitmap.height; y--;) | ||
fwrite(bitmap(0, y), 1, 4*bitmap.width, output); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool saveRgba(const BitmapConstRef<float, 1> &bitmap, const char *filename) { | ||
RgbaFileOutput output(filename, bitmap.width, bitmap.height); | ||
if (output) { | ||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) }; | ||
for (int y = bitmap.height; y--;) { | ||
for (const float *p = bitmap(0, y), *end = p+bitmap.width; p < end; ++p) { | ||
rgba[0] = rgba[1] = rgba[2] = pixelFloatToByte(*p); | ||
output.writePixel(rgba); | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool saveRgba(const BitmapConstRef<float, 3> &bitmap, const char *filename) { | ||
RgbaFileOutput output(filename, bitmap.width, bitmap.height); | ||
if (output) { | ||
byte rgba[4] = { byte(0), byte(0), byte(0), byte(0xff) }; | ||
for (int y = bitmap.height; y--;) { | ||
for (const float *p = bitmap(0, y), *end = p+3*bitmap.width; p < end; p += 3) { | ||
rgba[0] = pixelFloatToByte(p[0]); | ||
rgba[1] = pixelFloatToByte(p[1]); | ||
rgba[2] = pixelFloatToByte(p[2]); | ||
output.writePixel(rgba); | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool saveRgba(const BitmapConstRef<float, 4> &bitmap, const char *filename) { | ||
RgbaFileOutput output(filename, bitmap.width, bitmap.height); | ||
if (output) { | ||
byte rgba[4]; | ||
for (int y = bitmap.height; y--;) { | ||
for (const float *p = bitmap(0, y), *end = p+4*bitmap.width; p < end; p += 4) { | ||
rgba[0] = pixelFloatToByte(p[0]); | ||
rgba[1] = pixelFloatToByte(p[1]); | ||
rgba[2] = pixelFloatToByte(p[2]); | ||
rgba[3] = pixelFloatToByte(p[3]); | ||
output.writePixel(rgba); | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
#pragma once | ||
|
||
#include "BitmapRef.hpp" | ||
|
||
namespace msdfgen { | ||
|
||
/// Saves the bitmap as a simple RGBA file, which can be decoded trivially. | ||
bool saveRgba(const BitmapConstRef<byte, 1> &bitmap, const char *filename); | ||
bool saveRgba(const BitmapConstRef<byte, 3> &bitmap, const char *filename); | ||
bool saveRgba(const BitmapConstRef<byte, 4> &bitmap, const char *filename); | ||
bool saveRgba(const BitmapConstRef<float, 1> &bitmap, const char *filename); | ||
bool saveRgba(const BitmapConstRef<float, 3> &bitmap, const char *filename); | ||
bool saveRgba(const BitmapConstRef<float, 4> &bitmap, const char *filename); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.