Bug 249159 - Part 1 Add word-break interface to nsILineBreaker. r=smontagu

This commit is contained in:
Makoto Kato 2012-05-07 12:18:23 -07:00
Родитель dccf22649b
Коммит 388efdff7d
5 изменённых файлов: 62 добавлений и 23 удалений

Просмотреть файл

@ -201,6 +201,12 @@ public:
*/
nsresult Reset(bool* aTrailingBreak);
/*
* Set word-break mode for linebreaker. This is set by word-break property.
* @param aMode is nsILineBreaker::kWordBreak_* value.
*/
void SetWordBreak(PRUint8 aMode) { mWordBreak = aMode; }
private:
// This is a list of text sources that make up the "current word" (i.e.,
// run of text which does not contain any whitespace). All the mLengths
@ -243,6 +249,8 @@ private:
// True if a break must be allowed at the current position because
// a run of breakable whitespace ends here
bool mBreakHere;
// line break mode by "word-break" style
PRUint8 mWordBreak;
};
#endif /*NSLINEBREAKER_H_*/

Просмотреть файл

@ -47,7 +47,8 @@ nsLineBreaker::nsLineBreaker()
: mCurrentWordLangGroup(nsnull),
mCurrentWordContainsMixedLang(false),
mCurrentWordContainsComplexChar(false),
mAfterBreakableSpace(false), mBreakHere(false)
mAfterBreakableSpace(false), mBreakHere(false),
mWordBreak(nsILineBreaker::kWordBreak_Normal)
{
}
@ -96,13 +97,17 @@ nsLineBreaker::FlushCurrentWord()
nsTArray<bool> capitalizationState;
if (!mCurrentWordContainsComplexChar) {
// Just set everything internal to "no break"!
// For break-strict set everything internal to "break", otherwise
// to "no break"!
memset(breakState.Elements(),
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NONE,
mWordBreak == nsILineBreaker::kWordBreak_BreakAll ?
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NORMAL :
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NONE,
length*sizeof(PRUint8));
} else {
nsContentUtils::LineBreaker()->
GetJISx4051Breaks(mCurrentWord.Elements(), length, breakState.Elements());
GetJISx4051Breaks(mCurrentWord.Elements(), length, mWordBreak,
breakState.Elements());
}
bool autoHyphenate = mCurrentWordLangGroup &&
@ -266,6 +271,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32
PRUint8 currentStart = breakState[wordStart];
nsContentUtils::LineBreaker()->
GetJISx4051Breaks(aText + wordStart, offset - wordStart,
mWordBreak,
breakState.Elements() + wordStart);
breakState[wordStart] = currentStart;
}
@ -411,8 +417,11 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL
bool isBreakableSpace = isSpace && !(aFlags & BREAK_SUPPRESS_INSIDE);
if (aSink) {
// Consider word-break style. Since the break position of CJK scripts
// will be set by nsILineBreaker, we don't consider CJK at this point.
breakState[offset] =
mBreakHere || (mAfterBreakableSpace && !isBreakableSpace) ?
mBreakHere || (mAfterBreakableSpace && !isBreakableSpace) ||
(mWordBreak == nsILineBreaker::kWordBreak_BreakAll) ?
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NORMAL :
gfxTextRun::CompressedGlyph::FLAG_BREAK_TYPE_NONE;
}
@ -427,6 +436,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL
PRUint8 currentStart = breakState[wordStart];
nsContentUtils::LineBreaker()->
GetJISx4051Breaks(aText + wordStart, offset - wordStart,
mWordBreak,
breakState.Elements() + wordStart);
breakState[wordStart] = currentStart;
}

Просмотреть файл

@ -43,15 +43,22 @@
#define NS_LINEBREAKER_NEED_MORE_TEXT -1
// {5ae68851-d9a3-49fd-9388-58586dad8044}
// {0x4b0b9e04-6ffb-4647-aa5f-2fa2ebd883e8}
#define NS_ILINEBREAKER_IID \
{ 0x5ae68851, 0xd9a3, 0x49fd, \
{ 0x93, 0x88, 0x58, 0x58, 0x6d, 0xad, 0x80, 0x44 } }
{0x4b0b9e04, 0x6ffb, 0x4647, \
{0xaa, 0x5f, 0x2f, 0xa2, 0xeb, 0xd8, 0x83, 0xe8}}
class nsILineBreaker : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINEBREAKER_IID)
enum {
kWordBreak_Normal = 0, // default
kWordBreak_BreakAll = 1, // break all
kWordBreak_KeepAll = 2 // always keep
};
virtual PRInt32 Next( const PRUnichar* aText, PRUint32 aLen,
PRUint32 aPos) = 0;
@ -65,8 +72,10 @@ public:
// aLength is the length of the aText array and also the length of the aBreakBefore
// output array.
virtual void GetJISx4051Breaks(const PRUnichar* aText, PRUint32 aLength,
PRUint8 aWordBreak,
PRUint8* aBreakBefore) = 0;
virtual void GetJISx4051Breaks(const PRUint8* aText, PRUint32 aLength,
PRUint8 aWordBreak,
PRUint8* aBreakBefore) = 0;
};

Просмотреть файл

@ -797,7 +797,8 @@ nsJISx4051LineBreaker::WordMove(const PRUnichar* aText, PRUint32 aLen,
ret = end;
}
} else {
GetJISx4051Breaks(aText + begin, end - begin, breakState.Elements());
GetJISx4051Breaks(aText + begin, end - begin, nsILineBreaker::kWordBreak_Normal,
breakState.Elements());
ret = aPos;
do {
@ -833,6 +834,7 @@ nsJISx4051LineBreaker::Prev(const PRUnichar* aText, PRUint32 aLen,
void
nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUnichar* aChars, PRUint32 aLength,
PRUint8 aWordBreak,
PRUint8* aBreakBefore)
{
PRUint32 cur;
@ -855,16 +857,16 @@ nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUnichar* aChars, PRUint32 aLeng
cl = GetClass(ch);
}
bool allowBreak;
bool allowBreak = false;
if (cur > 0) {
NS_ASSERTION(CLASS_COMPLEX != lastClass || CLASS_COMPLEX != cl,
"Loop should have prevented adjacent complex chars here");
if (state.UseConservativeBreaking())
allowBreak = GetPairConservative(lastClass, cl);
else
allowBreak = GetPair(lastClass, cl);
} else {
allowBreak = false;
if (aWordBreak == nsILineBreaker::kWordBreak_Normal) {
allowBreak = (state.UseConservativeBreaking()) ?
GetPairConservative(lastClass, cl) : GetPair(lastClass, cl);
} else if (aWordBreak == nsILineBreaker::kWordBreak_BreakAll) {
allowBreak = true;
}
}
aBreakBefore[cur] = allowBreak;
if (allowBreak)
@ -879,6 +881,13 @@ nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUnichar* aChars, PRUint32 aLeng
NS_GetComplexLineBreaks(aChars + cur, end - cur, aBreakBefore + cur);
// We have to consider word-break value again for complex characters
if (aWordBreak != nsILineBreaker::kWordBreak_Normal) {
// Respect word-break property
for (PRUint32 i = cur; i < end; i++)
aBreakBefore[i] = (aWordBreak == nsILineBreaker::kWordBreak_BreakAll);
}
// restore breakability at chunk begin, which was always set to false
// by the complex line breaker
aBreakBefore[cur] = allowBreak;
@ -890,6 +899,7 @@ nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUnichar* aChars, PRUint32 aLeng
void
nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUint8* aChars, PRUint32 aLength,
PRUint8 aWordBreak,
PRUint8* aBreakBefore)
{
PRUint32 cur;
@ -912,14 +922,14 @@ nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUint8* aChars, PRUint32 aLength
cl = GetClass(ch);
}
bool allowBreak;
bool allowBreak = false;
if (cur > 0) {
if (state.UseConservativeBreaking())
allowBreak = GetPairConservative(lastClass, cl);
else
allowBreak = GetPair(lastClass, cl);
} else {
allowBreak = false;
if (aWordBreak == nsILineBreaker::kWordBreak_Normal) {
allowBreak = (state.UseConservativeBreaking()) ?
GetPairConservative(lastClass, cl) : GetPair(lastClass, cl);
} else if (aWordBreak == nsILineBreaker::kWordBreak_BreakAll) {
allowBreak = true;
}
}
aBreakBefore[cur] = allowBreak;
if (allowBreak)

Просмотреть файл

@ -53,8 +53,10 @@ public:
PRInt32 Prev( const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos);
virtual void GetJISx4051Breaks(const PRUnichar* aText, PRUint32 aLength,
PRUint8 aBreakMode,
PRUint8* aBreakBefore);
virtual void GetJISx4051Breaks(const PRUint8* aText, PRUint32 aLength,
PRUint8 aBreakMode,
PRUint8* aBreakBefore);
private: