зеркало из https://github.com/mozilla/pjs.git
Bug 421353 Moving the mouse over text hyperlinks which become underlined spikes cpu usage r=roc+stuart, sr=roc, a1.9=beltzner
This commit is contained in:
Родитель
091ed296f1
Коммит
8210b6e92d
|
@ -138,17 +138,36 @@ nsThebesFontMetrics::GetStrikeout(nscoord& aOffset, nscoord& aSize)
|
|||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetUnderline(nscoord& aOffset, nscoord& aSize)
|
||||
{
|
||||
aOffset = ROUND_TO_TWIPS(GetMetrics().underlineOffset);
|
||||
aOffset = ROUND_TO_TWIPS(mFontGroup->GetUnderlineOffset());
|
||||
aSize = ROUND_TO_TWIPS(GetMetrics().underlineSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// GetHeight/GetMaxAscent/GetMaxDescent/GetMaxHeight must contain the
|
||||
// text-decoration lines drawable area. See bug 421353.
|
||||
// BE CAREFUL for rounding each values. The logic MUST be same as
|
||||
// nsCSSRendering::GetTextDecorationRectInternal's.
|
||||
|
||||
static gfxFloat ComputeMaxDescent(const gfxFont::Metrics& aMetrics,
|
||||
gfxFontGroup* aFontGroup)
|
||||
{
|
||||
gfxFloat offset = NS_floor(-aFontGroup->GetUnderlineOffset() + 0.5);
|
||||
gfxFloat size = NS_round(aMetrics.underlineSize);
|
||||
gfxFloat minDescent = NS_floor(offset + size + 0.5);
|
||||
return PR_MAX(minDescent, aMetrics.maxDescent);
|
||||
}
|
||||
|
||||
static gfxFloat ComputeMaxAscent(const gfxFont::Metrics& aMetrics)
|
||||
{
|
||||
return NS_floor(aMetrics.maxAscent + 0.5);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetHeight(nscoord &aHeight)
|
||||
{
|
||||
aHeight = CEIL_TO_TWIPS(GetMetrics().maxAscent) +
|
||||
CEIL_TO_TWIPS(GetMetrics().maxDescent);
|
||||
aHeight = CEIL_TO_TWIPS(ComputeMaxAscent(GetMetrics())) +
|
||||
CEIL_TO_TWIPS(ComputeMaxDescent(GetMetrics(), mFontGroup));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -190,22 +209,22 @@ nsThebesFontMetrics::GetEmDescent(nscoord &aDescent)
|
|||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxHeight(nscoord &aHeight)
|
||||
{
|
||||
aHeight = CEIL_TO_TWIPS(GetMetrics().maxAscent) +
|
||||
CEIL_TO_TWIPS(GetMetrics().maxDescent);
|
||||
aHeight = CEIL_TO_TWIPS(ComputeMaxAscent(GetMetrics())) +
|
||||
CEIL_TO_TWIPS(ComputeMaxDescent(GetMetrics(), mFontGroup));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxAscent(nscoord &aAscent)
|
||||
{
|
||||
aAscent = CEIL_TO_TWIPS(GetMetrics().maxAscent);
|
||||
aAscent = CEIL_TO_TWIPS(ComputeMaxAscent(GetMetrics()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesFontMetrics::GetMaxDescent(nscoord &aDescent)
|
||||
{
|
||||
aDescent = CEIL_TO_TWIPS(GetMetrics().maxDescent);
|
||||
aDescent = CEIL_TO_TWIPS(ComputeMaxDescent(GetMetrics(), mFontGroup));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1469,7 +1469,7 @@ public:
|
|||
// The value should be lower value of first font's metrics and the bad font's metrics.
|
||||
// Otherwise, this returns from first font's metrics.
|
||||
gfxFloat GetUnderlineOffset() {
|
||||
if (mUnderlineOffset == 0)
|
||||
if (mStyle.size != 0 && mUnderlineOffset == 0)
|
||||
mUnderlineOffset = GetFontAt(0)->GetMetrics().underlineOffset;
|
||||
return mUnderlineOffset;
|
||||
}
|
||||
|
|
|
@ -470,13 +470,15 @@ gfxAtsuiFontGroup::gfxAtsuiFontGroup(const nsAString& families,
|
|||
|
||||
mPageLang = gfxPlatform::GetFontPrefLangFor(mStyle.langGroup.get());
|
||||
|
||||
for (PRUint32 i = 0; i < mFonts.Length(); ++i) {
|
||||
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(mFonts[i].get());
|
||||
if (font->GetFontEntry()->FamilyEntry()->IsBadUnderlineFontFamily()) {
|
||||
gfxFloat first = mFonts[0]->GetMetrics().underlineOffset;
|
||||
gfxFloat bad = font->GetMetrics().underlineOffset;
|
||||
mUnderlineOffset = PR_MIN(first, bad);
|
||||
break;
|
||||
if (!mStyle.systemFont) {
|
||||
for (PRUint32 i = 0; i < mFonts.Length(); ++i) {
|
||||
gfxAtsuiFont* font = static_cast<gfxAtsuiFont*>(mFonts[i].get());
|
||||
if (font->GetFontEntry()->FamilyEntry()->IsBadUnderlineFontFamily()) {
|
||||
gfxFloat first = mFonts[0]->GetMetrics().underlineOffset;
|
||||
gfxFloat bad = font->GetMetrics().underlineOffset;
|
||||
mUnderlineOffset = PR_MIN(first, bad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -549,6 +549,13 @@ gfxFont::SetupGlyphExtents(gfxContext *aContext, PRUint32 aGlyphID, PRBool aNeed
|
|||
void
|
||||
gfxFont::SanitizeMetrics(gfxFont::Metrics *aMetrics, PRBool aIsBadUnderlineFont)
|
||||
{
|
||||
// Even if this font size is zero, this font is created with non-zero size.
|
||||
// However, for layout and others, we should return the metrics of zero size font.
|
||||
if (mStyle.size == 0) {
|
||||
memset(aMetrics, 0, sizeof(gfxFont::Metrics));
|
||||
return;
|
||||
}
|
||||
|
||||
// MS (P)Gothic and MS (P)Mincho are not having suitable values in their super script offset.
|
||||
// If the values are not suitable, we should use x-height instead of them.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=353632
|
||||
|
@ -579,10 +586,6 @@ gfxFont::SanitizeMetrics(gfxFont::Metrics *aMetrics, PRBool aIsBadUnderlineFont)
|
|||
aMetrics->underlineOffset = PR_MIN(aMetrics->underlineOffset, -2.0);
|
||||
|
||||
// Next, we put the underline to bottom of below of the descent space.
|
||||
// Note that the underline might overlap to next line when the line height is 1em.
|
||||
// However, in CJK text, such case is very rare, so, we don't need to worry about such case.
|
||||
// Becasue most CJK glyphs use top of the em square. Therefore, for readability, CJK text needs
|
||||
// larger line gap than Western text, generally.
|
||||
if (aMetrics->internalLeading + aMetrics->externalLeading > aMetrics->underlineSize) {
|
||||
aMetrics->underlineOffset = PR_MIN(aMetrics->underlineOffset, -aMetrics->emDescent);
|
||||
} else {
|
||||
|
|
|
@ -747,12 +747,14 @@ gfxWindowsFontGroup::gfxWindowsFontGroup(const nsAString& aFamilies, const gfxFo
|
|||
|
||||
mFonts.AppendElements(mFontEntries.Length());
|
||||
|
||||
for (PRUint32 i = 0; i < mFontEntries.Length(); ++i) {
|
||||
if (mFontEntries[i]->IsBadUnderlineFont()) {
|
||||
gfxFloat first = GetFontAt(0)->GetMetrics().underlineOffset;
|
||||
gfxFloat bad = GetFontAt(i)->GetMetrics().underlineOffset;
|
||||
mUnderlineOffset = PR_MIN(first, bad);
|
||||
break;
|
||||
if (!mStyle.systemFont) {
|
||||
for (PRUint32 i = 0; i < mFontEntries.Length(); ++i) {
|
||||
if (mFontEntries[i]->IsBadUnderlineFont()) {
|
||||
gfxFloat first = GetFontAt(0)->GetMetrics().underlineOffset;
|
||||
gfxFloat bad = GetFontAt(i)->GetMetrics().underlineOffset;
|
||||
mUnderlineOffset = PR_MIN(first, bad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3984,16 +3984,6 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
// might have moved frames around!
|
||||
nsRect combinedArea;
|
||||
aLineLayout.RelativePositionFrames(combinedArea); // XXXldb This returned width as -15, 2001-06-12, Bugzilla
|
||||
if (aState.mPresContext->CompatibilityMode() != eCompatibility_NavQuirks) {
|
||||
PRUint8 decorations;
|
||||
nscolor underColor, overColor, strikeColor;
|
||||
GetTextDecorations(aState.mPresContext, PR_TRUE, decorations,
|
||||
underColor, overColor, strikeColor);
|
||||
if (decorations) {
|
||||
nsLineLayout::CombineTextDecorations(aState.mPresContext, decorations,
|
||||
this, combinedArea);
|
||||
}
|
||||
}
|
||||
aLine->SetCombinedArea(combinedArea);
|
||||
if (addedBullet) {
|
||||
aLineLayout.RemoveBulletFrame(mBullet);
|
||||
|
|
|
@ -2606,8 +2606,6 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
|
|||
combinedAreaResult.height = mFinalLineHeight;
|
||||
}
|
||||
|
||||
PRBool isStandardsMode =
|
||||
mPresContext->CompatibilityMode() != eCompatibility_NavQuirks;
|
||||
for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) {
|
||||
nsIFrame* frame = pfd->mFrame;
|
||||
nsPoint origin = frame->GetPosition();
|
||||
|
@ -2636,15 +2634,6 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
|
|||
// <b>x</b> and <b>y</b> which were computed above.
|
||||
nsRect r;
|
||||
if (pfd->mSpan) {
|
||||
if (isStandardsMode) {
|
||||
// Combine the text decoration area for inline elements of standards
|
||||
// mode
|
||||
PRUint8 decorations = frame->GetStyleTextReset()->mTextDecoration;
|
||||
if (decorations) {
|
||||
nsLineLayout::CombineTextDecorations(mPresContext, decorations,
|
||||
frame, pfd->mSpan->mFrame->mCombinedArea);
|
||||
}
|
||||
}
|
||||
// Compute a new combined area for the child span before
|
||||
// aggregating it into our combined area.
|
||||
RelativePositionFrames(pfd->mSpan, r);
|
||||
|
@ -2708,7 +2697,7 @@ nsLineLayout::CombineTextDecorations(nsPresContext* aPresContext,
|
|||
gfxFontGroup* fontGroup = tfm->GetThebesFontGroup();
|
||||
gfxFont* firstFont = fontGroup->GetFontAt(0);
|
||||
if (!firstFont)
|
||||
return; // OOM
|
||||
return; // OOM
|
||||
const gfxFont::Metrics& metrics = firstFont->GetMetrics();
|
||||
|
||||
gfxFloat ascent = aAscentOverride == 0 ? metrics.maxAscent :
|
||||
|
|
|
@ -379,7 +379,6 @@ protected:
|
|||
PRBool isBidiSystem);
|
||||
|
||||
void UnionTextDecorationOverflow(nsPresContext* aPresContext,
|
||||
const gfxTextRun::Metrics& aTextMetrics,
|
||||
nsRect* aOverflowRect);
|
||||
|
||||
struct TextDecorations {
|
||||
|
@ -409,6 +408,9 @@ protected:
|
|||
}
|
||||
};
|
||||
TextDecorations GetTextDecorations(nsPresContext* aPresContext);
|
||||
|
||||
PRBool HasSelectionOverflowingDecorations(nsPresContext* aPresContext,
|
||||
float* aRatio = nsnull);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -142,10 +142,13 @@
|
|||
// This bit is set on frames that trimmed trailing whitespace characters when
|
||||
// calculating their width during reflow.
|
||||
#define TEXT_TRIMMED_TRAILING_WHITESPACE 0x01000000
|
||||
// Set this bit if the textframe has overflow area for IME/spellcheck underline.
|
||||
#define TEXT_SELECTION_UNDERLINE_OVERFLOWED 0x04000000
|
||||
|
||||
#define TEXT_REFLOW_FLAGS \
|
||||
(TEXT_FIRST_LETTER|TEXT_START_OF_LINE|TEXT_END_OF_LINE|TEXT_HYPHEN_BREAK| \
|
||||
TEXT_TRIMMED_TRAILING_WHITESPACE|TEXT_HAS_NONCOLLAPSED_CHARACTERS)
|
||||
TEXT_TRIMMED_TRAILING_WHITESPACE|TEXT_HAS_NONCOLLAPSED_CHARACTERS| \
|
||||
TEXT_SELECTION_UNDERLINE_OVERFLOWED)
|
||||
|
||||
// Cache bits for IsEmpty().
|
||||
// Set this bit if the textframe is known to be only collapsible whitespace.
|
||||
|
@ -1260,8 +1263,12 @@ GetSpacingFlags(const nsStyleCoord& aStyleCoord)
|
|||
}
|
||||
|
||||
static gfxFontGroup*
|
||||
GetFontGroupForFrame(nsIFrame* aFrame)
|
||||
GetFontGroupForFrame(nsIFrame* aFrame,
|
||||
nsIFontMetrics** aOutFontMetrics = nsnull)
|
||||
{
|
||||
if (aOutFontMetrics)
|
||||
*aOutFontMetrics = nsnull;
|
||||
|
||||
nsCOMPtr<nsIFontMetrics> metrics;
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(metrics));
|
||||
|
||||
|
@ -1269,6 +1276,10 @@ GetFontGroupForFrame(nsIFrame* aFrame)
|
|||
return nsnull;
|
||||
|
||||
nsIFontMetrics* metricsRaw = metrics;
|
||||
if (aOutFontMetrics) {
|
||||
*aOutFontMetrics = metricsRaw;
|
||||
NS_ADDREF(*aOutFontMetrics);
|
||||
}
|
||||
nsIThebesFontMetrics* fm = static_cast<nsIThebesFontMetrics*>(metricsRaw);
|
||||
// XXX this is a bit bogus, we're releasing 'metrics' so the returned font-group
|
||||
// might actually be torn down, although because of the way the device context
|
||||
|
@ -1326,7 +1337,7 @@ GetHyphenTextRun(gfxTextRun* aTextRun, gfxContext* aContext, nsTextFrame* aTextF
|
|||
}
|
||||
|
||||
static gfxFont::Metrics
|
||||
GetFontMetrics(gfxFontGroup* aFontGroup)
|
||||
GetFirstFontMetrics(gfxFontGroup* aFontGroup)
|
||||
{
|
||||
if (!aFontGroup)
|
||||
return gfxFont::Metrics();
|
||||
|
@ -1980,7 +1991,8 @@ public:
|
|||
const gfxSkipCharsIterator& aStart, PRInt32 aLength,
|
||||
nsIFrame* aLineContainer,
|
||||
nscoord aOffsetFromBlockOriginForTabs)
|
||||
: mTextRun(aTextRun), mFontGroup(nsnull), mTextStyle(aTextStyle), mFrag(aFrag),
|
||||
: mTextRun(aTextRun), mFontGroup(nsnull),
|
||||
mTextStyle(aTextStyle), mFrag(aFrag),
|
||||
mLineContainer(aLineContainer),
|
||||
mFrame(aFrame), mStart(aStart), mTempIterator(aStart),
|
||||
mTabWidths(nsnull), mLength(aLength),
|
||||
|
@ -2054,21 +2066,31 @@ public:
|
|||
const nsTextFragment* GetFragment() { return mFrag; }
|
||||
|
||||
gfxFontGroup* GetFontGroup() {
|
||||
if (!mFontGroup) {
|
||||
mFontGroup = GetFontGroupForFrame(mFrame);
|
||||
}
|
||||
if (!mFontGroup)
|
||||
InitFontGroupAndFontMetrics();
|
||||
return mFontGroup;
|
||||
}
|
||||
|
||||
nsIFontMetrics* GetFontMetrics() {
|
||||
if (!mFontMetrics)
|
||||
InitFontGroupAndFontMetrics();
|
||||
return mFontMetrics;
|
||||
}
|
||||
|
||||
gfxFloat* GetTabWidths(PRUint32 aTransformedStart, PRUint32 aTransformedLength);
|
||||
|
||||
const gfxSkipCharsIterator& GetEndHint() { return mTempIterator; }
|
||||
|
||||
protected:
|
||||
void SetupJustificationSpacing();
|
||||
|
||||
|
||||
void InitFontGroupAndFontMetrics() {
|
||||
mFontGroup = GetFontGroupForFrame(mFrame, getter_AddRefs(mFontMetrics));
|
||||
}
|
||||
|
||||
gfxTextRun* mTextRun;
|
||||
gfxFontGroup* mFontGroup;
|
||||
nsCOMPtr<nsIFontMetrics> mFontMetrics;
|
||||
const nsStyleText* mTextStyle;
|
||||
const nsTextFragment* mFrag;
|
||||
nsIFrame* mLineContainer;
|
||||
|
@ -2299,7 +2321,8 @@ PropertyProvider::GetTabWidths(PRUint32 aStart, PRUint32 aLength)
|
|||
// Round the space width when converting to appunits the same way
|
||||
// textruns do
|
||||
gfxFloat spaceWidthAppUnits =
|
||||
NS_roundf(GetFontMetrics(GetFontGroupForFrame(mLineContainer)).spaceWidth*
|
||||
NS_roundf(GetFirstFontMetrics(
|
||||
GetFontGroupForFrame(mLineContainer)).spaceWidth *
|
||||
mTextRun->GetAppUnitsPerDevUnit());
|
||||
gfxFloat tabWidth = 8*spaceWidthAppUnits;
|
||||
for (PRUint32 i = tabsEnd; i < aStart + aLength; ++i) {
|
||||
|
@ -3645,26 +3668,19 @@ nsTextFrame::GetTextDecorations(nsPresContext* aPresContext)
|
|||
}
|
||||
|
||||
void
|
||||
nsTextFrame::UnionTextDecorationOverflow(
|
||||
nsPresContext* aPresContext,
|
||||
const gfxTextRun::Metrics& aTextMetrics,
|
||||
nsRect* aOverflowRect)
|
||||
nsTextFrame::UnionTextDecorationOverflow(nsPresContext* aPresContext,
|
||||
nsRect* aOverflowRect)
|
||||
{
|
||||
NS_ASSERTION(mTextRun, "mTextRun is null");
|
||||
nsRect rect;
|
||||
TextDecorations decorations = GetTextDecorations(aPresContext);
|
||||
float ratio = 1.0f;
|
||||
// Note that we need to add underline area when this frame has selection for
|
||||
// spellchecking and IME.
|
||||
if (mState & NS_FRAME_SELECTED_CONTENT) {
|
||||
nsILookAndFeel* look = aPresContext->LookAndFeel();
|
||||
look->GetMetric(nsILookAndFeel::eMetricFloat_IMEUnderlineRelativeSize,
|
||||
ratio);
|
||||
decorations.mDecorations |= NS_STYLE_TEXT_DECORATION_UNDERLINE;
|
||||
}
|
||||
nsLineLayout::CombineTextDecorations(aPresContext, decorations.mDecorations,
|
||||
this, *aOverflowRect, NSToCoordRound(aTextMetrics.mAscent),
|
||||
ratio);
|
||||
// When this frame is not selected, the text-decoration area must be in
|
||||
// frame bounds.
|
||||
float ratio;
|
||||
if (!HasSelectionOverflowingDecorations(aPresContext, &ratio))
|
||||
return;
|
||||
|
||||
nsLineLayout::CombineTextDecorations(aPresContext,
|
||||
NS_STYLE_TEXT_DECORATION_UNDERLINE,
|
||||
this, *aOverflowRect, mAscent, ratio);
|
||||
AddStateBits(TEXT_SELECTION_UNDERLINE_OVERFLOWED);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4318,6 +4334,26 @@ nsTextFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint) {
|
|||
return offsets;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTextFrame::HasSelectionOverflowingDecorations(nsPresContext* aPresContext,
|
||||
float* aRatio)
|
||||
{
|
||||
float ratio;
|
||||
nsILookAndFeel* look = aPresContext->LookAndFeel();
|
||||
look->GetMetric(nsILookAndFeel::eMetricFloat_IMEUnderlineRelativeSize, ratio);
|
||||
if (aRatio)
|
||||
*aRatio = ratio;
|
||||
if (ratio <= 1.0f)
|
||||
return PR_FALSE;
|
||||
|
||||
for (SelectionDetails *sd = GetSelectionDetails(); sd; sd = sd->mNext) {
|
||||
if (sd->mStart != sd->mEnd &&
|
||||
sd->mType & SelectionTypesWithDecorations)
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//null range means the whole thing
|
||||
NS_IMETHODIMP
|
||||
nsTextFrame::SetSelected(nsPresContext* aPresContext,
|
||||
|
@ -4387,7 +4423,6 @@ nsTextFrame::SetSelected(nsPresContext* aPresContext,
|
|||
found = PR_TRUE;
|
||||
}
|
||||
|
||||
nsFrameState oldState = mState;
|
||||
if ( aSelected )
|
||||
AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
else
|
||||
|
@ -4400,16 +4435,14 @@ nsTextFrame::SetSelected(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
if (found) {
|
||||
// If the selection state is changed, we need to reflow to recompute
|
||||
// the overflow area for underline of spellchecking or IME. However, if
|
||||
// the non-selected text already has underline, we don't need to reflow.
|
||||
// And also when the IME underline is thicker than normal underline.
|
||||
nsILookAndFeel* look = aPresContext->LookAndFeel();
|
||||
float ratio;
|
||||
look->GetMetric(nsILookAndFeel::eMetricFloat_IMEUnderlineRelativeSize,
|
||||
ratio);
|
||||
if (oldState != mState &&
|
||||
(ratio > 1.0 || !GetTextDecorations(aPresContext).HasUnderline())) {
|
||||
// If the selection state is changed in this content, we need to reflow
|
||||
// to recompute the overflow area for underline of spellchecking or IME if
|
||||
// their underline is thicker than normal decoration line.
|
||||
PRBool didHaveSelectionUnderline =
|
||||
!!(mState & TEXT_SELECTION_UNDERLINE_OVERFLOWED);
|
||||
PRBool willHaveSelectionUnderline =
|
||||
aSelected && HasSelectionOverflowingDecorations(PresContext());
|
||||
if (didHaveSelectionUnderline != willHaveSelectionUnderline) {
|
||||
PresContext()->PresShell()->FrameNeedsReflow(this,
|
||||
nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
|
@ -5533,12 +5566,21 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
textMetrics.mAscent = PR_MAX(0, -textMetrics.mBoundingBox.Y());
|
||||
textMetrics.mDescent = PR_MAX(0, textMetrics.mBoundingBox.YMost());
|
||||
}
|
||||
|
||||
|
||||
// Setup metrics for caller
|
||||
// Disallow negative widths
|
||||
aMetrics.width = NSToCoordCeil(PR_MAX(0, textMetrics.mAdvanceWidth));
|
||||
aMetrics.ascent = NSToCoordCeil(textMetrics.mAscent);
|
||||
aMetrics.height = aMetrics.ascent + NSToCoordCeil(textMetrics.mDescent);
|
||||
|
||||
// nsIFontMetrics::GetMaxAscent and nsIFontMetrics::GetMaxDescent return
|
||||
// the decoration lines drawable size when the font-size is not zero.
|
||||
nscoord minAscent, minDescent;
|
||||
nsIFontMetrics* fm = provider.GetFontMetrics();
|
||||
fm->GetMaxAscent(minAscent);
|
||||
fm->GetMaxDescent(minDescent);
|
||||
aMetrics.ascent = PR_MAX(NSToCoordCeil(textMetrics.mAscent), minAscent);
|
||||
nscoord descent = PR_MAX(NSToCoordCeil(textMetrics.mDescent), minDescent);
|
||||
|
||||
aMetrics.height = aMetrics.ascent + descent;
|
||||
NS_ASSERTION(aMetrics.ascent >= 0, "Negative ascent???");
|
||||
NS_ASSERTION(aMetrics.height - aMetrics.ascent >= 0, "Negative descent???");
|
||||
|
||||
|
@ -5546,12 +5588,11 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
|
||||
// Handle text that runs outside its normal bounds.
|
||||
nsRect boundingBox =
|
||||
ConvertGfxRectOutward(textMetrics.mBoundingBox + gfxPoint(0, textMetrics.mAscent));
|
||||
ConvertGfxRectOutward(textMetrics.mBoundingBox + gfxPoint(0, mAscent));
|
||||
aMetrics.mOverflowArea.UnionRect(boundingBox,
|
||||
nsRect(0, 0, aMetrics.width, aMetrics.height));
|
||||
|
||||
UnionTextDecorationOverflow(aPresContext, textMetrics,
|
||||
&aMetrics.mOverflowArea);
|
||||
UnionTextDecorationOverflow(aPresContext, &aMetrics.mOverflowArea);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Clean up, update state
|
||||
|
@ -5772,11 +5813,11 @@ nsTextFrame::RecomputeOverflowRect()
|
|||
&provider);
|
||||
|
||||
nsRect boundingBox =
|
||||
ConvertGfxRectOutward(textMetrics.mBoundingBox + gfxPoint(0, textMetrics.mAscent));
|
||||
ConvertGfxRectOutward(textMetrics.mBoundingBox + gfxPoint(0, mAscent));
|
||||
boundingBox.UnionRect(boundingBox,
|
||||
nsRect(nsPoint(0,0), GetSize()));
|
||||
|
||||
UnionTextDecorationOverflow(PresContext(), textMetrics, &boundingBox);
|
||||
UnionTextDecorationOverflow(PresContext(), &boundingBox);
|
||||
|
||||
return boundingBox;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
fails-if(MOZ_WIDGET_TOOLKIT=="windows") == z-index-1.html z-index-1-ref.html # bug 388744
|
||||
== z-index-1.html z-index-1-ref.html
|
||||
|
|
|
@ -1517,10 +1517,18 @@ nsStyleTextReset::~nsStyleTextReset(void) { }
|
|||
|
||||
nsChangeHint nsStyleTextReset::CalcDifference(const nsStyleTextReset& aOther) const
|
||||
{
|
||||
if (mVerticalAlign == aOther.mVerticalAlign &&
|
||||
mUnicodeBidi == aOther.mUnicodeBidi &&
|
||||
mTextDecoration == aOther.mTextDecoration)
|
||||
if (mVerticalAlign == aOther.mVerticalAlign
|
||||
&& mUnicodeBidi == aOther.mUnicodeBidi) {
|
||||
if (mTextDecoration != aOther.mTextDecoration) {
|
||||
// Reflow for blink changes, repaint for others
|
||||
return
|
||||
(mTextDecoration & NS_STYLE_TEXT_DECORATION_BLINK) ==
|
||||
(aOther.mTextDecoration & NS_STYLE_TEXT_DECORATION_BLINK) ?
|
||||
NS_STYLE_HINT_VISUAL : NS_STYLE_HINT_REFLOW;
|
||||
}
|
||||
|
||||
return NS_STYLE_HINT_NONE;
|
||||
}
|
||||
return NS_STYLE_HINT_REFLOW;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче