From 5fc06a177be5dc1c1fb42cb90716ce21d4087ad1 Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Thu, 30 Mar 2023 16:19:13 +0200 Subject: [PATCH] glyph pairs for interpolation --- src/Atlas.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/Atlas.h | 7 ++++ 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/src/Atlas.cpp b/src/Atlas.cpp index e6ae7e6..9b7f04f 100644 --- a/src/Atlas.cpp +++ b/src/Atlas.cpp @@ -1,5 +1,6 @@ #include "Atlas.h" #include "conversion.h" +#include "edge-coloring.h" #include "import-font.h" namespace ofxMsdfgen { @@ -184,6 +185,16 @@ bool Atlas::generate(){ //} } + int vgi = 0; + for(const auto & vg : variationGlyphs){ + const unsigned char cp = vg.getCodepoint(); + GlyphVariationKey key; + key.character = cp; + key.variation = variation; + glyphGeometryMap[key] = glyphs.size() + vgi; + vgi++; + } + glyphs.insert(glyphs.end(), variationGlyphs.begin(), variationGlyphs.end()); @@ -192,10 +203,18 @@ bool Atlas::generate(){ } // Apply MSDF edge coloring. See edge-coloring.h for other coloring strategies. for(msdf_atlas::GlyphGeometry & glyph : glyphs){ - //FIXME: we do not need to inverse y axis, something else is wrong + // NOTE: const_cast is potentially evil, + // but like this we can use clipper for preprocessing shapes // msdfgen::Shape & shape = const_cast (glyph.getShape()); + // then convert Shape to ofPolyline and use getResampledBySpacing + // to convert it into straight lines + // then use clipper2 to union the shapes + // convert back into ofPolyline and then Shape + // or directly into Shape + // + // don't do this: // shape.inverseYAxis = true; - glyph.edgeColoring(&msdfgen::edgeColoringInkTrap, // strategy + glyph.edgeColoring(&msdfgen::edgeColoringSimple, // strategy settings.maxCornerAngle, // angleThreshold 0); // seed } @@ -277,12 +296,76 @@ const GlyphGeometry & Atlas::getGlyphGeometry(unsigned char character){ const GlyphGeometry & Atlas::getGlyphGeometry(unsigned char character, FontVariation variation){ // FIXME: error handling? - //GlyphVariationKey key = {character, variation}; - //int index = glyphGeometryMap[key]; - return glyphGeometries[0]; + float smallestDistance = FLT_MAX; + int closestIndex = 0; + int i = 0; + for(const auto & v : variationSteps){ + float distance = abs(v.value - variation.value); + if(distance < smallestDistance){ + smallestDistance = distance; + closestIndex = i; + } + i++; + } + const auto & closestVariation = variationSteps[closestIndex]; + GlyphVariationKey key = {character, closestVariation}; + int index = glyphGeometryMap[key]; + return glyphGeometries[index]; +} + +bool Atlas::getGlyphGeometryPair(const unsigned char character, + const FontVariation variation, + GlyphGeometry & a, + GlyphGeometry & b, + float & mix){ + float smallestDistanceDown = -1 * FLT_MAX; + float smallestDistanceUp = FLT_MAX; + int closestIndexDown = 0; + int closestIndexUp = 0; + int i = 0; + for(const auto & v : variationSteps){ + float distance = v.value - variation.value; + if(distance <= 0){ + if(distance > smallestDistanceDown){ + closestIndexDown = i; + smallestDistanceDown = distance; + } + }else{ + if(distance < smallestDistanceUp){ + closestIndexUp = i; + smallestDistanceUp = distance; + } + } + i++; + } + + { + float total = abs(smallestDistanceUp) + abs(smallestDistanceDown); + //mix = ofMap(abs(smallestDistanceDown), 0, total, 0, 1); + mix = total == 0 || smallestDistanceDown == 0 ? 0 : abs(smallestDistanceDown) / total; + } + if(mix < 0 || mix > 1){ + ofLogError("Atlas::getGlyphGeometryPair") + << "mix out of range.\n" + << "sorry for the shitty error message, just check the code"; + return false; + } + const auto & closestVariationUp = variationSteps[closestIndexUp]; + const auto & closestVariationDown = variationSteps[closestIndexDown]; + GlyphVariationKey glyphKeyUp = {character, closestVariationUp}; + GlyphVariationKey glyphKeyDown = {character, closestVariationDown}; + int index_a = glyphGeometryMap[glyphKeyDown]; + int index_b = glyphGeometryMap[glyphKeyUp]; + a = glyphGeometries[index_a]; + b = glyphGeometries[index_b]; + + return true; } const FontGeometry & Atlas::getFontGeometry(){ return fontGeometry; } +const vector & Atlas::getVariationAxesAvailable(){ + return variationAxesAvailable; +} } diff --git a/src/Atlas.h b/src/Atlas.h index a2429f1..0396094 100644 --- a/src/Atlas.h +++ b/src/Atlas.h @@ -93,8 +93,15 @@ class Atlas { const GlyphGeometry & getGlyphGeometry(unsigned char character); const GlyphGeometry & getGlyphGeometry(unsigned char character, FontVariation variation); + bool getGlyphGeometryPair(const unsigned char character, + const FontVariation variation, + GlyphGeometry & a, + GlyphGeometry & b, + float & mix); + //const GlyphGeometry & getGlyphGeometry(GlyphVariationKey key); const FontGeometry & getFontGeometry(); + const vector & getVariationAxesAvailable(); AtlasSettings settings; msdfgen::FontHandle * font; msdfgen::FreetypeHandle * ft;