Merge pull request #13 from khaledhosny/bbox
Fix simple glyph bounding box handling
This commit is contained in:
@@ -40,28 +40,6 @@ void StoreLoca(int index_fmt, uint32_t value, size_t* offset, uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
void NormalizeSimpleGlyphBoundingBox(Glyph* glyph) {
|
||||
if (glyph->contours.empty() || glyph->contours[0].empty()) {
|
||||
return;
|
||||
}
|
||||
int16_t x_min = glyph->contours[0][0].x;
|
||||
int16_t y_min = glyph->contours[0][0].y;
|
||||
int16_t x_max = x_min;
|
||||
int16_t y_max = y_min;
|
||||
for (const auto& contour : glyph->contours) {
|
||||
for (const auto& point : contour) {
|
||||
if (point.x < x_min) x_min = point.x;
|
||||
if (point.x > x_max) x_max = point.x;
|
||||
if (point.y < y_min) y_min = point.y;
|
||||
if (point.y > y_max) y_max = point.y;
|
||||
}
|
||||
}
|
||||
glyph->x_min = x_min;
|
||||
glyph->y_min = y_min;
|
||||
glyph->x_max = x_max;
|
||||
glyph->y_max = y_max;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
@@ -88,7 +66,6 @@ bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) {
|
||||
(glyph_size > 0 && !ReadGlyph(glyph_data, glyph_size, &glyph))) {
|
||||
return FONT_COMPRESSION_FAILURE();
|
||||
}
|
||||
NormalizeSimpleGlyphBoundingBox(&glyph);
|
||||
size_t glyf_dst_size = glyf_table->buffer.size() - glyf_offset;
|
||||
if (!StoreGlyph(glyph, glyf_dst + glyf_offset, &glyf_dst_size)) {
|
||||
return FONT_COMPRESSION_FAILURE();
|
||||
|
||||
+33
-8
@@ -58,11 +58,10 @@ void WriteLong(std::vector<uint8_t>* out, int value) {
|
||||
|
||||
// Glyf table preprocessing, based on
|
||||
// GlyfEncoder.java
|
||||
// but only the "sbbox" and "cbbox" options are supported.
|
||||
class GlyfEncoder {
|
||||
public:
|
||||
explicit GlyfEncoder(int num_glyphs)
|
||||
: sbbox_(false), cbbox_(true), n_glyphs_(num_glyphs) {
|
||||
: n_glyphs_(num_glyphs) {
|
||||
bbox_bitmap_.resize(((num_glyphs + 31) >> 5) << 2);
|
||||
}
|
||||
|
||||
@@ -105,10 +104,40 @@ class GlyfEncoder {
|
||||
glyph.instructions_data, glyph.instructions_size);
|
||||
}
|
||||
|
||||
bool ShouldWriteSimpleGlyphBbox(const Glyph& glyph) {
|
||||
if (glyph.contours.empty() || glyph.contours[0].empty()) {
|
||||
return glyph.x_min || glyph.y_min || glyph.x_max || glyph.y_max;
|
||||
}
|
||||
|
||||
int16_t x_min = glyph.contours[0][0].x;
|
||||
int16_t y_min = glyph.contours[0][0].y;
|
||||
int16_t x_max = x_min;
|
||||
int16_t y_max = y_min;
|
||||
for (const auto& contour : glyph.contours) {
|
||||
for (const auto& point : contour) {
|
||||
if (point.x < x_min) x_min = point.x;
|
||||
if (point.x > x_max) x_max = point.x;
|
||||
if (point.y < y_min) y_min = point.y;
|
||||
if (point.y > y_max) y_max = point.y;
|
||||
}
|
||||
}
|
||||
|
||||
if (glyph.x_min != x_min)
|
||||
return true;
|
||||
if (glyph.y_min != y_min)
|
||||
return true;
|
||||
if (glyph.x_max != x_max)
|
||||
return true;
|
||||
if (glyph.y_max != y_max)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void WriteSimpleGlyph(int glyph_id, const Glyph& glyph) {
|
||||
int num_contours = glyph.contours.size();
|
||||
WriteUShort(&n_contour_stream_, num_contours);
|
||||
if (sbbox_) {
|
||||
if (ShouldWriteSimpleGlyphBbox(glyph)) {
|
||||
WriteBbox(glyph_id, glyph);
|
||||
}
|
||||
// TODO: check that bbox matches, write bbox if not
|
||||
@@ -136,9 +165,7 @@ class GlyfEncoder {
|
||||
|
||||
void WriteCompositeGlyph(int glyph_id, const Glyph& glyph) {
|
||||
WriteUShort(&n_contour_stream_, -1);
|
||||
if (cbbox_) {
|
||||
WriteBbox(glyph_id, glyph);
|
||||
}
|
||||
WriteBbox(glyph_id, glyph);
|
||||
WriteBytes(&composite_stream_,
|
||||
glyph.composite_data,
|
||||
glyph.composite_data_size);
|
||||
@@ -204,8 +231,6 @@ class GlyfEncoder {
|
||||
std::vector<uint8_t> bbox_stream_;
|
||||
std::vector<uint8_t> glyph_stream_;
|
||||
std::vector<uint8_t> instruction_stream_;
|
||||
bool sbbox_;
|
||||
bool cbbox_;
|
||||
int n_glyphs_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user