bug 916048 - SVG-in-OpenType glyphs should use the font's unitsPerEm value. r=roc

This commit is contained in:
Jonathan Kew 2013-09-14 12:40:57 +01:00
Родитель fa21bde76e
Коммит c9f388d0f2
4 изменённых файлов: 57 добавлений и 24 удалений

Просмотреть файл

@ -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
*