Open Bug 271163 Opened 20 years ago Updated 2 years ago

Columns are not aligned (use Tab ) if the content contains Chinese/Korean/Japanese letter

Categories

(Core :: Layout: Text and Fonts, defect)

defect

Tracking

()

People

(Reporter: john.fang, Unassigned)

References

Details

(Keywords: intl, jp-critical)

Attachments

(2 files)

User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7) Gecko/20041116
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7) Gecko/20041116

Columns are not aligned (use Tab ) if the content contains Chinese letter

Reproducible: Always
Steps to Reproduce:
1.open the test case


Actual Results:  
Columns are not aligned

Expected Results:  
Columns are aligned
Attachment #166722 - Attachment description: click the testcase you will see the column (use "Tab") is not aligned → click the testcase you will see the column ( with the character encoding "zh") is not aligned
Attachment #166722 - Attachment description: click the testcase you will see the column ( with the character encoding "zh") is not aligned → click the testcase you will see the column ( with the character encoding "zh" or "GB") is not aligned
John, do you see the same problem when using spaces instead of tabs? I am not
sure that what I am seeing is the same as what you are seeing. This may be the
same issue as bug 156200, if the Chinese characters are not present in the
default monospaced font.
Assignee: roc → nobody
Component: Layout: View Rendering → Layout: Fonts and Text
QA Contact: ian → core.layout.fonts-and-text
(In reply to comment #2)
> John, do you see the same problem when using spaces instead of tabs? I am not
> sure that what I am seeing is the same as what you are seeing. This may be the
> same issue as bug 156200, if the Chinese characters are not present in the
> default monospaced font.

Simon:
  When I use the spaces instead od tabs, the problem was resolved. There are
aligned 
correctly. But Why "tab" can't do it corretly ?
  The bug 156200 may be issue as this. I mean they are so like , but I am not sure.
I am confused.
In http://www.w3.org/TR/CSS21/text.html
As each line is laid out,
   1. If a space (U+0020) at the beginning of a line has 'white-space' set to
'normal', 'nowrap', or 'pre-line', it is removed.
   2. All tabs (U+0009) are rendered as a horizontal shift that lines up the
start edge of the next glyph with the next tab stop. Tab stops occur at points
that are mutiples of 8 times the width of a space (U+0020) rendered in the
block's font from the block's starting content edge.
   3. If a space (U+0020) at the end of a line has 'white-space' set to
'normal', 'nowrap', or 'pre-line', it is also removed.

So in CSS2 tabs are rendered as horizontal shift. The width of shift is 8 times
width of a space rendered, but not 8 spaces.
In different language the word width is defferent, for exmple, Chinese char is
about 2 times of normal english char.
But in mozilla 
nsTextFrame.cpp
1631     if (isWhitespace) {
1632       if ('\t' == bp[0]) {
1633         PRInt32 spaces = 8 - (7 & column);
1634         PRUnichar* tp = bp;
1635         wordLen = spaces;
1636         while (--spaces >= 0) {
1637           *tp++ = ' ';
1638         }
           ....
          }
It is not correct, which only expand a few space to make up for .
If the word before of '\t' is a char which width is larger then
a space width, the position of the char behind of '\t' is incorrect,
like the testcase show.


This will happen when mozilla open a text file which contain '\t' to 
align composited text. It will also happen when the html contain "<pre>"
or "white-space : pre"
hi rbs:
   Can you help me review this path?
Attachment #169810 - Flags: review?(rbs)
Comment on attachment 169810 [details] [diff] [review]
align text correttly, when the text contain different width font aligned by '\t'. 

>Index: nsTextFrame.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/layout/generic/nsTextFrame.cpp,v
>retrieving revision 1.490
>diff -u -r1.490 nsTextFrame.cpp
>--- nsTextFrame.cpp	12 Dec 2004 16:14:43 -0000	1.490
>+++ nsTextFrame.cpp	29 Dec 2004 11:22:02 -0000
>@@ -771,6 +771,17 @@
>                                    PRUint32 aWordBufSize,
>                                    PRBool aCanBreakBefore);
> 
>+  void DrawStringWithTab(nsIRenderingContext& aRenderingContext,
>+				PRUnichar* aDrawString,
>+				PRInt32 aLength,
>+				PRInt32 aOffset,
>+				PRInt32 aLineOffset,
>+				nscoord dx, nscoord dy,
>+				PRInt32 aIndex,
>+				PRInt32 aJustifyWidth);
>+
>+  PRInt32 JustifyWithTab(PRInt32 aOffset = 0,PRInt32* aIndex = nsnull);
>+
> #ifdef DEBUG
>   void ToCString(nsString& aBuf, PRInt32* aTotalContentLength) const;
> #endif
>@@ -783,6 +794,8 @@
>   PRInt32   mContentLength;
>   PRInt32   mColumn;
>   nscoord   mAscent;
>+  nsAutoIndexBuffer* mTabPosAndOffset;
>+  PRInt32   mTabNum;
>   //factored out method for GetTextDimensions and getlengthslowly. if aGetTextDimensions is non-zero number then measure to the width field and return the length. else shove total dimensions into result
>   PRInt32 GetTextDimensionsOrLength(nsIRenderingContext& aRenderingContext,
>                 TextStyle& aStyle,
>@@ -801,6 +814,15 @@
> 
>   PRBool IsChineseJapaneseLangGroup();
>   PRBool IsJustifiableCharacter(PRUnichar aChar, PRBool aLangIsCJ);
>+  PRBool BinarySearchForPositionWithTab(nsIRenderingContext* acx, 
>+                        const PRUnichar* aText,
>+                        PRInt32    aBaseWidth,
>+                        PRInt32    aBaseInx,
>+                        PRInt32    aStartInx, 
>+                        PRInt32    aEndInx, 
>+                        PRInt32    aCursorPos, 
>+                        PRInt32&   aIndex,
>+                        PRInt32&   aTextWidth);
> };
> 
> #ifdef ACCESSIBILITY
>@@ -1314,6 +1336,7 @@
> }
> 
> nsTextFrame::nsTextFrame()
>+:mTabPosAndOffset(nsnull)
> {
> }
> 
>@@ -1323,6 +1346,10 @@
>   {
>     nsBlinkTimer::RemoveBlinkFrame(this);
>   }
>+  if (mTabPosAndOffset)
>+  {
>+      delete mTabPosAndOffset;
>+  }
> }
> 
> nsIDocument*
>@@ -1630,7 +1657,7 @@
>     inWord = PR_FALSE;
>     if (isWhitespace) {
>       if ('\t' == bp[0]) {
>-        PRInt32 spaces = 8 - (7 & column);
>+	PRInt32 spaces = 8 - (7 & (column));
>         PRUnichar* tp = bp;
>         wordLen = spaces;
>         while (--spaces >= 0) {
>@@ -2337,7 +2364,12 @@
>       // simplest rendering approach
> 
>       aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));
>-      aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);
>+      //if the textframe has '\t',we use DrawStringWidthTab to draw unicode string
>+      if (!mTabPosAndOffset || mTabNum == 0) {
>+         aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);
>+      } else {
>+	 DrawStringWithTab(aRenderingContext,text,PRUint32(textLength),0,dx,dx,dy + mAscent,0,0);
>+      }
>       PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext,
>                            aTextStyle, dx, dy, width);
>     }
>@@ -2420,6 +2452,8 @@
>           if (NS_SUCCEEDED(aRenderingContext.GetWidth(text, textLength, FrameWidth)))
>             currentX = dx + FrameWidth;
> #endif
>+	PRInt32 totallength = 0;
>+	PRInt32 currentoffset = 0; 
>         while (!iter.IsDone())
>         {
>           PRUnichar *currenttext  = iter.CurrentTextUnicharPtr();
>@@ -2428,6 +2462,11 @@
>           nscolor    currentFGColor = iter.CurrentForeGroundColor();
>           nscolor    currentBKColor;
>           PRBool     isCurrentBKColorTransparent;
>+	  currentoffset = totallength;
>+	  totallength += currentlength;
>+          PRInt32 adjustbegin = 0;
>+	  PRInt32 adjustwidth = 0;	
>+	  PRInt32 currentindex = 0;	
> 
> #ifdef IBMBIDI
>           if (currentlength > 0
>@@ -2440,24 +2479,40 @@
>           if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING
>           {
> #endif
>+	    // Compute the adjusting width to make an adjustment 
>+            if (mTabPosAndOffset && mTabNum > 0) {
>+	          if (currentoffset >= 0) {
>+		       adjustbegin = JustifyWithTab(currentoffset,&currentindex);
>+	   	       adjustwidth = JustifyWithTab(totallength) - adjustbegin;
>+		  }
>+	    }
>             if (iter.CurrentBackGroundColor(currentBKColor, &isCurrentBKColorTransparent) && !isPaginated)
>             {//DRAW RECT HERE!!!
>               if (!isCurrentBKColorTransparent) {
>                 aRenderingContext.SetColor(currentBKColor);
>-                aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height);
>+                aRenderingContext.FillRect(currentX + adjustbegin , dy, newWidth + adjustwidth, mRect.height);
>               }
>               currentFGColor = EnsureDifferentColors(currentFGColor, currentBKColor);
>             }
>           }
>           else
>             newWidth =0;
>-          
>+
>           if (isPaginated && !iter.IsBeforeOrAfter()) {
>             aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));
>-            aRenderingContext.DrawString(currenttext, currentlength, currentX, dy + mAscent);
>+            // If DrawString contain '\t', we use DrawStringWithTab to draw unicode string
>+            if (!mTabPosAndOffset || mTabNum == 0) {
>+    		  aRenderingContext.DrawString(currenttext, currentlength, currentX , dy + mAscent);
>+            } else {
>+		  DrawStringWithTab(aRenderingContext,currenttext,currentlength,currentoffset,dx,currentX,dy + mAscent,currentindex,adjustbegin);
>+	    }
>           } else if (!isPaginated) {
>             aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor));
>-            aRenderingContext.DrawString(currenttext, currentlength, currentX, dy + mAscent);
>+            if (!mTabPosAndOffset || mTabNum == 0) {
>+    		  aRenderingContext.DrawString(currenttext, currentlength, currentX , dy + mAscent);
>+   	    } else {
>+		  DrawStringWithTab(aRenderingContext,currenttext,currentlength,currentoffset,dx,currentX,dy + mAscent,currentindex,adjustbegin);
>+	    }    
>           }
> 
> #ifdef IBMBIDI
>@@ -2471,7 +2526,11 @@
>       else if (!isPaginated) 
>       {
>         aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor));
>-        aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);
>+        if (!mTabPosAndOffset || mTabNum == 0) {
>+          aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent);
>+        } else {
>+	  DrawStringWithTab(aRenderingContext,text,PRUint32(textLength),0,dx,dx,dy + mAscent,0,0);
>+	}
>       }
>       PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext,
>                            aTextStyle, dx, dy, width, text, details, 0,
>@@ -2494,6 +2553,65 @@
> #endif // IBMBIDI
>   }
> }
>+//Draw String which contain '\t'. If we will make
>+void
>+nsTextFrame::DrawStringWithTab(nsIRenderingContext& aRenderingContext,
>+				PRUnichar* aDrawString,
>+				PRInt32 aLength,
>+				PRInt32 aOffset,
>+				PRInt32 aLineOffset, 
>+				nscoord dx, nscoord dy,
>+				PRInt32 aIndex,
>+				PRInt32 aAdjustBegin)
>+{
>+  if (aIndex == mTabNum){ 
>+	aRenderingContext.DrawString(aDrawString, PRUint32(aLength), dx + aAdjustBegin,  dy);
>+	return;
>+  }
>+  if (aLength <= mTabPosAndOffset->mBuffer[aIndex] - aOffset) {
>+	aRenderingContext.DrawString(aDrawString, PRUint32(aLength), dx + aAdjustBegin, dy);
>+  } else {
>+        aRenderingContext.DrawString(aDrawString, PRUint32(mTabPosAndOffset->mBuffer[aIndex] - aOffset), dx + aAdjustBegin, dy);
>+        PRInt32 pretaboffset = mTabPosAndOffset->mBuffer[aIndex];
>+        PRInt32 pretabposition = mTabPosAndOffset->mBuffer[aIndex + 1];
>+        aDrawString += pretaboffset - aOffset;
>+        for (PRInt32 i=aIndex+3;i<mTabNum;i+=3){
>+           if (aLength > mTabPosAndOffset->mBuffer[i] - aOffset) {
>+              aRenderingContext.DrawString(aDrawString, PRUint32(mTabPosAndOffset->mBuffer[i] - pretaboffset), aLineOffset + pretabposition, dy);
>+              aDrawString += mTabPosAndOffset->mBuffer[i] - pretaboffset;
>+              pretaboffset = mTabPosAndOffset->mBuffer[i];
>+              pretabposition = mTabPosAndOffset->mBuffer[i+1];
>+           }
>+	   else
>+    	      break;
>+        }
>+	if (aLength + aOffset - pretaboffset > 0)
>+             aRenderingContext.DrawString(aDrawString, PRUint32(aLength + aOffset - pretaboffset), aLineOffset + pretabposition, dy);
>+  }
>+  return;	
>+}
>+
>+/* this function return the adjust width. Becaue the '\t' and the width 
>+of word make the word align error. The adjust width is the sum of all 
>+of the error preduced by previous tabs ('\t').
>+*/
>+
>+PRInt32
>+nsTextFrame::JustifyWithTab(PRInt32 aOffset,PRInt32* aIndex)
>+{
>+  PRInt32 index = 0;	
>+  for (index=0;index<mTabNum;index+=3) {
>+      if (aOffset < mTabPosAndOffset->mBuffer[index]) { 
>+	    if (aIndex)
>+	   	 *aIndex = index;
>+	    return (index == 0)?0:mTabPosAndOffset->mBuffer[index - 1];
>+      }
>+  }
>+  if (aIndex)
>+ 	 *aIndex = index; 
>+  return mTabPosAndOffset->mBuffer[index - 1];
>+}
>+
> 
> //measure Spaced Textvoid
> nsresult
>@@ -3416,6 +3534,59 @@
>   return PR_FALSE;
> }
> 
>+
>+
>+
>+PRBool
>+nsTextFrame::BinarySearchForPositionWithTab(nsIRenderingContext* acx, 
>+                        const PRUnichar* aText,
>+                        PRInt32    aBaseWidth,
>+                        PRInt32    aBaseInx,
>+                        PRInt32    aStartInx, 
>+                        PRInt32    aEndInx, 
>+                        PRInt32    aCursorPos, 
>+                        PRInt32&   aIndex,
>+                        PRInt32&   aTextWidth)
>+{
>+  PRInt32 range = aEndInx - aStartInx;
>+  if ((range == 1)) {// || (range == 2 && IS_HIGH_SURROGATE(aText[aStartInx]))) {
>+    aIndex   = aStartInx + aBaseInx;
>+    acx->GetWidth(aText, aIndex, aTextWidth);
>+    if (mTabPosAndOffset && mTabNum > 0) 
>+       aTextWidth += JustifyWithTab(aIndex);
>+    return PR_TRUE;
>+  }
>+
>+  PRInt32 inx = aStartInx + (range / 2);
>+
>+  // Make sure we don't leave a dangling low surrogate
>+  if (IS_HIGH_SURROGATE(aText[inx-1]))
>+    inx++;
>+
>+  PRInt32 textWidth = 0;
>+  acx->GetWidth(aText, inx, textWidth);
>+  if (mTabPosAndOffset && mTabNum > 0) 
>+       textWidth += JustifyWithTab(inx);
>+  PRInt32 fullWidth = aBaseWidth + textWidth;
>+  if (fullWidth == aCursorPos) {
>+    aTextWidth = textWidth;
>+    aIndex = inx;
>+    return PR_TRUE;
>+  } else if (aCursorPos < fullWidth) {
>+    aTextWidth = aBaseWidth;
>+    if (BinarySearchForPositionWithTab(acx, aText, aBaseWidth, aBaseInx, aStartInx, inx, aCursorPos, aIndex, aTextWidth)) {
>+      return PR_TRUE;
>+    }
>+  } else {
>+    aTextWidth = fullWidth;
>+    if (BinarySearchForPositionWithTab(acx, aText, aBaseWidth, aBaseInx, inx, aEndInx, aCursorPos, aIndex, aTextWidth)) {
>+      return PR_TRUE;
>+    }
>+  }
>+  return PR_FALSE;
>+}
>+
>+
> //---------------------------------------------------------------------------
> // Uses a binary search to find the position of the cursor in the text.
> // The "indices array is used to map from the compressed text back to the 
>@@ -3504,22 +3675,21 @@
> //END STYLE IF
>         PRInt32* ip = indexBuffer.mBuffer;
> 
>-        PRInt32 indx;
>+        PRInt32 indx = 0;
>         PRInt32 textWidth = 0;
>         PRUnichar* text = paintBuffer.mBuffer;
>-
>+        //PRUnichar* tempip = text; 
> #ifdef IBMBIDI
>         PRBool getReversedPos = NS_GET_EMBEDDING_LEVEL(this) & 1;
>         nscoord posX = (getReversedPos) ?
>                        (mRect.width + origin.x) - (aPoint.x - origin.x) : aPoint.x;
> 
>-        PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0,
>+        PRBool found = BinarySearchForPositionWithTab(acx, text, origin.x, 0, 0,
>                                                PRInt32(textLength),
>                                                PRInt32(posX) , //go to local coordinates
>                                                indx, textWidth);
>-
> #else
>-        PRBool found = BinarySearchForPosition(acx, text, origin.x, 0, 0,
>+	PRBool found = BinarySearchForPositionWithTab(acx, text, origin.x, 0, 0,
>                                                PRInt32(textLength),
>                                                PRInt32(aPoint.x) , //go to local coordinates
>                                                indx, textWidth);
>@@ -3834,10 +4004,15 @@
>       }
>       if ((hitLength == textLength) && (inOffset = mContentLength) &&
>           (mContentOffset + mContentLength == totalLength)) {
>+        if (mTabPosAndOffset  && mTabNum > 0) 
>+            inRendContext->GetWidth(paintBuffer.mBuffer, hitLength, width);
>         // no need to re-measure when at the end of the last-in-flow
>       }
>       else
>         inRendContext->GetWidth(paintBuffer.mBuffer, hitLength, width);
>+      //adjust the width because of '\t'
>+      if (mTabPosAndOffset  && mTabNum > 0) 
>+		 width += JustifyWithTab(hitLength);
>     }
>     if ((hitLength == textLength) && (TEXT_TRIMMED_WS & mState)) {
>       //
>@@ -4601,11 +4776,16 @@
>   PRBool  justDidFirstLetter = PR_FALSE;
>   nsTextDimensions dimensions, lastWordDimensions;
>   PRBool  measureTextRuns = PR_FALSE;
>-
>+  PRBool  ishavetab = PR_FALSE;
>   if (contentLength == 0) {
>     aTextData.mX = 0;
>     aTextData.mAscent = 0;
>     aTextData.mDescent = 0;
>+    if (mTabPosAndOffset) {
>+	mTabNum = 0;
>+	delete mTabPosAndOffset	;
>+	mTabPosAndOffset = nsnull;
>+    }
>     return NS_FRAME_COMPLETE;
>   }
> #if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS)
>@@ -4768,11 +4948,45 @@
>       aTextData.mFirstLetterOK = PR_FALSE;
>  
>       if ('\t' == firstChar) {
>+	ishavetab = PR_TRUE;
>         // Expand tabs to the proper width
>-        wordLen = 8 - (7 & column);
>+	wordLen = 8 - (7 & (column));
>         // Apply word spacing to every space derived from a tab
>-        dimensions.width = (aTs.mSpaceWidth + aTs.mWordSpacing + aTs.mLetterSpacing)*wordLen;
>-
>+        // The '\t'(U+0009) should be rendered as a horizontal shift with 8 times the width of a space 
>+	// (U+0020) rendered, but not add a few space (U+0020) to make up for. Because the width of
>+	// different language of word is different. The dimensions.width should be computed like below. 
>+        PRInt32 tabwidth = 8 * (aTs.mSpaceWidth + aTs.mWordSpacing + aTs.mLetterSpacing);
>+        dimensions.width = tabwidth - (aTextData.mX % tabwidth);
>+	// Like aTextData.mX, If nothing should be meausure again, we only recompute mTabNum; 
>+        if (aTextData.mMeasureText) {
>+        if (!mTabPosAndOffset) {
>+		mTabPosAndOffset = new nsAutoIndexBuffer(); 
>+		if (!mTabPosAndOffset)
>+			return NS_FRAME_NOT_COMPLETE;
>+		mTabNum = 0;
>+	}
>+        if (mTabPosAndOffset->mBufferLen < mTabNum) {
>+	  if (NS_FAILED(mTabPosAndOffset->GrowTo(mTabNum+20))) {
>+		return NS_FRAME_NOT_COMPLETE;
>+	  }
>+	}
>+	PRInt32 wordwidth = wordLen * (aTs.mSpaceWidth + aTs.mWordSpacing + aTs.mLetterSpacing);
>+	// Because when we render string, we use a randerable string in which all the '\t' was expaned by 
>+	// a few space, so we need a struct to record some useful imformation which will be use when wu paint
>+	// string in correct style.
>+	// In mTabPosAndOffset->mBuffer[3*index+i]
>+	// (i == 0) means the offsetindex of the expanded '\t' in the measure text 
>+	// (i == 1) means the layoutPosition of the expanded '\t' 
>+	// (i == 2) means the the different width  prduced by '\t' and the different word width
>+	// mTabNum means the num of '\t' in the measure text
>+        mTabPosAndOffset->mBuffer[mTabNum] = column + wordLen - mColumn;
>+        mTabPosAndOffset->mBuffer[mTabNum + 1] = dimensions.width + aTextData.mX;
>+	
>+        mTabPosAndOffset->mBuffer[mTabNum + 2] = (mTabNum == 0) ? dimensions.width - wordwidth : dimensions.width - wordwidth + mTabPosAndOffset->mBuffer[mTabNum-1];
>+	}
>+        mTabNum +=  3;
>+		
>+	//}
>         // Because we have to expand the tab when rendering consider that
>         // a transformation of the text
>         mState |= TEXT_WAS_TRANSFORMED;
>@@ -5228,6 +5442,13 @@
>     rs = NS_INLINE_LINE_BREAK_BEFORE();
>   }
> 
>+  if (!ishavetab) {
>+	if (mTabPosAndOffset) {
>+		mTabNum = 0;
>+		delete mTabPosAndOffset	;
>+		mTabPosAndOffset = nsnull;
>+	}
>+  }
>   return rs;
> }
> 
>@@ -5245,6 +5466,8 @@
>          aReflowState.availableWidth, aReflowState.availableHeight);
> #endif
> 
>+  // make the num of '\t' equal 0 when reflow begin
>+  mTabNum = 0;
>   // XXX If there's no line layout, we shouldn't even have created this
>   // frame. This may happen if, for example, this is text inside a table
>   // but not inside a cell. For now, just don't reflow.
I still think that the problem is there if you manually replace '\t' in your
testcase with 8 whitespace characters explicitly, therefore the patch doesn't
solve the problem, and it makes nsTextFrame unduly complex, and I don't like
reviewing such patches anyway.

The root of the problem is that GFX caches the width of the space character for
(premature?) optimization. And where does GFX takes that space character? In an
ASCII/Western font. I think that if you avoid this caching and make GFX actually
computes the width from the current (Chinese) font, the problem will go away.
Attachment #169810 - Flags: review?(rbs) → review-
(In reply to comment #7)
> I still think that the problem is there if you manually replace '\t' in your
> testcase with 8 whitespace characters explicitly, therefore the patch doesn't
> solve the problem, and it makes nsTextFrame unduly complex, and I don't like
> reviewing such patches anyway.
> 
> The root of the problem is that GFX caches the width of the space character for
> (premature?) optimization. And where does GFX takes that space character? In an
> ASCII/Western font. I think that if you avoid this caching and make GFX actually
> computes the width from the current (Chinese) font, the problem will go away.
> 

Thanks!
I think I should make a good study at GFX.
thank you!
This is an automated message, with ID "auto-resolve01".

This bug has had no comments for a long time. Statistically, we have found that
bug reports that have not been confirmed by a second user after three months are
highly unlikely to be the source of a fix to the code.

While your input is very important to us, our resources are limited and so we
are asking for your help in focussing our efforts. If you can still reproduce
this problem in the latest version of the product (see below for how to obtain a
copy) or, for feature requests, if it's not present in the latest version and
you still believe we should implement it, please visit the URL of this bug
(given at the top of this mail) and add a comment to that effect, giving more
reproduction information if you have it.

If it is not a problem any longer, you need take no action. If this bug is not
changed in any way in the next two weeks, it will be automatically resolved.
Thank you for your help in this matter.

The latest beta releases can be obtained from:
Firefox:     http://www.mozilla.org/projects/firefox/
Thunderbird: http://www.mozilla.org/products/thunderbird/releases/1.5beta1.html
Seamonkey:   http://www.mozilla.org/projects/seamonkey/
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: intl
OS: Linux → All
Summary: Columns are not aligned (use Tab ) if the content contains Chinese letter → Columns are not aligned (use Tab ) if the content contains Chinese/Korean/Japanese letter
*** Bug 312621 has been marked as a duplicate of this bug. ***
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: