From 2cc0239904f986161869d7087aed94628cf444bb Mon Sep 17 00:00:00 2001 From: Ian Neal Date: Sun, 27 Jul 2008 17:43:07 +0100 Subject: [PATCH] =?UTF-8?q?Bug=20447776=20=E2=80=93=20Hang=20with=20word-w?= =?UTF-8?q?rap:=20break-word=20and=20width:=200px=20with=20testcase=20and?= =?UTF-8?q?=20crashtests=20p=3Dsmontagu=20r/sr=3Droc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gfx/thebes/src/gfxFont.cpp | 56 +++++++++++++---------- layout/reftests/text/reftest.list | 1 + layout/reftests/text/wordwrap-07-ref.html | 10 ++++ layout/reftests/text/wordwrap-07.html | 13 ++++++ layout/style/crashtests/447776-1.html | 7 +++ layout/style/crashtests/447783-1.html | 8 ++++ layout/style/crashtests/crashtests.list | 2 + 7 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 layout/reftests/text/wordwrap-07-ref.html create mode 100644 layout/reftests/text/wordwrap-07.html create mode 100644 layout/style/crashtests/447776-1.html create mode 100644 layout/style/crashtests/447783-1.html diff --git a/gfx/thebes/src/gfxFont.cpp b/gfx/thebes/src/gfxFont.cpp index 699fbfc585e..32d4cf4cd19 100644 --- a/gfx/thebes/src/gfxFont.cpp +++ b/gfx/thebes/src/gfxFont.cpp @@ -1742,32 +1742,38 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength, } } - PRBool lineBreakHere = mCharacterGlyphs[i].CanBreakBefore() && - (!aSuppressInitialBreak || i > aStart); - PRBool hyphenation = haveHyphenation && hyphenBuffer[i - bufferStart]; - PRBool wordWrapping = aCanWordWrap && *aBreakPriority <= eWordWrapBreak; - if (lineBreakHere || hyphenation || wordWrapping) { - gfxFloat hyphenatedAdvance = advance; - if (!lineBreakHere && !wordWrapping) { - hyphenatedAdvance += aProvider->GetHyphenWidth(); - } - - if (lastBreak < 0 || width + hyphenatedAdvance - trimmableAdvance <= aWidth) { - // We can break here. - lastBreak = i; - lastBreakTrimmableChars = trimmableChars; - lastBreakTrimmableAdvance = trimmableAdvance; - lastBreakUsedHyphenation = !lineBreakHere && !wordWrapping; - *aBreakPriority = hyphenation || lineBreakHere ? - eNormalBreak : eWordWrapBreak; - } + // There can't be a word-wrap break opportunity at the beginning of the + // line: if the width is too small for even one character to fit, it + // could be the first and last break opportunity on the line, and that + // would trigger an infinite loop. + if (!aSuppressInitialBreak || i > aStart) { + PRBool lineBreakHere = mCharacterGlyphs[i].CanBreakBefore(); + PRBool hyphenation = haveHyphenation && hyphenBuffer[i - bufferStart]; + PRBool wordWrapping = aCanWordWrap && *aBreakPriority <= eWordWrapBreak; - width += advance; - advance = 0; - if (width - trimmableAdvance > aWidth) { - // No more text fits. Abort - aborted = PR_TRUE; - break; + if (lineBreakHere || hyphenation || wordWrapping) { + gfxFloat hyphenatedAdvance = advance; + if (!lineBreakHere && !wordWrapping) { + hyphenatedAdvance += aProvider->GetHyphenWidth(); + } + + if (lastBreak < 0 || width + hyphenatedAdvance - trimmableAdvance <= aWidth) { + // We can break here. + lastBreak = i; + lastBreakTrimmableChars = trimmableChars; + lastBreakTrimmableAdvance = trimmableAdvance; + lastBreakUsedHyphenation = !lineBreakHere && !wordWrapping; + *aBreakPriority = hyphenation || lineBreakHere ? + eNormalBreak : eWordWrapBreak; + } + + width += advance; + advance = 0; + if (width - trimmableAdvance > aWidth) { + // No more text fits. Abort + aborted = PR_TRUE; + break; + } } } diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 70c42ca8a14..275ced91d98 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -11,6 +11,7 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == wordwrap-03.html wordwrap-03-ref.html # == wordwrap-04.html wordwrap-04-ref.html == wordwrap-05.html wordwrap-05-ref.html == wordwrap-06.html wordwrap-06-ref.html +== wordwrap-07.html wordwrap-07-ref.html == zwnj-01.html zwnj-01-ref.html == zwnj-02.html zwnj-02-ref.html random-if(MOZ_WIDGET_TOOLKIT=="gtk2") != zwnj-01.html zwnj-02-ref.html # Bad fonts on the tinderbox -- works locally diff --git a/layout/reftests/text/wordwrap-07-ref.html b/layout/reftests/text/wordwrap-07-ref.html new file mode 100644 index 00000000000..c6cae567b5d --- /dev/null +++ b/layout/reftests/text/wordwrap-07-ref.html @@ -0,0 +1,10 @@ + + + + + Test Wordwrap + + +
H
e
l
l
o

K
i
t
t
y
+ + diff --git a/layout/reftests/text/wordwrap-07.html b/layout/reftests/text/wordwrap-07.html new file mode 100644 index 00000000000..b0259d68efc --- /dev/null +++ b/layout/reftests/text/wordwrap-07.html @@ -0,0 +1,13 @@ + + + + + + Test Wordwrap + + +
HelloKitty
+ + diff --git a/layout/style/crashtests/447776-1.html b/layout/style/crashtests/447776-1.html new file mode 100644 index 00000000000..dde700fae1f --- /dev/null +++ b/layout/style/crashtests/447776-1.html @@ -0,0 +1,7 @@ + + + +Hang with zero width and word-wrap + +
abc
+ diff --git a/layout/style/crashtests/447783-1.html b/layout/style/crashtests/447783-1.html new file mode 100644 index 00000000000..05f12bf72d8 --- /dev/null +++ b/layout/style/crashtests/447783-1.html @@ -0,0 +1,8 @@ + + +Hang with -moz-column-count and word-wrap + +
+aabcde +
+ diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index 87b6d07d5f6..23accb66c35 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -16,3 +16,5 @@ load 437170-1.html skip load 439184-1.html # skip until we figure out how to test this load 444237-1.html load 444848-1.html +load 447776-1.html +load 447783-1.html