From a3fd4a6e9bba6b375c7a00abe902a88ef31dfbe0 Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sat, 27 May 2023 10:31:45 +0200 Subject: [PATCH] flip contour if counter-clockwise --- src/gpufont/font.hpp | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/gpufont/font.hpp b/src/gpufont/font.hpp index 49f0348..fa2bb70 100644 --- a/src/gpufont/font.hpp +++ b/src/gpufont/font.hpp @@ -906,7 +906,11 @@ class Font { // This function takes a single contour (defined by firstIndex and // lastIndex, both inclusive) from outline and converts it into individual // quadratic bezier curves, which are added to the curves vector. - void convertContour(std::vector & curves, const FT_Outline * outline, short firstIndex, short lastIndex, float emSize){ + void convertContour(std::vector & all_curves, const FT_Outline * outline, short firstIndex, short lastIndex, float emSize){ + // we might have to flip the direction + // so let's buffer our buffercurves in a buffer curves of buffercurves + std::vector curves; + // See https://freetype.org/freetype2/docs/glyphs/glyphs-6.html // for a detailed description of the outline format. // @@ -989,7 +993,21 @@ class Font { return 0.5f * (a + b); }; - auto makeCurve = [](const glm::vec2 & p0, const glm::vec2 & p1, const glm::vec2 & p2){ + + // Get Direction of a point pair. + // Notice that we can ignore the middle point. + auto getDirection = [](const glm::vec2 & p0, const glm::vec2 & p1){ + return (p1.x - p0.x) * (p1.y + p0.y); + }; + + // keep track of collected direction + float direction = 0; + + // We will inject getDirection in makeCurve, + // so anytime the curve is made it updates the direction. + // This is less error prone than calling it separately. + // wisdom: Any error you cannot make, you will not make. :) + auto makeCurve = [&direction, getDirection](const glm::vec2 & p0, const glm::vec2 & p1, const glm::vec2 & p2){ BufferCurve result; result.x0 = p0.x; result.y0 = p0.y; @@ -997,6 +1015,7 @@ class Font { result.y1 = p1.y; result.x2 = p2.x; result.y2 = p2.y; + direction += getDirection(p0, p2); return result; }; @@ -1086,6 +1105,18 @@ class Font { }else{ curves.push_back(makeCurve(start, previous, first)); } + if(direction < 0){ + for(BufferCurve & curve : curves){ + float tmp_x = curve.x0; + float tmp_y = curve.y0; + curve.x0 = curve.x2; + curve.y0 = curve.y2; + curve.x2 = tmp_x; + curve.y2 = tmp_y; + } + std::reverse(curves.begin(), curves.end()); + } + all_curves.insert(all_curves.end(), curves.begin(), curves.end()); }