From b7240dcf1afbe2942faccf46f386520e334cfecb Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Mon, 20 Aug 2012 19:23:32 -0700 Subject: [PATCH] Only do hyphenation when the language was specified explicitly, rather than using an encoding-inferred language. (Bug 702121, patch 2) r=jfkthame --- content/base/public/nsLineBreaker.h | 8 ++--- content/base/src/nsLineBreaker.cpp | 30 ++++++++++--------- layout/generic/nsTextFrameThebes.cpp | 10 +++++-- layout/reftests/text/auto-hyphenation-10.html | 11 +++++++ layout/reftests/text/auto-hyphenation-8.html | 10 +++++++ layout/reftests/text/auto-hyphenation-9.html | 11 +++++++ layout/reftests/text/reftest.list | 4 ++- 7 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 layout/reftests/text/auto-hyphenation-10.html create mode 100644 layout/reftests/text/auto-hyphenation-8.html create mode 100644 layout/reftests/text/auto-hyphenation-9.html diff --git a/content/base/public/nsLineBreaker.h b/content/base/public/nsLineBreaker.h index d4b9723b00b..883c532d8c4 100644 --- a/content/base/public/nsLineBreaker.h +++ b/content/base/public/nsLineBreaker.h @@ -147,14 +147,14 @@ public: * @param aSink can be null if the breaks are not actually needed (we may * still be setting up state for later breaks) */ - nsresult AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 aLength, + nsresult AppendText(nsIAtom* aHyphenationLanguage, const PRUnichar* aText, PRUint32 aLength, PRUint32 aFlags, nsILineBreakSink* aSink); /** * Feed 8-bit text into the linebreaker for analysis. aLength must be nonzero. * @param aSink can be null if the breaks are not actually needed (we may * still be setting up state for later breaks) */ - nsresult AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aLength, + nsresult AppendText(nsIAtom* aHyphenationLanguage, const PRUint8* aText, PRUint32 aLength, PRUint32 aFlags, nsILineBreakSink* aSink); /** * Reset all state. This means the current run has ended; any outstanding @@ -198,7 +198,7 @@ private: // appropriate sink(s). Then we clear the current word state. nsresult FlushCurrentWord(); - void UpdateCurrentWordLangGroup(nsIAtom *aLangGroup); + void UpdateCurrentWordLanguage(nsIAtom *aHyphenationLanguage); void FindHyphenationPoints(nsHyphenator *aHyphenator, const PRUnichar *aTextStart, @@ -208,7 +208,7 @@ private: nsAutoTArray mCurrentWord; // All the items that contribute to mCurrentWord nsAutoTArray mTextItems; - nsIAtom* mCurrentWordLangGroup; + nsIAtom* mCurrentWordLanguage; bool mCurrentWordContainsMixedLang; bool mCurrentWordContainsComplexChar; diff --git a/content/base/src/nsLineBreaker.cpp b/content/base/src/nsLineBreaker.cpp index ef84cd53e49..4773bd2a86c 100644 --- a/content/base/src/nsLineBreaker.cpp +++ b/content/base/src/nsLineBreaker.cpp @@ -11,7 +11,7 @@ #include "nsHyphenator.h" nsLineBreaker::nsLineBreaker() - : mCurrentWordLangGroup(nullptr), + : mCurrentWordLanguage(nullptr), mCurrentWordContainsMixedLang(false), mCurrentWordContainsComplexChar(false), mAfterBreakableSpace(false), mBreakHere(false), @@ -77,7 +77,7 @@ nsLineBreaker::FlushCurrentWord() breakState.Elements()); } - bool autoHyphenate = mCurrentWordLangGroup && + bool autoHyphenate = mCurrentWordLanguage && !mCurrentWordContainsMixedLang; PRUint32 i; for (i = 0; autoHyphenate && i < mTextItems.Length(); ++i) { @@ -88,7 +88,7 @@ nsLineBreaker::FlushCurrentWord() } if (autoHyphenate) { nsRefPtr hyphenator = - nsHyphenationManager::Instance()->GetHyphenator(mCurrentWordLangGroup); + nsHyphenationManager::Instance()->GetHyphenator(mCurrentWordLanguage); if (hyphenator) { FindHyphenationPoints(hyphenator, mCurrentWord.Elements(), @@ -140,12 +140,12 @@ nsLineBreaker::FlushCurrentWord() mTextItems.Clear(); mCurrentWordContainsComplexChar = false; mCurrentWordContainsMixedLang = false; - mCurrentWordLangGroup = nullptr; + mCurrentWordLanguage = nullptr; return NS_OK; } nsresult -nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 aLength, +nsLineBreaker::AppendText(nsIAtom* aHyphenationLanguage, const PRUnichar* aText, PRUint32 aLength, PRUint32 aFlags, nsILineBreakSink* aSink) { NS_ASSERTION(aLength > 0, "Appending empty text..."); @@ -161,7 +161,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 if (!mCurrentWordContainsComplexChar && IsComplexChar(aText[offset])) { mCurrentWordContainsComplexChar = true; } - UpdateCurrentWordLangGroup(aLangGroup); + UpdateCurrentWordLanguage(aHyphenationLanguage); ++offset; } @@ -211,8 +211,10 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 bool wordHasComplexChar = false; nsRefPtr hyphenator; - if ((aFlags & BREAK_USE_AUTO_HYPHENATION) && !(aFlags & BREAK_SUPPRESS_INSIDE)) { - hyphenator = nsHyphenationManager::Instance()->GetHyphenator(aLangGroup); + if ((aFlags & BREAK_USE_AUTO_HYPHENATION) && + !(aFlags & BREAK_SUPPRESS_INSIDE) && + aHyphenationLanguage) { + hyphenator = nsHyphenationManager::Instance()->GetHyphenator(aHyphenationLanguage); } for (;;) { @@ -275,7 +277,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 mTextItems.AppendElement(TextItem(aSink, wordStart, len, aFlags)); // Ensure that the break-before for this word is written out offset = wordStart + 1; - UpdateCurrentWordLangGroup(aLangGroup); + UpdateCurrentWordLanguage(aHyphenationLanguage); break; } } @@ -311,7 +313,7 @@ nsLineBreaker::FindHyphenationPoints(nsHyphenator *aHyphenator, } nsresult -nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aLength, +nsLineBreaker::AppendText(nsIAtom* aHyphenationLanguage, const PRUint8* aText, PRUint32 aLength, PRUint32 aFlags, nsILineBreakSink* aSink) { NS_ASSERTION(aLength > 0, "Appending empty text..."); @@ -321,7 +323,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL nsAutoString str; const char* cp = reinterpret_cast(aText); CopyASCIItoUTF16(nsDependentCSubstring(cp, cp + aLength), str); - return AppendText(aLangGroup, str.get(), aLength, aFlags, aSink); + return AppendText(aHyphenationLanguage, str.get(), aLength, aFlags, aSink); } PRUint32 offset = 0; @@ -446,12 +448,12 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL } void -nsLineBreaker::UpdateCurrentWordLangGroup(nsIAtom *aLangGroup) +nsLineBreaker::UpdateCurrentWordLanguage(nsIAtom *aHyphenationLanguage) { - if (mCurrentWordLangGroup && mCurrentWordLangGroup != aLangGroup) { + if (mCurrentWordLanguage && mCurrentWordLanguage != aHyphenationLanguage) { mCurrentWordContainsMixedLang = true; } else { - mCurrentWordLangGroup = aLangGroup; + mCurrentWordLanguage = aHyphenationLanguage; } } diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index 70cbe293b86..4832c9bfa7c 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -2215,7 +2215,11 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, PRUint32 aFlags) { // textruns have uniform language - nsIAtom* language = mMappedFlows[0].mStartFrame->GetStyleFont()->mLanguage; + const nsStyleFont *styleFont = mMappedFlows[0].mStartFrame->GetStyleFont(); + // We should only use a language for hyphenation if it was specified + // explicitly. + nsIAtom* hyphenationLanguage = + styleFont->mExplicitLanguage ? styleFont->mLanguage : nullptr; // We keep this pointed at the skip-chars data for the current mappedFlow. // This lets us cheaply check whether the flow has compressed initial // whitespace... @@ -2269,11 +2273,11 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, (aFlags & SBS_SUPPRESS_SINK) ? nullptr : (*breakSink).get(); if (aFlags & SBS_DOUBLE_BYTE) { const PRUnichar* text = reinterpret_cast(aTextPtr); - mLineBreaker.AppendText(language, text + offset, + mLineBreaker.AppendText(hyphenationLanguage, text + offset, length, flags, sink); } else { const PRUint8* text = reinterpret_cast(aTextPtr); - mLineBreaker.AppendText(language, text + offset, + mLineBreaker.AppendText(hyphenationLanguage, text + offset, length, flags, sink); } } diff --git a/layout/reftests/text/auto-hyphenation-10.html b/layout/reftests/text/auto-hyphenation-10.html new file mode 100644 index 00000000000..41f35cf3d1a --- /dev/null +++ b/layout/reftests/text/auto-hyphenation-10.html @@ -0,0 +1,11 @@ + + + + + +
+supercalifragilisticexpialidocious +
+ + + diff --git a/layout/reftests/text/auto-hyphenation-8.html b/layout/reftests/text/auto-hyphenation-8.html new file mode 100644 index 00000000000..4956bce75cf --- /dev/null +++ b/layout/reftests/text/auto-hyphenation-8.html @@ -0,0 +1,10 @@ + + + + +
+supercalifragilisticexpialidocious +
+ + + diff --git a/layout/reftests/text/auto-hyphenation-9.html b/layout/reftests/text/auto-hyphenation-9.html new file mode 100644 index 00000000000..53714136e6d --- /dev/null +++ b/layout/reftests/text/auto-hyphenation-9.html @@ -0,0 +1,11 @@ + + + + + +
+supercalifragilisticexpialidocious +
+ + + diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 9d7812b0e78..d52d3fd5c45 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -180,6 +180,9 @@ HTTP(..) == graphite-05-feat.html graphite-05-ref.html == auto-hyphenation-5.html auto-hyphenation-5-ref.html == auto-hyphenation-6.html auto-hyphenation-6-ref.html == auto-hyphenation-7.html auto-hyphenation-7-ref.html +== auto-hyphenation-8.html auto-hyphenation-4-ref.html +== auto-hyphenation-9.html auto-hyphenation-4-ref.html +== auto-hyphenation-10.html auto-hyphenation-4-ref.html == auto-hyphenation-af-1.html auto-hyphenation-af-1-ref.html == auto-hyphenation-bg-1.html auto-hyphenation-bg-1-ref.html == auto-hyphenation-ca-1.html auto-hyphenation-ca-1-ref.html @@ -217,4 +220,3 @@ HTTP(..) == graphite-05-feat.html graphite-05-ref.html != auto-hyphenation-sv-1.html auto-hyphenation-sv-1-notref.html # verify swedish != english == auto-hyphenation-tr-1.html auto-hyphenation-tr-1-ref.html == auto-hyphenation-uk-1.html auto-hyphenation-uk-1-ref.html -