mirror of https://github.com/Chlumsky/msdfgen.git
Font loading, reverseorder fixed, binary removed
This commit is contained in:
parent
4e443d8a72
commit
2ab2e6186c
|
|
@ -14,11 +14,6 @@ The following comparison demonstrates the improvement in image quality.
|
|||

|
||||

|
||||
|
||||
## New in version 1.2
|
||||
- Option to specify that shape is defined in reverse order (-reverseorder)
|
||||
- Option to set a seed for the edge coloring heuristic (-seed \<n\>), which can be used to adjust the output
|
||||
- Fixed parsing of glyph contours starting that start with a curve control point.
|
||||
|
||||
## Getting started
|
||||
|
||||
The project can be used either as a library or as a console program. is divided into two parts, **[core](core)**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <queue>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "freetype.lib")
|
||||
|
|
@ -35,6 +36,44 @@ class FontHandle {
|
|||
|
||||
};
|
||||
|
||||
struct FtContext {
|
||||
Point2 position;
|
||||
Shape *shape;
|
||||
Contour *contour;
|
||||
};
|
||||
|
||||
static Point2 ftPoint2(const FT_Vector &vector) {
|
||||
return Point2(vector.x/64., vector.y/64.);
|
||||
}
|
||||
|
||||
static int ftMoveTo(const FT_Vector *to, void *user) {
|
||||
FtContext *context = reinterpret_cast<FtContext *>(user);
|
||||
context->contour = &context->shape->addContour();
|
||||
context->position = ftPoint2(*to);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ftLineTo(const FT_Vector *to, void *user) {
|
||||
FtContext *context = reinterpret_cast<FtContext *>(user);
|
||||
context->contour->addEdge(new LinearSegment(context->position, ftPoint2(*to)));
|
||||
context->position = ftPoint2(*to);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ftConicTo(const FT_Vector *control, const FT_Vector *to, void *user) {
|
||||
FtContext *context = reinterpret_cast<FtContext *>(user);
|
||||
context->contour->addEdge(new QuadraticSegment(context->position, ftPoint2(*control), ftPoint2(*to)));
|
||||
context->position = ftPoint2(*to);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ftCubicTo(const FT_Vector *control1, const FT_Vector *control2, const FT_Vector *to, void *user) {
|
||||
FtContext *context = reinterpret_cast<FtContext *>(user);
|
||||
context->contour->addEdge(new CubicSegment(context->position, ftPoint2(*control1), ftPoint2(*control2), ftPoint2(*to)));
|
||||
context->position = ftPoint2(*to);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FreetypeHandle * initializeFreetype() {
|
||||
FreetypeHandle *handle = new FreetypeHandle;
|
||||
FT_Error error = FT_Init_FreeType(&handle->library);
|
||||
|
|
@ -85,14 +124,6 @@ bool getFontWhitespaceWidth(double &spaceAdvance, double &tabAdvance, FontHandle
|
|||
}
|
||||
|
||||
bool loadGlyph(Shape &output, FontHandle *font, int unicode, double *advance) {
|
||||
enum PointType {
|
||||
NONE = 0,
|
||||
PATH_POINT,
|
||||
QUADRATIC_POINT,
|
||||
CUBIC_POINT,
|
||||
CUBIC_POINT2
|
||||
};
|
||||
|
||||
if (!font)
|
||||
return false;
|
||||
FT_Error error = FT_Load_Char(font->face, unicode, FT_LOAD_NO_SCALE);
|
||||
|
|
@ -103,84 +134,18 @@ bool loadGlyph(Shape &output, FontHandle *font, int unicode, double *advance) {
|
|||
if (advance)
|
||||
*advance = font->face->glyph->advance.x/64.;
|
||||
|
||||
int last = -1;
|
||||
// For each contour
|
||||
for (int i = 0; i < font->face->glyph->outline.n_contours; ++i) {
|
||||
|
||||
Contour &contour = output.addContour();
|
||||
int first = last+1;
|
||||
int firstPathPoint = -1;
|
||||
last = font->face->glyph->outline.contours[i];
|
||||
|
||||
PointType state = NONE;
|
||||
Point2 startPoint;
|
||||
Point2 controlPoint[2];
|
||||
|
||||
// For each point on the contour
|
||||
for (int round = 0, index = first; round == 0; ++index) {
|
||||
if (index > last) {
|
||||
REQUIRE(firstPathPoint >= 0);
|
||||
index = first;
|
||||
}
|
||||
// Close contour
|
||||
if (index == firstPathPoint)
|
||||
++round;
|
||||
|
||||
Point2 point(font->face->glyph->outline.points[index].x/64., font->face->glyph->outline.points[index].y/64.);
|
||||
PointType pointType = font->face->glyph->outline.tags[index]&1 ? PATH_POINT : font->face->glyph->outline.tags[index]&2 ? CUBIC_POINT : QUADRATIC_POINT;
|
||||
|
||||
switch (state) {
|
||||
case NONE:
|
||||
if (pointType == PATH_POINT) {
|
||||
firstPathPoint = index;
|
||||
startPoint = point;
|
||||
state = PATH_POINT;
|
||||
}
|
||||
break;
|
||||
case PATH_POINT:
|
||||
if (pointType == PATH_POINT) {
|
||||
contour.addEdge(new LinearSegment(startPoint, point));
|
||||
startPoint = point;
|
||||
} else {
|
||||
controlPoint[0] = point;
|
||||
state = pointType;
|
||||
}
|
||||
break;
|
||||
case QUADRATIC_POINT:
|
||||
REQUIRE(pointType != CUBIC_POINT);
|
||||
if (pointType == PATH_POINT) {
|
||||
contour.addEdge(new QuadraticSegment(startPoint, controlPoint[0], point));
|
||||
startPoint = point;
|
||||
state = PATH_POINT;
|
||||
} else {
|
||||
Point2 midPoint = .5*controlPoint[0]+.5*point;
|
||||
contour.addEdge(new QuadraticSegment(startPoint, controlPoint[0], midPoint));
|
||||
startPoint = midPoint;
|
||||
controlPoint[0] = point;
|
||||
}
|
||||
break;
|
||||
case CUBIC_POINT:
|
||||
REQUIRE(pointType == CUBIC_POINT);
|
||||
controlPoint[1] = point;
|
||||
state = CUBIC_POINT2;
|
||||
break;
|
||||
case CUBIC_POINT2:
|
||||
REQUIRE(pointType != QUADRATIC_POINT);
|
||||
if (pointType == PATH_POINT) {
|
||||
contour.addEdge(new CubicSegment(startPoint, controlPoint[0], controlPoint[1], point));
|
||||
startPoint = point;
|
||||
} else {
|
||||
Point2 midPoint = .5*controlPoint[1]+.5*point;
|
||||
contour.addEdge(new CubicSegment(startPoint, controlPoint[0], controlPoint[1], midPoint));
|
||||
startPoint = midPoint;
|
||||
controlPoint[0] = point;
|
||||
}
|
||||
state = pointType;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
FtContext context = { };
|
||||
context.shape = &output;
|
||||
FT_Outline_Funcs ftFunctions;
|
||||
ftFunctions.move_to = &ftMoveTo;
|
||||
ftFunctions.line_to = &ftLineTo;
|
||||
ftFunctions.conic_to = &ftConicTo;
|
||||
ftFunctions.cubic_to = &ftCubicTo;
|
||||
ftFunctions.shift = 0;
|
||||
ftFunctions.delta = 0;
|
||||
error = FT_Outline_Decompose(&font->face->glyph->outline, &ftFunctions, &context);
|
||||
if (error)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
main.cpp
10
main.cpp
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/*
|
||||
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.2 (2016-07-20) - standalone console program
|
||||
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.3 (2016-12-07) - standalone console program
|
||||
* --------------------------------------------------------------------------------------------
|
||||
* A utility by Viktor Chlumsky, (c) 2014 - 2016
|
||||
*
|
||||
|
|
@ -134,16 +134,16 @@ static void parseColoring(Shape &shape, const char *edgeAssignment) {
|
|||
static void invertColor(Bitmap<FloatRGB> &bitmap) {
|
||||
for (int y = 0; y < bitmap.height(); ++y)
|
||||
for (int x = 0; x < bitmap.width(); ++x) {
|
||||
bitmap(x, y).r = .5f-bitmap(x, y).r;
|
||||
bitmap(x, y).g = .5f-bitmap(x, y).g;
|
||||
bitmap(x, y).b = .5f-bitmap(x, y).b;
|
||||
bitmap(x, y).r = 1.f-bitmap(x, y).r;
|
||||
bitmap(x, y).g = 1.f-bitmap(x, y).g;
|
||||
bitmap(x, y).b = 1.f-bitmap(x, y).b;
|
||||
}
|
||||
}
|
||||
|
||||
static void invertColor(Bitmap<float> &bitmap) {
|
||||
for (int y = 0; y < bitmap.height(); ++y)
|
||||
for (int x = 0; x < bitmap.width(); ++x)
|
||||
bitmap(x, y) = .5f-bitmap(x, y);
|
||||
bitmap(x, y) = 1.f-bitmap(x, y);
|
||||
}
|
||||
|
||||
static bool writeTextBitmap(FILE *file, const float *values, int cols, int rows) {
|
||||
|
|
|
|||
BIN
msdfgen.exe
BIN
msdfgen.exe
Binary file not shown.
|
|
@ -2,7 +2,7 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.2 (2016-07-20)
|
||||
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.3 (2016-12-07)
|
||||
* ---------------------------------------------------------------
|
||||
* A utility by Viktor Chlumsky, (c) 2014 - 2016
|
||||
*
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
#include "core/save-bmp.h"
|
||||
#include "core/shape-description.h"
|
||||
|
||||
#define MSDFGEN_VERSION "1.2"
|
||||
#define MSDFGEN_VERSION "1.3"
|
||||
|
||||
namespace msdfgen {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue