bug 4238; r/a=ftang,buster,waterson; added language specific transforms so

that we can do things like U+005C -> U+00A5 (backslash -> yen sign for ja)


git-svn-id: svn://10.0.0.236/trunk@79661 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
erik%netscape.com
2000-09-20 23:00:32 +00:00
parent 47844e796a
commit 791ffe17b5
6 changed files with 152 additions and 40 deletions

View File

@@ -1780,7 +1780,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),
@@ -1930,7 +1930,7 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
// Transform text from content into renderable form
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
PRInt32 numSpaces;
@@ -2302,7 +2302,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 numSpaces;
numSpaces = PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),
@@ -2456,7 +2456,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
// See if we need to transform the text. If the text fragment is ascii and
// wasn't transformed, then we can skip this step. If we're displaying the
@@ -2713,7 +2713,7 @@ nsTextFrame::GetPosition(nsIPresContext* aCX,
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(aCX)));
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aCX);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
@@ -3012,7 +3012,7 @@ nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext,
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(aPresContext)));
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
PRInt32 numSpaces;
@@ -3163,7 +3163,7 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
doc->GetLineBreaker(getter_AddRefs(lb));
NS_RELEASE(doc);
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
if (textLength)//if no renderable length, you cant park here.
@@ -3193,7 +3193,7 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
doc->GetLineBreaker(getter_AddRefs(lb));
NS_RELEASE(doc);
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
nsIFrame *frameUsed = nsnull;
@@ -3261,7 +3261,7 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
doc->GetWordBreaker(getter_AddRefs(wb));
NS_RELEASE(doc);
nsTextTransformer tx(lb, wb);
nsTextTransformer tx(lb, wb, aPresContext);
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
nsIFrame *frameUsed = nsnull;
@@ -3467,7 +3467,7 @@ nsTextFrame::CheckVisibility(nsIPresContext* aContext, PRInt32 aStartIndex, PRIn
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
//create texttransformer
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aContext);
//create the buffers
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
@@ -4172,7 +4172,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
}
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
// Keep the text in ascii if possible. Note that if we're measuring small
// caps text then transform to Unicode because the helper function only
// accepts Unicode text
@@ -4527,7 +4527,7 @@ nsTextFrame::ComputeWordFragmentWidth(nsIPresContext* aPresContext,
PRUint32& aRunningWordLen,
PRUint32 aWordBufSize)
{
nsTextTransformer tx(aLineBreaker, nsnull);
nsTextTransformer tx(aLineBreaker, nsnull, aPresContext);
tx.Init(aTextFrame, aContent, 0);
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;

View File

@@ -117,7 +117,8 @@ nsTextTransformer::Shutdown()
MOZ_DECL_CTOR_COUNTER(nsTextTransformer);
nsTextTransformer::nsTextTransformer(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker)
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext)
: mFrag(nsnull),
mOffset(0),
mMode(eNormal),
@@ -129,6 +130,9 @@ nsTextTransformer::nsTextTransformer(nsILineBreaker* aLineBreaker,
{
MOZ_COUNT_CTOR(nsTextTransformer);
aPresContext->
GetLanguageSpecificTransformType(&mLanguageSpecificTransformType);
if (aLineBreaker == nsnull && aWordBreaker == nsnull )
NS_ASSERTION(0, "invalid creation of nsTextTransformer");
@@ -136,7 +140,7 @@ nsTextTransformer::nsTextTransformer(nsILineBreaker* aLineBreaker,
static PRBool firstTime = PR_TRUE;
if (firstTime) {
firstTime = PR_FALSE;
SelfTest(aLineBreaker, aWordBreaker);
SelfTest(aLineBreaker, aWordBreaker, aPresContext);
}
#endif
}
@@ -182,8 +186,10 @@ nsTextTransformer::Init(nsIFrame* aFrame,
if (aLeaveAsAscii) { // See if the text fragment is 1-byte text
SetLeaveAsAscii(PR_TRUE);
// XXX Currently we only leave it as ascii for normal text and not for preformatted
// or preformatted wrapped text
if (mFrag->Is2b() || (eNormal != mMode))
// or preformatted wrapped text or language specific transforms
if (mFrag->Is2b() || (eNormal != mMode) ||
(mLanguageSpecificTransformType !=
eLanguageSpecificTransformType_None))
// We don't step down from Unicode to ascii
SetLeaveAsAscii(PR_FALSE);
}
@@ -673,6 +679,40 @@ static void ReplaceGermanSzligToSS(PRUnichar* aText, PRInt32 len, PRInt32 szCnt)
}
}
void
nsTextTransformer::LanguageSpecificTransform(PRUnichar* aText, PRInt32 aLen,
PRBool* aWasTransformed)
{
if (mLanguageSpecificTransformType ==
eLanguageSpecificTransformType_Japanese) {
for (PRInt32 i = 0; i < aLen; i++) {
if (aText[i] == 0x5C) { // BACKSLASH
aText[i] = 0xA5; // YEN SIGN
*aWasTransformed = PR_TRUE;
}
#if 0
/*
* We considered doing this, but since some systems may not have fonts
* with this OVERLINE glyph, we decided not to do this.
*/
else if (aText[i] == 0x7E) { // TILDE
aText[i] = 0x203E; // OVERLINE
*aWasTransformed = PR_TRUE;
}
#endif
}
}
else if (mLanguageSpecificTransformType ==
eLanguageSpecificTransformType_Korean) {
for (PRInt32 i = 0; i < aLen; i++) {
if (aText[i] == 0x5C) { // BACKSLASH
aText[i] = 0x20A9; // WON SIGN
*aWasTransformed = PR_TRUE;
}
}
}
}
PRUnichar*
nsTextTransformer::GetNextWord(PRBool aInWord,
PRInt32* aWordLenResult,
@@ -808,6 +848,9 @@ nsTextTransformer::GetNextWord(PRBool aInWord,
AsciiToUpperCase(wordPtr, wordLen);
break;
}
NS_ASSERTION(mLanguageSpecificTransformType ==
eLanguageSpecificTransformType_None,
"should not be ASCII for language specific transforms");
}
result = (PRUnichar*)wordPtr;
@@ -858,6 +901,10 @@ nsTextTransformer::GetNextWord(PRBool aInWord,
}
break;
}
if (mLanguageSpecificTransformType !=
eLanguageSpecificTransformType_None) {
LanguageSpecificTransform(result, wordLen, aWasTransformed);
}
}
}
@@ -1322,7 +1369,8 @@ static SelfTestData tests[] = {
void
nsTextTransformer::SelfTest(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker)
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext)
{
PRBool gNoisy = PR_FALSE;
if (PR_GetEnv("GECKO_TEXT_TRANSFORMER_NOISY_SELF_TEST")) {
@@ -1349,7 +1397,7 @@ nsTextTransformer::SelfTest(nsILineBreaker* aLineBreaker,
}
nsTextFragment frag(st->text);
nsTextTransformer tx(aLineBreaker, aWordBreaker);
nsTextTransformer tx(aLineBreaker, aWordBreaker, aPresContext);
for (PRInt32 preMode = 0; preMode < NUM_MODES; preMode++) {
// Do forwards test

View File

@@ -24,6 +24,7 @@
#include "nsTextFragment.h"
#include "nsISupports.h"
#include "nsIPresContext.h"
class nsIContent;
class nsIFrame;
@@ -97,7 +98,8 @@ public:
// Note: The text transformer does not hold a reference to the line
// breaker and work breaker objects
nsTextTransformer(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker);
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext);
~nsTextTransformer();
@@ -222,6 +224,9 @@ protected:
// Unicode
void ConvertTransformedTextToUnicode();
void LanguageSpecificTransform(PRUnichar* aText, PRInt32 aLen,
PRBool* aWasTransformed);
// The text fragment that we are looking at
const nsTextFragment* mFrag;
@@ -239,6 +244,8 @@ protected:
nsIWordBreaker* mWordBreaker; // [WEAK]
nsLanguageSpecificTransformType mLanguageSpecificTransformType;
// Buffer used to hold the transformed words from GetNextWord or
// GetPrevWord
nsAutoTextBuffer mTransformBuf;
@@ -255,7 +262,8 @@ protected:
#ifdef DEBUG
static void SelfTest(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker);
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext);
nsresult Init2(const nsTextFragment* aFrag,
PRInt32 aStartingOffset,

View File

@@ -1780,7 +1780,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),
@@ -1930,7 +1930,7 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
// Transform text from content into renderable form
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
PRInt32 numSpaces;
@@ -2302,7 +2302,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 numSpaces;
numSpaces = PrepareUnicodeText(tx, (displaySelection ? &indexBuffer : nsnull),
@@ -2456,7 +2456,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
return;
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
// See if we need to transform the text. If the text fragment is ascii and
// wasn't transformed, then we can skip this step. If we're displaying the
@@ -2713,7 +2713,7 @@ nsTextFrame::GetPosition(nsIPresContext* aCX,
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(aCX)));
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aCX);
PRInt32 textLength;
// no need to worry about justification, that's always on the slow path
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
@@ -3012,7 +3012,7 @@ nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext,
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(aPresContext)));
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PRInt32 textLength;
PRInt32 numSpaces;
@@ -3163,7 +3163,7 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
doc->GetLineBreaker(getter_AddRefs(lb));
NS_RELEASE(doc);
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
if (textLength)//if no renderable length, you cant park here.
@@ -3193,7 +3193,7 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
doc->GetLineBreaker(getter_AddRefs(lb));
NS_RELEASE(doc);
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
nsIFrame *frameUsed = nsnull;
@@ -3261,7 +3261,7 @@ nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
doc->GetWordBreaker(getter_AddRefs(wb));
NS_RELEASE(doc);
nsTextTransformer tx(lb, wb);
nsTextTransformer tx(lb, wb, aPresContext);
PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
nsIFrame *frameUsed = nsnull;
@@ -3467,7 +3467,7 @@ nsTextFrame::CheckVisibility(nsIPresContext* aContext, PRInt32 aStartIndex, PRIn
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
//create texttransformer
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aContext);
//create the buffers
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
@@ -4172,7 +4172,7 @@ nsTextFrame::Reflow(nsIPresContext* aPresContext,
}
nsCOMPtr<nsILineBreaker> lb;
doc->GetLineBreaker(getter_AddRefs(lb));
nsTextTransformer tx(lb, nsnull);
nsTextTransformer tx(lb, nsnull, aPresContext);
// Keep the text in ascii if possible. Note that if we're measuring small
// caps text then transform to Unicode because the helper function only
// accepts Unicode text
@@ -4527,7 +4527,7 @@ nsTextFrame::ComputeWordFragmentWidth(nsIPresContext* aPresContext,
PRUint32& aRunningWordLen,
PRUint32 aWordBufSize)
{
nsTextTransformer tx(aLineBreaker, nsnull);
nsTextTransformer tx(aLineBreaker, nsnull, aPresContext);
tx.Init(aTextFrame, aContent, 0);
PRBool isWhitespace, wasTransformed;
PRInt32 wordLen, contentLen;

View File

@@ -117,7 +117,8 @@ nsTextTransformer::Shutdown()
MOZ_DECL_CTOR_COUNTER(nsTextTransformer);
nsTextTransformer::nsTextTransformer(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker)
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext)
: mFrag(nsnull),
mOffset(0),
mMode(eNormal),
@@ -129,6 +130,9 @@ nsTextTransformer::nsTextTransformer(nsILineBreaker* aLineBreaker,
{
MOZ_COUNT_CTOR(nsTextTransformer);
aPresContext->
GetLanguageSpecificTransformType(&mLanguageSpecificTransformType);
if (aLineBreaker == nsnull && aWordBreaker == nsnull )
NS_ASSERTION(0, "invalid creation of nsTextTransformer");
@@ -136,7 +140,7 @@ nsTextTransformer::nsTextTransformer(nsILineBreaker* aLineBreaker,
static PRBool firstTime = PR_TRUE;
if (firstTime) {
firstTime = PR_FALSE;
SelfTest(aLineBreaker, aWordBreaker);
SelfTest(aLineBreaker, aWordBreaker, aPresContext);
}
#endif
}
@@ -182,8 +186,10 @@ nsTextTransformer::Init(nsIFrame* aFrame,
if (aLeaveAsAscii) { // See if the text fragment is 1-byte text
SetLeaveAsAscii(PR_TRUE);
// XXX Currently we only leave it as ascii for normal text and not for preformatted
// or preformatted wrapped text
if (mFrag->Is2b() || (eNormal != mMode))
// or preformatted wrapped text or language specific transforms
if (mFrag->Is2b() || (eNormal != mMode) ||
(mLanguageSpecificTransformType !=
eLanguageSpecificTransformType_None))
// We don't step down from Unicode to ascii
SetLeaveAsAscii(PR_FALSE);
}
@@ -673,6 +679,40 @@ static void ReplaceGermanSzligToSS(PRUnichar* aText, PRInt32 len, PRInt32 szCnt)
}
}
void
nsTextTransformer::LanguageSpecificTransform(PRUnichar* aText, PRInt32 aLen,
PRBool* aWasTransformed)
{
if (mLanguageSpecificTransformType ==
eLanguageSpecificTransformType_Japanese) {
for (PRInt32 i = 0; i < aLen; i++) {
if (aText[i] == 0x5C) { // BACKSLASH
aText[i] = 0xA5; // YEN SIGN
*aWasTransformed = PR_TRUE;
}
#if 0
/*
* We considered doing this, but since some systems may not have fonts
* with this OVERLINE glyph, we decided not to do this.
*/
else if (aText[i] == 0x7E) { // TILDE
aText[i] = 0x203E; // OVERLINE
*aWasTransformed = PR_TRUE;
}
#endif
}
}
else if (mLanguageSpecificTransformType ==
eLanguageSpecificTransformType_Korean) {
for (PRInt32 i = 0; i < aLen; i++) {
if (aText[i] == 0x5C) { // BACKSLASH
aText[i] = 0x20A9; // WON SIGN
*aWasTransformed = PR_TRUE;
}
}
}
}
PRUnichar*
nsTextTransformer::GetNextWord(PRBool aInWord,
PRInt32* aWordLenResult,
@@ -808,6 +848,9 @@ nsTextTransformer::GetNextWord(PRBool aInWord,
AsciiToUpperCase(wordPtr, wordLen);
break;
}
NS_ASSERTION(mLanguageSpecificTransformType ==
eLanguageSpecificTransformType_None,
"should not be ASCII for language specific transforms");
}
result = (PRUnichar*)wordPtr;
@@ -858,6 +901,10 @@ nsTextTransformer::GetNextWord(PRBool aInWord,
}
break;
}
if (mLanguageSpecificTransformType !=
eLanguageSpecificTransformType_None) {
LanguageSpecificTransform(result, wordLen, aWasTransformed);
}
}
}
@@ -1322,7 +1369,8 @@ static SelfTestData tests[] = {
void
nsTextTransformer::SelfTest(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker)
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext)
{
PRBool gNoisy = PR_FALSE;
if (PR_GetEnv("GECKO_TEXT_TRANSFORMER_NOISY_SELF_TEST")) {
@@ -1349,7 +1397,7 @@ nsTextTransformer::SelfTest(nsILineBreaker* aLineBreaker,
}
nsTextFragment frag(st->text);
nsTextTransformer tx(aLineBreaker, aWordBreaker);
nsTextTransformer tx(aLineBreaker, aWordBreaker, aPresContext);
for (PRInt32 preMode = 0; preMode < NUM_MODES; preMode++) {
// Do forwards test

View File

@@ -24,6 +24,7 @@
#include "nsTextFragment.h"
#include "nsISupports.h"
#include "nsIPresContext.h"
class nsIContent;
class nsIFrame;
@@ -97,7 +98,8 @@ public:
// Note: The text transformer does not hold a reference to the line
// breaker and work breaker objects
nsTextTransformer(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker);
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext);
~nsTextTransformer();
@@ -222,6 +224,9 @@ protected:
// Unicode
void ConvertTransformedTextToUnicode();
void LanguageSpecificTransform(PRUnichar* aText, PRInt32 aLen,
PRBool* aWasTransformed);
// The text fragment that we are looking at
const nsTextFragment* mFrag;
@@ -239,6 +244,8 @@ protected:
nsIWordBreaker* mWordBreaker; // [WEAK]
nsLanguageSpecificTransformType mLanguageSpecificTransformType;
// Buffer used to hold the transformed words from GetNextWord or
// GetPrevWord
nsAutoTextBuffer mTransformBuf;
@@ -255,7 +262,8 @@ protected:
#ifdef DEBUG
static void SelfTest(nsILineBreaker* aLineBreaker,
nsIWordBreaker* aWordBreaker);
nsIWordBreaker* aWordBreaker,
nsIPresContext* aPresContext);
nsresult Init2(const nsTextFragment* aFrag,
PRInt32 aStartingOffset,