|
|
|
Lines 309-324
AdvanceLineIteratorToFrame(nsIFrame* aFr
|
Link Here
|
|---|
|
| 309 |
* by EnsureBidiContinuation() in previous reflows into fluid continuations. |
309 |
* by EnsureBidiContinuation() in previous reflows into fluid continuations. |
| 310 |
*/ |
310 |
*/ |
| 311 |
nsresult |
311 |
nsresult |
| 312 |
nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) |
312 |
nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) |
| 313 |
{ |
313 |
{ |
| 314 |
mLogicalFrames.Clear(); |
314 |
mLogicalFrames.Clear(); |
| 315 |
mContentToFrameIndex.Clear(); |
315 |
mContentToFrameIndex.Clear(); |
| 316 |
mBuffer.SetLength(0); |
316 |
mBuffer.SetLength(0); |
|
|
317 |
mEmbeddingStack.SetLength(0); |
| 317 |
|
318 |
|
| 318 |
nsPresContext *presContext = aBlockFrame->PresContext(); |
319 |
nsPresContext *presContext = aBlockFrame->PresContext(); |
| 319 |
nsIPresShell* shell = presContext->PresShell(); |
320 |
nsIPresShell* shell = presContext->PresShell(); |
| 320 |
nsStyleContext* styleContext = aBlockFrame->GetStyleContext(); |
321 |
nsStyleContext* styleContext = aBlockFrame->GetStyleContext(); |
| 321 |
|
322 |
|
| 322 |
// handle bidi-override being set on the block itself before calling |
323 |
// handle bidi-override being set on the block itself before calling |
| 323 |
// InitLogicalArray. |
324 |
// InitLogicalArray. |
| 324 |
const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); |
325 |
const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); |
|
Lines 334-375
nsBidiPresUtils::Resolve(nsBlockFrame* a
|
Link Here
|
|---|
|
| 334 |
else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { |
335 |
else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { |
| 335 |
ch = kLRO; |
336 |
ch = kLRO; |
| 336 |
} |
337 |
} |
| 337 |
if (ch != 0) { |
338 |
if (ch != 0) { |
| 338 |
directionalFrame = NS_NewDirectionalFrame(shell, styleContext); |
339 |
directionalFrame = NS_NewDirectionalFrame(shell, styleContext); |
| 339 |
if (directionalFrame) { |
340 |
if (directionalFrame) { |
| 340 |
mLogicalFrames.AppendElement(directionalFrame); |
341 |
mLogicalFrames.AppendElement(directionalFrame); |
| 341 |
mBuffer.Append(ch); |
342 |
mBuffer.Append(ch); |
|
|
343 |
mEmbeddingStack.Append(ch); |
| 342 |
} |
344 |
} |
| 343 |
} |
345 |
} |
| 344 |
} |
346 |
} |
| 345 |
nsIContent* prevContent = nsnull; |
347 |
nsIContent* prevContent = nsnull; |
| 346 |
for (nsBlockFrame* block = aBlockFrame; block; |
348 |
for (nsBlockFrame* block = aBlockFrame; block; |
| 347 |
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) { |
349 |
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) { |
| 348 |
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION); |
350 |
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION); |
| 349 |
InitLogicalArray(block->GetFirstChild(nsnull), prevContent); |
351 |
InitLogicalArray(aBlockFrame, block->GetFirstChild(nsnull), prevContent); |
| 350 |
} |
352 |
} |
| 351 |
|
353 |
|
| 352 |
if (ch != 0) { |
354 |
if (ch != 0) { |
| 353 |
nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext); |
355 |
nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext); |
| 354 |
if (directionalFrame) { |
356 |
if (directionalFrame) { |
| 355 |
mLogicalFrames.AppendElement(directionalFrame); |
357 |
mLogicalFrames.AppendElement(directionalFrame); |
| 356 |
mBuffer.Append(kPDF); |
358 |
mBuffer.Append(kPDF); |
|
|
359 |
mEmbeddingStack.SetLength(mEmbeddingStack.Length() - 1); |
| 360 |
} |
| 361 |
} |
| 362 |
return ResolveParagraph(aBlockFrame, PR_FALSE); |
| 363 |
} |
| 364 |
|
| 365 |
nsresult |
| 366 |
nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame, PRBool aIsMore) |
| 367 |
{ |
| 368 |
// XXX: TODO: Handle preformatted text ('\n') |
| 369 |
mBuffer.ReplaceChar("\t\r\n", kSpace); |
| 370 |
|
| 371 |
if (aIsMore) { |
| 372 |
// pop all embeddings and overrides |
| 373 |
for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) { |
| 374 |
mBuffer.Append(kPDF); |
| 357 |
} |
375 |
} |
| 358 |
} |
376 |
} |
| 359 |
|
377 |
|
| 360 |
// XXX: TODO: Handle preformatted text ('\n') |
|
|
| 361 |
mBuffer.ReplaceChar("\t\r\n", kSpace); |
| 362 |
return ResolveParagraph(aBlockFrame); |
| 363 |
} |
| 364 |
|
| 365 |
nsresult |
| 366 |
nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame) |
| 367 |
{ |
| 368 |
nsPresContext *presContext = aBlockFrame->PresContext(); |
378 |
nsPresContext *presContext = aBlockFrame->PresContext(); |
| 369 |
const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); |
379 |
const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); |
| 370 |
PRInt32 bufferLength = mBuffer.Length(); |
380 |
PRInt32 bufferLength = mBuffer.Length(); |
| 371 |
|
381 |
|
| 372 |
if (bufferLength < 1) { |
382 |
if (bufferLength < 1) { |
| 373 |
mSuccess = NS_OK; |
383 |
mSuccess = NS_OK; |
| 374 |
return mSuccess; |
384 |
return mSuccess; |
| 375 |
} |
385 |
} |
|
Lines 578-600
nsBidiPresUtils::ResolveParagraph(nsBloc
|
Link Here
|
|---|
|
| 578 |
++lineOffset; |
588 |
++lineOffset; |
| 579 |
} |
589 |
} |
| 580 |
} // not directionalFrame |
590 |
} // not directionalFrame |
| 581 |
PRInt32 temp = runLength; |
591 |
PRInt32 temp = runLength; |
| 582 |
runLength -= fragmentLength; |
592 |
runLength -= fragmentLength; |
| 583 |
fragmentLength -= temp; |
593 |
fragmentLength -= temp; |
| 584 |
|
594 |
|
| 585 |
if (frame && fragmentLength <= 0) { |
595 |
if (frame && fragmentLength <= 0) { |
| 586 |
// If the frame is at the end of a run, split all ancestor inlines that |
596 |
// If the frame is at the end of a run, and this is not the end of our |
| 587 |
// need splitting. |
597 |
// paragrah, split all ancestor inlines that need splitting. |
| 588 |
// To determine whether we're at the end of the run, we check that we've |
598 |
// To determine whether we're at the end of the run, we check that we've |
| 589 |
// finished processing the current run, and that the current frame |
599 |
// finished processing the current run, and that the current frame |
| 590 |
// doesn't have a fluid continuation (it could have a fluid continuation |
600 |
// doesn't have a fluid continuation (it could have a fluid continuation |
| 591 |
// of zero length, so testing runLength alone is not sufficient). |
601 |
// of zero length, so testing runLength alone is not sufficient). |
| 592 |
if (runLength <= 0 && !frame->GetNextInFlow()) { |
602 |
if (numRun + 1 < runCount && runLength <= 0 && !frame->GetNextInFlow()) { |
| 593 |
nsIFrame* child = frame; |
603 |
nsIFrame* child = frame; |
| 594 |
nsIFrame* parent = frame->GetParent(); |
604 |
nsIFrame* parent = frame->GetParent(); |
| 595 |
// As long as we're on the last sibling, the parent doesn't have to be split. |
605 |
// As long as we're on the last sibling, the parent doesn't have to be split. |
| 596 |
// However, if the parent has a fluid continuation, we do have to make |
606 |
// However, if the parent has a fluid continuation, we do have to make |
| 597 |
// it non-fluid. This can happen e.g. when we have a first-letter frame |
607 |
// it non-fluid. This can happen e.g. when we have a first-letter frame |
| 598 |
// and the end of the first-letter coincides with the end of a |
608 |
// and the end of the first-letter coincides with the end of a |
| 599 |
// directional run. |
609 |
// directional run. |
| 600 |
while (parent && |
610 |
while (parent && |
|
Lines 615-642
nsBidiPresUtils::ResolveParagraph(nsBloc
|
Link Here
|
|---|
|
| 615 |
// We're not at an end of a run, and |frame| is the last child of its parent. |
625 |
// We're not at an end of a run, and |frame| is the last child of its parent. |
| 616 |
// If its ancestors happen to have bidi continuations, convert them into |
626 |
// If its ancestors happen to have bidi continuations, convert them into |
| 617 |
// fluid continuations. |
627 |
// fluid continuations. |
| 618 |
nsIFrame* parent = frame->GetParent(); |
628 |
nsIFrame* parent = frame->GetParent(); |
| 619 |
JoinInlineAncestors(parent); |
629 |
JoinInlineAncestors(parent); |
| 620 |
} |
630 |
} |
| 621 |
} |
631 |
} |
| 622 |
} // for |
632 |
} // for |
|
|
633 |
|
| 634 |
if (aIsMore) { |
| 635 |
// Clear the frame array and paragraph buffer, and restore the stored |
| 636 |
// embeddings and overrides |
| 637 |
mLogicalFrames.Clear(); |
| 638 |
mContentToFrameIndex.Clear(); |
| 639 |
mBuffer.SetLength(0); |
| 640 |
mBuffer.Append(mEmbeddingStack); |
| 641 |
|
| 642 |
nsIPresShell* shell = presContext->PresShell(); |
| 643 |
nsStyleContext* styleContext = aBlockFrame->GetStyleContext(); |
| 644 |
for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) { |
| 645 |
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); |
| 646 |
if (dirFrame) { |
| 647 |
mLogicalFrames.AppendElement(dirFrame); |
| 648 |
} |
| 649 |
} |
| 650 |
} |
| 623 |
return mSuccess; |
651 |
return mSuccess; |
| 624 |
} |
652 |
} |
| 625 |
|
653 |
|
| 626 |
// Should this frame be treated as a leaf (e.g. when building mLogicalFrames)? |
654 |
// Should this frame be treated as a leaf (e.g. when building mLogicalFrames)? |
| 627 |
PRBool IsBidiLeaf(nsIFrame* aFrame) { |
655 |
PRBool IsBidiLeaf(nsIFrame* aFrame) { |
| 628 |
nsIFrame* kid = aFrame->GetFirstChild(nsnull); |
656 |
nsIFrame* kid = aFrame->GetFirstChild(nsnull); |
| 629 |
return !kid |
657 |
return !kid |
| 630 |
|| !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer); |
658 |
|| !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer); |
| 631 |
} |
659 |
} |
| 632 |
|
660 |
|
| 633 |
void |
661 |
void |
| 634 |
nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame, |
662 |
nsBidiPresUtils::InitLogicalArray(nsBlockFrame* aBlockFrame, |
|
|
663 |
nsIFrame* aCurrentFrame, |
| 635 |
nsIContent*& aPrevContent) |
664 |
nsIContent*& aPrevContent) |
| 636 |
{ |
665 |
{ |
| 637 |
if (!aCurrentFrame) |
666 |
if (!aCurrentFrame) |
| 638 |
return; |
667 |
return; |
| 639 |
|
668 |
|
| 640 |
nsIPresShell* shell = aCurrentFrame->PresContext()->PresShell(); |
669 |
nsIPresShell* shell = aCurrentFrame->PresContext()->PresShell(); |
| 641 |
nsStyleContext* styleContext; |
670 |
nsStyleContext* styleContext; |
| 642 |
|
671 |
|
|
Lines 686-701
nsBidiPresUtils::InitLogicalArray(nsIFra
|
Link Here
|
|---|
|
| 686 |
|
715 |
|
| 687 |
// Create a directional frame before the first frame of an |
716 |
// Create a directional frame before the first frame of an |
| 688 |
// element specifying embedding or override |
717 |
// element specifying embedding or override |
| 689 |
if (ch != 0 && !frame->GetPrevContinuation()) { |
718 |
if (ch != 0 && !frame->GetPrevContinuation()) { |
| 690 |
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); |
719 |
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); |
| 691 |
if (dirFrame) { |
720 |
if (dirFrame) { |
| 692 |
mLogicalFrames.AppendElement(dirFrame); |
721 |
mLogicalFrames.AppendElement(dirFrame); |
| 693 |
mBuffer.Append(ch); |
722 |
mBuffer.Append(ch); |
|
|
723 |
mEmbeddingStack.Append(ch); |
| 694 |
} |
724 |
} |
| 695 |
} |
725 |
} |
| 696 |
} |
726 |
} |
| 697 |
|
727 |
|
| 698 |
if (IsBidiLeaf(frame)) { |
728 |
if (IsBidiLeaf(frame)) { |
| 699 |
/* Bidi leaf frame: add the frame to the mLogicalFrames array, |
729 |
/* Bidi leaf frame: add the frame to the mLogicalFrames array, |
| 700 |
* and add its index to the mContentToFrameIndex hashtable. This |
730 |
* and add its index to the mContentToFrameIndex hashtable. This |
| 701 |
* will be used in RemoveBidiContinuation() to identify the last |
731 |
* will be used in RemoveBidiContinuation() to identify the last |
|
Lines 712-747
nsBidiPresUtils::InitLogicalArray(nsIFra
|
Link Here
|
|---|
|
| 712 |
if (nsGkAtoms::textFrame == frameType) { |
742 |
if (nsGkAtoms::textFrame == frameType) { |
| 713 |
if (content != aPrevContent) { |
743 |
if (content != aPrevContent) { |
| 714 |
aPrevContent = content; |
744 |
aPrevContent = content; |
| 715 |
content->AppendTextTo(mBuffer); |
745 |
content->AppendTextTo(mBuffer); |
| 716 |
} |
746 |
} |
| 717 |
} else if (nsGkAtoms::brFrame == frameType) { |
747 |
} else if (nsGkAtoms::brFrame == frameType) { |
| 718 |
// break frame -- append line separator |
748 |
// break frame -- append line separator |
| 719 |
mBuffer.Append(kLineSeparator); |
749 |
mBuffer.Append(kLineSeparator); |
|
|
750 |
ResolveParagraph(aBlockFrame, PR_TRUE); |
| 720 |
} else { |
751 |
} else { |
| 721 |
// other frame type -- see the Unicode Bidi Algorithm: |
752 |
// other frame type -- see the Unicode Bidi Algorithm: |
| 722 |
// "...inline objects (such as graphics) are treated as if they are ... |
753 |
// "...inline objects (such as graphics) are treated as if they are ... |
| 723 |
// U+FFFC" |
754 |
// U+FFFC" |
| 724 |
mBuffer.Append(kObjectSubstitute); |
755 |
mBuffer.Append(kObjectSubstitute); |
|
|
756 |
if (frame->GetStyleContext()->GetStyleDisplay()->mDisplay != |
| 757 |
NS_STYLE_DISPLAY_INLINE) { |
| 758 |
// if it is not inline, end the paragraph |
| 759 |
ResolveParagraph(aBlockFrame, PR_TRUE); |
| 760 |
} |
| 725 |
} |
761 |
} |
| 726 |
} |
762 |
} |
| 727 |
else { |
763 |
else { |
| 728 |
nsIFrame* kid = frame->GetFirstChild(nsnull); |
764 |
nsIFrame* kid = frame->GetFirstChild(nsnull); |
| 729 |
InitLogicalArray(kid, aPrevContent); |
765 |
InitLogicalArray(aBlockFrame, kid, aPrevContent); |
| 730 |
} |
766 |
} |
| 731 |
|
767 |
|
| 732 |
// If the element is attributed by dir, indicate direction pop (add PDF frame) |
768 |
// If the element is attributed by dir, indicate direction pop (add PDF frame) |
| 733 |
if (ch != 0 && !frame->GetNextContinuation()) { |
769 |
if (ch != 0 && !frame->GetNextContinuation()) { |
| 734 |
// Create a directional frame after the last frame of an |
770 |
// Create a directional frame after the last frame of an |
| 735 |
// element specifying embedding or override |
771 |
// element specifying embedding or override |
| 736 |
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); |
772 |
nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); |
| 737 |
if (dirFrame) { |
773 |
if (dirFrame) { |
| 738 |
mLogicalFrames.AppendElement(dirFrame); |
774 |
mLogicalFrames.AppendElement(dirFrame); |
| 739 |
mBuffer.Append(kPDF); |
775 |
mBuffer.Append(kPDF); |
|
|
776 |
mEmbeddingStack.SetLength(mEmbeddingStack.Length() - 1); |
| 740 |
} |
777 |
} |
| 741 |
} |
778 |
} |
| 742 |
} // for |
779 |
} // for |
| 743 |
} |
780 |
} |
| 744 |
|
781 |
|
| 745 |
void |
782 |
void |
| 746 |
nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, |
783 |
nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, |
| 747 |
PRInt32 aNumFramesOnLine) |
784 |
PRInt32 aNumFramesOnLine) |