зеркало из https://github.com/mozilla/pjs.git
Fixed underlining bug; support justification
This commit is contained in:
Родитель
585f02420a
Коммит
178db0aa2c
|
@ -69,6 +69,9 @@ static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
||||||
|
|
||||||
#define XP_TO_UPPER(_ch) ((_ch) & ~32)
|
#define XP_TO_UPPER(_ch) ((_ch) & ~32)
|
||||||
|
|
||||||
|
#define XP_IS_SPACE(_ch) \
|
||||||
|
(((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n'))
|
||||||
|
|
||||||
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
|
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
|
||||||
|
|
||||||
class TextFrame;
|
class TextFrame;
|
||||||
|
@ -137,6 +140,10 @@ public:
|
||||||
nsHTMLReflowMetrics& aMetrics,
|
nsHTMLReflowMetrics& aMetrics,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
NS_IMETHOD AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace);
|
||||||
|
NS_IMETHOD TrimTrailingWhiteSpace(nsIPresContext& aPresContext,
|
||||||
|
nsIRenderingContext& aRC,
|
||||||
|
nscoord& aDeltaWidth);
|
||||||
|
|
||||||
// TextFrame methods
|
// TextFrame methods
|
||||||
struct SelectionInfo {
|
struct SelectionInfo {
|
||||||
|
@ -163,6 +170,10 @@ public:
|
||||||
nscolor mSelectionTextColor;
|
nscolor mSelectionTextColor;
|
||||||
nscolor mSelectionBGColor;
|
nscolor mSelectionBGColor;
|
||||||
nscoord mSpaceWidth;
|
nscoord mSpaceWidth;
|
||||||
|
PRBool mJustifying;
|
||||||
|
PRIntn mNumSpaces;
|
||||||
|
nscoord mExtraSpacePerSpace;
|
||||||
|
nscoord mRemainingExtraSpace;
|
||||||
|
|
||||||
TextStyle(nsIPresContext& aPresContext,
|
TextStyle(nsIPresContext& aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
@ -209,6 +220,9 @@ public:
|
||||||
mLetterSpacing = mText->mLetterSpacing.GetCoordValue();
|
mLetterSpacing = mText->mLetterSpacing.GetCoordValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mNumSpaces = 0;
|
||||||
|
mRemainingExtraSpace = 0;
|
||||||
|
mExtraSpacePerSpace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
~TextStyle() {
|
~TextStyle() {
|
||||||
|
@ -217,12 +231,12 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
PRIntn PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
nsTextTransformer& aTransformer,
|
nsTextTransformer& aTransformer,
|
||||||
PRInt32* aIndicies,
|
PRInt32* aIndicies,
|
||||||
PRUnichar* aBuffer,
|
PRUnichar* aBuffer,
|
||||||
PRInt32& aTextLen,
|
PRInt32& aTextLen,
|
||||||
nscoord& aNewWidth);
|
nscoord& aNewWidth);
|
||||||
|
|
||||||
void PaintTextDecorations(nsIRenderingContext& aRenderingContext,
|
void PaintTextDecorations(nsIRenderingContext& aRenderingContext,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
|
@ -286,6 +300,7 @@ protected:
|
||||||
PRInt32 mContentLength;
|
PRInt32 mContentLength;
|
||||||
PRUint32 mFlags;
|
PRUint32 mFlags;
|
||||||
PRInt32 mColumn;
|
PRInt32 mColumn;
|
||||||
|
nscoord mComputedWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flag information used by rendering code. This information is
|
// Flag information used by rendering code. This information is
|
||||||
|
@ -305,6 +320,8 @@ protected:
|
||||||
|
|
||||||
#define TEXT_FIRST_LETTER 0x20
|
#define TEXT_FIRST_LETTER 0x20
|
||||||
|
|
||||||
|
#define TEXT_TRIMMED_WS 0x40
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
static PRBool gBlinkTextOff;
|
static PRBool gBlinkTextOff;
|
||||||
|
@ -512,7 +529,8 @@ TextFrame::Paint(nsIPresContext& aPresContext,
|
||||||
if (disp->mVisible) {
|
if (disp->mVisible) {
|
||||||
TextStyle ts(aPresContext, aRenderingContext, sc);
|
TextStyle ts(aPresContext, aRenderingContext, sc);
|
||||||
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing) ||
|
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing) ||
|
||||||
(NS_STYLE_TEXT_ALIGN_JUSTIFY == ts.mText->mTextAlign)) {
|
((NS_STYLE_TEXT_ALIGN_JUSTIFY == ts.mText->mTextAlign) &&
|
||||||
|
(mRect.width > mComputedWidth))) {
|
||||||
PaintTextSlowly(aPresContext, aRenderingContext, sc, ts, 0, 0);
|
PaintTextSlowly(aPresContext, aRenderingContext, sc, ts, 0, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -671,7 +689,7 @@ TextFrame::ComputeSelectionInfo(nsIRenderingContext& aRenderingContext,
|
||||||
* then fill in aIndexes's with the mapping from the original input to
|
* then fill in aIndexes's with the mapping from the original input to
|
||||||
* the prepared output.
|
* the prepared output.
|
||||||
*/
|
*/
|
||||||
void
|
PRIntn
|
||||||
TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
nsTextTransformer& aTX,
|
nsTextTransformer& aTX,
|
||||||
PRInt32* aIndexes,
|
PRInt32* aIndexes,
|
||||||
|
@ -679,6 +697,7 @@ TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
PRInt32& aTextLen,
|
PRInt32& aTextLen,
|
||||||
nscoord& aNewWidth)
|
nscoord& aNewWidth)
|
||||||
{
|
{
|
||||||
|
PRIntn numSpaces = 0;
|
||||||
PRUnichar* dst = aBuffer;
|
PRUnichar* dst = aBuffer;
|
||||||
|
|
||||||
// Setup transform to operate starting in the content at our content
|
// Setup transform to operate starting in the content at our content
|
||||||
|
@ -727,6 +746,7 @@ TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
}
|
}
|
||||||
inWord = PR_FALSE;
|
inWord = PR_FALSE;
|
||||||
if (isWhitespace) {
|
if (isWhitespace) {
|
||||||
|
numSpaces++;
|
||||||
if ('\t' == bp[0]) {
|
if ('\t' == bp[0]) {
|
||||||
PRInt32 spaces = 8 - (7 & column);
|
PRInt32 spaces = 8 - (7 & column);
|
||||||
PRUnichar* tp = bp;
|
PRUnichar* tp = bp;
|
||||||
|
@ -771,28 +791,19 @@ TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
NS_ASSERTION(n >= 0, "whoops");
|
NS_ASSERTION(n >= 0, "whoops");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now remove trailing whitespace if appropriate. It's appropriate
|
// Remove trailing whitespace if it was trimmed after reflow
|
||||||
// if this frame is continued. And it's also appropriate if this is
|
if (TEXT_TRIMMED_WS & mFlags) {
|
||||||
// not last (or only) frame in a text-run.
|
if (--dst >= aBuffer) {
|
||||||
// XXX fix this to fully obey the comment!
|
PRUnichar ch = *dst;
|
||||||
if (nsnull != mNextInFlow) {
|
if (XP_IS_SPACE(ch)) {
|
||||||
PRIntn zapped = 0;
|
|
||||||
while (dst > aBuffer) {
|
|
||||||
if (dst[-1] == ' ') {
|
|
||||||
dst--;
|
|
||||||
textLength--;
|
textLength--;
|
||||||
zapped++;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (0 != zapped) {
|
|
||||||
nscoord spaceWidth;
|
|
||||||
aRenderingContext.GetWidth(' ', spaceWidth);
|
|
||||||
aNewWidth = aNewWidth - spaceWidth*zapped;
|
|
||||||
}
|
}
|
||||||
|
numSpaces--;
|
||||||
}
|
}
|
||||||
|
|
||||||
aTextLen = textLength;
|
aTextLen = textLength;
|
||||||
|
return numSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX This clearly needs to be done by the container, *somehow*
|
// XXX This clearly needs to be done by the container, *somehow*
|
||||||
|
@ -836,8 +847,8 @@ TextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext,
|
||||||
nscolor underColor;
|
nscolor underColor;
|
||||||
nscolor strikeColor;
|
nscolor strikeColor;
|
||||||
nsIStyleContext* context = aStyleContext;
|
nsIStyleContext* context = aStyleContext;
|
||||||
PRUint8 decorations = aTextStyle.mText->mTextDecoration;
|
PRUint8 decorations = aTextStyle.mFont->mFont.decorations;
|
||||||
PRUint8 decorMask = decorMask;
|
PRUint8 decorMask = decorations;
|
||||||
|
|
||||||
NS_ADDREF(context);
|
NS_ADDREF(context);
|
||||||
do { // find decoration colors
|
do { // find decoration colors
|
||||||
|
@ -1017,7 +1028,7 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
PRUnichar* bp = bp0;
|
PRUnichar* bp = bp0;
|
||||||
|
|
||||||
PRBool spacing = (0 != aTextStyle.mLetterSpacing) ||
|
PRBool spacing = (0 != aTextStyle.mLetterSpacing) ||
|
||||||
(0 != aTextStyle.mWordSpacing);
|
(0 != aTextStyle.mWordSpacing) || (mRect.width > mComputedWidth);
|
||||||
nscoord spacingMem[TEXT_BUF_SIZE];
|
nscoord spacingMem[TEXT_BUF_SIZE];
|
||||||
PRIntn* sp0 = spacingMem;
|
PRIntn* sp0 = spacingMem;
|
||||||
if (spacing && (aLength > TEXT_BUF_SIZE)) {
|
if (spacing && (aLength > TEXT_BUF_SIZE)) {
|
||||||
|
@ -1065,6 +1076,11 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
nextFont = aTextStyle.mNormalFont;
|
nextFont = aTextStyle.mNormalFont;
|
||||||
nextY = aY;
|
nextY = aY;
|
||||||
glyphWidth = aTextStyle.mSpaceWidth + aTextStyle.mWordSpacing;
|
glyphWidth = aTextStyle.mSpaceWidth + aTextStyle.mWordSpacing;
|
||||||
|
nscoord extra = aTextStyle.mExtraSpacePerSpace;
|
||||||
|
if (--aTextStyle.mNumSpaces == 0) {
|
||||||
|
extra += aTextStyle.mRemainingExtraSpace;
|
||||||
|
}
|
||||||
|
glyphWidth += extra;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (lastFont != aTextStyle.mNormalFont) {
|
if (lastFont != aTextStyle.mNormalFont) {
|
||||||
|
@ -1088,6 +1104,7 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
spacing ? sp0 : nsnull);
|
spacing ? sp0 : nsnull);
|
||||||
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
||||||
aX, lastY, width);
|
aX, lastY, width);
|
||||||
|
aWidth -= width;
|
||||||
aX += width;
|
aX += width;
|
||||||
runStart = bp = bp0;
|
runStart = bp = bp0;
|
||||||
sp = sp0;
|
sp = sp0;
|
||||||
|
@ -1107,7 +1124,7 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
aRenderingContext.DrawString(runStart, pendingCount, aX, lastY, width,
|
aRenderingContext.DrawString(runStart, pendingCount, aX, lastY, width,
|
||||||
spacing ? sp0 : nsnull);
|
spacing ? sp0 : nsnull);
|
||||||
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
||||||
aX, lastY, width);
|
aX, lastY, aWidth);
|
||||||
}
|
}
|
||||||
aTextStyle.mLastFont = lastFont;
|
aTextStyle.mLastFont = lastFont;
|
||||||
|
|
||||||
|
@ -1134,6 +1151,7 @@ TextFrame::MeasureSmallCapsText(const nsHTMLReflowState& aReflowState,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX factor in logic from RenderString into here; gaps, justification, etc.
|
||||||
void
|
void
|
||||||
TextFrame::GetWidth(nsIRenderingContext& aRenderingContext,
|
TextFrame::GetWidth(nsIRenderingContext& aRenderingContext,
|
||||||
TextStyle& aTextStyle,
|
TextStyle& aTextStyle,
|
||||||
|
@ -1214,9 +1232,24 @@ TextFrame::PaintTextSlowly(nsIPresContext& aPresContext,
|
||||||
|
|
||||||
// Transform text from content into renderable form
|
// Transform text from content into renderable form
|
||||||
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE);
|
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE);
|
||||||
PrepareUnicodeText(aRenderingContext, tx,
|
aTextStyle.mNumSpaces = PrepareUnicodeText(aRenderingContext, tx,
|
||||||
displaySelection ? ip : nsnull,
|
displaySelection ? ip : nsnull,
|
||||||
paintBuf, textLength, width);
|
paintBuf, textLength, width);
|
||||||
|
if (mRect.width > mComputedWidth) {
|
||||||
|
if (0 != aTextStyle.mNumSpaces) {
|
||||||
|
nscoord extra = mRect.width - mComputedWidth;
|
||||||
|
nscoord adjustPerSpace =
|
||||||
|
aTextStyle.mExtraSpacePerSpace = extra / aTextStyle.mNumSpaces;
|
||||||
|
aTextStyle.mRemainingExtraSpace = extra -
|
||||||
|
(aTextStyle.mExtraSpacePerSpace * aTextStyle.mNumSpaces);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We have no whitespace but were given some extra space. There
|
||||||
|
// are two plausible places to put the extra space: to the left
|
||||||
|
// and to the right. If this is anywhere but the last place on
|
||||||
|
// the line then the correct answer is to the right.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRUnichar* text = paintBuf;
|
PRUnichar* text = paintBuf;
|
||||||
if (0 != textLength) {
|
if (0 != textLength) {
|
||||||
|
@ -1807,6 +1840,7 @@ TextFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
|
|
||||||
// Setup metrics for caller; store final max-element-size information
|
// Setup metrics for caller; store final max-element-size information
|
||||||
aMetrics.width = x;
|
aMetrics.width = x;
|
||||||
|
mComputedWidth = x;
|
||||||
if (0 == x) {
|
if (0 == x) {
|
||||||
aMetrics.height = 0;
|
aMetrics.height = 0;
|
||||||
aMetrics.ascent = 0;
|
aMetrics.ascent = 0;
|
||||||
|
@ -1850,6 +1884,138 @@ TextFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TextFrame::AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace)
|
||||||
|
{
|
||||||
|
// Get the text fragments that make up our content
|
||||||
|
nsTextFragment* frag;
|
||||||
|
PRInt32 numFrags;
|
||||||
|
nsITextContent* tc;
|
||||||
|
if (NS_OK == mContent->QueryInterface(kITextContentIID, (void**) &tc)) {
|
||||||
|
tc->GetText(frag, numFrags);
|
||||||
|
NS_RELEASE(tc);
|
||||||
|
|
||||||
|
// Find fragment that contains the end of the mapped content
|
||||||
|
PRInt32 endIndex = mContentOffset + mContentLength;
|
||||||
|
PRInt32 offset = 0;
|
||||||
|
nsTextFragment* lastFrag = frag + numFrags;
|
||||||
|
while (frag < lastFrag) {
|
||||||
|
PRInt32 fragLen = frag->GetLength();
|
||||||
|
if (endIndex <= offset + fragLen) {
|
||||||
|
offset = mContentOffset - offset;
|
||||||
|
if (frag->Is2b()) {
|
||||||
|
const PRUnichar* cp = frag->Get2b() + offset;
|
||||||
|
const PRUnichar* end = cp + mContentLength;
|
||||||
|
while (cp < end) {
|
||||||
|
PRUnichar ch = *cp++;
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
aUsedSpace = aExtraSpace;
|
||||||
|
mRect.width += aExtraSpace;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const unsigned char* cp =
|
||||||
|
((const unsigned char*)frag->Get1b()) + offset;
|
||||||
|
const unsigned char* end = cp + mContentLength;
|
||||||
|
while (cp < end) {
|
||||||
|
PRUnichar ch = PRUnichar(*cp++);
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
aUsedSpace = aExtraSpace;
|
||||||
|
mRect.width += aExtraSpace;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += fragLen;
|
||||||
|
frag++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aUsedSpace = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TextFrame::TrimTrailingWhiteSpace(nsIPresContext& aPresContext,
|
||||||
|
nsIRenderingContext& aRC,
|
||||||
|
nscoord& aDeltaWidth)
|
||||||
|
{
|
||||||
|
nscoord dw = 0;
|
||||||
|
const nsStyleText* textStyle = (const nsStyleText*)
|
||||||
|
mStyleContext->GetStyleData(eStyleStruct_Text);
|
||||||
|
if (NS_STYLE_WHITESPACE_PRE != textStyle->mWhiteSpace) {
|
||||||
|
// Get font metrics for a space so we can adjust the width by the
|
||||||
|
// right amount.
|
||||||
|
const nsStyleFont* fontStyle = (const nsStyleFont*)
|
||||||
|
mStyleContext->GetStyleData(eStyleStruct_Font);
|
||||||
|
nscoord spaceWidth;
|
||||||
|
aRC.SetFont(fontStyle->mFont);
|
||||||
|
aRC.GetWidth(' ', spaceWidth);
|
||||||
|
|
||||||
|
// Get the text fragments that make up our content
|
||||||
|
nsTextFragment* frag;
|
||||||
|
PRInt32 numFrags;
|
||||||
|
nsITextContent* tc;
|
||||||
|
if (NS_OK == mContent->QueryInterface(kITextContentIID, (void**) &tc)) {
|
||||||
|
tc->GetText(frag, numFrags);
|
||||||
|
NS_RELEASE(tc);
|
||||||
|
|
||||||
|
// Find fragment that contains the end of the mapped content
|
||||||
|
PRInt32 endIndex = mContentOffset + mContentLength;
|
||||||
|
PRInt32 offset = 0;
|
||||||
|
nsTextFragment* lastFrag = frag + numFrags;
|
||||||
|
while (frag < lastFrag) {
|
||||||
|
PRInt32 fragLen = frag->GetLength();
|
||||||
|
if (endIndex <= offset + fragLen) {
|
||||||
|
// Look inside the fragments last few characters and see if they
|
||||||
|
// are whitespace. If so, count how much width was supplied by
|
||||||
|
// them.
|
||||||
|
offset = mContentOffset - offset;
|
||||||
|
if (frag->Is2b()) {
|
||||||
|
// XXX If by chance the last content fragment is *all*
|
||||||
|
// whitespace then this won't back up far enough.
|
||||||
|
const PRUnichar* cp = frag->Get2b() + offset;
|
||||||
|
const PRUnichar* end = cp + mContentLength;
|
||||||
|
if (--end >= cp) {
|
||||||
|
PRUnichar ch = *end;
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
dw = spaceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const unsigned char* cp =
|
||||||
|
((const unsigned char*)frag->Get1b()) + offset;
|
||||||
|
const unsigned char* end = cp + mContentLength;
|
||||||
|
if (--end >= cp) {
|
||||||
|
PRUnichar ch = PRUnichar(*end);
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
dw = spaceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += fragLen;
|
||||||
|
frag++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mRect.width -= dw;
|
||||||
|
mComputedWidth -= dw;
|
||||||
|
}
|
||||||
|
if (0 != dw) {
|
||||||
|
mFlags |= TEXT_TRIMMED_WS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mFlags &= ~TEXT_TRIMMED_WS;
|
||||||
|
}
|
||||||
|
aDeltaWidth = dw;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nscoord
|
nscoord
|
||||||
TextFrame::ComputeTotalWordWidth(nsLineLayout& aLineLayout,
|
TextFrame::ComputeTotalWordWidth(nsLineLayout& aLineLayout,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
|
|
@ -69,6 +69,9 @@ static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
||||||
|
|
||||||
#define XP_TO_UPPER(_ch) ((_ch) & ~32)
|
#define XP_TO_UPPER(_ch) ((_ch) & ~32)
|
||||||
|
|
||||||
|
#define XP_IS_SPACE(_ch) \
|
||||||
|
(((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n'))
|
||||||
|
|
||||||
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
|
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
|
||||||
|
|
||||||
class TextFrame;
|
class TextFrame;
|
||||||
|
@ -137,6 +140,10 @@ public:
|
||||||
nsHTMLReflowMetrics& aMetrics,
|
nsHTMLReflowMetrics& aMetrics,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
NS_IMETHOD AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace);
|
||||||
|
NS_IMETHOD TrimTrailingWhiteSpace(nsIPresContext& aPresContext,
|
||||||
|
nsIRenderingContext& aRC,
|
||||||
|
nscoord& aDeltaWidth);
|
||||||
|
|
||||||
// TextFrame methods
|
// TextFrame methods
|
||||||
struct SelectionInfo {
|
struct SelectionInfo {
|
||||||
|
@ -163,6 +170,10 @@ public:
|
||||||
nscolor mSelectionTextColor;
|
nscolor mSelectionTextColor;
|
||||||
nscolor mSelectionBGColor;
|
nscolor mSelectionBGColor;
|
||||||
nscoord mSpaceWidth;
|
nscoord mSpaceWidth;
|
||||||
|
PRBool mJustifying;
|
||||||
|
PRIntn mNumSpaces;
|
||||||
|
nscoord mExtraSpacePerSpace;
|
||||||
|
nscoord mRemainingExtraSpace;
|
||||||
|
|
||||||
TextStyle(nsIPresContext& aPresContext,
|
TextStyle(nsIPresContext& aPresContext,
|
||||||
nsIRenderingContext& aRenderingContext,
|
nsIRenderingContext& aRenderingContext,
|
||||||
|
@ -209,6 +220,9 @@ public:
|
||||||
mLetterSpacing = mText->mLetterSpacing.GetCoordValue();
|
mLetterSpacing = mText->mLetterSpacing.GetCoordValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mNumSpaces = 0;
|
||||||
|
mRemainingExtraSpace = 0;
|
||||||
|
mExtraSpacePerSpace = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
~TextStyle() {
|
~TextStyle() {
|
||||||
|
@ -217,12 +231,12 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
PRIntn PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
nsTextTransformer& aTransformer,
|
nsTextTransformer& aTransformer,
|
||||||
PRInt32* aIndicies,
|
PRInt32* aIndicies,
|
||||||
PRUnichar* aBuffer,
|
PRUnichar* aBuffer,
|
||||||
PRInt32& aTextLen,
|
PRInt32& aTextLen,
|
||||||
nscoord& aNewWidth);
|
nscoord& aNewWidth);
|
||||||
|
|
||||||
void PaintTextDecorations(nsIRenderingContext& aRenderingContext,
|
void PaintTextDecorations(nsIRenderingContext& aRenderingContext,
|
||||||
nsIStyleContext* aStyleContext,
|
nsIStyleContext* aStyleContext,
|
||||||
|
@ -286,6 +300,7 @@ protected:
|
||||||
PRInt32 mContentLength;
|
PRInt32 mContentLength;
|
||||||
PRUint32 mFlags;
|
PRUint32 mFlags;
|
||||||
PRInt32 mColumn;
|
PRInt32 mColumn;
|
||||||
|
nscoord mComputedWidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flag information used by rendering code. This information is
|
// Flag information used by rendering code. This information is
|
||||||
|
@ -305,6 +320,8 @@ protected:
|
||||||
|
|
||||||
#define TEXT_FIRST_LETTER 0x20
|
#define TEXT_FIRST_LETTER 0x20
|
||||||
|
|
||||||
|
#define TEXT_TRIMMED_WS 0x40
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
static PRBool gBlinkTextOff;
|
static PRBool gBlinkTextOff;
|
||||||
|
@ -512,7 +529,8 @@ TextFrame::Paint(nsIPresContext& aPresContext,
|
||||||
if (disp->mVisible) {
|
if (disp->mVisible) {
|
||||||
TextStyle ts(aPresContext, aRenderingContext, sc);
|
TextStyle ts(aPresContext, aRenderingContext, sc);
|
||||||
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing) ||
|
if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing) ||
|
||||||
(NS_STYLE_TEXT_ALIGN_JUSTIFY == ts.mText->mTextAlign)) {
|
((NS_STYLE_TEXT_ALIGN_JUSTIFY == ts.mText->mTextAlign) &&
|
||||||
|
(mRect.width > mComputedWidth))) {
|
||||||
PaintTextSlowly(aPresContext, aRenderingContext, sc, ts, 0, 0);
|
PaintTextSlowly(aPresContext, aRenderingContext, sc, ts, 0, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -671,7 +689,7 @@ TextFrame::ComputeSelectionInfo(nsIRenderingContext& aRenderingContext,
|
||||||
* then fill in aIndexes's with the mapping from the original input to
|
* then fill in aIndexes's with the mapping from the original input to
|
||||||
* the prepared output.
|
* the prepared output.
|
||||||
*/
|
*/
|
||||||
void
|
PRIntn
|
||||||
TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
nsTextTransformer& aTX,
|
nsTextTransformer& aTX,
|
||||||
PRInt32* aIndexes,
|
PRInt32* aIndexes,
|
||||||
|
@ -679,6 +697,7 @@ TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
PRInt32& aTextLen,
|
PRInt32& aTextLen,
|
||||||
nscoord& aNewWidth)
|
nscoord& aNewWidth)
|
||||||
{
|
{
|
||||||
|
PRIntn numSpaces = 0;
|
||||||
PRUnichar* dst = aBuffer;
|
PRUnichar* dst = aBuffer;
|
||||||
|
|
||||||
// Setup transform to operate starting in the content at our content
|
// Setup transform to operate starting in the content at our content
|
||||||
|
@ -727,6 +746,7 @@ TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
}
|
}
|
||||||
inWord = PR_FALSE;
|
inWord = PR_FALSE;
|
||||||
if (isWhitespace) {
|
if (isWhitespace) {
|
||||||
|
numSpaces++;
|
||||||
if ('\t' == bp[0]) {
|
if ('\t' == bp[0]) {
|
||||||
PRInt32 spaces = 8 - (7 & column);
|
PRInt32 spaces = 8 - (7 & column);
|
||||||
PRUnichar* tp = bp;
|
PRUnichar* tp = bp;
|
||||||
|
@ -771,28 +791,19 @@ TextFrame::PrepareUnicodeText(nsIRenderingContext& aRenderingContext,
|
||||||
NS_ASSERTION(n >= 0, "whoops");
|
NS_ASSERTION(n >= 0, "whoops");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now remove trailing whitespace if appropriate. It's appropriate
|
// Remove trailing whitespace if it was trimmed after reflow
|
||||||
// if this frame is continued. And it's also appropriate if this is
|
if (TEXT_TRIMMED_WS & mFlags) {
|
||||||
// not last (or only) frame in a text-run.
|
if (--dst >= aBuffer) {
|
||||||
// XXX fix this to fully obey the comment!
|
PRUnichar ch = *dst;
|
||||||
if (nsnull != mNextInFlow) {
|
if (XP_IS_SPACE(ch)) {
|
||||||
PRIntn zapped = 0;
|
|
||||||
while (dst > aBuffer) {
|
|
||||||
if (dst[-1] == ' ') {
|
|
||||||
dst--;
|
|
||||||
textLength--;
|
textLength--;
|
||||||
zapped++;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (0 != zapped) {
|
|
||||||
nscoord spaceWidth;
|
|
||||||
aRenderingContext.GetWidth(' ', spaceWidth);
|
|
||||||
aNewWidth = aNewWidth - spaceWidth*zapped;
|
|
||||||
}
|
}
|
||||||
|
numSpaces--;
|
||||||
}
|
}
|
||||||
|
|
||||||
aTextLen = textLength;
|
aTextLen = textLength;
|
||||||
|
return numSpaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX This clearly needs to be done by the container, *somehow*
|
// XXX This clearly needs to be done by the container, *somehow*
|
||||||
|
@ -836,8 +847,8 @@ TextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext,
|
||||||
nscolor underColor;
|
nscolor underColor;
|
||||||
nscolor strikeColor;
|
nscolor strikeColor;
|
||||||
nsIStyleContext* context = aStyleContext;
|
nsIStyleContext* context = aStyleContext;
|
||||||
PRUint8 decorations = aTextStyle.mText->mTextDecoration;
|
PRUint8 decorations = aTextStyle.mFont->mFont.decorations;
|
||||||
PRUint8 decorMask = decorMask;
|
PRUint8 decorMask = decorations;
|
||||||
|
|
||||||
NS_ADDREF(context);
|
NS_ADDREF(context);
|
||||||
do { // find decoration colors
|
do { // find decoration colors
|
||||||
|
@ -1017,7 +1028,7 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
PRUnichar* bp = bp0;
|
PRUnichar* bp = bp0;
|
||||||
|
|
||||||
PRBool spacing = (0 != aTextStyle.mLetterSpacing) ||
|
PRBool spacing = (0 != aTextStyle.mLetterSpacing) ||
|
||||||
(0 != aTextStyle.mWordSpacing);
|
(0 != aTextStyle.mWordSpacing) || (mRect.width > mComputedWidth);
|
||||||
nscoord spacingMem[TEXT_BUF_SIZE];
|
nscoord spacingMem[TEXT_BUF_SIZE];
|
||||||
PRIntn* sp0 = spacingMem;
|
PRIntn* sp0 = spacingMem;
|
||||||
if (spacing && (aLength > TEXT_BUF_SIZE)) {
|
if (spacing && (aLength > TEXT_BUF_SIZE)) {
|
||||||
|
@ -1065,6 +1076,11 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
nextFont = aTextStyle.mNormalFont;
|
nextFont = aTextStyle.mNormalFont;
|
||||||
nextY = aY;
|
nextY = aY;
|
||||||
glyphWidth = aTextStyle.mSpaceWidth + aTextStyle.mWordSpacing;
|
glyphWidth = aTextStyle.mSpaceWidth + aTextStyle.mWordSpacing;
|
||||||
|
nscoord extra = aTextStyle.mExtraSpacePerSpace;
|
||||||
|
if (--aTextStyle.mNumSpaces == 0) {
|
||||||
|
extra += aTextStyle.mRemainingExtraSpace;
|
||||||
|
}
|
||||||
|
glyphWidth += extra;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (lastFont != aTextStyle.mNormalFont) {
|
if (lastFont != aTextStyle.mNormalFont) {
|
||||||
|
@ -1088,6 +1104,7 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
spacing ? sp0 : nsnull);
|
spacing ? sp0 : nsnull);
|
||||||
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
||||||
aX, lastY, width);
|
aX, lastY, width);
|
||||||
|
aWidth -= width;
|
||||||
aX += width;
|
aX += width;
|
||||||
runStart = bp = bp0;
|
runStart = bp = bp0;
|
||||||
sp = sp0;
|
sp = sp0;
|
||||||
|
@ -1107,7 +1124,7 @@ TextFrame::RenderString(nsIRenderingContext& aRenderingContext,
|
||||||
aRenderingContext.DrawString(runStart, pendingCount, aX, lastY, width,
|
aRenderingContext.DrawString(runStart, pendingCount, aX, lastY, width,
|
||||||
spacing ? sp0 : nsnull);
|
spacing ? sp0 : nsnull);
|
||||||
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
|
||||||
aX, lastY, width);
|
aX, lastY, aWidth);
|
||||||
}
|
}
|
||||||
aTextStyle.mLastFont = lastFont;
|
aTextStyle.mLastFont = lastFont;
|
||||||
|
|
||||||
|
@ -1134,6 +1151,7 @@ TextFrame::MeasureSmallCapsText(const nsHTMLReflowState& aReflowState,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX factor in logic from RenderString into here; gaps, justification, etc.
|
||||||
void
|
void
|
||||||
TextFrame::GetWidth(nsIRenderingContext& aRenderingContext,
|
TextFrame::GetWidth(nsIRenderingContext& aRenderingContext,
|
||||||
TextStyle& aTextStyle,
|
TextStyle& aTextStyle,
|
||||||
|
@ -1214,9 +1232,24 @@ TextFrame::PaintTextSlowly(nsIPresContext& aPresContext,
|
||||||
|
|
||||||
// Transform text from content into renderable form
|
// Transform text from content into renderable form
|
||||||
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE);
|
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE);
|
||||||
PrepareUnicodeText(aRenderingContext, tx,
|
aTextStyle.mNumSpaces = PrepareUnicodeText(aRenderingContext, tx,
|
||||||
displaySelection ? ip : nsnull,
|
displaySelection ? ip : nsnull,
|
||||||
paintBuf, textLength, width);
|
paintBuf, textLength, width);
|
||||||
|
if (mRect.width > mComputedWidth) {
|
||||||
|
if (0 != aTextStyle.mNumSpaces) {
|
||||||
|
nscoord extra = mRect.width - mComputedWidth;
|
||||||
|
nscoord adjustPerSpace =
|
||||||
|
aTextStyle.mExtraSpacePerSpace = extra / aTextStyle.mNumSpaces;
|
||||||
|
aTextStyle.mRemainingExtraSpace = extra -
|
||||||
|
(aTextStyle.mExtraSpacePerSpace * aTextStyle.mNumSpaces);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We have no whitespace but were given some extra space. There
|
||||||
|
// are two plausible places to put the extra space: to the left
|
||||||
|
// and to the right. If this is anywhere but the last place on
|
||||||
|
// the line then the correct answer is to the right.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRUnichar* text = paintBuf;
|
PRUnichar* text = paintBuf;
|
||||||
if (0 != textLength) {
|
if (0 != textLength) {
|
||||||
|
@ -1807,6 +1840,7 @@ TextFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
|
|
||||||
// Setup metrics for caller; store final max-element-size information
|
// Setup metrics for caller; store final max-element-size information
|
||||||
aMetrics.width = x;
|
aMetrics.width = x;
|
||||||
|
mComputedWidth = x;
|
||||||
if (0 == x) {
|
if (0 == x) {
|
||||||
aMetrics.height = 0;
|
aMetrics.height = 0;
|
||||||
aMetrics.ascent = 0;
|
aMetrics.ascent = 0;
|
||||||
|
@ -1850,6 +1884,138 @@ TextFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TextFrame::AdjustFrameSize(nscoord aExtraSpace, nscoord& aUsedSpace)
|
||||||
|
{
|
||||||
|
// Get the text fragments that make up our content
|
||||||
|
nsTextFragment* frag;
|
||||||
|
PRInt32 numFrags;
|
||||||
|
nsITextContent* tc;
|
||||||
|
if (NS_OK == mContent->QueryInterface(kITextContentIID, (void**) &tc)) {
|
||||||
|
tc->GetText(frag, numFrags);
|
||||||
|
NS_RELEASE(tc);
|
||||||
|
|
||||||
|
// Find fragment that contains the end of the mapped content
|
||||||
|
PRInt32 endIndex = mContentOffset + mContentLength;
|
||||||
|
PRInt32 offset = 0;
|
||||||
|
nsTextFragment* lastFrag = frag + numFrags;
|
||||||
|
while (frag < lastFrag) {
|
||||||
|
PRInt32 fragLen = frag->GetLength();
|
||||||
|
if (endIndex <= offset + fragLen) {
|
||||||
|
offset = mContentOffset - offset;
|
||||||
|
if (frag->Is2b()) {
|
||||||
|
const PRUnichar* cp = frag->Get2b() + offset;
|
||||||
|
const PRUnichar* end = cp + mContentLength;
|
||||||
|
while (cp < end) {
|
||||||
|
PRUnichar ch = *cp++;
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
aUsedSpace = aExtraSpace;
|
||||||
|
mRect.width += aExtraSpace;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const unsigned char* cp =
|
||||||
|
((const unsigned char*)frag->Get1b()) + offset;
|
||||||
|
const unsigned char* end = cp + mContentLength;
|
||||||
|
while (cp < end) {
|
||||||
|
PRUnichar ch = PRUnichar(*cp++);
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
aUsedSpace = aExtraSpace;
|
||||||
|
mRect.width += aExtraSpace;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += fragLen;
|
||||||
|
frag++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aUsedSpace = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
TextFrame::TrimTrailingWhiteSpace(nsIPresContext& aPresContext,
|
||||||
|
nsIRenderingContext& aRC,
|
||||||
|
nscoord& aDeltaWidth)
|
||||||
|
{
|
||||||
|
nscoord dw = 0;
|
||||||
|
const nsStyleText* textStyle = (const nsStyleText*)
|
||||||
|
mStyleContext->GetStyleData(eStyleStruct_Text);
|
||||||
|
if (NS_STYLE_WHITESPACE_PRE != textStyle->mWhiteSpace) {
|
||||||
|
// Get font metrics for a space so we can adjust the width by the
|
||||||
|
// right amount.
|
||||||
|
const nsStyleFont* fontStyle = (const nsStyleFont*)
|
||||||
|
mStyleContext->GetStyleData(eStyleStruct_Font);
|
||||||
|
nscoord spaceWidth;
|
||||||
|
aRC.SetFont(fontStyle->mFont);
|
||||||
|
aRC.GetWidth(' ', spaceWidth);
|
||||||
|
|
||||||
|
// Get the text fragments that make up our content
|
||||||
|
nsTextFragment* frag;
|
||||||
|
PRInt32 numFrags;
|
||||||
|
nsITextContent* tc;
|
||||||
|
if (NS_OK == mContent->QueryInterface(kITextContentIID, (void**) &tc)) {
|
||||||
|
tc->GetText(frag, numFrags);
|
||||||
|
NS_RELEASE(tc);
|
||||||
|
|
||||||
|
// Find fragment that contains the end of the mapped content
|
||||||
|
PRInt32 endIndex = mContentOffset + mContentLength;
|
||||||
|
PRInt32 offset = 0;
|
||||||
|
nsTextFragment* lastFrag = frag + numFrags;
|
||||||
|
while (frag < lastFrag) {
|
||||||
|
PRInt32 fragLen = frag->GetLength();
|
||||||
|
if (endIndex <= offset + fragLen) {
|
||||||
|
// Look inside the fragments last few characters and see if they
|
||||||
|
// are whitespace. If so, count how much width was supplied by
|
||||||
|
// them.
|
||||||
|
offset = mContentOffset - offset;
|
||||||
|
if (frag->Is2b()) {
|
||||||
|
// XXX If by chance the last content fragment is *all*
|
||||||
|
// whitespace then this won't back up far enough.
|
||||||
|
const PRUnichar* cp = frag->Get2b() + offset;
|
||||||
|
const PRUnichar* end = cp + mContentLength;
|
||||||
|
if (--end >= cp) {
|
||||||
|
PRUnichar ch = *end;
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
dw = spaceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const unsigned char* cp =
|
||||||
|
((const unsigned char*)frag->Get1b()) + offset;
|
||||||
|
const unsigned char* end = cp + mContentLength;
|
||||||
|
if (--end >= cp) {
|
||||||
|
PRUnichar ch = PRUnichar(*end);
|
||||||
|
if (XP_IS_SPACE(ch)) {
|
||||||
|
dw = spaceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += fragLen;
|
||||||
|
frag++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mRect.width -= dw;
|
||||||
|
mComputedWidth -= dw;
|
||||||
|
}
|
||||||
|
if (0 != dw) {
|
||||||
|
mFlags |= TEXT_TRIMMED_WS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mFlags &= ~TEXT_TRIMMED_WS;
|
||||||
|
}
|
||||||
|
aDeltaWidth = dw;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nscoord
|
nscoord
|
||||||
TextFrame::ComputeTotalWordWidth(nsLineLayout& aLineLayout,
|
TextFrame::ComputeTotalWordWidth(nsLineLayout& aLineLayout,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче