Browse Source

Font loading, reverseorder fixed, binary removed

Viktor Chlumský 9 years ago
parent
commit
2ab2e6186c
7 changed files with 58 additions and 98 deletions
  1. 0 5
      README.md
  2. 51 86
      ext/import-font.cpp
  3. 0 0
      lib/freetype6.dll
  4. 0 0
      lib/zlib1.dll
  5. 5 5
      main.cpp
  6. BIN
      msdfgen.exe
  7. 2 2
      msdfgen.h

+ 0 - 5
README.md

@@ -14,11 +14,6 @@ The following comparison demonstrates the improvement in image quality.
 ![demo-sdf16](https://cloud.githubusercontent.com/assets/18639794/14770360/20c51156-0a70-11e6-8f03-ed7632d07997.png)
 ![demo-sdf32](https://cloud.githubusercontent.com/assets/18639794/14770361/251a4406-0a70-11e6-95a7-e30e235ac729.png)
 
-## 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)**

+ 51 - 86
ext/import-font.cpp

@@ -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;
 }
 

+ 0 - 0
freetype6.dll → lib/freetype6.dll


+ 0 - 0
zlib1.dll → lib/zlib1.dll


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


+ 2 - 2
msdfgen.h

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