Glyph wrap keeps integer origin
This commit is contained in:
parent
f1ad23f7c4
commit
3e73a31618
|
|
@ -52,6 +52,31 @@ void GlyphGeometry::edgeColoring(void (*fn)(msdfgen::Shape &, double, unsigned l
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlyphGeometry::wrapBox(double scale, double range, double miterLimit) {
|
void GlyphGeometry::wrapBox(double scale, double range, double miterLimit) {
|
||||||
|
scale *= geometryScale;
|
||||||
|
range /= geometryScale;
|
||||||
|
box.range = range;
|
||||||
|
box.scale = scale;
|
||||||
|
if (bounds.l < bounds.r && bounds.b < bounds.t) {
|
||||||
|
double l = bounds.l, b = bounds.b, r = bounds.r, t = bounds.t;
|
||||||
|
l -= .5*range, b -= .5*range;
|
||||||
|
r += .5*range, t += .5*range;
|
||||||
|
if (miterLimit > 0)
|
||||||
|
shape.boundMiters(l, b, r, t, .5*range, miterLimit, 1);
|
||||||
|
int sl = (int) floor(scale*l-.5);
|
||||||
|
int sb = (int) floor(scale*b-.5);
|
||||||
|
int sr = (int) ceil(scale*r+.5);
|
||||||
|
int st = (int) ceil(scale*t+.5);
|
||||||
|
box.rect.w = sr-sl;
|
||||||
|
box.rect.h = st-sb;
|
||||||
|
box.translate.x = -sl/scale;
|
||||||
|
box.translate.y = -sb/scale;
|
||||||
|
} else {
|
||||||
|
box.rect.w = 0, box.rect.h = 0;
|
||||||
|
box.translate = msdfgen::Vector2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlyphGeometry::wrapBoxUnaligned(double scale, double range, double miterLimit) {
|
||||||
scale *= geometryScale;
|
scale *= geometryScale;
|
||||||
range /= geometryScale;
|
range /= geometryScale;
|
||||||
box.range = range;
|
box.range = range;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ public:
|
||||||
void edgeColoring(void (*fn)(msdfgen::Shape &, double, unsigned long long), double angleThreshold, unsigned long long seed);
|
void edgeColoring(void (*fn)(msdfgen::Shape &, double, unsigned long long), double angleThreshold, unsigned long long seed);
|
||||||
/// Computes the dimensions of the glyph's box as well as the transformation for the generator function
|
/// Computes the dimensions of the glyph's box as well as the transformation for the generator function
|
||||||
void wrapBox(double scale, double range, double miterLimit);
|
void wrapBox(double scale, double range, double miterLimit);
|
||||||
|
/// Computes the dimensions of the glyph's box and the transformation for the generator function, allowing origin to be located at a non-integer coordinate
|
||||||
|
void wrapBoxUnaligned(double scale, double range, double miterLimit);
|
||||||
/// Sets the glyph's box's position in the atlas
|
/// Sets the glyph's box's position in the atlas
|
||||||
void placeBox(int x, int y);
|
void placeBox(int x, int y);
|
||||||
/// Sets the glyph's box's rectangle in the atlas
|
/// Sets the glyph's box's rectangle in the atlas
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,20 @@
|
||||||
|
|
||||||
namespace msdf_atlas {
|
namespace msdf_atlas {
|
||||||
|
|
||||||
int TightAtlasPacker::tryPack(GlyphGeometry *glyphs, int count, DimensionsConstraint dimensionsConstraint, int &width, int &height, int padding, double scale, double range, double miterLimit) {
|
TightAtlasPacker::TightAtlasPacker() :
|
||||||
|
width(-1), height(-1),
|
||||||
|
padding(0),
|
||||||
|
dimensionsConstraint(DimensionsConstraint::POWER_OF_TWO_SQUARE),
|
||||||
|
scale(-1),
|
||||||
|
minScale(1),
|
||||||
|
unitRange(0),
|
||||||
|
pxRange(0),
|
||||||
|
miterLimit(0),
|
||||||
|
scaleMaximizationTolerance(.001)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
int TightAtlasPacker::tryPack(GlyphGeometry *glyphs, int count, DimensionsConstraint dimensionsConstraint, int &width, int &height, double scale) const {
|
||||||
|
double range = unitRange+pxRange/scale;
|
||||||
// Wrap glyphs into boxes
|
// Wrap glyphs into boxes
|
||||||
std::vector<Rectangle> rectangles;
|
std::vector<Rectangle> rectangles;
|
||||||
std::vector<GlyphGeometry *> rectangleGlyphs;
|
std::vector<GlyphGeometry *> rectangleGlyphs;
|
||||||
|
|
@ -64,9 +77,10 @@ int TightAtlasPacker::tryPack(GlyphGeometry *glyphs, int count, DimensionsConstr
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double TightAtlasPacker::packAndScale(GlyphGeometry *glyphs, int count, int width, int height, int padding, double unitRange, double pxRange, double miterLimit, double tolerance) {
|
double TightAtlasPacker::packAndScale(GlyphGeometry *glyphs, int count) const {
|
||||||
bool lastResult = false;
|
bool lastResult = false;
|
||||||
#define TRY_PACK(scale) (lastResult = !tryPack(glyphs, count, DimensionsConstraint(), width, height, padding, (scale), unitRange+pxRange/(scale), miterLimit))
|
int w = width, h = height;
|
||||||
|
#define TRY_PACK(scale) (lastResult = !tryPack(glyphs, count, DimensionsConstraint(), w, h, (scale)))
|
||||||
double minScale = 1, maxScale = 1;
|
double minScale = 1, maxScale = 1;
|
||||||
if (TRY_PACK(1)) {
|
if (TRY_PACK(1)) {
|
||||||
while (maxScale < 1e+32 && ((maxScale = 2*minScale), TRY_PACK(maxScale)))
|
while (maxScale < 1e+32 && ((maxScale = 2*minScale), TRY_PACK(maxScale)))
|
||||||
|
|
@ -77,7 +91,7 @@ double TightAtlasPacker::packAndScale(GlyphGeometry *glyphs, int count, int widt
|
||||||
}
|
}
|
||||||
if (minScale == maxScale)
|
if (minScale == maxScale)
|
||||||
return 0;
|
return 0;
|
||||||
while (minScale/maxScale < 1-tolerance) {
|
while (minScale/maxScale < 1-scaleMaximizationTolerance) {
|
||||||
double midScale = .5*(minScale+maxScale);
|
double midScale = .5*(minScale+maxScale);
|
||||||
if (TRY_PACK(midScale))
|
if (TRY_PACK(midScale))
|
||||||
minScale = midScale;
|
minScale = midScale;
|
||||||
|
|
@ -89,27 +103,15 @@ double TightAtlasPacker::packAndScale(GlyphGeometry *glyphs, int count, int widt
|
||||||
return minScale;
|
return minScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
TightAtlasPacker::TightAtlasPacker() :
|
|
||||||
width(-1), height(-1),
|
|
||||||
padding(0),
|
|
||||||
dimensionsConstraint(DimensionsConstraint::POWER_OF_TWO_SQUARE),
|
|
||||||
scale(-1),
|
|
||||||
minScale(1),
|
|
||||||
unitRange(0),
|
|
||||||
pxRange(0),
|
|
||||||
miterLimit(0),
|
|
||||||
scaleMaximizationTolerance(.001)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
int TightAtlasPacker::pack(GlyphGeometry *glyphs, int count) {
|
int TightAtlasPacker::pack(GlyphGeometry *glyphs, int count) {
|
||||||
double initialScale = scale > 0 ? scale : minScale;
|
double initialScale = scale > 0 ? scale : minScale;
|
||||||
if (initialScale > 0) {
|
if (initialScale > 0) {
|
||||||
if (int remaining = tryPack(glyphs, count, dimensionsConstraint, width, height, padding, initialScale, unitRange+pxRange/initialScale, miterLimit))
|
if (int remaining = tryPack(glyphs, count, dimensionsConstraint, width, height, initialScale))
|
||||||
return remaining;
|
return remaining;
|
||||||
} else if (width < 0 || height < 0)
|
} else if (width < 0 || height < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (scale <= 0)
|
if (scale <= 0)
|
||||||
scale = packAndScale(glyphs, count, width, height, padding, unitRange, pxRange, miterLimit, scaleMaximizationTolerance);
|
scale = packAndScale(glyphs, count);
|
||||||
if (scale <= 0)
|
if (scale <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
pxRange += scale*unitRange;
|
pxRange += scale*unitRange;
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ private:
|
||||||
double miterLimit;
|
double miterLimit;
|
||||||
double scaleMaximizationTolerance;
|
double scaleMaximizationTolerance;
|
||||||
|
|
||||||
static int tryPack(GlyphGeometry *glyphs, int count, DimensionsConstraint dimensionsConstraint, int &width, int &height, int padding, double scale, double range, double miterLimit);
|
int tryPack(GlyphGeometry *glyphs, int count, DimensionsConstraint dimensionsConstraint, int &width, int &height, double scale) const;
|
||||||
static double packAndScale(GlyphGeometry *glyphs, int count, int width, int height, int padding, double unitRange, double pxRange, double miterLimit, double tolerance);
|
double packAndScale(GlyphGeometry *glyphs, int count) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue