Bug 1081858 - Part 4. Implement segment break transformation rules. r=jfkthame

MozReview-Commit-ID: BcOm4LVWGzW
This commit is contained in:
Kan-Ru Chen 2016-10-25 22:35:02 +08:00
Родитель 62f72040da
Коммит 7366a10541
6 изменённых файлов: 125 добавлений и 6 удалений

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -425,4 +425,11 @@ HashUTF8AsUTF16(const char* aUTF8, uint32_t aLength, bool* aErr)
return hash;
}
bool
IsSegmentBreakSkipChar(uint32_t u)
{
return unicode::IsEastAsianWidthFWH(u) &&
unicode::GetScriptCode(u) != unicode::Script::HANGUL;
}
} // namespace mozilla

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

@ -16,6 +16,8 @@
(0xf900u <= (u) && (u) <= 0xfaffu) || \
(0xff00u <= (u) && (u) <= 0xffefu) )
#define IS_ZERO_WIDTH_SPACE(u) ((u) == 0x200B)
void ToLowerCase(nsAString&);
void ToUpperCase(nsAString&);
@ -142,6 +144,9 @@ namespace mozilla {
uint32_t
HashUTF8AsUTF16(const char* aUTF8, uint32_t aLength, bool* aErr);
bool
IsSegmentBreakSkipChar(uint32_t u);
} // namespace mozilla
#endif /* nsUnicharUtils_h__ */

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

@ -5,11 +5,12 @@
#include "nsTextFrameUtils.h"
#include "nsUnicharUtils.h"
#include "nsBidiUtils.h"
#include "nsCharTraits.h"
#include "nsIContent.h"
#include "nsStyleStruct.h"
#include "nsTextFragment.h"
#include "nsUnicharUtils.h"
#include <algorithm>
static bool IsDiscardable(char16_t ch, uint32_t* aFlags)
@ -89,10 +90,31 @@ nsTextFrameUtils::TransformText(const char16_t* aText, uint32_t aLength,
!IsSpaceCombiningSequenceTail(&aText[i + 1], aLength - (i + 1)))) {
nowInWhitespace = true;
} else if (ch == '\n' && aCompression == COMPRESS_WHITESPACE_NEWLINE) {
if (i > 0 && IS_CJ_CHAR(aText[i - 1]) &&
i + 1 < aLength && IS_CJ_CHAR(aText[i + 1])) {
// Discard newlines between CJK chars.
// XXX this really requires more context to get right!
if ((i > 0 && IS_ZERO_WIDTH_SPACE(aText[i - 1])) ||
(i + 1 < aLength && IS_ZERO_WIDTH_SPACE(aText[i + 1]))) {
aSkipChars->SkipChar();
continue;
}
uint32_t ucs4before;
uint32_t ucs4after;
if (i > 1 &&
NS_IS_LOW_SURROGATE(aText[i - 1]) &&
NS_IS_HIGH_SURROGATE(aText[i - 2])) {
ucs4before = SURROGATE_TO_UCS4(aText[i - 2], aText[i - 1]);
} else if (i > 0) {
ucs4before = aText[i - 1];
}
if (i + 2 < aLength &&
NS_IS_HIGH_SURROGATE(aText[i + 1]) &&
NS_IS_LOW_SURROGATE(aText[i + 2])) {
ucs4after = SURROGATE_TO_UCS4(aText[i + 1], aText[i + 2]);
} else if (i + 1 < aLength) {
ucs4after = aText[i + 1];
}
if (i > 0 && IsSegmentBreakSkipChar(ucs4before) &&
i + 1 < aLength && IsSegmentBreakSkipChar(ucs4after)) {
// Discard newlines between characters that have F, W, or H
// EastAsianWidth property and neither side is Hangul.
aSkipChars->SkipChar();
continue;
}

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

@ -338,3 +338,4 @@ HTTP(..) == space-font-1.html space-font-1-ref.html
# handling of highly negative letter-spacing and intrinsic width
== negative-letter-spacing-1.html negative-letter-spacing-1-ref.html
== segment-break-transformation-1.html segment-break-transformation-1-ref.html

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

@ -0,0 +1,34 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Reference -->
<style type="text/css">
div { border:1px solid black; }
b { font-weight:normal; background-color:yellow; }
</style>
</head>
<body>
<div>
<p><b><span>&#x65b7;&#x884c;&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;<br>
&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;<br>
&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;<br>
&#x6e2c;&#x8a66;</span></b>
<p><b><span>Hello Kitty</span></b>
<p><b><span>HelloKitty</span></b>
<p><b><span>HelloKitty</span></b>
<p><b><span>HelloKitty</span></b>
<!-- test surrogates handling -->
<p><b><span>&#x20000;&#x20001;&#x20002;&#x20003;</span></b>
<p><b><span>&#x20000;&#x6e2c;&#x20002;&#x20003;</span></b>
<p><b><span>&#x20000;&#x20001;&#x6e2c;&#x20003;</span></b>
</div>
</body>
</html>

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

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
div { border:1px solid black; }
b { font-weight:normal; background-color:yellow; }
.nowrap { white-space:nowrap; }
.pre { white-space:pre; }
.prewrap { white-space:pre-wrap; }
.preline { white-space:pre-line; }
</style>
</head>
<body>
<div>
<p><b><span>&#x65b7;&#x884c;
&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;&#x200B;
&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;
&#x200B;&#x6e2c;&#x8a66;</span></b>
<p><b><span>&#x65b7;&#x884c;&#x200B;
&#x200B;&#x6e2c;&#x8a66;</span></b>
<p><b><span class="nowrap">&#x65b7;&#x884c;
&#x6e2c;&#x8a66;</span></b>
<p><b><span class="pre">&#x65b7;&#x884c;
&#x6e2c;&#x8a66;</span></b>
<p><b><span class="prewrap">&#x65b7;&#x884c;
&#x6e2c;&#x8a66;</span></b>
<p><b><span class="preline">&#x65b7;&#x884c;
&#x6e2c;&#x8a66;</span></b>
<p><b><span>Hello
Kitty</span></b>
<p><b><span>Hello&#x200B;
Kitty</span></b>
<p><b><span>Hello
&#x200B;Kitty</span></b>
<p><b><span>Hello&#x200B;
&#x200B;Kitty</span></b>
<!-- test surrogates handling -->
<p><b><span>&#x20000;&#x20001;
&#x20002;&#x20003;</span></b>
<p><b><span>&#x20000;&#x6e2c;
&#x20002;&#x20003;</span></b>
<p><b><span>&#x20000;&#x20001;
&#x6e2c;&#x20003;</span></b>
</div>
</body>
</html>