mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 263359 part 1: refactor bidi resolution code, combining InitLogicalArray and CreateBlockBuffer. r=roc
This commit is contained in:
parent
ac0eb6cddb
commit
bfef246b4b
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user