Bug 312156 - Implement CSS3 text-overflow. r=roc
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
#include "nsCSSRendering.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "TextOverflow.h"
|
||||
#include "mozilla/Util.h" // for DebugOnly
|
||||
|
||||
#ifdef IBMBIDI
|
||||
@@ -107,6 +108,7 @@ static const PRUnichar kSquareCharacter = 0x25aa;
|
||||
#define DISABLE_FLOAT_BREAKING_IN_COLUMNS
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::css;
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "nsPrintfCString.h"
|
||||
@@ -6072,15 +6074,17 @@ nsBlockFrame::IsVisibleInSelection(nsISelection* aSelection)
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsBlockFrame::PaintTextDecorationLine(gfxContext* aCtx,
|
||||
const nsPoint& aPt,
|
||||
nsLineBox* aLine,
|
||||
nscolor aColor,
|
||||
PRUint8 aStyle,
|
||||
gfxFloat aOffset,
|
||||
gfxFloat aAscent,
|
||||
gfxFloat aSize,
|
||||
const PRUint8 aDecoration)
|
||||
nsBlockFrame::PaintTextDecorationLine(
|
||||
gfxContext* aCtx,
|
||||
const nsPoint& aPt,
|
||||
nsLineBox* aLine,
|
||||
nscolor aColor,
|
||||
PRUint8 aStyle,
|
||||
gfxFloat aOffset,
|
||||
gfxFloat aAscent,
|
||||
gfxFloat aSize,
|
||||
const nsCharClipDisplayItem::ClipEdges& aClipEdges,
|
||||
const PRUint8 aDecoration)
|
||||
{
|
||||
NS_ASSERTION(!aLine->IsBlock(), "Why did we ask for decorations on a block?");
|
||||
|
||||
@@ -6088,10 +6092,12 @@ nsBlockFrame::PaintTextDecorationLine(gfxContext* aCtx,
|
||||
nscoord width = aLine->mBounds.width;
|
||||
|
||||
AdjustForTextIndent(aLine, start, width);
|
||||
|
||||
nscoord x = start + aPt.x;
|
||||
aClipEdges.Intersect(&x, &width);
|
||||
|
||||
// Only paint if we have a positive width
|
||||
if (width > 0) {
|
||||
gfxPoint pt(PresContext()->AppUnitsToGfxUnits(start + aPt.x),
|
||||
gfxPoint pt(PresContext()->AppUnitsToGfxUnits(x),
|
||||
PresContext()->AppUnitsToGfxUnits(aLine->mBounds.y + aPt.y));
|
||||
gfxSize size(PresContext()->AppUnitsToGfxUnits(width), aSize);
|
||||
nsCSSRendering::PaintDecorationLine(
|
||||
@@ -6151,7 +6157,7 @@ static nsresult
|
||||
DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea,
|
||||
const nsRect& aDirtyRect, nsBlockFrame::line_iterator& aLine,
|
||||
PRInt32 aDepth, PRInt32& aDrawnLines, const nsDisplayListSet& aLists,
|
||||
nsBlockFrame* aFrame) {
|
||||
nsBlockFrame* aFrame, TextOverflow* aTextOverflow) {
|
||||
// If the line's combined area (which includes child frames that
|
||||
// stick outside of the line's bounding box or our bounding box)
|
||||
// intersects the dirty rect then paint the line.
|
||||
@@ -6169,24 +6175,27 @@ DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea,
|
||||
// on all the frames on the line, but that might be expensive. So
|
||||
// we approximate it by checking it on aFrame; if it's true for any
|
||||
// frame in the line, it's also true for aFrame.
|
||||
if (!intersect && !aBuilder->ShouldDescendIntoFrame(aFrame))
|
||||
PRBool lineInline = aLine->IsInline();
|
||||
PRBool lineMayHaveTextOverflow = aTextOverflow && lineInline;
|
||||
if (!intersect && !aBuilder->ShouldDescendIntoFrame(aFrame) &&
|
||||
!lineMayHaveTextOverflow)
|
||||
return NS_OK;
|
||||
|
||||
nsDisplayListCollection collection;
|
||||
nsresult rv;
|
||||
nsDisplayList aboveTextDecorations;
|
||||
PRBool lineInline = aLine->IsInline();
|
||||
if (lineInline) {
|
||||
// Display the text-decoration for the hypothetical anonymous inline box
|
||||
// that wraps these inlines
|
||||
rv = aFrame->DisplayTextDecorations(aBuilder, aLists.Content(),
|
||||
rv = aFrame->DisplayTextDecorations(aBuilder, collection.Content(),
|
||||
&aboveTextDecorations, aLine);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Block-level child backgrounds go on the blockBorderBackgrounds list ...
|
||||
// Inline-level child backgrounds go on the regular child content list.
|
||||
nsDisplayListSet childLists(aLists,
|
||||
lineInline ? aLists.Content() : aLists.BlockBorderBackgrounds());
|
||||
nsDisplayListSet childLists(collection,
|
||||
lineInline ? collection.Content() : collection.BlockBorderBackgrounds());
|
||||
nsIFrame* kid = aLine->mFirstChild;
|
||||
PRInt32 n = aLine->GetChildCount();
|
||||
while (--n >= 0) {
|
||||
@@ -6196,7 +6205,13 @@ DisplayLine(nsDisplayListBuilder* aBuilder, const nsRect& aLineArea,
|
||||
kid = kid->GetNextSibling();
|
||||
}
|
||||
|
||||
aLists.Content()->AppendToTop(&aboveTextDecorations);
|
||||
collection.Content()->AppendToTop(&aboveTextDecorations);
|
||||
|
||||
if (lineMayHaveTextOverflow) {
|
||||
aTextOverflow->ProcessLine(collection, aLine.get());
|
||||
}
|
||||
|
||||
collection.MoveTo(aLists);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -6238,6 +6253,10 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect);
|
||||
|
||||
// Prepare for text-overflow processing.
|
||||
nsAutoPtr<TextOverflow> textOverflow(
|
||||
TextOverflow::WillProcessLines(aBuilder, aLists, this));
|
||||
|
||||
// Don't use the line cursor if we might have a descendant placeholder ...
|
||||
// it might skip lines that contain placeholders but don't themselves
|
||||
// intersect with the dirty area.
|
||||
@@ -6262,7 +6281,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
break;
|
||||
}
|
||||
rv = DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines,
|
||||
aLists, this);
|
||||
aLists, this, textOverflow);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
@@ -6277,7 +6296,7 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
++line) {
|
||||
nsRect lineArea = line->GetVisualOverflowArea();
|
||||
rv = DisplayLine(aBuilder, lineArea, aDirtyRect, line, depth, drawnLines,
|
||||
aLists, this);
|
||||
aLists, this, textOverflow);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
if (!lineArea.IsEmpty()) {
|
||||
@@ -6296,6 +6315,11 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize text-overflow processing.
|
||||
if (textOverflow) {
|
||||
textOverflow->DidProcessLines();
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && (nsnull != mBullet) && HaveOutsideBullet()) {
|
||||
// Display outside bullets manually
|
||||
rv = BuildDisplayListForChild(aBuilder, mBullet, aDirtyRect, aLists);
|
||||
|
||||
Reference in New Issue
Block a user