bug 605021 - handle surrogates in text-run transformations. r=smontagu
authorJonathan Kew <jfkthame@gmail.com>
Wed, 14 Mar 2012 06:45:11 +0000
changeset 92681 6913a9ff86e1290334679ec96754edb2b1b0c91f
parent 92680 edc0871b4e5b4230a27c3726ab95459fa1a46175
child 92682 6ac8b89ae5f05537238d71aab696cce9a3ab5000
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmontagu
bugs605021
milestone14.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 605021 - handle surrogates in text-run transformations. r=smontagu
layout/generic/nsTextRunTransformations.cpp
layout/reftests/text-transform/reftest.list
--- a/layout/generic/nsTextRunTransformations.cpp
+++ b/layout/generic/nsTextRunTransformations.cpp
@@ -285,19 +285,21 @@ nsFontVariantTextRunFactory::RebuildText
     bool isLowercase = false;
     if (i < length) {
       // Characters that aren't the start of a cluster are ignored here. They
       // get added to whatever lowercase/non-lowercase run we're in.
       if (!inner->IsClusterStart(i)) {
         isLowercase = runIsLowercase;
       } else {
         if (styles[i]->GetStyleFont()->mFont.variant == NS_STYLE_FONT_VARIANT_SMALL_CAPS) {
-          PRUnichar ch = str[i];
-          PRUnichar ch2;
-          ch2 = ToUpperCase(ch);
+          PRUint32 ch = str[i];
+          if (NS_IS_HIGH_SURROGATE(ch) && i < length - 1 && NS_IS_LOW_SURROGATE(str[i + 1])) {
+            ch = SURROGATE_TO_UCS4(ch, str[i + 1]);
+          }
+          PRUint32 ch2 = ToUpperCase(ch);
           isLowercase = ch != ch2 || ch == SZLIG;
         } else {
           // Don't transform the character! I.e., pretend that it's not lowercase
         }
       }
     }
 
     if ((i == length || runIsLowercase != isLowercase) && runStart < i) {
@@ -352,26 +354,30 @@ nsCaseTransformTextRunFactory::RebuildTe
   nsAutoString convertedString;
   nsAutoTArray<bool,50> charsToMergeArray;
   nsAutoTArray<nsStyleContext*,50> styleArray;
   nsAutoTArray<PRUint8,50> canBreakBeforeArray;
   PRUint32 extraCharsCount = 0;
 
   PRUint32 i;
   for (i = 0; i < length; ++i) {
-    PRUnichar ch = str[i];
+    PRUint32 ch = str[i];
 
     charsToMergeArray.AppendElement(false);
     styleArray.AppendElement(styles[i]);
     canBreakBeforeArray.AppendElement(aTextRun->CanBreakLineBefore(i));
 
     PRUint8 style = mAllUppercase ? NS_STYLE_TEXT_TRANSFORM_UPPERCASE
       : styles[i]->GetStyleText()->mTextTransform;
     bool extraChar = false;
 
+    if (NS_IS_HIGH_SURROGATE(ch) && i < length - 1 && NS_IS_LOW_SURROGATE(str[i + 1])) {
+      ch = SURROGATE_TO_UCS4(ch, str[i + 1]);
+    }
+
     switch (style) {
     case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
       ch = ToLowerCase(ch);
       break;
     case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
       if (ch == SZLIG) {
         convertedString.Append('S');
         extraChar = true;
@@ -390,17 +396,27 @@ nsCaseTransformTextRunFactory::RebuildTe
           ch = ToTitleCase(ch);
         }
       }
       break;
     default:
       break;
     }
 
-    convertedString.Append(ch);
+    if (IS_IN_BMP(ch)) {
+      convertedString.Append(ch);
+    } else {
+      convertedString.Append(H_SURROGATE(ch));
+      convertedString.Append(L_SURROGATE(ch));
+      i++;
+      charsToMergeArray.AppendElement(true);
+      styleArray.AppendElement(styles[i]);
+      canBreakBeforeArray.AppendElement(false);
+    }
+
     if (extraChar) {
       ++extraCharsCount;
       charsToMergeArray.AppendElement(true);
       styleArray.AppendElement(styles[i]);
       canBreakBeforeArray.AppendElement(false);
     }
   }
 
--- a/layout/reftests/text-transform/reftest.list
+++ b/layout/reftests/text-transform/reftest.list
@@ -3,11 +3,11 @@
 == capitalize-3.html capitalize-3-ref.html
 == lowercase-1.html lowercase-ref.html
 == small-caps-1.html small-caps-1-ref.html
 == uppercase-1.html uppercase-ref.html
 == uppercase-szlig-1.html uppercase-szlig-ref.html
 == all-upper.html all-upper-ref.html
 == all-lower.html all-lower-ref.html
 == all-title.html all-title-ref.html
-!= smtp-upper.html smtp-upper-ref.html # bug 210501
-!= smtp-lower.html smtp-lower-ref.html # bug 210501
-!= smtp-title.html smtp-title-ref.html # bug 210501
+== smtp-upper.html smtp-upper-ref.html
+== smtp-lower.html smtp-lower-ref.html
+== smtp-title.html smtp-title-ref.html