Commit acb27cdd authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

Move Capitalize function to platform/text

This patch moves Capitalize (titlecase) function from LayoutText
to platform/text in order to share with LayoutNG.

Bug: 636993
Change-Id: I1d0e78139424a20d4184976d1f920c75fc8190ac
Reviewed-on: https://chromium-review.googlesource.com/1047925Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557113}
parent 84d795bc
......@@ -60,6 +60,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/text/bidi_resolver.h"
#include "third_party/blink/renderer/platform/text/capitalize.h"
#include "third_party/blink/renderer/platform/text/character.h"
#include "third_party/blink/renderer/platform/text/hyphenation.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
......@@ -112,51 +113,6 @@ class SecureTextTimer final : public TimerBase {
int last_typed_character_offset_;
};
static void MakeCapitalized(String* string, UChar previous) {
if (string->IsNull())
return;
unsigned length = string->length();
const StringImpl& input = *string->Impl();
CHECK_LT(length, std::numeric_limits<unsigned>::max());
StringBuffer<UChar> string_with_previous(length + 1);
string_with_previous[0] =
previous == kNoBreakSpaceCharacter ? kSpaceCharacter : previous;
for (unsigned i = 1; i < length + 1; i++) {
// Replace &nbsp with a real space since ICU no longer treats &nbsp as a
// word separator.
if (input[i - 1] == kNoBreakSpaceCharacter)
string_with_previous[i] = kSpaceCharacter;
else
string_with_previous[i] = input[i - 1];
}
TextBreakIterator* boundary =
WordBreakIterator(string_with_previous.Characters(), length + 1);
if (!boundary)
return;
StringBuilder result;
result.ReserveCapacity(length);
int32_t end_of_word;
int32_t start_of_word = boundary->first();
for (end_of_word = boundary->next(); end_of_word != kTextBreakDone;
start_of_word = end_of_word, end_of_word = boundary->next()) {
if (start_of_word) { // Ignore first char of previous string
result.Append(
input[start_of_word - 1] == kNoBreakSpaceCharacter
? kNoBreakSpaceCharacter
: WTF::Unicode::ToTitleCase(string_with_previous[start_of_word]));
}
for (int i = start_of_word + 1; i < end_of_word; i++)
result.Append(input[i - 1]);
}
*string = result.ToString();
}
LayoutText::LayoutText(Node* node, scoped_refptr<StringImpl> str)
: LayoutObject(node),
has_tab_(false),
......@@ -1717,7 +1673,7 @@ void ApplyTextTransform(const ComputedStyle* style,
case ETextTransform::kNone:
break;
case ETextTransform::kCapitalize:
MakeCapitalized(&text, previous_character);
text = Capitalize(text, previous_character);
break;
case ETextTransform::kUppercase:
text = text.UpperUnicode(style->Locale());
......
......@@ -1357,6 +1357,8 @@ jumbo_component("platform") {
"text/bidi_run_list.h",
"text/bidi_text_run.cc",
"text/bidi_text_run.h",
"text/capitalize.cc",
"text/capitalize.h",
"text/character.cc",
"text/character.h",
"text/character_emoji.cc",
......@@ -1889,6 +1891,7 @@ jumbo_source_set("blink_platform_unittests_sources") {
"testing/tree_test_helpers.h",
"text/bidi_resolver_test.cc",
"text/bidi_test_harness.h",
"text/capitalize_test.cc",
"text/character_test.cc",
"text/date_time_format_test.cc",
"text/hyphenation_test.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/text/capitalize.h"
#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
String Capitalize(const String& string, UChar previous_character) {
if (string.IsNull())
return string;
unsigned length = string.length();
const StringImpl& input = *string.Impl();
CHECK_LT(length, std::numeric_limits<unsigned>::max());
StringBuffer<UChar> string_with_previous(length + 1);
string_with_previous[0] = previous_character == kNoBreakSpaceCharacter
? kSpaceCharacter
: previous_character;
for (unsigned i = 1; i < length + 1; i++) {
// Replace &nbsp with a real space since ICU no longer treats &nbsp as a
// word separator.
if (input[i - 1] == kNoBreakSpaceCharacter)
string_with_previous[i] = kSpaceCharacter;
else
string_with_previous[i] = input[i - 1];
}
TextBreakIterator* boundary =
WordBreakIterator(string_with_previous.Characters(), length + 1);
if (!boundary)
return string;
StringBuilder result;
result.ReserveCapacity(length);
int32_t end_of_word;
int32_t start_of_word = boundary->first();
for (end_of_word = boundary->next(); end_of_word != kTextBreakDone;
start_of_word = end_of_word, end_of_word = boundary->next()) {
if (start_of_word) { // Ignore first char of previous string
result.Append(
input[start_of_word - 1] == kNoBreakSpaceCharacter
? kNoBreakSpaceCharacter
: WTF::Unicode::ToTitleCase(string_with_previous[start_of_word]));
}
for (int i = start_of_word + 1; i < end_of_word; i++)
result.Append(input[i - 1]);
}
return result.ToString();
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_CAPITALIZE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_CAPITALIZE_H_
#include <unicode/utypes.h>
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
// Capitalize (titlecase) each word of a string.
// https://drafts.csswg.org/css-text-3/#valdef-text-transform-capitalize
PLATFORM_EXPORT String Capitalize(const String&,
UChar previous_character = ' ');
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_CAPITALIZE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/text/capitalize.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/text/character.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
struct CapitalizeTestData {
String input;
String expected;
UChar previous_character = kSpaceCharacter;
};
class CapitalizeTest : public testing::Test,
public testing::WithParamInterface<CapitalizeTestData> {
};
INSTANTIATE_TEST_CASE_P(CapitalizeTest,
CapitalizeTest,
testing::Values(CapitalizeTestData{String(), String()},
CapitalizeTestData{"", ""},
CapitalizeTestData{"hello, world",
"Hello, World"}));
TEST_P(CapitalizeTest, Data) {
const auto& data = GetParam();
EXPECT_EQ(data.expected, Capitalize(data.input, data.previous_character));
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment