mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1120101 - Calculate vertical glyph origin based on 'vmtx' table in TrueType fonts. r=jdaggett
This commit is contained in:
parent
22e73356e6
commit
eb9c988460
@ -41,6 +41,8 @@ gfxHarfBuzzShaper::gfxHarfBuzzShaper(gfxFont *aFont)
|
|||||||
mHmtxTable(nullptr),
|
mHmtxTable(nullptr),
|
||||||
mVmtxTable(nullptr),
|
mVmtxTable(nullptr),
|
||||||
mVORGTable(nullptr),
|
mVORGTable(nullptr),
|
||||||
|
mLocaTable(nullptr),
|
||||||
|
mGlyfTable(nullptr),
|
||||||
mCmapTable(nullptr),
|
mCmapTable(nullptr),
|
||||||
mCmapFormat(-1),
|
mCmapFormat(-1),
|
||||||
mSubtableOffset(0),
|
mSubtableOffset(0),
|
||||||
@ -50,7 +52,8 @@ gfxHarfBuzzShaper::gfxHarfBuzzShaper(gfxFont *aFont)
|
|||||||
mUseFontGetGlyph(aFont->ProvidesGetGlyph()),
|
mUseFontGetGlyph(aFont->ProvidesGetGlyph()),
|
||||||
mUseFontGlyphWidths(false),
|
mUseFontGlyphWidths(false),
|
||||||
mInitialized(false),
|
mInitialized(false),
|
||||||
mVerticalInitialized(false)
|
mVerticalInitialized(false),
|
||||||
|
mLocaLongOffsets(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +68,18 @@ gfxHarfBuzzShaper::~gfxHarfBuzzShaper()
|
|||||||
if (mKernTable) {
|
if (mKernTable) {
|
||||||
hb_blob_destroy(mKernTable);
|
hb_blob_destroy(mKernTable);
|
||||||
}
|
}
|
||||||
|
if (mVmtxTable) {
|
||||||
|
hb_blob_destroy(mVmtxTable);
|
||||||
|
}
|
||||||
|
if (mVORGTable) {
|
||||||
|
hb_blob_destroy(mVORGTable);
|
||||||
|
}
|
||||||
|
if (mLocaTable) {
|
||||||
|
hb_blob_destroy(mLocaTable);
|
||||||
|
}
|
||||||
|
if (mGlyfTable) {
|
||||||
|
hb_blob_destroy(mGlyfTable);
|
||||||
|
}
|
||||||
if (mHBFont) {
|
if (mHBFont) {
|
||||||
hb_font_destroy(mHBFont);
|
hb_font_destroy(mHBFont);
|
||||||
}
|
}
|
||||||
@ -330,6 +345,72 @@ gfxHarfBuzzShaper::GetGlyphVOrigin(hb_codepoint_t aGlyph,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mVmtxTable) {
|
||||||
|
if (mLocaTable && mGlyfTable) {
|
||||||
|
// TrueType outlines: use glyph bbox + top sidebearing
|
||||||
|
uint32_t offset; // offset of glyph record in the 'glyf' table
|
||||||
|
uint32_t len;
|
||||||
|
const char* data = hb_blob_get_data(mLocaTable, &len);
|
||||||
|
if (mLocaLongOffsets) {
|
||||||
|
if ((aGlyph + 1) * sizeof(AutoSwap_PRUint32) > len) {
|
||||||
|
*aY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const AutoSwap_PRUint32* offsets =
|
||||||
|
reinterpret_cast<const AutoSwap_PRUint32*>(data);
|
||||||
|
offset = offsets[aGlyph];
|
||||||
|
if (offset == offsets[aGlyph + 1]) {
|
||||||
|
// empty glyph
|
||||||
|
*aY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((aGlyph + 1) * sizeof(AutoSwap_PRUint16) > len) {
|
||||||
|
*aY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const AutoSwap_PRUint16* offsets =
|
||||||
|
reinterpret_cast<const AutoSwap_PRUint16*>(data);
|
||||||
|
offset = uint16_t(offsets[aGlyph]);
|
||||||
|
if (offset == uint16_t(offsets[aGlyph + 1])) {
|
||||||
|
// empty glyph
|
||||||
|
*aY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Glyf { // we only need the bounding-box at the beginning
|
||||||
|
// of the glyph record, not the actual outline data
|
||||||
|
AutoSwap_PRInt16 numberOfContours;
|
||||||
|
AutoSwap_PRInt16 xMin;
|
||||||
|
AutoSwap_PRInt16 yMin;
|
||||||
|
AutoSwap_PRInt16 xMax;
|
||||||
|
AutoSwap_PRInt16 yMax;
|
||||||
|
};
|
||||||
|
data = hb_blob_get_data(mGlyfTable, &len);
|
||||||
|
if (offset + sizeof(Glyf) > len) {
|
||||||
|
*aY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const Glyf* glyf = reinterpret_cast<const Glyf*>(data + offset);
|
||||||
|
|
||||||
|
if (aGlyph >= uint32_t(mNumLongVMetrics)) {
|
||||||
|
aGlyph = mNumLongVMetrics - 1;
|
||||||
|
}
|
||||||
|
const GlyphMetrics* metrics =
|
||||||
|
reinterpret_cast<const GlyphMetrics*>
|
||||||
|
(hb_blob_get_data(mVmtxTable, nullptr));
|
||||||
|
*aY = -FloatToFixed(mFont->FUnitsToDevUnitsFactor() *
|
||||||
|
(int16_t(metrics->metrics[aGlyph].lsb) +
|
||||||
|
int16_t(glyf->yMax)));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// XXX TODO: CFF outlines - need to get glyph extents.
|
||||||
|
// For now, fall through to default code below.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// XXX should we consider using OS/2 sTypo* metrics if available?
|
// XXX should we consider using OS/2 sTypo* metrics if available?
|
||||||
|
|
||||||
gfxFontEntry::AutoTable hheaTable(GetFont()->GetFontEntry(),
|
gfxFontEntry::AutoTable hheaTable(GetFont()->GetFontEntry(),
|
||||||
@ -1144,6 +1225,20 @@ gfxHarfBuzzShaper::InitializeVertical()
|
|||||||
mVORGTable = nullptr;
|
mVORGTable = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (mVmtxTable) {
|
||||||
|
// Otherwise, try to load loca and glyf tables so that we can read
|
||||||
|
// bounding boxes (needed to support vertical glyph origin).
|
||||||
|
uint32_t len;
|
||||||
|
gfxFontEntry::AutoTable headTable(entry,
|
||||||
|
TRUETYPE_TAG('h','e','a','d'));
|
||||||
|
const HeadTable* head =
|
||||||
|
reinterpret_cast<const HeadTable*>(hb_blob_get_data(headTable,
|
||||||
|
&len));
|
||||||
|
if (len >= sizeof(HeadTable)) {
|
||||||
|
mLocaLongOffsets = int16_t(head->indexToLocFormat) > 0;
|
||||||
|
mLocaTable = entry->GetFontTable(TRUETYPE_TAG('l','o','c','a'));
|
||||||
|
mGlyfTable = entry->GetFontTable(TRUETYPE_TAG('g','l','y','f'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -130,6 +130,10 @@ protected:
|
|||||||
// For vertical fonts, cached vmtx and VORG table, if present.
|
// For vertical fonts, cached vmtx and VORG table, if present.
|
||||||
mutable hb_blob_t *mVmtxTable;
|
mutable hb_blob_t *mVmtxTable;
|
||||||
mutable hb_blob_t *mVORGTable;
|
mutable hb_blob_t *mVORGTable;
|
||||||
|
// And for vertical TrueType (not CFF) fonts that have vmtx,
|
||||||
|
// we also use loca and glyf to get glyph bounding boxes.
|
||||||
|
mutable hb_blob_t *mLocaTable;
|
||||||
|
mutable hb_blob_t *mGlyfTable;
|
||||||
|
|
||||||
// Cached pointer to cmap subtable to be used for char-to-glyph mapping.
|
// Cached pointer to cmap subtable to be used for char-to-glyph mapping.
|
||||||
// This comes from GetFontTablePtr; if it is non-null, our destructor
|
// This comes from GetFontTablePtr; if it is non-null, our destructor
|
||||||
@ -157,6 +161,7 @@ protected:
|
|||||||
|
|
||||||
bool mInitialized;
|
bool mInitialized;
|
||||||
bool mVerticalInitialized;
|
bool mVerticalInitialized;
|
||||||
|
bool mLocaLongOffsets;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* GFX_HARFBUZZSHAPER_H */
|
#endif /* GFX_HARFBUZZSHAPER_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user