2023-02-21 18:41:53 +01:00
|
|
|
#include "Atlas.h"
|
|
|
|
#include "BitmapRef.hpp"
|
2023-02-22 18:28:56 +01:00
|
|
|
#include "GlyphBox.h"
|
|
|
|
#include "ofFileUtils.h"
|
|
|
|
#include "ofTrueTypeFont.h"
|
|
|
|
|
|
|
|
|
|
|
|
ofxMsdfgen::Atlas::Atlas(){
|
|
|
|
}
|
|
|
|
ofxMsdfgen::Atlas::~Atlas(){
|
|
|
|
}
|
2023-02-21 18:41:53 +01:00
|
|
|
|
|
|
|
void ofxMsdfgen::Atlas::setup(string _fontPath){
|
|
|
|
fontPath = _fontPath;
|
|
|
|
if(generate()){
|
|
|
|
ofLogNotice("ofxMsdfgen::Atlas::setup()") << "generated Atlas";
|
|
|
|
}else{
|
|
|
|
ofLogError("ofxMsdfgen::Atlas::setup()") << "whoops, could not generate Atlas";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ofxMsdfgen::Atlas::setup(string _fontPath,
|
|
|
|
AtlasSettings _settings){
|
|
|
|
settings = _settings;
|
|
|
|
setup(_fontPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ofxMsdfgen::Atlas::generate(){
|
|
|
|
bool success = false;
|
2023-02-22 18:28:56 +01:00
|
|
|
//{
|
|
|
|
msdfgen::FreetypeHandle * ft = msdfgen::initializeFreetype();
|
|
|
|
if(ft){
|
|
|
|
const char * fontPath_c_str = fontPath.c_str();
|
|
|
|
msdfgen::FontHandle * font = loadFont(ft, fontPath_c_str);
|
|
|
|
if(font){
|
2023-02-21 18:41:53 +01:00
|
|
|
// Storage for glyph geometry and their coordinates in the atlas
|
|
|
|
std::vector <msdf_atlas::GlyphGeometry> glyphs;
|
|
|
|
// FontGeometry is a helper class that loads a set of glyphs from a single font.
|
|
|
|
// It can also be used to get additional font metrics, kerning information, etc.
|
|
|
|
msdf_atlas::FontGeometry fontGeometry(&glyphs);
|
|
|
|
// Load a set of character glyphs:
|
|
|
|
// The second argument can be ignored unless you mix different font sizes in one atlas.
|
|
|
|
// In the last argument, you can specify a charset other than ASCII.
|
|
|
|
// To load specific glyph indices, use loadGlyphs instead.
|
|
|
|
fontGeometry.loadCharset(font, 1.0, msdf_atlas::Charset::ASCII);
|
|
|
|
// Apply MSDF edge coloring. See edge-coloring.h for other coloring strategies.
|
|
|
|
for(msdf_atlas::GlyphGeometry & glyph : glyphs){
|
|
|
|
glyph.edgeColoring(&msdfgen::edgeColoringInkTrap,
|
|
|
|
settings.maxCornerAngle,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
// TightAtlasPacker class computes the layout of the atlas.
|
|
|
|
msdf_atlas::TightAtlasPacker packer;
|
|
|
|
// Set atlas parameters:
|
|
|
|
// setDimensions or setDimensionsConstraint to find the best value
|
|
|
|
packer.setDimensionsConstraint(msdf_atlas::TightAtlasPacker::DimensionsConstraint::SQUARE);
|
|
|
|
// setScale for a fixed size or setMinimumScale to use the largest that fits
|
|
|
|
packer.setMinimumScale(settings.minimumScale);
|
|
|
|
// setPixelRange or setUnitRange
|
|
|
|
packer.setPixelRange(settings.pixelRange);
|
|
|
|
packer.setMiterLimit(settings.miterLimit);
|
|
|
|
// Compute atlas layout - pack glyphs
|
|
|
|
packer.pack(glyphs.data(), glyphs.size());
|
|
|
|
// Get final atlas dimensions
|
|
|
|
int width = 0, height = 0;
|
|
|
|
packer.getDimensions(width, height);
|
|
|
|
// The ImmediateAtlasGenerator class facilitates the generation of the atlas bitmap.
|
|
|
|
msdf_atlas::ImmediateAtlasGenerator <
|
2023-02-22 18:28:56 +01:00
|
|
|
float, // pixel type of buffer for individual glyphs depends on generator function
|
|
|
|
3, // number of atlas color channels
|
|
|
|
& msdf_atlas::msdfGenerator, // function to generate bitmaps for individual glyphs
|
|
|
|
msdf_atlas::BitmapAtlasStorage <float, 3> // class that stores the atlas bitmap
|
2023-02-21 18:41:53 +01:00
|
|
|
// For example, a custom atlas storage class that stores it in VRAM can be used.
|
|
|
|
> generator(width, height);
|
|
|
|
// GeneratorAttributes can be modified to change the generator's default settings.
|
|
|
|
msdf_atlas::GeneratorAttributes attributes;
|
|
|
|
generator.setAttributes(attributes);
|
|
|
|
generator.setThreadCount(settings.threadCount);
|
|
|
|
// Generate atlas bitmap
|
|
|
|
generator.generate(glyphs.data(), glyphs.size());
|
|
|
|
// The atlas bitmap can now be retrieved via atlasStorage as a BitmapConstRef.
|
|
|
|
// The glyphs array (or fontGeometry) contains positioning data for typesetting text.
|
|
|
|
msdfgen::Bitmap <float, 3> bitmap(generator.atlasStorage());
|
|
|
|
ofxMsdfgen::toOfImage(bitmap, atlasImage);
|
|
|
|
|
2023-02-22 18:28:56 +01:00
|
|
|
std::vector <msdf_atlas::GlyphBox> layout = generator.getLayout();
|
|
|
|
int i = 0;
|
|
|
|
cout << "glyphs.size() = " << ofToString(glyphs.size()) << endl;
|
|
|
|
for(const msdf_atlas::GlyphBox & gb : layout){
|
|
|
|
msdf_atlas::Rectangle rect = gb.rect;
|
|
|
|
msdf_atlas::GlyphGeometry gg = glyphs.data()[i];
|
|
|
|
cout << "glyphbox " << ofToString(i) << "/" << layout.size() << endl;
|
|
|
|
cout
|
|
|
|
<< "\t\tindex: " << gb.index << endl
|
|
|
|
<< "\t\tadvance: " << gb.advance << endl
|
|
|
|
<< "\t\tr x: " << rect.x << endl
|
|
|
|
<< "\t\tr y: " << rect.y << endl
|
|
|
|
<< "\t\tr w: " << rect.w << endl
|
|
|
|
<< "\t\tr h: " << rect.h << endl;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2023-02-21 18:41:53 +01:00
|
|
|
// Cleanup
|
|
|
|
msdfgen::destroyFont(font);
|
|
|
|
|
2023-02-22 18:28:56 +01:00
|
|
|
success = true; // FIXME: always turns true, why do we have this
|
2023-02-21 18:41:53 +01:00
|
|
|
}
|
|
|
|
msdfgen::deinitializeFreetype(ft);
|
|
|
|
}
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ofImage & ofxMsdfgen::Atlas::getAtlasImage(){
|
|
|
|
return atlasImage;
|
|
|
|
}
|