зеркало из https://github.com/mozilla/pjs.git
merge
This commit is contained in:
Коммит
ee3abc1a8f
|
@ -285,11 +285,43 @@ inline nscoord NSToCoordFloor(float aValue)
|
|||
return nscoord(NS_floorf(aValue));
|
||||
}
|
||||
|
||||
inline nscoord NSToCoordFloorClamped(float aValue)
|
||||
{
|
||||
#ifndef NS_COORD_IS_FLOAT
|
||||
// Bounds-check before converting out of float, to avoid overflow
|
||||
if (aValue >= nscoord_MAX) {
|
||||
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord");
|
||||
return nscoord_MAX;
|
||||
}
|
||||
if (aValue <= nscoord_MIN) {
|
||||
NS_WARNING("Overflowed nscoord_MIN in conversion to nscoord");
|
||||
return nscoord_MIN;
|
||||
}
|
||||
#endif
|
||||
return NSToCoordFloor(aValue);
|
||||
}
|
||||
|
||||
inline nscoord NSToCoordCeil(float aValue)
|
||||
{
|
||||
return nscoord(NS_ceilf(aValue));
|
||||
}
|
||||
|
||||
inline nscoord NSToCoordCeilClamped(float aValue)
|
||||
{
|
||||
#ifndef NS_COORD_IS_FLOAT
|
||||
// Bounds-check before converting out of float, to avoid overflow
|
||||
if (aValue >= nscoord_MAX) {
|
||||
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord");
|
||||
return nscoord_MAX;
|
||||
}
|
||||
if (aValue <= nscoord_MIN) {
|
||||
NS_WARNING("Overflowed nscoord_MIN in conversion to nscoord");
|
||||
return nscoord_MIN;
|
||||
}
|
||||
#endif
|
||||
return NSToCoordCeil(aValue);
|
||||
}
|
||||
|
||||
inline nscoord NSToCoordRound(float aValue)
|
||||
{
|
||||
#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
|
||||
|
@ -299,6 +331,22 @@ inline nscoord NSToCoordRound(float aValue)
|
|||
#endif /* XP_WIN32 && _M_IX86 && !__GNUC__ */
|
||||
}
|
||||
|
||||
inline nscoord NSToCoordRoundWithClamp(float aValue)
|
||||
{
|
||||
#ifndef NS_COORD_IS_FLOAT
|
||||
// Bounds-check before converting out of float, to avoid overflow
|
||||
if (aValue >= nscoord_MAX) {
|
||||
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord");
|
||||
return nscoord_MAX;
|
||||
}
|
||||
if (aValue <= nscoord_MIN) {
|
||||
NS_WARNING("Overflowed nscoord_MIN in conversion to nscoord");
|
||||
return nscoord_MIN;
|
||||
}
|
||||
#endif
|
||||
return NSToCoordRound(aValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Int Rounding Functions
|
||||
*/
|
||||
|
@ -322,27 +370,7 @@ inline PRInt32 NSToIntRound(float aValue)
|
|||
*/
|
||||
inline nscoord NSFloatPixelsToAppUnits(float aPixels, float aAppUnitsPerPixel)
|
||||
{
|
||||
float product = aPixels * aAppUnitsPerPixel;
|
||||
nscoord result;
|
||||
|
||||
#ifdef NS_COORD_IS_FLOAT
|
||||
// No need to bounds-check if converting float to float
|
||||
result = NSToCoordRound(product);
|
||||
#else
|
||||
// Bounds-check before converting out of float, to avoid overflow
|
||||
if (product >= nscoord_MAX) {
|
||||
NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord");
|
||||
result = nscoord_MAX;
|
||||
} else if (product <= nscoord_MIN) {
|
||||
NS_WARNING("Overflowed nscoord_MIN in conversion to nscoord");
|
||||
result = nscoord_MIN;
|
||||
} else {
|
||||
result = NSToCoordRound(product);
|
||||
}
|
||||
#endif
|
||||
|
||||
VERIFY_COORD(result);
|
||||
return result;
|
||||
return NSToCoordRoundWithClamp(aPixels * aAppUnitsPerPixel);
|
||||
}
|
||||
|
||||
inline nscoord NSIntPixelsToAppUnits(PRInt32 aPixels, PRInt32 aAppUnitsPerPixel)
|
||||
|
|
|
@ -1425,6 +1425,9 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
|||
NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus);
|
||||
}
|
||||
|
||||
// Screen out negative heights --- can happen due to integer overflows :-(
|
||||
aMetrics.height = PR_MAX(0, aMetrics.height);
|
||||
|
||||
#ifdef DEBUG_blocks
|
||||
if (CRAZY_WIDTH(aMetrics.width) || CRAZY_HEIGHT(aMetrics.height)) {
|
||||
ListTag(stdout);
|
||||
|
|
|
@ -714,6 +714,14 @@ public:
|
|||
aCapitalize, mContext);
|
||||
}
|
||||
|
||||
void Finish() {
|
||||
if (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_IS_TRANSFORMED) {
|
||||
nsTransformedTextRun* transformedTextRun =
|
||||
static_cast<nsTransformedTextRun*>(mTextRun);
|
||||
transformedTextRun->FinishSettingProperties(mContext);
|
||||
}
|
||||
}
|
||||
|
||||
gfxTextRun* mTextRun;
|
||||
gfxContext* mContext;
|
||||
PRUint32 mOffsetIntoTextRun;
|
||||
|
@ -776,10 +784,32 @@ TextContainsLineBreakerWhiteSpace(const void* aText, PRUint32 aLength,
|
|||
}
|
||||
|
||||
struct FrameTextTraversal {
|
||||
nsIFrame* mFrameToDescendInto;
|
||||
PRPackedBool mDescendIntoFrameSiblings;
|
||||
// These fields identify which frames should be recursively scanned
|
||||
// The first normal frame to scan (or null, if no such frame should be scanned)
|
||||
nsIFrame* mFrameToScan;
|
||||
// The first overflow frame to scan (or null, if no such frame should be scanned)
|
||||
nsIFrame* mOverflowFrameToScan;
|
||||
// Whether to scan the siblings of mFrameToDescendInto/mOverflowFrameToDescendInto
|
||||
PRPackedBool mScanSiblings;
|
||||
|
||||
// These identify the boundaries of the context required for
|
||||
// line breaking or textrun construction
|
||||
PRPackedBool mLineBreakerCanCrossFrameBoundary;
|
||||
PRPackedBool mTextRunCanCrossFrameBoundary;
|
||||
|
||||
nsIFrame* NextFrameToScan() {
|
||||
nsIFrame* f;
|
||||
if (mFrameToScan) {
|
||||
f = mFrameToScan;
|
||||
mFrameToScan = mScanSiblings ? f->GetNextSibling() : nsnull;
|
||||
} else if (mOverflowFrameToScan) {
|
||||
f = mOverflowFrameToScan;
|
||||
mOverflowFrameToScan = mScanSiblings ? f->GetNextSibling() : nsnull;
|
||||
} else {
|
||||
f = nsnull;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
static FrameTextTraversal
|
||||
|
@ -794,28 +824,33 @@ CanTextCrossFrameBoundary(nsIFrame* aFrame, nsIAtom* aType)
|
|||
// placeholders are "invisible", so a text run should be able to span
|
||||
// across one. But don't descend into the out-of-flow.
|
||||
result.mLineBreakerCanCrossFrameBoundary = PR_TRUE;
|
||||
result.mOverflowFrameToScan = nsnull;
|
||||
if (continuesTextRun) {
|
||||
// ... Except for first-letter floats, which are really in-flow
|
||||
// from the point of view of capitalization etc, so we'd better
|
||||
// descend into them. But we actually need to break the textrun for
|
||||
// first-letter floats since things look bad if, say, we try to make a
|
||||
// ligature across the float boundary.
|
||||
result.mFrameToDescendInto =
|
||||
result.mFrameToScan =
|
||||
(static_cast<nsPlaceholderFrame*>(aFrame))->GetOutOfFlowFrame();
|
||||
result.mDescendIntoFrameSiblings = PR_FALSE;
|
||||
result.mScanSiblings = PR_FALSE;
|
||||
result.mTextRunCanCrossFrameBoundary = PR_FALSE;
|
||||
} else {
|
||||
result.mFrameToDescendInto = nsnull;
|
||||
result.mFrameToScan = nsnull;
|
||||
result.mTextRunCanCrossFrameBoundary = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
if (continuesTextRun) {
|
||||
result.mFrameToDescendInto = aFrame->GetFirstChild(nsnull);
|
||||
result.mDescendIntoFrameSiblings = PR_TRUE;
|
||||
result.mFrameToScan = aFrame->GetFirstChild(nsnull);
|
||||
result.mOverflowFrameToScan = aFrame->GetFirstChild(nsGkAtoms::overflowList);
|
||||
NS_WARN_IF_FALSE(!result.mOverflowFrameToScan,
|
||||
"Scanning overflow inline frames is something we should avoid");
|
||||
result.mScanSiblings = PR_TRUE;
|
||||
result.mTextRunCanCrossFrameBoundary = PR_TRUE;
|
||||
result.mLineBreakerCanCrossFrameBoundary = PR_TRUE;
|
||||
} else {
|
||||
result.mFrameToDescendInto = nsnull;
|
||||
result.mFrameToScan = nsnull;
|
||||
result.mOverflowFrameToScan = nsnull;
|
||||
result.mTextRunCanCrossFrameBoundary = PR_FALSE;
|
||||
result.mLineBreakerCanCrossFrameBoundary = PR_FALSE;
|
||||
}
|
||||
|
@ -871,13 +906,11 @@ BuildTextRunsScanner::FindBoundaries(nsIFrame* aFrame, FindBoundaryState* aState
|
|||
return FB_FOUND_VALID_TEXTRUN_BOUNDARY;
|
||||
}
|
||||
|
||||
for (nsIFrame* f = traversal.mFrameToDescendInto; f;
|
||||
f = f->GetNextSibling()) {
|
||||
for (nsIFrame* f = traversal.NextFrameToScan(); f;
|
||||
f = traversal.NextFrameToScan()) {
|
||||
FindBoundaryResult result = FindBoundaries(f, aState);
|
||||
if (result != FB_CONTINUE)
|
||||
return result;
|
||||
if (!traversal.mDescendIntoFrameSiblings)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!traversal.mTextRunCanCrossFrameBoundary) {
|
||||
|
@ -1129,6 +1162,7 @@ void BuildTextRunsScanner::FlushFrames(PRBool aFlushLineBreaks, PRBool aSuppress
|
|||
// TODO cause frames associated with the textrun to be reflowed, if they
|
||||
// aren't being reflowed already!
|
||||
}
|
||||
mBreakSinks[i]->Finish();
|
||||
}
|
||||
mBreakSinks.Clear();
|
||||
}
|
||||
|
@ -1285,11 +1319,9 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame)
|
|||
FlushFrames(PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
for (nsIFrame* f = traversal.mFrameToDescendInto; f;
|
||||
f = f->GetNextSibling()) {
|
||||
for (nsIFrame* f = traversal.NextFrameToScan(); f;
|
||||
f = traversal.NextFrameToScan()) {
|
||||
ScanFrame(f);
|
||||
if (!traversal.mDescendIntoFrameSiblings)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!traversal.mLineBreakerCanCrossFrameBoundary) {
|
||||
|
@ -4769,7 +4801,7 @@ nsTextFrame::GetPointFromOffset(PRInt32 inOffset,
|
|||
mTextRun->GetAdvanceWidth(properties.GetStart().GetSkippedOffset(),
|
||||
GetSkippedDistance(properties.GetStart(), iter),
|
||||
&properties);
|
||||
nscoord width = NSToCoordCeil(advanceWidth);
|
||||
nscoord width = NSToCoordCeilClamped(advanceWidth);
|
||||
|
||||
if (mTextRun->IsRightToLeft()) {
|
||||
outPoint->x = mRect.width - width;
|
||||
|
@ -5292,8 +5324,8 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext,
|
|||
|
||||
if (i > wordStart) {
|
||||
nscoord width =
|
||||
NSToCoordCeil(mTextRun->GetAdvanceWidth(wordStart, i - wordStart, &provider));
|
||||
aData->currentLine += width;
|
||||
NSToCoordCeilClamped(mTextRun->GetAdvanceWidth(wordStart, i - wordStart, &provider));
|
||||
aData->currentLine = NSCoordSaturatingAdd(aData->currentLine, width);
|
||||
aData->atStartOfLine = PR_FALSE;
|
||||
|
||||
if (collapseWhitespace) {
|
||||
|
@ -5305,7 +5337,7 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext,
|
|||
} else {
|
||||
// Some non-whitespace so the old trailingWhitespace is no longer trailing
|
||||
aData->trailingWhitespace =
|
||||
NSToCoordCeil(mTextRun->GetAdvanceWidth(trimStart, i - trimStart, &provider));
|
||||
NSToCoordCeilClamped(mTextRun->GetAdvanceWidth(trimStart, i - trimStart, &provider));
|
||||
}
|
||||
} else {
|
||||
aData->trailingWhitespace = 0;
|
||||
|
@ -5414,7 +5446,7 @@ nsTextFrame::AddInlinePrefWidthForFlow(nsIRenderingContext *aRenderingContext,
|
|||
|
||||
if (i > lineStart) {
|
||||
nscoord width =
|
||||
NSToCoordCeil(mTextRun->GetAdvanceWidth(lineStart, i - lineStart, &provider));
|
||||
NSToCoordCeilClamped(mTextRun->GetAdvanceWidth(lineStart, i - lineStart, &provider));
|
||||
aData->currentLine = NSCoordSaturatingAdd(aData->currentLine, width);
|
||||
|
||||
if (collapseWhitespace) {
|
||||
|
@ -5426,7 +5458,7 @@ nsTextFrame::AddInlinePrefWidthForFlow(nsIRenderingContext *aRenderingContext,
|
|||
} else {
|
||||
// Some non-whitespace so the old trailingWhitespace is no longer trailing
|
||||
aData->trailingWhitespace =
|
||||
NSToCoordCeil(mTextRun->GetAdvanceWidth(trimStart, i - trimStart, &provider));
|
||||
NSToCoordCeilClamped(mTextRun->GetAdvanceWidth(trimStart, i - trimStart, &provider));
|
||||
}
|
||||
} else {
|
||||
aData->trailingWhitespace = 0;
|
||||
|
|
|
@ -72,7 +72,7 @@ nsTransformedTextRun::SetCapitalization(PRUint32 aStart, PRUint32 aLength,
|
|||
memset(mCapitalize.Elements(), 0, GetLength()*sizeof(PRPackedBool));
|
||||
}
|
||||
memcpy(mCapitalize.Elements() + aStart, aCapitalization, aLength*sizeof(PRPackedBool));
|
||||
mFactory->RebuildTextRun(this, aRefContext);
|
||||
mNeedsRebuild = PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -82,76 +82,20 @@ nsTransformedTextRun::SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength,
|
|||
{
|
||||
PRBool changed = gfxTextRun::SetPotentialLineBreaks(aStart, aLength,
|
||||
aBreakBefore, aRefContext);
|
||||
mFactory->RebuildTextRun(this, aRefContext);
|
||||
if (changed) {
|
||||
mNeedsRebuild = PR_TRUE;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTransformedTextRun::SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
|
||||
PRBool aLineBreakBefore, PRBool aLineBreakAfter,
|
||||
gfxFloat* aAdvanceWidthDelta,
|
||||
gfxContext* aRefContext)
|
||||
{
|
||||
nsTArray<PRUint32> newBreaks;
|
||||
PRUint32 i;
|
||||
PRBool changed = PR_FALSE;
|
||||
for (i = 0; i < mLineBreaks.Length(); ++i) {
|
||||
PRUint32 pos = mLineBreaks[i];
|
||||
if (pos >= aStart)
|
||||
break;
|
||||
newBreaks.AppendElement(pos);
|
||||
}
|
||||
if (aLineBreakBefore != (i < mLineBreaks.Length() &&
|
||||
mLineBreaks[i] == aStart)) {
|
||||
changed = PR_TRUE;
|
||||
}
|
||||
if (aLineBreakBefore) {
|
||||
nsTextFrameUtils::AppendLineBreakOffset(&newBreaks, aStart);
|
||||
}
|
||||
if (aLineBreakAfter != (i + 1 < mLineBreaks.Length() &&
|
||||
mLineBreaks[i + 1] == aStart + aLength)) {
|
||||
changed = PR_TRUE;
|
||||
}
|
||||
if (aLineBreakAfter) {
|
||||
nsTextFrameUtils::AppendLineBreakOffset(&newBreaks, aStart + aLength);
|
||||
}
|
||||
for (; i < mLineBreaks.Length(); ++i) {
|
||||
if (mLineBreaks[i] > aStart + aLength)
|
||||
break;
|
||||
changed = PR_TRUE;
|
||||
}
|
||||
if (!changed) {
|
||||
if (aAdvanceWidthDelta) {
|
||||
*aAdvanceWidthDelta = 0;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
newBreaks.AppendElements(mLineBreaks.Elements() + i, mLineBreaks.Length() - i);
|
||||
mLineBreaks.SwapElements(newBreaks);
|
||||
|
||||
gfxFloat currentAdvance = GetAdvanceWidth(aStart, aLength, nsnull);
|
||||
mFactory->RebuildTextRun(this, aRefContext);
|
||||
if (aAdvanceWidthDelta) {
|
||||
*aAdvanceWidthDelta = GetAdvanceWidth(aStart, aLength, nsnull) - currentAdvance;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
gfxTextRun*
|
||||
nsTransformingTextRunFactory::MakeTextRun(const PRUnichar* aString, PRUint32 aLength,
|
||||
const gfxTextRunFactory::Parameters* aParams,
|
||||
gfxFontGroup* aFontGroup, PRUint32 aFlags,
|
||||
nsStyleContext** aStyles, PRBool aOwnsFactory)
|
||||
{
|
||||
nsTransformedTextRun* textRun =
|
||||
nsTransformedTextRun::Create(aParams, this, aFontGroup,
|
||||
aString, aLength, aFlags, aStyles, aOwnsFactory);
|
||||
if (!textRun)
|
||||
return nsnull;
|
||||
|
||||
RebuildTextRun(textRun, aParams->mContext);
|
||||
return textRun;
|
||||
return nsTransformedTextRun::Create(aParams, this, aFontGroup,
|
||||
aString, aLength, aFlags, aStyles, aOwnsFactory);
|
||||
}
|
||||
|
||||
gfxTextRun*
|
||||
|
@ -271,7 +215,7 @@ GetParametersForInner(nsTransformedTextRun* aTextRun, PRUint32* aFlags,
|
|||
{
|
||||
gfxTextRunFactory::Parameters params =
|
||||
{ aRefContext, nsnull, nsnull,
|
||||
nsnull, nsnull, aTextRun->GetAppUnitsPerDevUnit()
|
||||
nsnull, 0, aTextRun->GetAppUnitsPerDevUnit()
|
||||
};
|
||||
*aFlags = aTextRun->GetFlags() & ~gfxFontGroup::TEXT_IS_PERSISTENT;
|
||||
return params;
|
||||
|
@ -313,17 +257,9 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
PRBool runIsLowercase = PR_FALSE;
|
||||
nsAutoTArray<nsStyleContext*,50> styleArray;
|
||||
nsAutoTArray<PRPackedBool,50> canBreakBeforeArray;
|
||||
nsAutoTArray<PRUint32,10> lineBreakBeforeArray;
|
||||
|
||||
PRUint32 nextLineBreak = 0;
|
||||
PRUint32 i;
|
||||
for (i = 0; i <= length; ++i) {
|
||||
if (nextLineBreak < aTextRun->mLineBreaks.Length() &&
|
||||
aTextRun->mLineBreaks[nextLineBreak] == i) {
|
||||
lineBreakBeforeArray.AppendElement(i - runStart);
|
||||
++nextLineBreak;
|
||||
}
|
||||
|
||||
PRBool isLowercase = PR_FALSE;
|
||||
if (i < length) {
|
||||
// Characters that aren't the start of a cluster are ignored here. They
|
||||
|
@ -346,9 +282,7 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
nsAutoPtr<gfxTextRun> transformedChild;
|
||||
gfxTextRunCache::AutoTextRun cachedChild;
|
||||
gfxTextRun* child;
|
||||
// Setup actual line break data for child (which may affect shaping)
|
||||
innerParams.mInitialBreaks = lineBreakBeforeArray.Elements();
|
||||
innerParams.mInitialBreakCount = lineBreakBeforeArray.Length();
|
||||
|
||||
if (runIsLowercase) {
|
||||
transformedChild = uppercaseFactory.MakeTextRun(str + runStart, i - runStart,
|
||||
&innerParams, smallFont, flags, styleArray.Elements(), PR_FALSE);
|
||||
|
@ -372,10 +306,6 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
runStart = i;
|
||||
styleArray.Clear();
|
||||
canBreakBeforeArray.Clear();
|
||||
lineBreakBeforeArray.Clear();
|
||||
if (nextLineBreak > 0 && aTextRun->mLineBreaks[nextLineBreak - 1] == i) {
|
||||
lineBreakBeforeArray.AppendElement(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (i < length) {
|
||||
|
@ -384,8 +314,6 @@ nsFontVariantTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
canBreakBeforeArray.AppendElement(aTextRun->CanBreakLineBefore(i));
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(nextLineBreak == aTextRun->mLineBreaks.Length(),
|
||||
"lost track of line breaks somehow");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -404,8 +332,6 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
nsAutoTArray<PRPackedBool,50> charsToMergeArray;
|
||||
nsAutoTArray<nsStyleContext*,50> styleArray;
|
||||
nsAutoTArray<PRPackedBool,50> canBreakBeforeArray;
|
||||
nsAutoTArray<PRUint32,10> lineBreakBeforeArray;
|
||||
PRUint32 nextLineBreak = 0;
|
||||
PRUint32 extraCharsCount = 0;
|
||||
|
||||
PRUint32 i;
|
||||
|
@ -415,11 +341,6 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
charsToMergeArray.AppendElement(PR_FALSE);
|
||||
styleArray.AppendElement(styles[i]);
|
||||
canBreakBeforeArray.AppendElement(aTextRun->CanBreakLineBefore(i));
|
||||
if (nextLineBreak < aTextRun->mLineBreaks.Length() &&
|
||||
aTextRun->mLineBreaks[nextLineBreak] == i) {
|
||||
lineBreakBeforeArray.AppendElement(i + extraCharsCount);
|
||||
++nextLineBreak;
|
||||
}
|
||||
|
||||
PRUint8 style = mAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE
|
||||
: styles[i]->GetStyleText()->mTextTransform;
|
||||
|
@ -461,13 +382,6 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
canBreakBeforeArray.AppendElement(PR_FALSE);
|
||||
}
|
||||
}
|
||||
if (nextLineBreak < aTextRun->mLineBreaks.Length() &&
|
||||
aTextRun->mLineBreaks[nextLineBreak] == length) {
|
||||
lineBreakBeforeArray.AppendElement(length + extraCharsCount);
|
||||
++nextLineBreak;
|
||||
}
|
||||
NS_ASSERTION(nextLineBreak == aTextRun->mLineBreaks.Length(),
|
||||
"lost track of line breaks somehow");
|
||||
|
||||
PRUint32 flags;
|
||||
gfxTextRunFactory::Parameters innerParams =
|
||||
|
@ -477,9 +391,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||
nsAutoPtr<gfxTextRun> transformedChild;
|
||||
gfxTextRunCache::AutoTextRun cachedChild;
|
||||
gfxTextRun* child;
|
||||
// Setup actual line break data for child (which may affect shaping)
|
||||
innerParams.mInitialBreaks = lineBreakBeforeArray.Elements();
|
||||
innerParams.mInitialBreakCount = lineBreakBeforeArray.Length();
|
||||
|
||||
if (mInnerTransformingTextRunFactory) {
|
||||
transformedChild = mInnerTransformingTextRunFactory->MakeTextRun(
|
||||
convertedString.BeginReading(), convertedString.Length(),
|
||||
|
|
|
@ -113,22 +113,30 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void SetCapitalization(PRUint32 aStart, PRUint32 aLength,
|
||||
PRPackedBool* aCapitalization,
|
||||
gfxContext* aRefContext);
|
||||
void SetCapitalization(PRUint32 aStart, PRUint32 aLength,
|
||||
PRPackedBool* aCapitalization,
|
||||
gfxContext* aRefContext);
|
||||
virtual PRBool SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength,
|
||||
PRPackedBool* aBreakBefore,
|
||||
gfxContext* aRefContext);
|
||||
virtual PRBool SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
|
||||
PRBool aLineBreakBefore, PRBool aLineBreakAfter,
|
||||
gfxFloat* aAdvanceWidthDelta,
|
||||
gfxContext* aRefContext);
|
||||
/**
|
||||
* Called after SetCapitalization and SetPotentialLineBreaks
|
||||
* are done and before we request any data from the textrun. Also always
|
||||
* called after a Create.
|
||||
*/
|
||||
void FinishSettingProperties(gfxContext* aRefContext)
|
||||
{
|
||||
if (mNeedsRebuild) {
|
||||
mNeedsRebuild = PR_FALSE;
|
||||
mFactory->RebuildTextRun(this, aRefContext);
|
||||
}
|
||||
}
|
||||
|
||||
nsTransformingTextRunFactory *mFactory;
|
||||
nsTArray<PRUint32> mLineBreaks;
|
||||
nsTArray<nsRefPtr<nsStyleContext> > mStyles;
|
||||
nsTArray<PRPackedBool> mCapitalize;
|
||||
PRPackedBool mOwnsFactory;
|
||||
PRPackedBool mNeedsRebuild;
|
||||
|
||||
private:
|
||||
nsTransformedTextRun(const gfxTextRunFactory::Parameters* aParams,
|
||||
|
@ -138,15 +146,12 @@ private:
|
|||
const PRUint32 aFlags, nsStyleContext** aStyles,
|
||||
PRBool aOwnsFactory)
|
||||
: gfxTextRun(aParams, aString, aLength, aFontGroup, aFlags, sizeof(nsTransformedTextRun)),
|
||||
mFactory(aFactory), mOwnsFactory(aOwnsFactory)
|
||||
mFactory(aFactory), mOwnsFactory(aOwnsFactory), mNeedsRebuild(PR_TRUE)
|
||||
{
|
||||
PRUint32 i;
|
||||
for (i = 0; i < aLength; ++i) {
|
||||
mStyles.AppendElement(aStyles[i]);
|
||||
}
|
||||
for (i = 0; i < aParams->mInitialBreakCount; ++i) {
|
||||
mLineBreaks.AppendElement(aParams->mInitialBreaks[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body style="font-family: monospace; white-space:pre;">aa
|
||||
aa
|
||||
a<b>a a</b></body>
|
||||
</html>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body style="font-family: monospace; width: 4.1ch;">aa aa a<b>a a</b></body>
|
||||
</html>
|
|
@ -946,6 +946,7 @@ fails == 441259-2.html 441259-2-ref.html # bug 441400
|
|||
== 455105-2.html 455105-ref.html
|
||||
== 455171-5.html 455171-5-ref.html
|
||||
== 455280-1.xhtml 455280-1-ref.xhtml
|
||||
== 455826-1.html 455826-1-ref.html
|
||||
fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 456147.xul 456147-ref.html # bug 456147, but not caused by it
|
||||
== 456330-1.gif 456330-1-ref.png
|
||||
== 456484-1.html 456484-1-ref.html
|
||||
|
|
|
@ -195,11 +195,11 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
|||
}
|
||||
switch (unit) {
|
||||
case eCSSUnit_EM: {
|
||||
return NSToCoordRound(aValue.GetFloatValue() * float(aFontSize));
|
||||
return NSToCoordRoundWithClamp(aValue.GetFloatValue() * float(aFontSize));
|
||||
// XXX scale against font metrics height instead?
|
||||
}
|
||||
case eCSSUnit_EN: {
|
||||
return NSToCoordRound((aValue.GetFloatValue() * float(aFontSize)) / 2.0f);
|
||||
return NSToCoordRoundWithClamp((aValue.GetFloatValue() * float(aFontSize)) / 2.0f);
|
||||
}
|
||||
case eCSSUnit_XHeight: {
|
||||
nsFont font = aStyleFont->mFont;
|
||||
|
@ -207,12 +207,12 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
|||
nsCOMPtr<nsIFontMetrics> fm = aPresContext->GetMetricsFor(font);
|
||||
nscoord xHeight;
|
||||
fm->GetXHeight(xHeight);
|
||||
return NSToCoordRound(aValue.GetFloatValue() * float(xHeight));
|
||||
return NSToCoordRoundWithClamp(aValue.GetFloatValue() * float(xHeight));
|
||||
}
|
||||
case eCSSUnit_CapHeight: {
|
||||
NS_NOTYETIMPLEMENTED("cap height unit");
|
||||
nscoord capHeight = ((aFontSize / 3) * 2); // XXX HACK!
|
||||
return NSToCoordRound(aValue.GetFloatValue() * float(capHeight));
|
||||
return NSToCoordRoundWithClamp(aValue.GetFloatValue() * float(capHeight));
|
||||
}
|
||||
case eCSSUnit_Char: {
|
||||
nsFont font = aStyleFont->mFont;
|
||||
|
@ -222,7 +222,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
|
|||
gfxFloat zeroWidth = (tfm->GetThebesFontGroup()->GetFontAt(0)
|
||||
->GetMetrics().zeroOrAveCharWidth);
|
||||
|
||||
return NSToCoordRound(aValue.GetFloatValue() *
|
||||
return NSToCoordRoundWithClamp(aValue.GetFloatValue() *
|
||||
NS_ceil(aPresContext->AppUnitsPerDevPixel() *
|
||||
zeroWidth));
|
||||
}
|
||||
|
|
|
@ -336,16 +336,23 @@ public:
|
|||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
|
||||
const nsRect& aDirtyRect);
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
||||
NS_DISPLAY_DECL_NAME("XULTextBox")
|
||||
};
|
||||
|
||||
void nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
|
||||
void
|
||||
nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
|
||||
{
|
||||
static_cast<nsTextBoxFrame*>(mFrame)->
|
||||
PaintTitle(*aCtx, aDirtyRect, aBuilder->ToReferenceFrame(mFrame));
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder) {
|
||||
return mFrame->GetOverflowRect() + aBuilder->ToReferenceFrame(mFrame);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
|
@ -952,6 +959,12 @@ nsTextBoxFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState)
|
|||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTextBoxFrame::ComputesOwnOverflowArea()
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsTextBoxFrame::MarkIntrinsicWidthsDirty()
|
||||
{
|
||||
|
|
|
@ -87,6 +87,8 @@ public:
|
|||
const nsRect& aDirtyRect,
|
||||
nsPoint aPt);
|
||||
|
||||
virtual PRBool ComputesOwnOverflowArea();
|
||||
|
||||
protected:
|
||||
friend class nsAsyncAccesskeyUpdate;
|
||||
// Should be called only by nsAsyncAccesskeyUpdate.
|
||||
|
|
Загрузка…
Ссылка в новой задаче