Attachment #493937: Patch part 1: preliminary refactoring -- combine InitLogicalArray and CreateBlockBuffer for bug #263359

View | Details | Raw Unified | Return to bug 263359
Collapse All | Expand All

(-)a/layout/base/nsBidiPresUtils.cpp (-58 / +42 lines)
Line     Link Here 
 Lines 67-83   static const PRUnichar kLRO Link Here 
67
static const PRUnichar kRLO              = 0x202E;
67
static const PRUnichar kRLO              = 0x202E;
68
static const PRUnichar kPDF              = 0x202C;
68
static const PRUnichar kPDF              = 0x202C;
69
static const PRUnichar ALEF              = 0x05D0;
69
static const PRUnichar ALEF              = 0x05D0;
70
70
71
#define CHAR_IS_HEBREW(c) ((0x0590 <= (c)) && ((c)<= 0x05FF))
71
#define CHAR_IS_HEBREW(c) ((0x0590 <= (c)) && ((c)<= 0x05FF))
72
// Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp
72
// Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp
73
73
74
nsIFrame*
74
nsIFrame*
75
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar);
75
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
76
76
77
nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8),
77
nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8),
78
                                     mIndexMap(nsnull),
78
                                     mIndexMap(nsnull),
79
                                     mLevels(nsnull),
79
                                     mLevels(nsnull),
80
                                     mSuccess(NS_ERROR_FAILURE),
80
                                     mSuccess(NS_ERROR_FAILURE),
81
                                     mBidiEngine(nsnull)
81
                                     mBidiEngine(nsnull)
82
{
82
{
83
  mBidiEngine = new nsBidi();
83
  mBidiEngine = new nsBidi();
 Lines 308-361   AdvanceLineIteratorToFrame(nsIFrame* aFr Link Here 
308
 *  We may also need to call RemoveBidiContinuation() to convert frames created
308
 *  We may also need to call RemoveBidiContinuation() to convert frames created
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
  
317
  
317
  nsPresContext *presContext = aBlockFrame->PresContext();
318
  nsPresContext *presContext = aBlockFrame->PresContext();
318
  nsIPresShell* shell = presContext->PresShell();
319
  nsIPresShell* shell = presContext->PresShell();
319
  nsStyleContext* styleContext = aBlockFrame->GetStyleContext();
320
  nsStyleContext* styleContext = aBlockFrame->GetStyleContext();
320
321
321
  // handle bidi-override being set on the block itself before calling
322
  // handle bidi-override being set on the block itself before calling
322
  // InitLogicalArray.
323
  // InitLogicalArray.
323
  const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility();
324
  const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility();
324
  const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
325
  const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset();
325
326
327
  PRUnichar ch = 0;
326
  if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
328
  if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
327
    nsIFrame *directionalFrame = nsnull;
329
    nsIFrame *directionalFrame = nsnull;
328
330
329
    if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
331
    if (NS_STYLE_DIRECTION_RTL == vis->mDirection) {
330
      directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kRLO);
332
      ch = kRLO;
331
    }
333
    }
332
    else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
334
    else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) {
333
      directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kLRO);
335
      ch = kLRO;
334
    }
336
    }
335
337
    if (ch != 0) {
336
    if (directionalFrame) {
338
      directionalFrame = NS_NewDirectionalFrame(shell, styleContext);
337
      mLogicalFrames.AppendElement(directionalFrame);
339
      if (directionalFrame) {
340
        mLogicalFrames.AppendElement(directionalFrame);
341
        mBuffer.Append(ch);
342
      }
338
    }
343
    }
339
  }
344
  }
345
  nsIContent* prevContent = nsnull;
340
  for (nsBlockFrame* block = aBlockFrame; block;
346
  for (nsBlockFrame* block = aBlockFrame; block;
341
       block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
347
       block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
342
    block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
348
    block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
343
    InitLogicalArray(block->GetFirstChild(nsnull));
349
    InitLogicalArray(block->GetFirstChild(nsnull), prevContent);
344
  }
350
  }
345
351
346
  if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) {
352
  if (ch != 0) {
347
    nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
353
    nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext);
348
    if (directionalFrame) {
354
    if (directionalFrame) {
349
      mLogicalFrames.AppendElement(directionalFrame);
355
      mLogicalFrames.AppendElement(directionalFrame);
356
      mBuffer.Append(kPDF);
350
    }
357
    }
351
  }
358
  }
352
359
353
  CreateBlockBuffer();
360
  // XXX: TODO: Handle preformatted text ('\n')
361
  mBuffer.ReplaceChar("\t\r\n", kSpace);
354
362
355
  PRInt32 bufferLength = mBuffer.Length();
363
  PRInt32 bufferLength = mBuffer.Length();
356
364
357
  if (bufferLength < 1) {
365
  if (bufferLength < 1) {
358
    mSuccess = NS_OK;
366
    mSuccess = NS_OK;
359
    return mSuccess;
367
    return mSuccess;
360
  }
368
  }
361
  PRInt32 runCount;
369
  PRInt32 runCount;
 Lines 611-627   nsBidiPresUtils::Resolve(nsBlockFrame* a Link Here 
611
// Should this frame be treated as a leaf (e.g. when building mLogicalFrames)?
619
// Should this frame be treated as a leaf (e.g. when building mLogicalFrames)?
612
PRBool IsBidiLeaf(nsIFrame* aFrame) {
620
PRBool IsBidiLeaf(nsIFrame* aFrame) {
613
  nsIFrame* kid = aFrame->GetFirstChild(nsnull);
621
  nsIFrame* kid = aFrame->GetFirstChild(nsnull);
614
  return !kid
622
  return !kid
615
    || !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer);
623
    || !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer);
616
}
624
}
617
625
618
void
626
void
619
nsBidiPresUtils::InitLogicalArray(nsIFrame*       aCurrentFrame)
627
nsBidiPresUtils::InitLogicalArray(nsIFrame*    aCurrentFrame,
628
                                  nsIContent*& aPrevContent)
620
{
629
{
621
  if (!aCurrentFrame)
630
  if (!aCurrentFrame)
622
    return;
631
    return;
623
632
624
  nsIPresShell* shell = aCurrentFrame->PresContext()->PresShell();
633
  nsIPresShell* shell = aCurrentFrame->PresContext()->PresShell();
625
  nsStyleContext* styleContext;
634
  nsStyleContext* styleContext;
626
635
627
  for (nsIFrame* childFrame = aCurrentFrame; childFrame;
636
  for (nsIFrame* childFrame = aCurrentFrame; childFrame;
 Lines 666-762   nsBidiPresUtils::InitLogicalArray(nsIFra Link Here 
666
            ch = kLRO;
675
            ch = kLRO;
667
          }
676
          }
668
          break;
677
          break;
669
      }
678
      }
670
679
671
      // Create a directional frame before the first frame of an
680
      // Create a directional frame before the first frame of an
672
      // element specifying embedding or override
681
      // element specifying embedding or override
673
      if (ch != 0 && !frame->GetPrevContinuation()) {
682
      if (ch != 0 && !frame->GetPrevContinuation()) {
674
        nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, ch);
683
        nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext);
675
        if (dirFrame) {
684
        if (dirFrame) {
676
          mLogicalFrames.AppendElement(dirFrame);
685
          mLogicalFrames.AppendElement(dirFrame);
686
          mBuffer.Append(ch);
677
        }
687
        }
678
      }
688
      }
679
    }
689
    }
680
690
681
    if (IsBidiLeaf(frame)) {
691
    if (IsBidiLeaf(frame)) {
682
      /* Bidi leaf frame: add the frame to the mLogicalFrames array,
692
      /* Bidi leaf frame: add the frame to the mLogicalFrames array,
683
       * and add its index to the mContentToFrameIndex hashtable. This
693
       * and add its index to the mContentToFrameIndex hashtable. This
684
       * will be used in RemoveBidiContinuation() to identify the last
694
       * will be used in RemoveBidiContinuation() to identify the last
685
       * frame in the array with a given content.
695
       * frame in the array with a given content.
686
       */
696
       */
687
      nsIContent* content = frame->GetContent();
697
      nsIContent* content = frame->GetContent();
688
      if (content) {
698
      if (content) {
689
        mContentToFrameIndex.Put(content, mLogicalFrames.Length());
699
        mContentToFrameIndex.Put(content, mLogicalFrames.Length());
690
      }
700
      }
691
      mLogicalFrames.AppendElement(frame);
701
      mLogicalFrames.AppendElement(frame);
702
703
      // Append the content of the frame to the paragraph buffer
704
      nsIAtom* frameType = frame->GetType();
705
      if (nsGkAtoms::textFrame == frameType) {
706
        if (content != aPrevContent) {
707
          aPrevContent = content;
708
          content->AppendTextTo(mBuffer);
709
        }
710
      } else if (nsGkAtoms::brFrame == frameType) {
711
        // break frame -- append line separator
712
        mBuffer.Append(kLineSeparator);
713
      } else { 
714
        // other frame type -- see the Unicode Bidi Algorithm:
715
        // "...inline objects (such as graphics) are treated as if they are ...
716
        // U+FFFC"
717
        mBuffer.Append(kObjectSubstitute);
718
      }
692
    }
719
    }
693
    else {
720
    else {
694
      nsIFrame* kid = frame->GetFirstChild(nsnull);
721
      nsIFrame* kid = frame->GetFirstChild(nsnull);
695
      InitLogicalArray(kid);
722
      InitLogicalArray(kid, aPrevContent);
696
    }
723
    }
697
724
698
    // If the element is attributed by dir, indicate direction pop (add PDF frame)
725
    // If the element is attributed by dir, indicate direction pop (add PDF frame)
699
    if (ch != 0 && !frame->GetNextContinuation()) {
726
    if (ch != 0 && !frame->GetNextContinuation()) {
700
      // Create a directional frame after the last frame of an
727
      // Create a directional frame after the last frame of an
701
      // element specifying embedding or override
728
      // element specifying embedding or override
702
      nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF);
729
      nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext);
703
      if (dirFrame) {
730
      if (dirFrame) {
704
        mLogicalFrames.AppendElement(dirFrame);
731
        mLogicalFrames.AppendElement(dirFrame);
732
        mBuffer.Append(kPDF);
705
      }
733
      }
706
    }
734
    }
707
  } // for
735
  } // for
708
}
736
}
709
737
710
void
738
void
711
nsBidiPresUtils::CreateBlockBuffer()
712
{
713
  mBuffer.SetLength(0);
714
715
  nsIFrame*                 frame;
716
  nsIContent*               prevContent = nsnull;
717
  PRUint32                  i;
718
  PRUint32                  count = mLogicalFrames.Length();
719
720
  for (i = 0; i < count; i++) {
721
    frame = mLogicalFrames[i];
722
    nsIAtom* frameType = frame->GetType();
723
724
    if (nsGkAtoms::textFrame == frameType) {
725
      nsIContent* content = frame->GetContent();
726
      if (!content) {
727
        mSuccess = NS_OK;
728
        break;
729
      }
730
      if (content == prevContent) {
731
        continue;
732
      }
733
      prevContent = content;
734
      content->AppendTextTo(mBuffer);
735
    }
736
    else if (nsGkAtoms::brFrame == frameType) { // break frame
737
      // Append line separator
738
      mBuffer.Append(kLineSeparator);
739
    }
740
    else if (nsGkAtoms::directionalFrame == frameType) {
741
      nsDirectionalFrame* dirFrame = static_cast<nsDirectionalFrame*>(frame);
742
      mBuffer.Append(dirFrame->GetChar());
743
    }
744
    else { // not text frame
745
      // See the Unicode Bidi Algorithm:
746
      // "...inline objects (such as graphics) are treated as if they are ... U+FFFC"
747
      mBuffer.Append(kObjectSubstitute);
748
    }
749
  }
750
  // XXX: TODO: Handle preformatted text ('\n')
751
  mBuffer.ReplaceChar("\t\r\n", kSpace);
752
}
753
754
void
755
nsBidiPresUtils::ReorderFrames(nsIFrame*            aFirstFrameOnLine,
739
nsBidiPresUtils::ReorderFrames(nsIFrame*            aFirstFrameOnLine,
756
                               PRInt32              aNumFramesOnLine)
740
                               PRInt32              aNumFramesOnLine)
757
{
741
{
758
  // If this line consists of a line frame, reorder the line frame's children.
742
  // If this line consists of a line frame, reorder the line frame's children.
759
  if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) {
743
  if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) {
760
    aFirstFrameOnLine = aFirstFrameOnLine->GetFirstChild(nsnull);
744
    aFirstFrameOnLine = aFirstFrameOnLine->GetFirstChild(nsnull);
761
    if (!aFirstFrameOnLine)
745
    if (!aFirstFrameOnLine)
762
      return;
746
      return;
(-)a/layout/base/nsBidiPresUtils.h (-8 / +1 lines)
Line     Link Here 
 Lines 332-359   private: Link Here 
332
                                          Mode                   aMode,
332
                                          Mode                   aMode,
333
                                          nscoord                aX, // DRAW only
333
                                          nscoord                aX, // DRAW only
334
                                          nscoord                aY, // DRAW only
334
                                          nscoord                aY, // DRAW only
335
                                          nsBidiPositionResolve* aPosResolve,  /* may be null */
335
                                          nsBidiPositionResolve* aPosResolve,  /* may be null */
336
                                          PRInt32                aPosResolveCount,
336
                                          PRInt32                aPosResolveCount,
337
                                          nscoord*               aWidth /* may be null */);
337
                                          nscoord*               aWidth /* may be null */);
338
338
339
  /**
339
  /**
340
   *  Create a string containing entire text content of this block.
341
   *
342
   *  @lina 05/02/2000
343
   */
344
  void CreateBlockBuffer();
345
346
  /**
347
   * Set up an array of the frames after splitting frames so that each frame has
340
   * Set up an array of the frames after splitting frames so that each frame has
348
   * consistent directionality. At this point the frames are still in logical
341
   * consistent directionality. At this point the frames are still in logical
349
   * order
342
   * order
350
   */
343
   */
351
  void InitLogicalArray(nsIFrame* aCurrentFrame);
344
  void InitLogicalArray(nsIFrame* aCurrentFrame, nsIContent*& aPrevContent);
352
345
353
  /**
346
  /**
354
   * Initialize the logically-ordered array of frames
347
   * Initialize the logically-ordered array of frames
355
   * using the top-level frames of a single line
348
   * using the top-level frames of a single line
356
   */
349
   */
357
  void InitLogicalArrayFromLine(nsIFrame* aFirstFrameOnLine,
350
  void InitLogicalArrayFromLine(nsIFrame* aFirstFrameOnLine,
358
                                PRInt32   aNumFramesOnLine);
351
                                PRInt32   aNumFramesOnLine);
359
352
(-)a/layout/generic/nsBidiFrames.cpp (-4 / +4 lines)
Line     Link Here 
 Lines 37-54    Link Here 
37
 * ***** END LICENSE BLOCK ***** */
37
 * ***** END LICENSE BLOCK ***** */
38
38
39
#ifdef IBMBIDI
39
#ifdef IBMBIDI
40
40
41
#include "nsBidiFrames.h"
41
#include "nsBidiFrames.h"
42
#include "nsGkAtoms.h"
42
#include "nsGkAtoms.h"
43
43
44
44
45
nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar)
45
nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext)
46
  : nsFrame(aContext), mChar(aChar)
46
  : nsFrame(aContext)
47
{
47
{
48
}
48
}
49
49
50
nsDirectionalFrame::~nsDirectionalFrame()
50
nsDirectionalFrame::~nsDirectionalFrame()
51
{
51
{
52
}
52
}
53
53
54
nsIAtom*
54
nsIAtom*
 Lines 61-76   nsDirectionalFrame::GetType() const Link Here 
61
NS_IMETHODIMP
61
NS_IMETHODIMP
62
nsDirectionalFrame::GetFrameName(nsAString& aResult) const
62
nsDirectionalFrame::GetFrameName(nsAString& aResult) const
63
{
63
{
64
  return MakeFrameName(NS_LITERAL_STRING("Directional"), aResult);
64
  return MakeFrameName(NS_LITERAL_STRING("Directional"), aResult);
65
}
65
}
66
#endif
66
#endif
67
67
68
nsIFrame*
68
nsIFrame*
69
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar)
69
NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
70
{
70
{
71
  return new (aPresShell) nsDirectionalFrame(aContext, aChar);
71
  return new (aPresShell) nsDirectionalFrame(aContext);
72
}
72
}
73
73
74
NS_IMPL_FRAMEARENA_HELPERS(nsDirectionalFrame)
74
NS_IMPL_FRAMEARENA_HELPERS(nsDirectionalFrame)
75
75
76
#endif /* IBMBIDI */
76
#endif /* IBMBIDI */
(-)a/layout/generic/nsBidiFrames.h (-6 / +1 lines)
Line     Link Here 
 Lines 47-76    Link Here 
47
class nsDirectionalFrame : public nsFrame
47
class nsDirectionalFrame : public nsFrame
48
{
48
{
49
protected:
49
protected:
50
  virtual ~nsDirectionalFrame();
50
  virtual ~nsDirectionalFrame();
51
51
52
public:
52
public:
53
  NS_DECL_FRAMEARENA_HELPERS
53
  NS_DECL_FRAMEARENA_HELPERS
54
54
55
  nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar);
55
  nsDirectionalFrame(nsStyleContext* aContext);
56
56
57
  /**
57
  /**
58
   * Get the "type" of the frame
58
   * Get the "type" of the frame
59
   *
59
   *
60
   * @see nsGkAtoms::directionalFrame
60
   * @see nsGkAtoms::directionalFrame
61
   */
61
   */
62
  virtual nsIAtom* GetType() const;
62
  virtual nsIAtom* GetType() const;
63
63
64
  PRUnichar GetChar() const { return mChar; }
65
66
#ifdef NS_DEBUG
64
#ifdef NS_DEBUG
67
  NS_IMETHOD GetFrameName(nsAString& aResult) const;
65
  NS_IMETHOD GetFrameName(nsAString& aResult) const;
68
#endif
66
#endif
69
70
private:
71
  PRUnichar mChar;
72
};
67
};
73
68
74
69
75
#endif /* nsBidiFrames_h___ */
70
#endif /* nsBidiFrames_h___ */
76
#endif /* IBMBIDI */
71
#endif /* IBMBIDI */

Return to bug 263359