зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 1 changesets (bug 1582749) for build bustage at /builds/worker/workspace/build/src/gfx/thebes/gfxFT2FontBase
Backed out changeset db3d77b313a0 (bug 1582749)
This commit is contained in:
Родитель
95c42fceb9
Коммит
c8913746b5
|
@ -138,14 +138,6 @@ static void SnapLineToPixels(gfxFloat& aOffset, gfxFloat& aSize) {
|
|||
aSize = snappedSize;
|
||||
}
|
||||
|
||||
static inline gfxRect ScaleGlyphBounds(const IntRect& aBounds,
|
||||
gfxFloat aScale) {
|
||||
return gfxRect(FLOAT_FROM_26_6(aBounds.x) * aScale,
|
||||
FLOAT_FROM_26_6(aBounds.y) * aScale,
|
||||
FLOAT_FROM_26_6(aBounds.width) * aScale,
|
||||
FLOAT_FROM_26_6(aBounds.height) * aScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extents for a simple character representable by a single glyph.
|
||||
* The return value is the glyph id of that glyph or zero if no such glyph
|
||||
|
@ -156,14 +148,10 @@ uint32_t gfxFT2FontBase::GetCharExtents(char aChar, gfxFloat* aWidth,
|
|||
gfxRect* aBounds) {
|
||||
FT_UInt gid = GetGlyph(aChar);
|
||||
int32_t width;
|
||||
IntRect bounds;
|
||||
if (gid && GetFTGlyphExtents(gid, &width, &bounds)) {
|
||||
if (gid && GetFTGlyphExtents(gid, &width, aBounds)) {
|
||||
if (aWidth) {
|
||||
*aWidth = FLOAT_FROM_16_16(width);
|
||||
}
|
||||
if (aBounds) {
|
||||
*aBounds = ScaleGlyphBounds(bounds, GetAdjustedSize() / mFTSize);
|
||||
}
|
||||
return gid;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -520,7 +508,7 @@ FT_Vector gfxFT2FontBase::GetEmboldenStrength(FT_Face aFace) {
|
|||
}
|
||||
|
||||
bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance,
|
||||
IntRect* aBounds) {
|
||||
gfxRect* aBounds) {
|
||||
gfxFT2LockedFace face(this);
|
||||
MOZ_ASSERT(face.get());
|
||||
if (!face.get()) {
|
||||
|
@ -529,7 +517,8 @@ bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Factory::LoadFTGlyph(face.get(), aGID, mFTLoadFlags) != FT_Err_Ok) {
|
||||
FT_Error ftError = Factory::LoadFTGlyph(face.get(), aGID, mFTLoadFlags);
|
||||
if (ftError != FT_Err_Ok) {
|
||||
// FT_Face was somehow broken/invalid? Don't try to access glyph slot.
|
||||
// This probably shouldn't happen, but does: see bug 1440938.
|
||||
NS_WARNING("failed to load glyph!");
|
||||
|
@ -583,56 +572,36 @@ bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance,
|
|||
x2 = (x2 + 63) & -64;
|
||||
y2 = (y2 + 63) & -64;
|
||||
}
|
||||
*aBounds = IntRect(x, y, x2 - x, y2 - y);
|
||||
*aBounds = gfxRect(FLOAT_FROM_26_6(x) * extentsScale,
|
||||
FLOAT_FROM_26_6(y) * extentsScale,
|
||||
FLOAT_FROM_26_6(x2 - x) * extentsScale,
|
||||
FLOAT_FROM_26_6(y2 - y) * extentsScale);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cached glyph metrics for the glyph id if available. Otherwise, query
|
||||
* FreeType for the glyph extents and initialize the glyph metrics.
|
||||
*/
|
||||
const gfxFT2FontBase::GlyphMetrics& gfxFT2FontBase::GetCachedGlyphMetrics(
|
||||
uint16_t aGID) {
|
||||
if (!mGlyphMetrics) {
|
||||
mGlyphMetrics =
|
||||
mozilla::MakeUnique<nsDataHashtable<nsUint32HashKey, GlyphMetrics>>(
|
||||
128);
|
||||
}
|
||||
|
||||
if (const GlyphMetrics* metrics = mGlyphMetrics->GetValue(aGID)) {
|
||||
return *metrics;
|
||||
}
|
||||
|
||||
GlyphMetrics& metrics = mGlyphMetrics->GetOrInsert(aGID);
|
||||
IntRect bounds;
|
||||
if (GetFTGlyphExtents(aGID, &metrics.mAdvance, &bounds)) {
|
||||
metrics.SetBounds(bounds);
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
int32_t gfxFT2FontBase::GetGlyphWidth(uint16_t aGID) {
|
||||
return GetCachedGlyphMetrics(aGID).mAdvance;
|
||||
if (!mGlyphWidths) {
|
||||
mGlyphWidths =
|
||||
mozilla::MakeUnique<nsDataHashtable<nsUint32HashKey, int32_t>>(128);
|
||||
}
|
||||
|
||||
int32_t width;
|
||||
if (mGlyphWidths->Get(aGID, &width)) {
|
||||
return width;
|
||||
}
|
||||
|
||||
if (!GetFTGlyphExtents(aGID, &width)) {
|
||||
width = 0;
|
||||
}
|
||||
mGlyphWidths->Put(aGID, width);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
bool gfxFT2FontBase::GetGlyphBounds(uint16_t aGID, gfxRect* aBounds,
|
||||
bool aTight) {
|
||||
const GlyphMetrics& metrics = GetCachedGlyphMetrics(aGID);
|
||||
if (!metrics.HasValidBounds()) {
|
||||
return false;
|
||||
}
|
||||
// Check if there are cached bounds and use those if available. Otherwise,
|
||||
// fall back to directly querying the glyph extents.
|
||||
IntRect bounds;
|
||||
if (metrics.HasCachedBounds()) {
|
||||
bounds = metrics.GetBounds();
|
||||
} else if (!GetFTGlyphExtents(aGID, nullptr, &bounds)) {
|
||||
return false;
|
||||
}
|
||||
// The bounds are stored unscaled, so must be scaled to the adjusted size.
|
||||
*aBounds = ScaleGlyphBounds(bounds, GetAdjustedSize() / mFTSize);
|
||||
return true;
|
||||
return GetFTGlyphExtents(aGID, nullptr, aBounds);
|
||||
}
|
||||
|
||||
// For variation fonts, figure out the variation coordinates to be applied
|
||||
|
|
|
@ -48,7 +48,7 @@ class gfxFT2FontBase : public gfxFont {
|
|||
// Get advance (and optionally bounds) of a single glyph from FreeType,
|
||||
// and return true, or return false if we failed.
|
||||
bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth,
|
||||
mozilla::gfx::IntRect* aBounds = nullptr);
|
||||
gfxRect* aBounds = nullptr);
|
||||
|
||||
protected:
|
||||
void InitMetrics();
|
||||
|
@ -70,50 +70,7 @@ class gfxFT2FontBase : public gfxFont {
|
|||
// range reported by the face.
|
||||
nsTArray<FT_Fixed> mCoords;
|
||||
|
||||
// Store cached glyph metrics for reasonably small glyph sizes. The bounds
|
||||
// are stored unscaled to losslessly compress 26.6 fixed point to an int16_t.
|
||||
// Larger glyphs are handled directly via GetFTGlyphExtents.
|
||||
struct GlyphMetrics {
|
||||
// Set the X coord to INT16_MIN to signal the bounds are invalid, or
|
||||
// INT16_MAX to signal that the bounds would overflow an int16_t.
|
||||
enum { INVALID = INT16_MIN, OVERFLOW = INT16_MAX };
|
||||
|
||||
GlyphMetrics() : mAdvance(0), mX(INVALID), mY(0), mWidth(0), mHeight(0) {}
|
||||
|
||||
bool HasValidBounds() const { return mX != INVALID; }
|
||||
bool HasCachedBounds() const { return mX != OVERFLOW; }
|
||||
|
||||
// If the bounds can fit in an int16_t, set them. Otherwise, leave the
|
||||
// bounds invalid to signal that GetFTGlyphExtents should be queried
|
||||
// directly.
|
||||
void SetBounds(const mozilla::gfx::IntRect& aBounds) {
|
||||
if (aBounds.x > INT16_MIN && aBounds.x < INT16_MAX &&
|
||||
aBounds.y > INT16_MIN && aBounds.y < INT16_MAX &&
|
||||
aBounds.width <= UINT16_MAX && aBounds.height <= UINT16_MAX) {
|
||||
mX = aBounds.x;
|
||||
mY = aBounds.y;
|
||||
mWidth = aBounds.width;
|
||||
mHeight = aBounds.height;
|
||||
} else {
|
||||
mX = OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::gfx::IntRect GetBounds() const {
|
||||
return mozilla::gfx::IntRect(mX, mY, mWidth, mHeight);
|
||||
}
|
||||
|
||||
int32_t mAdvance;
|
||||
int16_t mX;
|
||||
int16_t mY;
|
||||
uint16_t mWidth;
|
||||
uint16_t mHeight;
|
||||
};
|
||||
|
||||
const GlyphMetrics& GetCachedGlyphMetrics(uint16_t aGID);
|
||||
|
||||
mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey, GlyphMetrics>>
|
||||
mGlyphMetrics;
|
||||
mozilla::UniquePtr<nsDataHashtable<nsUint32HashKey, int32_t>> mGlyphWidths;
|
||||
};
|
||||
|
||||
// Helper classes used for clearing out user font data when FT font
|
||||
|
|
Загрузка…
Ссылка в новой задаче