mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 05:44:10 +00:00
bug 916048 - SVG-in-OpenType glyphs should use the font's unitsPerEm value. r=roc
This commit is contained in:
parent
fa21bde76e
commit
c9f388d0f2
@ -111,6 +111,7 @@ gfxFontEntry::gfxFontEntry() :
|
||||
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
mUnitsPerEm(0),
|
||||
mHBFace(nullptr),
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
@ -137,6 +138,7 @@ gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
|
||||
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
mUnitsPerEm(0),
|
||||
mHBFace(nullptr),
|
||||
mGrFace(nullptr),
|
||||
mGrFaceRefCnt(0)
|
||||
@ -264,6 +266,30 @@ gfxFontEntry::FindOrMakeFont(const gfxFontStyle *aStyle, bool aNeedsBold)
|
||||
return font.forget();
|
||||
}
|
||||
|
||||
uint16_t
|
||||
gfxFontEntry::UnitsPerEm()
|
||||
{
|
||||
if (!mUnitsPerEm) {
|
||||
AutoTable headTable(this, TRUETYPE_TAG('h','e','a','d'));
|
||||
if (headTable) {
|
||||
uint32_t len;
|
||||
const HeadTable* head =
|
||||
reinterpret_cast<const HeadTable*>(hb_blob_get_data(headTable,
|
||||
&len));
|
||||
if (len >= sizeof(HeadTable)) {
|
||||
mUnitsPerEm = head->unitsPerEm;
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find a usable 'head' table, or if the value was
|
||||
// outside the valid range, record it as invalid
|
||||
if (mUnitsPerEm < kMinUPEM || mUnitsPerEm > kMaxUPEM) {
|
||||
mUnitsPerEm = kInvalidUPEM;
|
||||
}
|
||||
}
|
||||
return mUnitsPerEm;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxFontEntry::HasSVGGlyph(uint32_t aGlyphId)
|
||||
{
|
||||
@ -275,15 +301,17 @@ bool
|
||||
gfxFontEntry::GetSVGGlyphExtents(gfxContext *aContext, uint32_t aGlyphId,
|
||||
gfxRect *aResult)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mSVGInitialized, "SVG data has not yet been loaded. TryGetSVGData() first.");
|
||||
NS_ABORT_IF_FALSE(mSVGInitialized,
|
||||
"SVG data has not yet been loaded. TryGetSVGData() first.");
|
||||
NS_ABORT_IF_FALSE(mUnitsPerEm >= kMinUPEM && mUnitsPerEm <= kMaxUPEM,
|
||||
"font has invalid unitsPerEm");
|
||||
|
||||
gfxContextAutoSaveRestore matrixRestore(aContext);
|
||||
cairo_matrix_t fontMatrix;
|
||||
cairo_get_font_matrix(aContext->GetCairo(), &fontMatrix);
|
||||
|
||||
gfxMatrix svgToAppSpace = *reinterpret_cast<gfxMatrix*>(&fontMatrix);
|
||||
svgToAppSpace.Scale(1.0f / gfxSVGGlyphs::SVG_UNITS_PER_EM,
|
||||
1.0f / gfxSVGGlyphs::SVG_UNITS_PER_EM);
|
||||
svgToAppSpace.Scale(1.0f / mUnitsPerEm, 1.0f / mUnitsPerEm);
|
||||
|
||||
return mSVGGlyphs->GetGlyphExtents(aGlyphId, svgToAppSpace, aResult);
|
||||
}
|
||||
@ -307,8 +335,13 @@ gfxFontEntry::TryGetSVGData(gfxFont* aFont)
|
||||
if (!mSVGInitialized) {
|
||||
mSVGInitialized = true;
|
||||
|
||||
// We don't use AutoTable here because we'll pass ownership of these
|
||||
// blobs to the gfxSVGGlyphs, once we've confirmed the tables exist
|
||||
// If UnitsPerEm is not known/valid, we can't use SVG glyphs
|
||||
if (UnitsPerEm() == kInvalidUPEM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't use AutoTable here because we'll pass ownership of this
|
||||
// blob to the gfxSVGGlyphs, once we've confirmed the table exists
|
||||
hb_blob_t *svgTable = GetFontTable(TRUETYPE_TAG('S','V','G',' '));
|
||||
if (!svgTable) {
|
||||
return false;
|
||||
@ -2818,7 +2851,8 @@ gfxFont::RenderSVGGlyph(gfxContext *aContext, gfxPoint aPoint, DrawMode aDrawMod
|
||||
return false;
|
||||
}
|
||||
|
||||
const gfxFloat devUnitsPerSVGUnit = GetStyle()->size / gfxSVGGlyphs::SVG_UNITS_PER_EM;
|
||||
const gfxFloat devUnitsPerSVGUnit =
|
||||
GetAdjustedSize() / GetFontEntry()->UnitsPerEm();
|
||||
gfxContextMatrixAutoSaveRestore matrixRestore(aContext);
|
||||
|
||||
aContext->Translate(gfxPoint(aPoint.x, aPoint.y));
|
||||
@ -3548,7 +3582,6 @@ gfxFont::InitMetricsFromSfntTables(Metrics& aMetrics)
|
||||
{
|
||||
mIsValid = false; // font is NOT valid in case of early return
|
||||
|
||||
const uint32_t kHeadTableTag = TRUETYPE_TAG('h','e','a','d');
|
||||
const uint32_t kHheaTableTag = TRUETYPE_TAG('h','h','e','a');
|
||||
const uint32_t kPostTableTag = TRUETYPE_TAG('p','o','s','t');
|
||||
const uint32_t kOS_2TableTag = TRUETYPE_TAG('O','S','/','2');
|
||||
@ -3557,21 +3590,11 @@ gfxFont::InitMetricsFromSfntTables(Metrics& aMetrics)
|
||||
|
||||
if (mFUnitsConvFactor == 0.0) {
|
||||
// If the conversion factor from FUnits is not yet set,
|
||||
// 'head' table is required; otherwise we cannot read any metrics
|
||||
// because we don't know unitsPerEm
|
||||
gfxFontEntry::AutoTable headTable(mFontEntry, kHeadTableTag);
|
||||
if (!headTable) {
|
||||
// get the unitsPerEm from the 'head' table via the font entry
|
||||
uint16_t unitsPerEm = GetFontEntry()->UnitsPerEm();
|
||||
if (unitsPerEm == gfxFontEntry::kInvalidUPEM) {
|
||||
return false;
|
||||
}
|
||||
const HeadTable* head =
|
||||
reinterpret_cast<const HeadTable*>(hb_blob_get_data(headTable, &len));
|
||||
if (len < sizeof(HeadTable)) {
|
||||
return false;
|
||||
}
|
||||
uint32_t unitsPerEm = head->unitsPerEm;
|
||||
if (!unitsPerEm) {
|
||||
return true; // is an sfnt, but not valid
|
||||
}
|
||||
mFUnitsConvFactor = mAdjustedSize / unitsPerEm;
|
||||
}
|
||||
|
||||
|
@ -375,6 +375,16 @@ public:
|
||||
hb_blob_t *ShareFontTableAndGetBlob(uint32_t aTag,
|
||||
FallibleTArray<uint8_t>* aTable);
|
||||
|
||||
// Get the font's unitsPerEm from the 'head' table, in the case of an
|
||||
// sfnt resource. Will return kInvalidUPEM for non-sfnt fonts,
|
||||
// if present on the platform.
|
||||
uint16_t UnitsPerEm();
|
||||
enum {
|
||||
kMinUPEM = 16, // Limits on valid unitsPerEm range, from the
|
||||
kMaxUPEM = 16384, // OpenType spec
|
||||
kInvalidUPEM = uint16_t(-1)
|
||||
};
|
||||
|
||||
// Shaper face accessors:
|
||||
// NOTE that harfbuzz and graphite handle ownership/lifetime of the face
|
||||
// object in completely different ways.
|
||||
@ -473,6 +483,10 @@ protected:
|
||||
// caller is responsible to do any sanitization/validation necessary.
|
||||
hb_blob_t* GetTableFromFontData(const void* aFontData, uint32_t aTableTag);
|
||||
|
||||
// Font's unitsPerEm from the 'head' table, if available (will be set to
|
||||
// kInvalidUPEM for non-sfnt font formats)
|
||||
uint16_t mUnitsPerEm;
|
||||
|
||||
// Shaper-specific face objects, shared by all instantiations of the same
|
||||
// physical font, regardless of size.
|
||||
// Usually, only one of these will actually be created for any given font
|
||||
|
@ -44,8 +44,6 @@ typedef mozilla::dom::Element Element;
|
||||
|
||||
mozilla::gfx::UserDataKey gfxTextContextPaint::sUserDataKey;
|
||||
|
||||
const float gfxSVGGlyphs::SVG_UNITS_PER_EM = 1000.0f;
|
||||
|
||||
const gfxRGBA SimpleTextContextPaint::sZero = gfxRGBA(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
gfxSVGGlyphs::gfxSVGGlyphs(hb_blob_t *aSVGTable, gfxFontEntry *aFontEntry)
|
||||
|
@ -78,8 +78,6 @@ private:
|
||||
typedef gfxFont::DrawMode DrawMode;
|
||||
|
||||
public:
|
||||
static const float SVG_UNITS_PER_EM;
|
||||
|
||||
/**
|
||||
* @param aSVGTable The SVG table from the OpenType font
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user