Bug 1733877 - Remove LineBreaker::Prev() in nsXMLContentSerializer. r=jfkthame,m_kato
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 15 Oct 2021 18:10:08 +0000
changeset 596034 697c0f97356c0d46f18cc63698ca868ace07937f
parent 596033 9b4bbfc846ddf89c78fb0993e3f19124a4b4b2c4
child 596035 651174bac318d9fdf723afc14b656c07961b978e
push id38882
push userccozmuta@mozilla.com
push dateSat, 16 Oct 2021 09:37:23 +0000
treeherdermozilla-central@3e844ac540bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame, m_kato
bugs1733877
milestone95.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1733877 - Remove LineBreaker::Prev() in nsXMLContentSerializer. r=jfkthame,m_kato `dom/base/test/unit/test_xmlserializer.js` exercises this part of the code. Differential Revision: https://phabricator.services.mozilla.com/D128557
dom/serializers/nsXMLContentSerializer.cpp
--- a/dom/serializers/nsXMLContentSerializer.cpp
+++ b/dom/serializers/nsXMLContentSerializer.cpp
@@ -1531,30 +1531,44 @@ bool nsXMLContentSerializer::AppendWrapp
         onceAgainBecauseWeAddedBreakInFront = true;
       } else {
         // we must wrap
         onceAgainBecauseWeAddedBreakInFront = false;
         bool foundWrapPosition = false;
         int32_t wrapPosition = 0;
 
         if (mAllowLineBreaking) {
+          MOZ_ASSERT(aPos < aEnd,
+                     "We shouldn't be here if aPos reaches the end of text!");
           mozilla::intl::LineBreaker* lineBreaker =
               nsContentUtils::LineBreaker();
 
-          wrapPosition =
-              lineBreaker->Prev(aSequenceStart, (aEnd - aSequenceStart),
-                                (aPos - aSequenceStart) + 1);
-          if (wrapPosition != NS_LINEBREAKER_NEED_MORE_TEXT) {
+          // Search forward from aSequenceStart until we find the largest
+          // wrap position less than or equal to aPos.
+          int32_t nextWrapPosition = 0;
+          while (true) {
+            nextWrapPosition = lineBreaker->Next(
+                aSequenceStart, aEnd - aSequenceStart, wrapPosition);
+            MOZ_ASSERT(nextWrapPosition != NS_LINEBREAKER_NEED_MORE_TEXT,
+                       "We should've exited the loop when reaching the end of "
+                       "text in the previous iteration!");
+            if (aSequenceStart + nextWrapPosition > aPos) {
+              break;
+            }
+            wrapPosition = nextWrapPosition;
+          }
+
+          if (wrapPosition != 0) {
             foundWrapPosition = true;
           } else {
-            wrapPosition =
-                lineBreaker->Next(aSequenceStart, (aEnd - aSequenceStart),
-                                  (aPos - aSequenceStart));
-            MOZ_ASSERT(wrapPosition != NS_LINEBREAKER_NEED_MORE_TEXT,
-                       "Next() always treats end-of-text as a break");
+            // The wrap position found in the first iteration of the above loop
+            // already exceeds aPos. We however still accept it as valid a wrap
+            // position.
+            wrapPosition = nextWrapPosition;
+
             // If the line-breaker returned end-of-text, we don't know that it
             // is actually a good wrap position, so ignore it and continue to
             // use the fallback code below.
             if (wrapPosition < aEnd - aSequenceStart) {
               foundWrapPosition = true;
             }
           }
         }