Bug 665858 - Part 1: Optimize the conversion of native and cross platform text offsets; r=roc,masayuki

This commit is contained in:
Ehsan Akhgari 2011-06-27 08:58:43 -04:00
Родитель 26c9e312b0
Коммит 33ab8b1d77
1 изменённых файлов: 64 добавлений и 25 удалений

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

@ -188,15 +188,6 @@ static void ConvertToNativeNewlines(nsAFlatString& aString)
#endif #endif
} }
static void ConvertToXPNewlines(nsAFlatString& aString)
{
#if defined(XP_MACOSX)
aString.ReplaceSubstring(NS_LITERAL_STRING("\r"), NS_LITERAL_STRING("\n"));
#elif defined(XP_WIN)
aString.ReplaceSubstring(NS_LITERAL_STRING("\r\n"), NS_LITERAL_STRING("\n"));
#endif
}
static void AppendString(nsAString& aString, nsIContent* aContent) static void AppendString(nsAString& aString, nsIContent* aContent)
{ {
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT), NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
@ -218,28 +209,76 @@ static void AppendSubString(nsAString& aString, nsIContent* aContent,
text->AppendTo(aString, PRInt32(aXPOffset), PRInt32(aXPLength)); text->AppendTo(aString, PRInt32(aXPOffset), PRInt32(aXPLength));
} }
#if defined(XP_WIN)
static PRUint32 CountNewlinesIn(nsIContent* aContent, PRUint32 aMaxOffset)
{
NS_ASSERTION(aContent->IsNodeOfType(nsINode::eTEXT),
"aContent is not a text node!");
const nsTextFragment* text = aContent->GetText();
if (!text)
return 0;
if (aMaxOffset == PR_UINT32_MAX) {
// search the entire string
aMaxOffset = text->GetLength();
}
PRUint32 newlines = 0;
for (PRUint32 i = 0; i < aMaxOffset; ++i) {
if (text->CharAt(i) == '\n') {
++newlines;
}
}
return newlines;
}
#endif
static PRUint32 GetNativeTextLength(nsIContent* aContent) static PRUint32 GetNativeTextLength(nsIContent* aContent)
{ {
nsAutoString str; if (aContent->IsNodeOfType(nsINode::eTEXT)) {
if (aContent->IsNodeOfType(nsINode::eTEXT)) PRUint32 textLengthDifference =
AppendString(str, aContent); #if defined(XP_MACOSX)
else if (IsContentBR(aContent)) // On Mac, the length of a native newline ("\r") is equal to the length of
str.Assign(PRUnichar('\n')); // the XP newline ("\n"), so the native length is the same as the XP length.
ConvertToNativeNewlines(str); 0;
return str.Length(); #elif defined(XP_WIN)
// On Windows, the length of a native newline ("\r\n") is twice the length of
// the XP newline ("\n"), so XP length is equal to the length of the native
// offset plus the number of newlines encountered in the string.
CountNewlinesIn(aContent, PR_UINT32_MAX);
#else
// On other platforms, the native and XP newlines are the same.
0;
#endif
const nsTextFragment* text = aContent->GetText();
if (!text)
return 0;
return text->GetLength() + textLengthDifference;
} else if (IsContentBR(aContent)) {
#if defined(XP_WIN)
// Length of \r\n
return 2;
#else
return 1;
#endif
}
return 0;
} }
static PRUint32 ConvertToXPOffset(nsIContent* aContent, PRUint32 aNativeOffset) static PRUint32 ConvertToXPOffset(nsIContent* aContent, PRUint32 aNativeOffset)
{ {
#if defined(XP_MACOSX)
nsAutoString str; // On Mac, the length of a native newline ("\r") is equal to the length of
AppendString(str, aContent); // the XP newline ("\n"), so the native offset is the same as the XP offset.
ConvertToNativeNewlines(str); return aNativeOffset;
NS_ASSERTION(aNativeOffset <= str.Length(), #elif defined(XP_WIN)
"aOffsetForNativeLF is too large!"); // On Windows, the length of a native newline ("\r\n") is twice the length of
str.Truncate(aNativeOffset); // the XP newline ("\n"), so XP offset is equal to the length of the native
ConvertToXPNewlines(str); // offset minus the number of newlines encountered in the string.
return str.Length(); return aNativeOffset - CountNewlinesIn(aContent, aNativeOffset);
#else
// On other platforms, the native and XP newlines are the same.
return aNativeOffset;
#endif
} }
static nsresult GenerateFlatTextContent(nsIRange* aRange, static nsresult GenerateFlatTextContent(nsIRange* aRange,