Bug 263359 part 1: refactor bidi resolution code, combining InitLogicalArray and CreateBlockBuffer. r=roc

This commit is contained in:
Simon Montagu 2011-03-24 11:28:44 +02:00
Родитель ac0eb6cddb
Коммит bfef246b4b
4 изменённых файлов: 45 добавлений и 73 удалений

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

@ -77,7 +77,7 @@ static const PRUnichar ALEF = 0x05D0;
// Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp
nsIFrame*
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar);
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8),
mIndexMap(nsnull),
@ -318,6 +318,7 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
{
mLogicalFrames.Clear();
mContentToFrameIndex.Clear();
mBuffer.SetLength(0);
nsPresContext *presContext = aBlockFrame->PresContext();
nsIPresShell* shell = presContext->PresShell();
@ -328,34 +329,41 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility();
const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
PRUnichar ch = 0;
if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
nsIFrame *directionalFrame = nsnull;
if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kRLO);
ch = kRLO;
}
else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kLRO);
ch = kLRO;
}
if (directionalFrame) {
mLogicalFrames.AppendElement(directionalFrame);
if (ch != 0) {
directionalFrame = NS_NewDirectionalFrame(shell, styleContext);
if (directionalFrame) {
mLogicalFrames.AppendElement(directionalFrame);
mBuffer.Append(ch);
}
}
}
mPrevContent = nsnull;
for (nsBlockFrame* block = aBlockFrame; block;
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
InitLogicalArray(block->GetFirstChild(nsnull));
}
if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
if (ch != 0) {
nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext);
if (directionalFrame) {
mLogicalFrames.AppendElement(directionalFrame);
mBuffer.Append(kPDF);
}
}
CreateBlockBuffer();
// XXX: TODO: Handle preformatted text ('\n')
mBuffer.ReplaceChar("\t\r\n", kSpace);
PRInt32 bufferLength = mBuffer.Length();
@ -638,7 +646,7 @@ PRBool IsBidiLeaf(nsIFrame* aFrame) {
}
void
nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
{
if (!aCurrentFrame)
return;
@ -693,9 +701,10 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
// Create a directional frame before the first frame of an
// element specifying embedding or override
if (ch != 0 && !frame->GetPrevContinuation()) {
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, ch);
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext);
if (dirFrame) {
mLogicalFrames.AppendElement(dirFrame);
mBuffer.Append(ch);
}
}
}
@ -711,6 +720,23 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
mContentToFrameIndex.Put(content, mLogicalFrames.Length());
}
mLogicalFrames.AppendElement(frame);
// Append the content of the frame to the paragraph buffer
nsIAtom* frameType = frame->GetType();
if (nsGkAtoms::textFrame == frameType) {
if (content != mPrevContent) {
mPrevContent = content;
content->AppendTextTo(mBuffer);
}
} else if (nsGkAtoms::brFrame == frameType) {
// break frame -- append line separator
mBuffer.Append(kLineSeparator);
} else {
// other frame type -- see the Unicode Bidi Algorithm:
// "...inline objects (such as graphics) are treated as if they are ...
// U+FFFC"
mBuffer.Append(kObjectSubstitute);
}
}
else {
nsIFrame* kid = frame->GetFirstChild(nsnull);
@ -721,58 +747,15 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
if (ch != 0 && !frame->GetNextContinuation()) {
// Create a directional frame after the last frame of an
// element specifying embedding or override
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext);
if (dirFrame) {
mLogicalFrames.AppendElement(dirFrame);
mBuffer.Append(kPDF);
}
}
} // for
}
void
nsBidiPresUtils::CreateBlockBuffer()
{
mBuffer.SetLength(0);
nsIFrame* frame;
nsIContent* prevContent = nsnull;
PRUint32 i;
PRUint32 count = mLogicalFrames.Length();
for (i = 0; i < count; i++) {
frame = mLogicalFrames[i];
nsIAtom* frameType = frame->GetType();
if (nsGkAtoms::textFrame == frameType) {
nsIContent* content = frame->GetContent();
if (!content) {
mSuccess = NS_OK;
break;
}
if (content == prevContent) {
continue;
}
prevContent = content;
content->AppendTextTo(mBuffer);
}
else if (nsGkAtoms::brFrame == frameType) { // break frame
// Append line separator
mBuffer.Append(kLineSeparator);
}
else if (nsGkAtoms::directionalFrame == frameType) {
nsDirectionalFrame* dirFrame = static_cast<nsDirectionalFrame*>(frame);
mBuffer.Append(dirFrame->GetChar());
}
else { // not text frame
// See the Unicode Bidi Algorithm:
// "...inline objects (such as graphics) are treated as if they are ... U+FFFC"
mBuffer.Append(kObjectSubstitute);
}
}
// XXX: TODO: Handle preformatted text ('\n')
mBuffer.ReplaceChar("\t\r\n", kSpace);
}
void
nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine,
PRInt32 aNumFramesOnLine)

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

@ -361,13 +361,6 @@ private:
PRInt32 aPosResolveCount,
nscoord* aWidth /* may be null */);
/**
* Create a string containing entire text content of this block.
*
* @lina 05/02/2000
*/
void CreateBlockBuffer();
/**
* Set up an array of the frames after splitting frames so that each frame has
* consistent directionality. At this point the frames are still in logical
@ -521,6 +514,7 @@ private:
PRInt32* mIndexMap;
PRUint8* mLevels;
nsresult mSuccess;
nsIContent* mPrevContent;
nsBidi* mBidiEngine;
};

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

@ -42,8 +42,8 @@
#include "nsGkAtoms.h"
nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar)
: nsFrame(aContext), mChar(aChar)
nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext)
: nsFrame(aContext)
{
}
@ -66,9 +66,9 @@ nsDirectionalFrame::GetFrameName(nsAString& aResult) const
#endif
nsIFrame*
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar)
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsDirectionalFrame(aContext, aChar);
return new (aPresShell) nsDirectionalFrame(aContext);
}
NS_IMPL_FRAMEARENA_HELPERS(nsDirectionalFrame)

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

@ -52,7 +52,7 @@ protected:
public:
NS_DECL_FRAMEARENA_HELPERS
nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar);
nsDirectionalFrame(nsStyleContext* aContext);
/**
* Get the "type" of the frame
@ -61,14 +61,9 @@ public:
*/
virtual nsIAtom* GetType() const;
PRUnichar GetChar() const { return mChar; }
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif
private:
PRUnichar mChar;
};