diff options
Diffstat (limited to 'gfx/ots/ots-1850314.patch')
-rw-r--r-- | gfx/ots/ots-1850314.patch | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/gfx/ots/ots-1850314.patch b/gfx/ots/ots-1850314.patch new file mode 100644 index 0000000000..88088f5064 --- /dev/null +++ b/gfx/ots/ots-1850314.patch @@ -0,0 +1,177 @@ +commit 362a59be47f9e187eec43df0938def661be6c972 +Author: Jonathan Kew <jkew@mozilla.com> +Date: Wed Aug 30 12:55:02 2023 +0000 + + Bug 1850314 - Don't do glyph bounding-box fixup for "tricky" fonts, because it may disrupt glyph rendering on macOS. r=gfx-reviewers,lsalzman + + Differential Revision: https://phabricator.services.mozilla.com/D187096 + +diff --git a/src/glyf.cc b/src/glyf.cc +index 0ed9515ef16d6..31487957bf99b 100644 +--- a/src/glyf.cc ++++ b/src/glyf.cc +@@ -10,6 +10,7 @@ + #include "head.h" + #include "loca.h" + #include "maxp.h" ++#include "name.h" + + // glyf - Glyph Data + // http://www.microsoft.com/typography/otspec/glyf.htm +@@ -97,7 +98,8 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph, + int16_t& xmin, + int16_t& ymin, + int16_t& xmax, +- int16_t& ymax) { ++ int16_t& ymax, ++ bool is_tricky_font) { + // read the end-points array + uint16_t num_flags = 0; + for (int i = 0; i < num_contours; ++i) { +@@ -219,27 +221,32 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph, + } + + if (adjusted_bbox) { +- Warning("Glyph bbox was incorrect; adjusting (glyph %u)", gid); +- // copy the numberOfContours field +- this->iov.push_back(std::make_pair(glyph.buffer(), 2)); +- // output a fixed-up version of the bounding box +- uint8_t* fixed_bbox = new uint8_t[8]; +- fixed_bboxes.push_back(fixed_bbox); +- xmin = ots_htons(xmin); +- std::memcpy(fixed_bbox, &xmin, 2); +- ymin = ots_htons(ymin); +- std::memcpy(fixed_bbox + 2, &ymin, 2); +- xmax = ots_htons(xmax); +- std::memcpy(fixed_bbox + 4, &xmax, 2); +- ymax = ots_htons(ymax); +- std::memcpy(fixed_bbox + 6, &ymax, 2); +- this->iov.push_back(std::make_pair(fixed_bbox, 8)); +- // copy the remainder of the glyph data +- this->iov.push_back(std::make_pair(glyph.buffer() + 10, glyph.offset() - 10)); +- } else { +- this->iov.push_back(std::make_pair(glyph.buffer(), glyph.offset())); ++ if (is_tricky_font) { ++ Warning("Glyph bbox was incorrect; NOT adjusting tricky font (glyph %u)", gid); ++ } else { ++ Warning("Glyph bbox was incorrect; adjusting (glyph %u)", gid); ++ // copy the numberOfContours field ++ this->iov.push_back(std::make_pair(glyph.buffer(), 2)); ++ // output a fixed-up version of the bounding box ++ uint8_t* fixed_bbox = new uint8_t[8]; ++ fixed_bboxes.push_back(fixed_bbox); ++ xmin = ots_htons(xmin); ++ std::memcpy(fixed_bbox, &xmin, 2); ++ ymin = ots_htons(ymin); ++ std::memcpy(fixed_bbox + 2, &ymin, 2); ++ xmax = ots_htons(xmax); ++ std::memcpy(fixed_bbox + 4, &xmax, 2); ++ ymax = ots_htons(ymax); ++ std::memcpy(fixed_bbox + 6, &ymax, 2); ++ this->iov.push_back(std::make_pair(fixed_bbox, 8)); ++ // copy the remainder of the glyph data ++ this->iov.push_back(std::make_pair(glyph.buffer() + 10, glyph.offset() - 10)); ++ return true; ++ } + } + ++ this->iov.push_back(std::make_pair(glyph.buffer(), glyph.offset())); ++ + return true; + } + +@@ -342,6 +349,10 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) { + return Error("Missing maxp or loca or head table needed by glyf table"); + } + ++ OpenTypeNAME *name = static_cast<OpenTypeNAME*>( ++ GetFont()->GetTypedTable(OTS_TAG_NAME)); ++ bool is_tricky = name->IsTrickyFont(); ++ + this->maxp = maxp; + + const unsigned num_glyphs = maxp->num_glyphs; +@@ -397,7 +408,7 @@ bool OpenTypeGLYF::Parse(const uint8_t *data, size_t length) { + // does we will simply ignore it. + glyph.set_offset(0); + } else if (num_contours > 0) { +- if (!ParseSimpleGlyph(glyph, i, num_contours, xmin, ymin, xmax, ymax)) { ++ if (!ParseSimpleGlyph(glyph, i, num_contours, xmin, ymin, xmax, ymax, is_tricky)) { + return Error("Failed to parse glyph %d", i); + } + } else { +diff --git a/src/glyf.h b/src/glyf.h +index 05e846f1cb6e8..f85fdc4652fcf 100644 +--- a/src/glyf.h ++++ b/src/glyf.h +@@ -51,7 +51,8 @@ class OpenTypeGLYF : public Table { + int16_t& xmin, + int16_t& ymin, + int16_t& xmax, +- int16_t& ymax); ++ int16_t& ymax, ++ bool is_tricky_font); + bool ParseCompositeGlyph( + Buffer &glyph, + ComponentPointCount* component_point_count); +diff --git a/src/name.cc b/src/name.cc +index fc5074b0587a3..7526e1f72b9ea 100644 +--- a/src/name.cc ++++ b/src/name.cc +@@ -366,4 +366,44 @@ bool OpenTypeNAME::IsValidNameId(uint16_t nameID, bool addIfMissing) { + return this->name_ids.count(nameID); + } + ++// List of font names considered "tricky" (dependent on applying original TrueType instructions) by FreeType, see ++// https://gitlab.freedesktop.org/freetype/freetype/-/blob/2d9fce53d4ce89f36075168282fcdd7289e082f9/src/truetype/ttobjs.c#L170-241 ++static const char* tricky_font_names[] = { ++ "cpop", ++ "DFGirl-W6-WIN-BF", ++ "DFGothic-EB", ++ "DFGyoSho-Lt", ++ "DFHei", ++ "DFHSGothic-W5", ++ "DFHSMincho-W3", ++ "DFHSMincho-W7", ++ "DFKaiSho-SB", ++ "DFKaiShu", ++ "DFKai-SB", ++ "DFMing", ++ "DLC", ++ "HuaTianKaiTi?", ++ "HuaTianSongTi?", ++ "Ming(for ISO10646)", ++ "MingLiU", ++ "MingMedium", ++ "PMingLiU", ++ "MingLi43" ++}; ++ ++bool OpenTypeNAME::IsTrickyFont() const { ++ for (const auto& name : this->names) { ++ const uint16_t id = name.name_id; ++ if (id != 1) { ++ continue; ++ } ++ for (const auto* p : tricky_font_names) { ++ if (name.text.find(p) != std::string::npos) { ++ return true; ++ } ++ } ++ } ++ return false; ++} ++ + } // namespace +diff --git a/src/name.h b/src/name.h +index 68c7ac096d3f8..a241e77ee26bb 100644 +--- a/src/name.h ++++ b/src/name.h +@@ -52,6 +52,7 @@ class OpenTypeNAME : public Table { + bool Parse(const uint8_t *data, size_t length); + bool Serialize(OTSStream *out); + bool IsValidNameId(uint16_t nameID, bool addIfMissing = false); ++ bool IsTrickyFont() const; + + private: + std::vector<NameRecord> names; |