flip contour if counter-clockwise

This commit is contained in:
jrkb 2023-05-27 10:31:45 +02:00
parent 0cbcd35f52
commit a3fd4a6e9b

View file

@ -906,7 +906,11 @@ class Font {
// This function takes a single contour (defined by firstIndex and // This function takes a single contour (defined by firstIndex and
// lastIndex, both inclusive) from outline and converts it into individual // lastIndex, both inclusive) from outline and converts it into individual
// quadratic bezier curves, which are added to the curves vector. // quadratic bezier curves, which are added to the curves vector.
void convertContour(std::vector <BufferCurve> & curves, const FT_Outline * outline, short firstIndex, short lastIndex, float emSize){ void convertContour(std::vector <BufferCurve> & 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 <BufferCurve> curves;
// See https://freetype.org/freetype2/docs/glyphs/glyphs-6.html // See https://freetype.org/freetype2/docs/glyphs/glyphs-6.html
// for a detailed description of the outline format. // for a detailed description of the outline format.
// //
@ -989,7 +993,21 @@ class Font {
return 0.5f * (a + b); 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; BufferCurve result;
result.x0 = p0.x; result.x0 = p0.x;
result.y0 = p0.y; result.y0 = p0.y;
@ -997,6 +1015,7 @@ class Font {
result.y1 = p1.y; result.y1 = p1.y;
result.x2 = p2.x; result.x2 = p2.x;
result.y2 = p2.y; result.y2 = p2.y;
direction += getDirection(p0, p2);
return result; return result;
}; };
@ -1086,6 +1105,18 @@ class Font {
}else{ }else{
curves.push_back(makeCurve(start, previous, first)); 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());
} }