diff --git a/AUTHORS b/AUTHORS index 09258d484..dcb04609 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -166,6 +166,7 @@ Daniel Shaulov <dshaulov@ptc.com> Daniel Trebbien <dtrebbien@gmail.com> Daniel Waxweiler <daniel.waxweiler@gmail.com> +Dániel Bátyai <dbatyai@inf.u-szeged.hu> Darshini KN <kn.darshini@samsung.com> David Benjamin <davidben@mit.edu> David Erceg <erceg.david@gmail.com>
diff --git a/DEPS b/DEPS index 61737ac..fbc03ab 100644 --- a/DEPS +++ b/DEPS
@@ -44,7 +44,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '041e67fe01d8be05dd9d56514dd2b88be273ef21', + 'v8_revision': '11f9b0549e4409f0daab970f20be3c62cadecd4d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '27f7008827515836510b663c032e851f081af70a', + 'catapult_revision': '6adf18ab78fe7f20638206d2ca6ecd3d58efd9c9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 01f2830..9176b2fd 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -48,6 +48,7 @@ "input/selection.h", "input/single_scrollbar_animation_controller_thinning.cc", "input/single_scrollbar_animation_controller_thinning.h", + "input/touch_action.h", "layers/append_quads_data.cc", "layers/append_quads_data.h", "layers/content_layer_client.h",
diff --git a/cc/animation/animation_player_unittest.cc b/cc/animation/animation_player_unittest.cc index d896f21..7b4b82d8 100644 --- a/cc/animation/animation_player_unittest.cc +++ b/cc/animation/animation_player_unittest.cc
@@ -394,7 +394,7 @@ EXPECT_EQ(player_impl_->element_id(), element_id_); EXPECT_TRUE(CheckPlayerTimelineNeedsPushProperties(false)); - const ElementId new_element_id(NextTestLayerId(), 0); + const ElementId new_element_id(NextTestLayerId()); player_->DetachElement(); player_->AttachElement(new_element_id);
diff --git a/cc/base/rtree.cc b/cc/base/rtree.cc index 1cb0f99..ab4b128b 100644 --- a/cc/base/rtree.cc +++ b/cc/base/rtree.cc
@@ -23,11 +23,8 @@ // We don't allow reallocations, since that would invalidate references to // existing nodes, so verify that capacity > size. DCHECK_GT(nodes_.capacity(), nodes_.size()); - nodes_.emplace_back(); - Node& node = nodes_.back(); - node.num_children = 0; - node.level = level; - return &node; + nodes_.emplace_back(level); + return &nodes_.back(); } RTree::Branch RTree::BuildRecursive(std::vector<Branch>* branches, int level) {
diff --git a/cc/base/rtree.h b/cc/base/rtree.h index 3a19c29..679bc84 100644 --- a/cc/base/rtree.h +++ b/cc/base/rtree.h
@@ -52,10 +52,7 @@ if (bounds.IsEmpty()) continue; - branches.push_back(Branch()); - Branch& branch = branches.back(); - branch.bounds = bounds; - branch.index = i; + branches.emplace_back(i, bounds); } num_data_elements_ = branches.size(); @@ -115,12 +112,18 @@ size_t index; }; gfx::Rect bounds; + + Branch() {} + Branch(size_t index, const gfx::Rect& bounds) + : index(index), bounds(bounds) {} }; struct Node { uint16_t num_children; uint16_t level; Branch children[kMaxChildren]; + + explicit Node(uint16_t level) : num_children(0), level(level) {} }; void SearchRecursive(Node* root,
diff --git a/cc/input/touch_action.h b/cc/input/touch_action.h new file mode 100644 index 0000000..8b11c4c9 --- /dev/null +++ b/cc/input/touch_action.h
@@ -0,0 +1,56 @@ +// Copyright 2017 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 CC_INPUT_TOUCH_ACTION_H_ +#define CC_INPUT_TOUCH_ACTION_H_ + +#include <cstdlib> + +namespace cc { + +// The current touch action specifies what accelerated browser operations +// (panning and zooming) are currently permitted via touch input. +// See http://www.w3.org/TR/pointerevents/#the-touch-action-css-property. +// This is intended to be the single canonical definition of the enum, it's used +// elsewhere in both Blink and content since touch action logic spans those +// subsystems. +// TODO(crbug.com/720553): rework this enum to enum class. +const size_t kTouchActionBits = 6; + +enum TouchAction { + // No scrolling or zooming allowed. + kTouchActionNone = 0x0, + kTouchActionPanLeft = 0x1, + kTouchActionPanRight = 0x2, + kTouchActionPanX = kTouchActionPanLeft | kTouchActionPanRight, + kTouchActionPanUp = 0x4, + kTouchActionPanDown = 0x8, + kTouchActionPanY = kTouchActionPanUp | kTouchActionPanDown, + kTouchActionPan = kTouchActionPanX | kTouchActionPanY, + kTouchActionPinchZoom = 0x10, + kTouchActionManipulation = kTouchActionPan | kTouchActionPinchZoom, + kTouchActionDoubleTapZoom = 0x20, + kTouchActionAuto = kTouchActionManipulation | kTouchActionDoubleTapZoom, + kTouchActionMax = (1 << 6) - 1 +}; + +inline TouchAction operator|(TouchAction a, TouchAction b) { + return static_cast<TouchAction>(int(a) | int(b)); +} + +inline TouchAction& operator|=(TouchAction& a, TouchAction b) { + return a = a | b; +} + +inline TouchAction operator&(TouchAction a, TouchAction b) { + return static_cast<TouchAction>(int(a) & int(b)); +} + +inline TouchAction& operator&=(TouchAction& a, TouchAction b) { + return a = a & b; +} + +} // namespace cc + +#endif // CC_INPUT_TOUCH_ACTION_H_
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc index f8f55537..089119f5 100644 --- a/cc/layers/layer_impl_unittest.cc +++ b/cc/layers/layer_impl_unittest.cc
@@ -225,7 +225,7 @@ // Changing these properties does not cause the layer to be marked as changed // but does cause the layer to need to push properties. EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( - root->SetElementId(ElementId(2, 0))); + root->SetElementId(ElementId(2))); EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE( root->SetMutableProperties(MutableProperty::kOpacity); root->SetNeedsPushProperties()); @@ -349,7 +349,7 @@ VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetBackgroundColor(arbitrary_color)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size)); - VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetElementId(ElementId(2, 0))); + VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetElementId(ElementId(2))); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetMutableProperties(MutableProperty::kTransform)); }
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index 1a227ca..e6ef4d57 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -929,7 +929,7 @@ gfx::Rect(10, 10))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurfaceForTesting(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2, 0))); + EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2))); EXPECT_SET_NEEDS_COMMIT( 1, test_layer->SetMutableProperties(MutableProperty::kTransform)); @@ -1385,7 +1385,7 @@ // though currently there is no good place for this unittest to go. Move to // LayerTreeHost unittest when there is a good setup. scoped_refptr<Layer> layer = Layer::Create(); - layer->SetElementId(ElementId(2, 0)); + layer->SetElementId(ElementId(2)); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer)); auto element_id = layer->element_id(); @@ -1419,7 +1419,7 @@ EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2); - test_layer->SetElementId(ElementId(2, 0)); + test_layer->SetElementId(ElementId(2)); test_layer->SetMutableProperties(MutableProperty::kTransform); EXPECT_FALSE(impl_layer->element_id()); @@ -1427,7 +1427,7 @@ test_layer->PushPropertiesTo(impl_layer.get()); - EXPECT_EQ(ElementId(2, 0), impl_layer->element_id()); + EXPECT_EQ(ElementId(2), impl_layer->element_id()); EXPECT_EQ(MutableProperty::kTransform, impl_layer->mutable_properties()); }
diff --git a/cc/test/animation_timelines_test_common.cc b/cc/test/animation_timelines_test_common.cc index dd039a4..d986a4d 100644 --- a/cc/test/animation_timelines_test_common.cc +++ b/cc/test/animation_timelines_test_common.cc
@@ -355,7 +355,7 @@ host_ = client_.host(); host_impl_ = client_impl_.host(); - element_id_ = ElementId(NextTestLayerId(), 0); + element_id_ = ElementId(NextTestLayerId()); } AnimationTimelinesTest::~AnimationTimelinesTest() {
diff --git a/cc/trees/element_id.cc b/cc/trees/element_id.cc index 4591330..6e32b66 100644 --- a/cc/trees/element_id.cc +++ b/cc/trees/element_id.cc
@@ -13,7 +13,7 @@ namespace cc { bool ElementId::operator==(const ElementId& o) const { - return primaryId == o.primaryId && secondaryId == o.secondaryId; + return id_ == o.id_; } bool ElementId::operator!=(const ElementId& o) const { @@ -21,36 +21,33 @@ } bool ElementId::operator<(const ElementId& o) const { - return std::tie(primaryId, secondaryId) < - std::tie(o.primaryId, o.secondaryId); + return id_ < o.id_; } ElementId::operator bool() const { - return !!primaryId; + return !!id_; } ElementId LayerIdToElementIdForTesting(int layer_id) { - return ElementId(std::numeric_limits<int>::max() - layer_id, 0); + return ElementId(std::numeric_limits<int>::max() - layer_id); } void ElementId::AddToTracedValue(base::trace_event::TracedValue* res) const { - res->SetInteger("primaryId", primaryId); - res->SetInteger("secondaryId", secondaryId); + res->SetInteger("id_", id_); } std::unique_ptr<base::Value> ElementId::AsValue() const { std::unique_ptr<base::DictionaryValue> res(new base::DictionaryValue()); - res->SetInteger("primaryId", primaryId); - res->SetInteger("secondaryId", secondaryId); + res->SetInteger("id_", id_); return std::move(res); } size_t ElementIdHash::operator()(ElementId key) const { - return base::HashInts(key.primaryId, key.secondaryId); + return std::hash<int>()(key.id_); } std::ostream& operator<<(std::ostream& out, const ElementId& id) { - return out << "(" << id.primaryId << ", " << id.secondaryId << ")"; + return out << "(" << id.id_ << ")"; } } // namespace cc
diff --git a/cc/trees/element_id.h b/cc/trees/element_id.h index 8518cf8..059cf2b 100644 --- a/cc/trees/element_id.h +++ b/cc/trees/element_id.h
@@ -24,6 +24,10 @@ namespace cc { +using ElementIdType = uint64_t; + +static const ElementIdType kInvalidElementId = 0; + // Element ids are chosen by cc's clients and can be used as a stable identifier // across updates. // @@ -44,9 +48,8 @@ // the Layer's lifetime because non-default ElementIds are only set during an // animation's lifetime. struct CC_EXPORT ElementId { - ElementId(int primaryId, int secondaryId) - : primaryId(primaryId), secondaryId(secondaryId) {} - ElementId() : ElementId(0, 0) {} + explicit ElementId(int id) : id_(id) {} + ElementId() : ElementId(kInvalidElementId) {} bool operator==(const ElementId& o) const; bool operator!=(const ElementId& o) const; @@ -61,11 +64,10 @@ // The compositor treats this as an opaque handle and should not know how to // interpret these bits. Non-blink cc clients typically operate in terms of // layers and may set this value to match the client's layer id. - int primaryId; - int secondaryId; + ElementIdType id_; }; -CC_EXPORT ElementId LayerIdToElementIdForTesting(int layer_id); +ElementId CC_EXPORT LayerIdToElementIdForTesting(int layer_id); struct CC_EXPORT ElementIdHash { size_t operator()(ElementId key) const;
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 0c78c26..46f45d5 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -1378,7 +1378,7 @@ root_->SetBounds(gfx::Size(50, 50)); // Make sure child is registerd for animation. - child_->SetElementId(ElementId(2, 0)); + child_->SetElementId(ElementId(2)); // Make sure child and grand_child have transform nodes. gfx::Transform rotation;
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index a5513c7e..1eefcfc 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -490,7 +490,7 @@ AttachPlayersToTimeline(); scoped_refptr<Layer> layer = Layer::Create(); - layer->SetElementId(ElementId(42, 0)); + layer->SetElementId(ElementId(42)); player_->AttachElement(layer->element_id()); player_->set_animation_delegate(this);
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc index ad13e8dd..1def71a2 100644 --- a/cc/trees/tree_synchronizer_unittest.cc +++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -504,7 +504,7 @@ transient_scroll_layer->AddChild(scroll_clip_layer); scroll_clip_layer->AddChild(scroll_layer); - ElementId scroll_element_id = ElementId(5, 4); + ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); transient_scroll_layer->SetScrollClipLayerId( @@ -551,7 +551,7 @@ scoped_refptr<Layer> transient_scroll_clip_layer = Layer::Create(); scoped_refptr<Layer> transient_scroll_layer = Layer::Create(); - ElementId scroll_element_id = ElementId(5, 4); + ElementId scroll_element_id = ElementId(5); scroll_layer->SetElementId(scroll_element_id); layer_tree_root->AddChild(transient_scroll_clip_layer);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java index 5c4e7bd..793c7df4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java
@@ -226,8 +226,12 @@ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); for (ActiveNotification activeNotification : getActiveNotifications()) { manager.cancel(NOTIFICATION_TAG, activeNotification.mId); - recordCachedActionMetric(why); + if (removeActiveNotification( + activeNotification.mCategory, activeNotification.mIdWithinCategory)) { + recordCachedActionMetric(why); + } } + assert getActiveNotifications().isEmpty(); } private static class ActiveNotification {
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c7627bb7..559fc69b 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -12136,6 +12136,40 @@ </message> </if> + <!-- Windows 10 toast strings --> + <if expr="is_win"> + <message name="IDS_WIN10_TOAST_BROWSE_FAST" desc="Toast message variant: browse fast."> + Browse fast with Google Chrome + </message> + <message name="IDS_WIN10_TOAST_BROWSE_SAFELY" desc="Toast message variant: browse safely."> + Browse safely with Google Chrome + </message> + <message name="IDS_WIN10_TOAST_BROWSE_SMART" desc="Toast message variant: browse smart."> + Browse smart with Chrome + </message> + <message name="IDS_WIN10_TOAST_SWITCH_FAST" desc="Toast message variant: switch to a fast browser."> + Switch to a fast browser + </message> + <message name="IDS_WIN10_TOAST_SWITCH_SMART" desc="Toast message variant: switch to a smart browser."> + Switch to a smart browser + </message> + <message name="IDS_WIN10_TOAST_SWITCH_SECURE" desc="Toast message variant: switch to a secure browser."> + Switch to a secure browser + </message> + <message name="IDS_WIN10_TOAST_SWITCH_SMART_AND_SECURE" desc="Toast message variant: switch to a smart and secure browser."> + Switch to a smart and secure browser + </message> + <message name="IDS_WIN10_TOAST_RECOMMENDATION" desc="Toast header label noting Google recommends Chrome."> + Google recommends Chrome + </message> + <message name="IDS_WIN10_TOAST_OPEN_CHROME" desc="The label on the button to dismiss the toast and launch Chrome."> + Open Chrome + </message> + <message name="IDS_WIN10_TOAST_NO_THANKS" desc="The label on the button to dismiss the toast without launching Chrome."> + No thanks + </message> + </if> + <!-- Windows 10 Welcome page strings --> <if expr="is_win"> <message name="IDS_WIN10_WELCOME_OPEN_SETTINGS" desc="A link which, when clicked, will cause a particular page to open in the external Windows Settings dialog.">
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 45f192d..2d7895c 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -50,7 +50,6 @@ "incognito.1x.icon", "incognito.icon", "laptop.icon", - "lock.icon", "mixed_content.icon", "my_location.icon", "navigate_home.1x.icon",
diff --git a/chrome/browser/android/vr_shell/textures/url_bar_texture.cc b/chrome/browser/android/vr_shell/textures/url_bar_texture.cc index e1ca6cd..160e26d 100644 --- a/chrome/browser/android/vr_shell/textures/url_bar_texture.cc +++ b/chrome/browser/android/vr_shell/textures/url_bar_texture.cc
@@ -47,9 +47,7 @@ return ui::kInfoOutlineIcon; case SecurityLevel::SECURE: case SecurityLevel::EV_SECURE: - // TODO(cjgrant): Use the lock icon when available. - // return ui::kLockIcon; - return ui::kInfoOutlineIcon; + return ui::kLockIcon; case SecurityLevel::SECURE_WITH_POLICY_INSTALLED_CERT: case SecurityLevel::DANGEROUS: default:
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 472e239b..34b9491 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1774,6 +1774,7 @@ "../ui/webui/chromeos/login/l10n_util_test_util.cc", "../ui/webui/chromeos/login/l10n_util_test_util.h", "../ui/webui/chromeos/login/l10n_util_unittest.cc", + "../ui/webui/chromeos/login/oobe_display_chooser_unittest.cc", "../ui/webui/chromeos/login/signin_userlist_unittest.cc", "../ui/webui/options/chromeos/cros_language_options_handler_unittest.cc", "../ui/webui/settings/chromeos/easy_unlock_settings_handler_unittest.cc",
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc index 6db2b1af..7780fbf8 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -975,10 +975,15 @@ // LoginDisplayHostImpl, display::DisplayObserver: void LoginDisplayHostImpl::OnDisplayAdded(const display::Display& new_display) { + if (GetOobeUI()) + GetOobeUI()->OnDisplayConfigurationChanged(); } void LoginDisplayHostImpl::OnDisplayRemoved( - const display::Display& old_display) {} + const display::Display& old_display) { + if (GetOobeUI()) + GetOobeUI()->OnDisplayConfigurationChanged(); +} void LoginDisplayHostImpl::OnDisplayMetricsChanged( const display::Display& display,
diff --git a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc index bc32433..e784cabe 100644 --- a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc +++ b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.cc
@@ -29,8 +29,9 @@ private: void ReadBlob(int64_t position, int64_t length, - const ReadBlobCallback& callback) override { - safe_media_metadata_parser_->StartBlobRequest(callback, position, length); + ReadBlobCallback callback) override { + safe_media_metadata_parser_->StartBlobRequest(std::move(callback), position, + length); } mojo::Binding<extensions::mojom::MediaDataSource> binding_; @@ -126,7 +127,7 @@ } void SafeMediaMetadataParser::StartBlobRequest( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, int64_t position, int64_t length) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -134,11 +135,11 @@ content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, base::BindOnce(&SafeMediaMetadataParser::StartBlobReaderOnUIThread, this, - callback, position, length)); + std::move(callback), position, length)); } void SafeMediaMetadataParser::StartBlobReaderOnUIThread( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, int64_t position, int64_t length) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -146,13 +147,13 @@ BlobReader* reader = new BlobReader( // BlobReader is self-deleting. profile_, blob_uuid_, base::Bind(&SafeMediaMetadataParser::BlobReaderDoneOnUIThread, this, - callback)); + base::Passed(&callback))); reader->SetByteRange(position, length); reader->Start(); } void SafeMediaMetadataParser::BlobReaderDoneOnUIThread( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, std::unique_ptr<std::string> data, int64_t /* blob_total_size */) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -160,16 +161,16 @@ content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&SafeMediaMetadataParser::FinishBlobRequest, this, - callback, base::Passed(std::move(data)))); + std::move(callback), std::move(data))); } void SafeMediaMetadataParser::FinishBlobRequest( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, std::unique_ptr<std::string> data) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); if (utility_process_mojo_client_) - callback.Run(std::vector<uint8_t>(data->begin(), data->end())); + std::move(callback).Run(std::vector<uint8_t>(data->begin(), data->end())); } } // namespace metadata
diff --git a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h index 4bad0b13..5152aa3fb 100644 --- a/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h +++ b/chrome/browser/media_galleries/fileapi/safe_media_metadata_parser.h
@@ -71,19 +71,19 @@ // Sequence of functions that bounces from the IO thread to the UI thread to // read the blob data, then sends the data back to the utility process. void StartBlobRequest( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, int64_t position, int64_t length); void StartBlobReaderOnUIThread( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, int64_t position, int64_t length); void BlobReaderDoneOnUIThread( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, std::unique_ptr<std::string> data, int64_t /* blob_total_size */); void FinishBlobRequest( - const extensions::mojom::MediaDataSource::ReadBlobCallback& callback, + extensions::mojom::MediaDataSource::ReadBlobCallback callback, std::unique_ptr<std::string> data); // All member variables are only accessed on the IO thread.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index b70cd13..bc7f587 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -284,6 +284,8 @@ "webui/chromeos/login/network_screen_handler.h", "webui/chromeos/login/network_state_informer.cc", "webui/chromeos/login/network_state_informer.h", + "webui/chromeos/login/oobe_display_chooser.cc", + "webui/chromeos/login/oobe_display_chooser.h", "webui/chromeos/login/oobe_ui.cc", "webui/chromeos/login/oobe_ui.h", "webui/chromeos/login/reset_screen_handler.cc", @@ -2032,10 +2034,10 @@ "views/external_protocol_dialog.h", "views/frame/avatar_button_manager.cc", "views/frame/avatar_button_manager.h", + "views/profiles/avatar_button.cc", + "views/profiles/avatar_button.h", "views/profiles/avatar_button_delegate.h", "views/profiles/avatar_button_style.h", - "views/profiles/new_avatar_button.cc", - "views/profiles/new_avatar_button.h", "webui/app_launcher_page_ui.cc", "webui/app_launcher_page_ui.h", "webui/settings/settings_default_browser_handler.cc", @@ -2083,8 +2085,8 @@ # non-Views mode on Mac. It appears not to link in that case. "views/frame/avatar_button_manager.cc", "views/frame/avatar_button_manager.h", - "views/profiles/new_avatar_button.cc", - "views/profiles/new_avatar_button.h", + "views/profiles/avatar_button.cc", + "views/profiles/avatar_button.h", ] sources += [ "startup/session_crashed_infobar_delegate.cc",
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm index 9a43b64..11b5a57 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
@@ -609,7 +609,7 @@ + (CGFloat)computeContentsOffset:(const AutocompleteMatch&)match { const base::string16& inputText = base::UTF8ToUTF16( - match.GetAdditionalInfo(kACMatchPropertyInputText)); + match.GetAdditionalInfo(kACMatchPropertySuggestionText)); int contentsStartIndex = 0; base::StringToInt( match.GetAdditionalInfo(kACMatchPropertyContentsStartIndex),
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm index 7b024df..a6af133 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -87,6 +87,7 @@ #include "ui/gfx/text_elider.h" #include "ui/native_theme/common_theme.h" #include "ui/native_theme/native_theme.h" +#include "ui/vector_icons/vector_icons.h" namespace { @@ -2197,7 +2198,7 @@ text:l10n_util::GetNSString( IDS_PROFILES_PROFILE_SIGNOUT_BUTTON) image:NSImageFromImageSkia(gfx::CreateVectorIcon( - kLockIcon, icon_size, gfx::kChromeIconGrey)) + ui::kLockIcon, icon_size, gfx::kChromeIconGrey)) action:@selector(lockProfile:)]; [container addSubview:lockButton]; viewRect.origin.y = NSMaxY([lockButton frame]);
diff --git a/chrome/browser/ui/views/BUILD.gn b/chrome/browser/ui/views/BUILD.gn index d198a01..686e700f 100644 --- a/chrome/browser/ui/views/BUILD.gn +++ b/chrome/browser/ui/views/BUILD.gn
@@ -34,6 +34,7 @@ "//ui/events", "//ui/gfx", "//ui/gfx/geometry", + "//ui/vector_icons", "//url", ]
diff --git a/chrome/browser/ui/views/frame/avatar_button_manager.cc b/chrome/browser/ui/views/frame/avatar_button_manager.cc index 8101bf8b..fa8b448 100644 --- a/chrome/browser/ui/views/frame/avatar_button_manager.cc +++ b/chrome/browser/ui/views/frame/avatar_button_manager.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/frame/browser_frame.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/profiles/new_avatar_button.h" +#include "chrome/browser/ui/views/profiles/avatar_button.h" AvatarButtonManager::AvatarButtonManager(BrowserNonClientFrameView* frame_view) : frame_view_(frame_view), view_(nullptr) {}
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index 16ab9c2..aff68fc 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -547,8 +547,8 @@ if (match.type != AutocompleteMatchType::SEARCH_SUGGEST_TAIL) return 0; - const base::string16& input_text = - base::UTF8ToUTF16(match.GetAdditionalInfo(kACMatchPropertyInputText)); + const base::string16& input_text = base::UTF8ToUTF16( + match.GetAdditionalInfo(kACMatchPropertySuggestionText)); int contents_start_index = 0; base::StringToInt(match.GetAdditionalInfo(kACMatchPropertyContentsStartIndex), &contents_start_index);
diff --git a/chrome/browser/ui/views/profiles/new_avatar_button.cc b/chrome/browser/ui/views/profiles/avatar_button.cc similarity index 99% rename from chrome/browser/ui/views/profiles/new_avatar_button.cc rename to chrome/browser/ui/views/profiles/avatar_button.cc index 795ca23..bf5b01f 100644 --- a/chrome/browser/ui/views/profiles/new_avatar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_button.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/profiles/new_avatar_button.h" +#include "chrome/browser/ui/views/profiles/avatar_button.h" #include <utility>
diff --git a/chrome/browser/ui/views/profiles/new_avatar_button.h b/chrome/browser/ui/views/profiles/avatar_button.h similarity index 93% rename from chrome/browser/ui/views/profiles/new_avatar_button.h rename to chrome/browser/ui/views/profiles/avatar_button.h index 5cbcb61..4bab5aca 100644 --- a/chrome/browser/ui/views/profiles/new_avatar_button.h +++ b/chrome/browser/ui/views/profiles/avatar_button.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_NEW_AVATAR_BUTTON_H_ -#define CHROME_BROWSER_UI_VIEWS_PROFILES_NEW_AVATAR_BUTTON_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_AVATAR_BUTTON_H_ +#define CHROME_BROWSER_UI_VIEWS_PROFILES_AVATAR_BUTTON_H_ #include "base/macros.h" #include "chrome/browser/profiles/profile_attributes_storage.h" @@ -67,4 +67,4 @@ DISALLOW_COPY_AND_ASSIGN(NewAvatarButton); }; -#endif // CHROME_BROWSER_UI_VIEWS_PROFILES_NEW_AVATAR_BUTTON_H_ +#endif // CHROME_BROWSER_UI_VIEWS_PROFILES_AVATAR_BUTTON_H_
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 0969467..8216b74 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -1529,7 +1529,7 @@ if (display_lock) { lock_button_ = new BackgroundColorHoverButton( this, l10n_util::GetStringUTF16(IDS_PROFILES_PROFILE_SIGNOUT_BUTTON), - gfx::CreateVectorIcon(kLockIcon, kIconSize, gfx::kChromeIconGrey)); + gfx::CreateVectorIcon(ui::kLockIcon, kIconSize, gfx::kChromeIconGrey)); layout->StartRow(1, 0); layout->AddView(lock_button_); } else if (!is_guest) {
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc new file mode 100644 index 0000000..2e270164 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.cc
@@ -0,0 +1,54 @@ +// Copyright 2017 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 "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h" + +#include "ash/display/display_configuration_controller.h" +#include "ash/shell.h" +#include "ui/display/display.h" +#include "ui/display/display_layout.h" +#include "ui/display/manager/display_manager.h" +#include "ui/display/screen.h" + +namespace chromeos { + +namespace { + +bool TouchSupportAvailable(const display::Display& display) { + return display.touch_support() == + display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE; +} + +} // namespace + +OobeDisplayChooser::OobeDisplayChooser() {} + +OobeDisplayChooser::~OobeDisplayChooser() {} + +void OobeDisplayChooser::TryToPlaceUiOnTouchDisplay() { + display::Display primary_display = + display::Screen::GetScreen()->GetPrimaryDisplay(); + + if (primary_display.is_valid() && !TouchSupportAvailable(primary_display)) + MoveToTouchDisplay(); +} + +void OobeDisplayChooser::MoveToTouchDisplay() { + const display::Displays& displays = + ash::Shell::Get()->display_manager()->active_only_display_list(); + + if (displays.size() <= 1) + return; + + for (const display::Display& display : displays) { + if (TouchSupportAvailable(display)) { + ash::Shell::Get() + ->display_configuration_controller() + ->SetPrimaryDisplayId(display.id()); + break; + } + } +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h new file mode 100644 index 0000000..8482b91 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h
@@ -0,0 +1,28 @@ +// Copyright 2017 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_OOBE_DISPLAY_CHOOSER_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_OOBE_DISPLAY_CHOOSER_H_ + +#include "base/macros.h" + +namespace chromeos { + +// Tries to put the OOBE UI on a connected touch display (if available). +class OobeDisplayChooser { + public: + OobeDisplayChooser(); + ~OobeDisplayChooser(); + + void TryToPlaceUiOnTouchDisplay(); + + private: + void MoveToTouchDisplay(); + + DISALLOW_COPY_AND_ASSIGN(OobeDisplayChooser); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_OOBE_DISPLAY_CHOOSER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc new file mode 100644 index 0000000..517ec78 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/login/oobe_display_chooser_unittest.cc
@@ -0,0 +1,84 @@ +// Copyright 2017 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 "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h" + +#include <memory> + +#include "ash/display/display_configuration_controller.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/display.h" +#include "ui/display/display_observer.h" +#include "ui/display/manager/display_manager.h" +#include "ui/display/screen.h" +#include "ui/display/test/display_manager_test_api.h" + +namespace chromeos { + +namespace { + +class OobeDisplayChooserTest : public ash::test::AshTestBase { + public: + OobeDisplayChooserTest() : ash::test::AshTestBase() {} + + void SetUp() override { + ash::test::AshTestBase::SetUp(); + display_manager_test_api_.reset( + new display::test::DisplayManagerTestApi(display_manager())); + } + + void EnableTouch(int64_t id) { + display_manager_test_api_->SetTouchSupport( + id, display::Display::TouchSupport::TOUCH_SUPPORT_AVAILABLE); + } + + void DisableTouch(int64_t id) { + display_manager_test_api_->SetTouchSupport( + id, display::Display::TouchSupport::TOUCH_SUPPORT_UNAVAILABLE); + } + + int64_t GetPrimaryDisplay() { + return display::Screen::GetScreen()->GetPrimaryDisplay().id(); + } + + private: + std::unique_ptr<display::test::DisplayManagerTestApi> + display_manager_test_api_; + + DISALLOW_COPY_AND_ASSIGN(OobeDisplayChooserTest); +}; + +} // namespace + +TEST_F(OobeDisplayChooserTest, PreferTouchAsPrimary) { + OobeDisplayChooser display_chooser; + + UpdateDisplay("3000x2000,800x600"); + display::DisplayIdList ids = display_manager()->GetCurrentDisplayIdList(); + DisableTouch(ids[0]); + EnableTouch(ids[1]); + + EXPECT_EQ(ids[0], GetPrimaryDisplay()); + display_chooser.TryToPlaceUiOnTouchDisplay(); + + EXPECT_EQ(ids[1], GetPrimaryDisplay()); +} + +TEST_F(OobeDisplayChooserTest, AddingSecondTouchDisplayShouldbeNOP) { + OobeDisplayChooser display_chooser; + + UpdateDisplay("3000x2000,800x600"); + display::DisplayIdList ids = display_manager()->GetCurrentDisplayIdList(); + EnableTouch(ids[0]); + EnableTouch(ids[1]); + + EXPECT_EQ(ids[0], GetPrimaryDisplay()); + display_chooser.TryToPlaceUiOnTouchDisplay(); + + EXPECT_EQ(ids[0], GetPrimaryDisplay()); +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index 325a77fc..4497720 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -51,6 +51,7 @@ #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h" +#include "chrome/browser/ui/webui/chromeos/login/oobe_display_chooser.h" #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h" @@ -78,6 +79,9 @@ #include "content/public/common/content_switches.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/display/display.h" +#include "ui/events/devices/input_device.h" +#include "ui/events/devices/input_device_manager.h" namespace chromeos { @@ -207,6 +211,19 @@ return path; } +bool IsKeyboardConnected() { + const std::vector<ui::InputDevice>& keyboards = + ui::InputDeviceManager::GetInstance()->GetKeyboardDevices(); + for (const ui::InputDevice& keyboard : keyboards) { + if (keyboard.type == ui::INPUT_DEVICE_INTERNAL || + keyboard.type == ui::INPUT_DEVICE_EXTERNAL) { + return true; + } + } + + return false; +} + } // namespace // static @@ -337,6 +354,11 @@ // TabHelper is required for OOBE webui to make webview working on it. content::WebContents* contents = web_ui->GetWebContents(); extensions::TabHelper::CreateForWebContents(contents); + + // TODO(felixe): Display iteration and primary display selection not supported + // in Mash. See http://crbug.com/720917. + if (!ash_util::IsRunningInMash() && !IsKeyboardConnected()) + oobe_display_chooser_ = base::MakeUnique<OobeDisplayChooser>(); } OobeUI::~OobeUI() { @@ -560,6 +582,9 @@ void OobeUI::ShowOobeUI(bool show) { core_handler_->ShowOobeUI(show); + + if (show && oobe_display_chooser_) + oobe_display_chooser_->TryToPlaceUiOnTouchDisplay(); } void OobeUI::ShowSigninScreen(const LoginScreenContext& context, @@ -608,4 +633,9 @@ static_cast<CoreOobeView*>(core_handler_)->ReloadContent(localized_strings); } +void OobeUI::OnDisplayConfigurationChanged() { + if (oobe_display_chooser_) + oobe_display_chooser_->TryToPlaceUiOnTouchDisplay(); +} + } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h index 035cbbdc..a29a94c 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -53,6 +53,7 @@ class NetworkDropdownHandler; class NetworkStateInformer; class NetworkView; +class OobeDisplayChooser; class SigninScreenHandler; class SigninScreenHandlerDelegate; class SupervisedUserCreationScreenHandler; @@ -170,6 +171,9 @@ // changed). void UpdateLocalizedStringsIfNeeded(); + // Re-evaluate OOBE display placement. + void OnDisplayConfigurationChanged(); + private: // Lookup a view by its statically registered OobeScreen. template <typename TView> @@ -241,6 +245,8 @@ std::unique_ptr<ash::ScreenDimmer> screen_dimmer_; + std::unique_ptr<OobeDisplayChooser> oobe_display_chooser_; + // Store the deferred JS calls before the screen handler instance is // initialized. std::unique_ptr<JSCallsContainer> js_calls_container;
diff --git a/chrome/common/extensions/BUILD.gn b/chrome/common/extensions/BUILD.gn index 61c1973..fc461066 100644 --- a/chrome/common/extensions/BUILD.gn +++ b/chrome/common/extensions/BUILD.gn
@@ -36,7 +36,4 @@ public_deps = [ "//mojo/common:common_custom_types", ] - - # TODO(crbug.com/714018): Convert the implementation to use OnceCallback. - use_once_callback = false }
diff --git a/chrome/utility/extensions/extensions_handler.cc b/chrome/utility/extensions/extensions_handler.cc index a945228d..c02c962 100644 --- a/chrome/utility/extensions/extensions_handler.cc +++ b/chrome/utility/extensions/extensions_handler.cc
@@ -61,31 +61,31 @@ int64_t total_size, bool get_attached_images, extensions::mojom::MediaDataSourcePtr media_data_source, - const ParseMediaMetadataCallback& callback) override { + ParseMediaMetadataCallback callback) override { auto source = base::MakeUnique<metadata::IPCDataSource>( std::move(media_data_source), total_size); metadata::MediaMetadataParser* parser = new metadata::MediaMetadataParser( std::move(source), mime_type, get_attached_images); - parser->Start(base::Bind(&MediaParserImpl::ParseMediaMetadataDone, callback, - base::Owned(parser))); + parser->Start(base::Bind(&MediaParserImpl::ParseMediaMetadataDone, + base::Passed(&callback), base::Owned(parser))); } static void ParseMediaMetadataDone( - const ParseMediaMetadataCallback& callback, + ParseMediaMetadataCallback callback, metadata::MediaMetadataParser* /* parser */, const extensions::api::media_galleries::MediaMetadata& metadata, const std::vector<metadata::AttachedImage>& attached_images) { - callback.Run(true, metadata.ToValue(), attached_images); + std::move(callback).Run(true, metadata.ToValue(), attached_images); } void CheckMediaFile(base::TimeDelta decode_time, base::File file, - const CheckMediaFileCallback& callback) override { + CheckMediaFileCallback callback) override { #if !defined(MEDIA_DISABLE_FFMPEG) media::MediaFileChecker checker(std::move(file)); - callback.Run(checker.Start(decode_time)); + std::move(callback).Run(checker.Start(decode_time)); #else - callback.Run(false); + std::move(callback).Run(false); #endif } @@ -140,9 +140,10 @@ private: // extensions::mojom::WiFiCredentialsGetter: void GetWiFiCredentials(const std::string& ssid, - const GetWiFiCredentialsCallback& callback) override { + GetWiFiCredentialsCallback callback) override { if (ssid == kWiFiTestNetwork) { - callback.Run(true, ssid); // test-mode: return the ssid in key_data. + // test-mode: return the ssid in key_data. + std::move(callback).Run(true, ssid); return; } @@ -158,7 +159,7 @@ if (!success) key_data.clear(); - callback.Run(success, key_data); + std::move(callback).Run(success, key_data); } DISALLOW_COPY_AND_ASSIGN(WiFiCredentialsGetterImpl);
diff --git a/components/ntp_snippets/BUILD.gn b/components/ntp_snippets/BUILD.gn index 0cf1874a..54a66cf3d 100644 --- a/components/ntp_snippets/BUILD.gn +++ b/components/ntp_snippets/BUILD.gn
@@ -47,8 +47,6 @@ "pref_names.h", "pref_util.cc", "pref_util.h", - "reading_list/reading_list_distillation_state_util.cc", - "reading_list/reading_list_distillation_state_util.h", "reading_list/reading_list_suggestions_provider.cc", "reading_list/reading_list_suggestions_provider.h", "remote/json_request.cc",
diff --git a/components/ntp_snippets/content_suggestion.h b/components/ntp_snippets/content_suggestion.h index 5bc647e..1b70c38f 100644 --- a/components/ntp_snippets/content_suggestion.h +++ b/components/ntp_snippets/content_suggestion.h
@@ -49,14 +49,8 @@ // ReadingListSuggestionExtra contains additional data which is only available // for Reading List suggestions. struct ReadingListSuggestionExtra { - // State of the distillation a suggestion. This is the meaningful extract of - // ReadingListEntry::DistillationState for the suggestions. It is duplicated - // here to avoid a dependence on ReadingList. - enum class ReadingListSuggestionDistilledState { PENDING, SUCCESS, FAILURE }; - // State of the distillation of the suggestion. - ReadingListSuggestionDistilledState distilled_state = - ReadingListSuggestionDistilledState::PENDING; + bool distilled = false; // URL of the page whose favicon should be displayed for this suggestion. GURL favicon_page_url; };
diff --git a/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc b/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc deleted file mode 100644 index e7361ad..0000000 --- a/components/ntp_snippets/reading_list/reading_list_distillation_state_util.cc +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2017 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 "components/ntp_snippets/reading_list/reading_list_distillation_state_util.h" - -#include "base/logging.h" - -namespace ntp_snippets { - -ReadingListEntry::DistillationState ReadingListStateFromSuggestionState( - ReadingListSuggestionExtra::ReadingListSuggestionDistilledState - distilled_state) { - switch (distilled_state) { - case ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - PENDING: - return ReadingListEntry::WAITING; - case ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - SUCCESS: - return ReadingListEntry::PROCESSED; - case ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - FAILURE: - return ReadingListEntry::DISTILLATION_ERROR; - } - NOTREACHED(); - return ReadingListEntry::PROCESSING; -} - -ReadingListSuggestionExtra::ReadingListSuggestionDistilledState -SuggestionStateFromReadingListState( - ReadingListEntry::DistillationState distilled_state) { - switch (distilled_state) { - case ReadingListEntry::WILL_RETRY: - case ReadingListEntry::PROCESSING: - case ReadingListEntry::WAITING: - return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - PENDING; - case ReadingListEntry::PROCESSED: - return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - SUCCESS; - case ReadingListEntry::DISTILLATION_ERROR: - return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - FAILURE; - } - NOTREACHED(); - return ReadingListSuggestionExtra::ReadingListSuggestionDistilledState:: - PENDING; -} - -} // namespace ntp_snippets
diff --git a/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h b/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h deleted file mode 100644 index a00553f..0000000 --- a/components/ntp_snippets/reading_list/reading_list_distillation_state_util.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2017 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 COMPONENTS_NTP_SNIPPETS_READING_LIST_READING_LIST_DISTILLATION_STATE_UTIL_H_ -#define COMPONENTS_NTP_SNIPPETS_READING_LIST_READING_LIST_DISTILLATION_STATE_UTIL_H_ - -#include "components/ntp_snippets/content_suggestion.h" -#include "components/reading_list/core/reading_list_entry.h" - -namespace ntp_snippets { - -ReadingListEntry::DistillationState ReadingListStateFromSuggestionState( - ReadingListSuggestionExtra::ReadingListSuggestionDistilledState - distilled_state); - -ReadingListSuggestionExtra::ReadingListSuggestionDistilledState -SuggestionStateFromReadingListState( - ReadingListEntry::DistillationState distilled_state); - -} // namespace ntp_snippets - -#endif // COMPONENTS_NTP_SNIPPETS_READING_LIST_READING_LIST_DISTILLATION_STATE_UTIL_H_
diff --git a/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc b/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc index ed11ed8..9bf791c 100644 --- a/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc +++ b/components/ntp_snippets/reading_list/reading_list_suggestions_provider.cc
@@ -11,8 +11,8 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" #include "components/ntp_snippets/category.h" -#include "components/ntp_snippets/reading_list/reading_list_distillation_state_util.h" #include "components/reading_list/core/reading_list_entry.h" #include "components/reading_list/core/reading_list_model.h" #include "components/strings/grit/components_strings.h" @@ -218,10 +218,16 @@ } suggestion.set_publisher_name( url_formatter::FormatUrl(entry->URL().GetOrigin())); + int64_t entry_time = entry->DistillationTime(); + if (entry_time == 0) { + entry_time = entry->CreationTime(); + } + + suggestion.set_publish_date( + base::Time::FromDoubleT(entry_time / base::Time::kMicrosecondsPerSecond)); auto extra = base::MakeUnique<ReadingListSuggestionExtra>(); - extra->distilled_state = - SuggestionStateFromReadingListState(entry->DistilledState()); + extra->distilled = entry->DistilledState() == ReadingListEntry::PROCESSED; extra->favicon_page_url = entry->DistilledURL().is_valid() ? entry->DistilledURL() : entry->URL(); suggestion.set_reading_list_suggestion_extra(std::move(extra));
diff --git a/components/omnibox/browser/autocomplete_match.h b/components/omnibox/browser/autocomplete_match.h index f0465477..9c0a132 100644 --- a/components/omnibox/browser/autocomplete_match.h +++ b/components/omnibox/browser/autocomplete_match.h
@@ -31,7 +31,7 @@ struct VectorIcon; } // namespace gfx -const char kACMatchPropertyInputText[] = "input text"; +const char kACMatchPropertySuggestionText[] = "match suggestion text"; const char kACMatchPropertyContentsPrefix[] = "match contents prefix"; const char kACMatchPropertyContentsStartIndex[] = "match contents start index";
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc index 51e9d5b..a723f43 100644 --- a/components/omnibox/browser/base_search_provider.cc +++ b/components/omnibox/browser/base_search_provider.cc
@@ -253,8 +253,8 @@ match.answer = SuggestionAnswer::copy(suggestion.answer()); match.subtype_identifier = suggestion.subtype_identifier(); if (suggestion.type() == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) { - match.RecordAdditionalInfo( - kACMatchPropertyInputText, base::UTF16ToUTF8(input.text())); + match.RecordAdditionalInfo(kACMatchPropertySuggestionText, + base::UTF16ToUTF8(suggestion.suggestion())); match.RecordAdditionalInfo( kACMatchPropertyContentsPrefix, base::UTF16ToUTF8(suggestion.match_contents_prefix()));
diff --git a/components/omnibox/browser/base_search_provider_unittest.cc b/components/omnibox/browser/base_search_provider_unittest.cc index 1848c9f..65a17b7 100644 --- a/components/omnibox/browser/base_search_provider_unittest.cc +++ b/components/omnibox/browser/base_search_provider_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/strings/string16.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "components/omnibox/browser/autocomplete_match.h" #include "components/omnibox/browser/autocomplete_match_type.h" @@ -15,6 +16,7 @@ #include "components/omnibox/browser/mock_autocomplete_provider_client.h" #include "components/omnibox/browser/search_suggestion_parser.h" #include "components/omnibox/browser/suggestion_answer.h" +#include "components/omnibox/browser/test_scheme_classifier.h" #include "components/search_engines/search_terms_data.h" #include "components/search_engines/template_url_service.h" #include "components/search_engines/template_url_service_client.h" @@ -87,7 +89,7 @@ TEST_F(BaseSearchProviderTest, PreserveAnswersWhenDeduplicating) { TemplateURLData data; data.SetURL("http://foo.com/url?bar={searchTerms}"); - std::unique_ptr<TemplateURL> template_url(new TemplateURL(data)); + auto template_url = base::MakeUnique<TemplateURL>(data); TestBaseSearchProvider::MatchMap map; base::string16 query = base::ASCIIToUTF16("weather los angeles"); @@ -169,3 +171,41 @@ EXPECT_EQ(AutocompleteMatchType::SEARCH_SUGGEST, duplicate.type); EXPECT_EQ(850, duplicate.relevance); } + +TEST_F(BaseSearchProviderTest, MatchTailSuggestionProperly) { + TemplateURLData data; + data.SetURL("http://foo.com/url?bar={searchTerms}"); + auto template_url = base::MakeUnique<TemplateURL>(data); + + AutocompleteInput autocomplete_input( + base::ASCIIToUTF16("weather"), 7, std::string(), GURL(), base::string16(), + metrics::OmniboxEventProto::BLANK, false, false, false, false, false, + TestSchemeClassifier()); + + EXPECT_CALL(*provider_, GetInput(_)) + .WillRepeatedly(Return(autocomplete_input)); + EXPECT_CALL(*provider_, GetTemplateURL(_)) + .WillRepeatedly(Return(template_url.get())); + + base::string16 query = base::ASCIIToUTF16("angeles now"); + base::string16 suggestion = base::ASCIIToUTF16("weather los ") + query; + SearchSuggestionParser::SuggestResult suggest_result( + suggestion, AutocompleteMatchType::SEARCH_SUGGEST_TAIL, 0, query, + base::ASCIIToUTF16("..."), base::string16(), base::string16(), + base::string16(), nullptr, std::string(), std::string(), false, 1300, + true, false, query); + + TestBaseSearchProvider::MatchMap map; + provider_->AddMatchToMap(suggest_result, std::string(), + TemplateURLRef::NO_SUGGESTION_CHOSEN, false, false, + &map); + + ASSERT_EQ(1UL, map.size()); + const auto& entry = *(map.begin()); + std::string text = + entry.second.GetAdditionalInfo(kACMatchPropertyContentsStartIndex); + size_t length; + EXPECT_TRUE(base::StringToSizeT(text, &length)); + text = entry.second.GetAdditionalInfo(kACMatchPropertySuggestionText); + EXPECT_GE(text.length(), length); +}
diff --git a/components/reading_list/core/reading_list_entry.h b/components/reading_list/core/reading_list_entry.h index 878278b..d0f7451 100644 --- a/components/reading_list/core/reading_list_entry.h +++ b/components/reading_list/core/reading_list_entry.h
@@ -92,7 +92,7 @@ // The URL that has been distilled to produce file stored at |DistilledPath|. const GURL& DistilledURL() const; // The time distillation was done. The value is in microseconds since Jan 1st - // 1970. + // 1970. Returns 0 if the entry was not distilled. int64_t DistillationTime() const; // The size of the stored page in bytes. int64_t DistillationSize() const;
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc index 0e755245..01c8cb7 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.cc
@@ -9,7 +9,9 @@ #include "base/bind.h" #include "base/callback.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" +#include "components/subresource_filter/core/common/time_measurements.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -92,6 +94,8 @@ base::Bind(&ActivationStateComputingNavigationThrottle:: OnActivationStateComputed, weak_ptr_factory_.GetWeakPtr())); + + defer_timestamp_ = base::TimeTicks::Now(); return content::NavigationThrottle::ThrottleCheckResult::DEFER; } @@ -101,6 +105,18 @@ void ActivationStateComputingNavigationThrottle::OnActivationStateComputed( ActivationState state) { + DCHECK(!defer_timestamp_.is_null()); + base::TimeDelta delay = base::TimeTicks::Now() - defer_timestamp_; + UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( + "SubresourceFilter.DocumentLoad.ActivationComputingDelay", delay, + base::TimeDelta::FromMicroseconds(1), base::TimeDelta::FromSeconds(10), + 50); + if (navigation_handle()->IsInMainFrame()) { + UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( + "SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame", + delay, base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromSeconds(10), 50); + } navigation_handle()->Resume(); }
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h index f48d6c2..2ca8b3ef 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "base/time/time.h" #include "components/subresource_filter/content/browser/verified_ruleset_dealer.h" #include "components/subresource_filter/core/common/activation_state.h" #include "content/public/browser/navigation_throttle.h" @@ -89,6 +90,8 @@ // nullptr until NotifyPageActivationWithRuleset is called. VerifiedRuleset::Handle* ruleset_handle_; + base::TimeTicks defer_timestamp_; + // Becomes true when the throttle manager reaches ReadyToCommitNavigation and // sends an activation IPC to the render process. Makes sure a caller cannot // take ownership of the subresource filter unless an activation IPC is sent
diff --git a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc index 1de00cc..7fcb8fa 100644 --- a/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/activation_state_computing_navigation_throttle_unittest.cc
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/optional.h" #include "base/run_loop.h" +#include "base/test/histogram_tester.h" #include "base/test/test_simple_task_runner.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h" @@ -436,4 +437,39 @@ EXPECT_TRUE(state.generic_blocking_rules_disabled); } +TEST_F(ActivationStateComputingThrottleSubFrameTest, DelayMetrics) { + base::HistogramTester histogram_tester; + NavigateAndCommitMainFrameWithPageActivationState( + GURL("http://example.test/"), ActivationState(ActivationLevel::ENABLED)); + ActivationState state = last_activation_state(); + EXPECT_EQ(ActivationLevel::ENABLED, state.activation_level); + EXPECT_FALSE(state.filtering_disabled_for_document); + + const char kActivationDelay[] = + "SubresourceFilter.DocumentLoad.ActivationComputingDelay"; + const char kActivationDelayMainFrame[] = + "SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame"; + histogram_tester.ExpectTotalCount(kActivationDelay, 1); + histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1); + + // Subframe activation should not log main frame metrics. + CreateSubframeAndInitTestNavigation(GURL("http://example.test/"), + last_committed_frame_host(), + last_activation_state()); + SimulateStartAndExpectToProceed(); + SimulateCommitAndExpectToProceed(); + histogram_tester.ExpectTotalCount(kActivationDelay, 2); + histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1); + + // No page activation should imply no delay. + CreateTestNavigationForMainFrame(GURL("http://example.test2/")); + SimulateStartAndExpectToProceed(); + SimulateCommitAndExpectToProceed(); + + state = last_activation_state(); + EXPECT_EQ(ActivationLevel::DISABLED, state.activation_level); + histogram_tester.ExpectTotalCount(kActivationDelay, 2); + histogram_tester.ExpectTotalCount(kActivationDelayMainFrame, 1); +} + } // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc index 020b42f8..ebb562e 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc
@@ -6,6 +6,8 @@ #include "base/bind.h" #include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "components/subresource_filter/core/common/time_measurements.h" #include "content/public/browser/navigation_handle.h" namespace subresource_filter { @@ -20,7 +22,19 @@ DCHECK(parent_frame_filter_); } -SubframeNavigationFilteringThrottle::~SubframeNavigationFilteringThrottle() {} +SubframeNavigationFilteringThrottle::~SubframeNavigationFilteringThrottle() { + if (disallowed_) { + UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( + "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed", + total_defer_time_, base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromSeconds(10), 50); + } else { + UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( + "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Allowed", + total_defer_time_, base::TimeDelta::FromMicroseconds(1), + base::TimeDelta::FromSeconds(10), 50); + } +} content::NavigationThrottle::ThrottleCheckResult SubframeNavigationFilteringThrottle::WillStartRequest() { @@ -42,14 +56,18 @@ navigation_handle()->GetURL(), base::Bind(&SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy, weak_ptr_factory_.GetWeakPtr())); + last_defer_timestamp_ = base::TimeTicks::Now(); return content::NavigationThrottle::ThrottleCheckResult::DEFER; } void SubframeNavigationFilteringThrottle::OnCalculatedLoadPolicy( LoadPolicy policy) { + DCHECK(!last_defer_timestamp_.is_null()); + total_defer_time_ += base::TimeTicks::Now() - last_defer_timestamp_; // TODO(csharrison): Support WouldDisallow pattern and expose the policy for // metrics. Also, cancel with BLOCK_AND_COLLAPSE when it is implemented. if (policy == LoadPolicy::DISALLOW) { + disallowed_ = true; parent_frame_filter_->ReportDisallowedLoad(); navigation_handle()->CancelDeferredNavigation( content::NavigationThrottle::CANCEL);
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h index e0c8aef..1757b57 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "content/public/browser/navigation_throttle.h" @@ -46,6 +47,10 @@ // Must outlive this class. AsyncDocumentSubresourceFilter* parent_frame_filter_; + base::TimeTicks last_defer_timestamp_; + base::TimeDelta total_defer_time_; + bool disallowed_ = false; + base::WeakPtrFactory<SubframeNavigationFilteringThrottle> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SubframeNavigationFilteringThrottle);
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc index 71a5909..89c4320 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc
@@ -11,6 +11,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/histogram_tester.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h" #include "components/subresource_filter/core/common/activation_level.h" @@ -190,4 +191,29 @@ SimulateStartAndExpectResult(content::NavigationThrottle::CANCEL); } +TEST_F(SubframeNavigationFilteringThrottleTest, DelayMetrics) { + base::HistogramTester histogram_tester; + InitializeDocumentSubresourceFilter(GURL("https://example.test")); + CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), + main_rfh()); + + SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"), + content::NavigationThrottle::CANCEL); + + const char kFilterDelayDisallowed[] = + "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed"; + const char kFilterDelayAllowed[] = + "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Allowed"; + histogram_tester.ExpectTotalCount(kFilterDelayDisallowed, 1); + histogram_tester.ExpectTotalCount(kFilterDelayAllowed, 0); + + CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), + main_rfh()); + SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + histogram_tester.ExpectTotalCount(kFilterDelayDisallowed, 1); + histogram_tester.ExpectTotalCount(kFilterDelayAllowed, 1); +} + } // namespace subresource_filter
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index b3ef290..8b8f8b33 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -64,8 +64,8 @@ "//content/app/strings", "//content/browser/background_sync:background_sync_proto", "//content/browser/cache_storage:cache_storage_proto", + "//content/browser/devtools:devtools_resources", "//content/browser/devtools:protocol_sources", - "//content/browser/devtools:resources", "//content/browser/dom_storage:local_storage_proto", "//content/browser/notifications:notification_proto", "//content/browser/payments:payment_app_proto", @@ -138,6 +138,7 @@ "//third_party/WebKit/public:mojo_bindings", "//third_party/WebKit/public:resources", "//third_party/angle:angle_common", + "//third_party/brotli:dec", "//third_party/icu", "//third_party/libyuv", "//third_party/re2",
diff --git a/content/browser/devtools/BUILD.gn b/content/browser/devtools/BUILD.gn index 109d100..1f3a739e 100644 --- a/content/browser/devtools/BUILD.gn +++ b/content/browser/devtools/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//tools/grit/grit_rule.gni") +import("//third_party/brotli/brotli.gni") import("//third_party/inspector_protocol/inspector_protocol.gni") group("resources") { @@ -13,6 +14,17 @@ } } +compressed_protocol_file = + "$root_gen_dir/blink/core/inspector/protocol.json.bro" + +compress_file_brotli("compressed_protocol_json") { + input_file = "$root_gen_dir/blink/core/inspector/protocol.json" + output_file = compressed_protocol_file + deps = [ + "//third_party/WebKit/Source/core/inspector:protocol_version", + ] +} + grit("devtools_resources") { source = "$root_gen_dir/devtools/devtools_resources.grd" source_is_generated = true @@ -24,10 +36,18 @@ "grit/devtools_resources_map.h", ] + grit_flags = [ + "-E", + "compressed_protocol_file=" + + rebase_path(compressed_protocol_file, root_build_dir), + ] + defines = [ "SHARED_INTERMEDIATE_DIR=" + rebase_path(root_gen_dir, root_build_dir) ] deps = [ + ":compressed_protocol_json", + # This is the action that generates out .grd input file. "//third_party/WebKit/public:blink_generate_devtools_grd", ]
diff --git a/content/browser/devtools/DEPS b/content/browser/devtools/DEPS index 4029bd9..28ece8ad 100644 --- a/content/browser/devtools/DEPS +++ b/content/browser/devtools/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+third_party/brotli", # For compressed protocol.json. # V8 version info "+v8/include/v8-version-string.h", ]
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 7f06067..81eda4c 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -14,6 +14,7 @@ #include "base/json/json_writer.h" #include "base/location.h" #include "base/logging.h" +#include "base/memory/ref_counted_memory.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -23,10 +24,12 @@ #include "build/build_config.h" #include "content/browser/devtools/devtools_http_handler.h" #include "content/browser/devtools/devtools_manager.h" +#include "content/browser/devtools/grit/devtools_resources.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_external_agent_proxy_delegate.h" #include "content/public/browser/devtools_manager_delegate.h" #include "content/public/browser/devtools_socket_factory.h" +#include "content/public/common/content_client.h" #include "content/public/common/url_constants.h" #include "content/public/common/user_agent.h" #include "net/base/escape.h" @@ -37,6 +40,7 @@ #include "net/server/http_server_request_info.h" #include "net/server/http_server_response_info.h" #include "net/socket/server_socket.h" +#include "third_party/brotli/include/brotli/decode.h" #include "v8/include/v8-version-string.h" #if defined(OS_ANDROID) @@ -534,6 +538,11 @@ return; } + if (command == "protocol") { + DecompressAndSendJsonProtocol(connection_id); + return; + } + if (command == "list") { DevToolsManager* manager = DevToolsManager::GetInstance(); DevToolsAgentHost::List list = @@ -607,6 +616,47 @@ return; } +void DevToolsHttpHandler::DecompressAndSendJsonProtocol(int connection_id) { + scoped_refptr<base::RefCountedMemory> raw_bytes = + GetContentClient()->GetDataResourceBytes(COMPRESSED_PROTOCOL_JSON); + const uint8_t* next_encoded_byte = raw_bytes->front(); + size_t input_size_remaining = raw_bytes->size(); + BrotliDecoderState* decoder = BrotliDecoderCreateInstance( + nullptr /* no custom allocator */, nullptr /* no custom deallocator */, + nullptr /* no custom memory handle */); + CHECK(!!decoder); + std::vector<std::string> decoded_parts; + size_t decompressed_size = 0; + while (!BrotliDecoderIsFinished(decoder)) { + size_t output_size_remaining = 0; + CHECK(BrotliDecoderDecompressStream( + decoder, &input_size_remaining, &next_encoded_byte, + &output_size_remaining, nullptr, + nullptr) != BROTLI_DECODER_RESULT_ERROR); + const uint8_t* output_buffer = + BrotliDecoderTakeOutput(decoder, &output_size_remaining); + decoded_parts.emplace_back(reinterpret_cast<const char*>(output_buffer), + output_size_remaining); + decompressed_size += output_size_remaining; + } + BrotliDecoderDestroyInstance(decoder); + + // Ideally we'd use a StringBuilder here but there isn't one in base/. + std::string json_protocol; + json_protocol.reserve(decompressed_size); + for (const std::string& part : decoded_parts) { + json_protocol.append(part); + } + + net::HttpServerResponseInfo response(net::HTTP_OK); + response.SetBody(json_protocol, "application/json; charset=UTF-8"); + + thread_->task_runner()->PostTask( + FROM_HERE, + base::Bind(&ServerWrapper::SendResponse, + base::Unretained(server_wrapper_), connection_id, response)); +} + void DevToolsHttpHandler::RespondToJsonList( int connection_id, const std::string& host,
diff --git a/content/browser/devtools/devtools_http_handler.h b/content/browser/devtools/devtools_http_handler.h index 5989da0..72836212 100644 --- a/content/browser/devtools/devtools_http_handler.h +++ b/content/browser/devtools/devtools_http_handler.h
@@ -98,6 +98,8 @@ void AcceptWebSocket(int connection_id, const net::HttpServerRequestInfo& request); + void DecompressAndSendJsonProtocol(int connection_id); + // Returns the front end url without the host at the beginning. std::string GetFrontendURLInternal(const std::string& target_id, const std::string& host);
diff --git a/content/browser/notifications/notification_database.cc b/content/browser/notifications/notification_database.cc index 19236820..677a327 100644 --- a/content/browser/notifications/notification_database.cc +++ b/content/browser/notifications/notification_database.cc
@@ -328,11 +328,6 @@ continue; } - // Silently ignore the notification if it doesn't have an ID assigned. - // TODO(peter): Remove this clause when Chrome 55 has branched. - if (notification_database_data.notification_id.empty()) - continue; - notification_data_vector->push_back(notification_database_data); }
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc index 8ef474c6..8a15289 100644 --- a/content/browser/notifications/platform_notification_context_impl.cc +++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -281,10 +281,10 @@ UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadForServiceWorkerResult", status, NotificationDatabase::STATUS_COUNT); + std::vector<std::string> obsolete_notifications; + if (status == NotificationDatabase::STATUS_OK) { if (supports_synchronization) { - // Filter out notifications that are not actually on display anymore. - // TODO(miguelg) synchronize the database if there are inconsistencies. for (auto it = notification_datas.begin(); it != notification_datas.end();) { // The database is only used for persistent notifications. @@ -293,6 +293,7 @@ if (displayed_notifications->count(it->notification_id)) { ++it; } else { + obsolete_notifications.push_back(it->notification_id); it = notification_datas.erase(it); } } @@ -301,6 +302,10 @@ BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(callback, true /* success */, notification_datas)); + + // Remove notifications that are not actually on display anymore. + for (const auto& it : obsolete_notifications) + database_->DeleteNotificationData(it, origin); return; }
diff --git a/content/browser/notifications/platform_notification_context_unittest.cc b/content/browser/notifications/platform_notification_context_unittest.cc index 4aee64b..945fd16a 100644 --- a/content/browser/notifications/platform_notification_context_unittest.cc +++ b/content/browser/notifications/platform_notification_context_unittest.cc
@@ -15,8 +15,11 @@ #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/browser/notification_database_data.h" +#include "content/public/common/notification_resources.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/test/mock_platform_notification_service.h" +#include "content/test/test_content_browser_client.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -25,6 +28,19 @@ // Fake Service Worker registration id to use in tests requiring one. const int64_t kFakeServiceWorkerRegistrationId = 42; +class NotificationBrowserClient : public TestContentBrowserClient { + public: + NotificationBrowserClient() + : platform_notification_service_(new MockPlatformNotificationService()) {} + + PlatformNotificationService* GetPlatformNotificationService() override { + return platform_notification_service_.get(); + } + + private: + std::unique_ptr<PlatformNotificationService> platform_notification_service_; +}; + class PlatformNotificationContextTest : public ::testing::Test { public: PlatformNotificationContextTest() @@ -484,4 +500,69 @@ } } +TEST_F(PlatformNotificationContextTest, SynchronizeNotifications) { + NotificationBrowserClient notification_browser_client; + SetBrowserClientForTesting(¬ification_browser_client); + + scoped_refptr<PlatformNotificationContextImpl> context = + CreatePlatformNotificationContext(); + + GURL origin("https://example.com"); + NotificationDatabaseData notification_database_data; + notification_database_data.service_worker_registration_id = + kFakeServiceWorkerRegistrationId; + PlatformNotificationData notification_data; + content::NotificationResources notification_resources; + + context->WriteNotificationData( + origin, notification_database_data, + base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(success()); + EXPECT_FALSE(notification_id().empty()); + + PlatformNotificationService* service = + notification_browser_client.GetPlatformNotificationService(); + + service->DisplayPersistentNotification(browser_context(), notification_id(), + origin, origin, notification_data, + notification_resources); + + std::vector<NotificationDatabaseData> notification_database_datas; + context->ReadAllNotificationDataForServiceWorkerRegistration( + origin, kFakeServiceWorkerRegistrationId, + base::Bind(&PlatformNotificationContextTest::DidReadAllNotificationDatas, + base::Unretained(this), ¬ification_database_datas)); + + base::RunLoop().RunUntilIdle(); + + ASSERT_TRUE(success()); + ASSERT_EQ(1u, notification_database_datas.size()); + + // Delete the notification from the display service without removing it from + // the database. It should automatically synchronize on the next read. + service->ClosePersistentNotification(browser_context(), notification_id()); + context->ReadAllNotificationDataForServiceWorkerRegistration( + origin, kFakeServiceWorkerRegistrationId, + base::Bind(&PlatformNotificationContextTest::DidReadAllNotificationDatas, + base::Unretained(this), ¬ification_database_datas)); + base::RunLoop().RunUntilIdle(); + + ASSERT_TRUE(success()); + ASSERT_EQ(0u, notification_database_datas.size()); + + context->ReadNotificationData( + notification_id(), origin, + base::Bind(&PlatformNotificationContextTest::DidReadNotificationData, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + + // The notification was removed, so we shouldn't be able to read it from + // the database anymore. + EXPECT_FALSE(success()); +} + } // namespace content
diff --git a/content/browser/renderer_host/input/input_router_impl.cc b/content/browser/renderer_host/input/input_router_impl.cc index 4f00ab21..c3ff486a 100644 --- a/content/browser/renderer_host/input/input_router_impl.cc +++ b/content/browser/renderer_host/input/input_router_impl.cc
@@ -23,7 +23,6 @@ #include "content/common/content_constants_internal.h" #include "content/common/edit_command.h" #include "content/common/input/input_event_ack_state.h" -#include "content/common/input/touch_action.h" #include "content/common/input/web_touch_event_traits.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" @@ -501,7 +500,7 @@ client_->OnHasTouchEventHandlers(has_handlers); } -void InputRouterImpl::OnSetTouchAction(TouchAction touch_action) { +void InputRouterImpl::OnSetTouchAction(cc::TouchAction touch_action) { // Synthetic touchstart events should get filtered out in RenderWidget. DCHECK(touch_event_queue_->IsPendingAckTouchStart()); TRACE_EVENT1("input", "InputRouterImpl::OnSetTouchAction", @@ -509,7 +508,7 @@ touch_action_filter_.OnSetTouchAction(touch_action); - // TOUCH_ACTION_NONE should disable the touch ack timeout. + // kTouchActionNone should disable the touch ack timeout. UpdateTouchAckTimeoutEnabled(); } @@ -625,11 +624,11 @@ } void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { - // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves + // kTouchActionNone will prevent scrolling, in which case the timeout serves // little purpose. It's also a strong signal that touch handling is critical // to page functionality, so the timeout could do more harm than good. const bool touch_ack_timeout_enabled = - touch_action_filter_.allowed_touch_action() != TOUCH_ACTION_NONE; + touch_action_filter_.allowed_touch_action() != cc::kTouchActionNone; touch_event_queue_->SetAckTimeoutEnabled(touch_ack_timeout_enabled); }
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h index cbe2e2a..d26663a 100644 --- a/content/browser/renderer_host/input/input_router_impl.h +++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -14,6 +14,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/time/time.h" +#include "cc/input/touch_action.h" #include "content/browser/renderer_host/input/gesture_event_queue.h" #include "content/browser/renderer_host/input/input_router.h" #include "content/browser/renderer_host/input/mouse_wheel_event_queue.h" @@ -148,7 +149,7 @@ void OnMsgMoveCaretAck(); void OnSelectMessageAck(); void OnHasTouchEventHandlers(bool has_handlers); - void OnSetTouchAction(TouchAction touch_action); + void OnSetTouchAction(cc::TouchAction touch_action); void OnDidStopFlinging(); // Indicates the source of an ack provided to |ProcessInputEventAck()|.
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index 255e97b8..6719ef1e 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -23,6 +23,7 @@ #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "cc/input/touch_action.h" #include "content/browser/renderer_host/input/gesture_event_queue.h" #include "content/browser/renderer_host/input/input_router_client.h" #include "content/browser/renderer_host/input/mock_input_ack_handler.h" @@ -30,7 +31,6 @@ #include "content/common/content_constants_internal.h" #include "content/common/edit_command.h" #include "content/common/input/synthetic_web_input_event_builders.h" -#include "content/common/input/touch_action.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h" #include "content/public/common/content_features.h" @@ -368,7 +368,7 @@ ViewHostMsg_HasTouchEventHandlers(0, has_handlers)); } - void OnSetTouchAction(content::TouchAction touch_action) { + void OnSetTouchAction(cc::TouchAction touch_action) { input_router_->OnMessageReceived( InputHostMsg_SetTouchAction(0, touch_action)); } @@ -1380,11 +1380,11 @@ input_router()->NotifySiteIsMobileOptimized(false); EXPECT_TRUE(TouchEventTimeoutEnabled()); - // TOUCH_ACTION_NONE (and no other touch-action) should disable the timeout. + // kTouchActionNone (and no other touch-action) should disable the timeout. OnHasTouchEventHandlers(true); PressTouchPoint(1, 1); uint32_t touch_press_event_id2 = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_PAN_Y); + OnSetTouchAction(cc::kTouchActionPanY); EXPECT_TRUE(TouchEventTimeoutEnabled()); ReleaseTouchPoint(0); uint32_t touch_release_event_id2 = SendTouchEvent(); @@ -1395,7 +1395,7 @@ PressTouchPoint(1, 1); uint32_t touch_press_event_id3 = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_NONE); + OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(TouchEventTimeoutEnabled()); ReleaseTouchPoint(0); uint32_t touch_release_event_id3 = SendTouchEvent(); @@ -1411,7 +1411,7 @@ EXPECT_TRUE(TouchEventTimeoutEnabled()); } -// Test that a touch sequenced preceded by TOUCH_ACTION_NONE is not affected by +// Test that a touch sequenced preceded by kTouchActionNone is not affected by // the touch timeout. TEST_F(InputRouterImplTest, TouchAckTimeoutDisabledForTouchSequenceAfterTouchActionNone) { @@ -1426,8 +1426,8 @@ uint32_t touch_press_event_id = SendTouchEvent(); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); - // TOUCH_ACTION_NONE should disable the timeout. - OnSetTouchAction(TOUCH_ACTION_NONE); + // kTouchActionNone should disable the timeout. + OnSetTouchAction(cc::kTouchActionNone); SendTouchEventACK(WebInputEvent::kTouchStart, INPUT_EVENT_ACK_STATE_CONSUMED, touch_press_event_id); EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); @@ -1475,7 +1475,7 @@ // Sequence 1. PressTouchPoint(1, 1); uint32_t touch_press_event_id1 = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_NONE); + OnSetTouchAction(cc::kTouchActionNone); MoveTouchPoint(0, 50, 50); uint32_t touch_move_event_id1 = SendTouchEvent(); ReleaseTouchPoint(0); @@ -1535,7 +1535,7 @@ uint32_t touch_press_event_id1 = SendTouchEvent(); MoveTouchPoint(0, 50, 50); uint32_t touch_move_event_id1 = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_NONE); + OnSetTouchAction(cc::kTouchActionNone); SendTouchEventACK(WebInputEvent::kTouchStart, INPUT_EVENT_ACK_STATE_CONSUMED, touch_press_event_id1); SendTouchEventACK(WebInputEvent::kTouchMove, INPUT_EVENT_ACK_STATE_CONSUMED, @@ -1587,7 +1587,7 @@ uint32_t touch_press_event_id = SendTouchEvent(); MoveTouchPoint(0, 50, 50); uint32_t touch_move_event_id = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_NONE); + OnSetTouchAction(cc::kTouchActionNone); ReleaseTouchPoint(0); uint32_t touch_release_event_id = SendTouchEvent(); EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); @@ -1661,7 +1661,7 @@ // Sequence 1. PressTouchPoint(1, 1); uint32_t touch_press_event_id1 = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_NONE); + OnSetTouchAction(cc::kTouchActionNone); SendTouchEventACK(WebInputEvent::kTouchStart, INPUT_EVENT_ACK_STATE_CONSUMED, touch_press_event_id1); @@ -1729,7 +1729,7 @@ // Sequence 1. PressTouchPoint(1, 1); uint32_t touch_press_event_id1 = SendTouchEvent(); - OnSetTouchAction(TOUCH_ACTION_NONE); + OnSetTouchAction(cc::kTouchActionNone); SendTouchEventACK(WebInputEvent::kTouchStart, INPUT_EVENT_ACK_STATE_CONSUMED, touch_press_event_id1);
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc index 1a201e6..f9304b8 100644 --- a/content/browser/renderer_host/input/touch_action_filter.cc +++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -17,12 +17,12 @@ // Actions on an axis are disallowed if the perpendicular axis has a filter set // and no filter is set for the queried axis. -bool IsYAxisActionDisallowed(TouchAction action) { - return (action & TOUCH_ACTION_PAN_X) && !(action & TOUCH_ACTION_PAN_Y); +bool IsYAxisActionDisallowed(cc::TouchAction action) { + return (action & cc::kTouchActionPanX) && !(action & cc::kTouchActionPanY); } -bool IsXAxisActionDisallowed(TouchAction action) { - return (action & TOUCH_ACTION_PAN_Y) && !(action & TOUCH_ACTION_PAN_X); +bool IsXAxisActionDisallowed(cc::TouchAction action) { + return (action & cc::kTouchActionPanY) && !(action & cc::kTouchActionPanX); } } // namespace @@ -31,7 +31,7 @@ : suppress_manipulation_events_(false), drop_current_tap_ending_event_(false), allow_current_double_tap_event_(true), - allowed_touch_action_(TOUCH_ACTION_AUTO) {} + allowed_touch_action_(cc::kTouchActionAuto) {} bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) { if (gesture_event->source_device != blink::kWebGestureDeviceTouchscreen) @@ -108,7 +108,7 @@ case WebInputEvent::kGestureTapUnconfirmed: DCHECK_EQ(1, gesture_event->data.tap.tap_count); allow_current_double_tap_event_ = - (allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0; + (allowed_touch_action_ & cc::kTouchActionDoubleTapZoom) != 0; if (!allow_current_double_tap_event_) { gesture_event->SetType(WebInputEvent::kGestureTap); drop_current_tap_ending_event_ = true; @@ -117,7 +117,7 @@ case WebInputEvent::kGestureTap: allow_current_double_tap_event_ = - (allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0; + (allowed_touch_action_ & cc::kTouchActionDoubleTapZoom) != 0; // Fall through. case WebInputEvent::kGestureTapCancel: @@ -148,7 +148,7 @@ return false; } -void TouchActionFilter::OnSetTouchAction(TouchAction touch_action) { +void TouchActionFilter::OnSetTouchAction(cc::TouchAction touch_action) { // For multiple fingers, we take the intersection of the touch actions for // all fingers that have gone down during this action. In the majority of // real-world scenarios the touch action for all fingers will be the same. @@ -166,7 +166,7 @@ void TouchActionFilter::ResetTouchAction() { // Note that resetting the action mid-sequence is tolerated. Gestures that had // their begin event(s) suppressed will be suppressed until the next sequence. - allowed_touch_action_ = TOUCH_ACTION_AUTO; + allowed_touch_action_ = cc::kTouchActionAuto; } bool TouchActionFilter::ShouldSuppressManipulation( @@ -177,7 +177,7 @@ // Any GestureScrollBegin with more than one fingers is like a pinch-zoom // for touch-actions, see crbug.com/632525. Therefore, we switch to // blocked-manipulation mode iff pinch-zoom is disallowed. - return (allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) == 0; + return (allowed_touch_action_ & cc::kTouchActionPinchZoom) == 0; } const float& deltaXHint = gesture_event.data.scroll_begin.delta_x_hint; @@ -189,20 +189,20 @@ const float absDeltaXHint = fabs(deltaXHint); const float absDeltaYHint = fabs(deltaYHint); - TouchAction minimal_conforming_touch_action = TOUCH_ACTION_NONE; + cc::TouchAction minimal_conforming_touch_action = cc::kTouchActionNone; if (absDeltaXHint >= absDeltaYHint) { if (deltaXHint > 0) - minimal_conforming_touch_action |= TOUCH_ACTION_PAN_LEFT; + minimal_conforming_touch_action |= cc::kTouchActionPanLeft; else if (deltaXHint < 0) - minimal_conforming_touch_action |= TOUCH_ACTION_PAN_RIGHT; + minimal_conforming_touch_action |= cc::kTouchActionPanRight; } if (absDeltaYHint >= absDeltaXHint) { if (deltaYHint > 0) - minimal_conforming_touch_action |= TOUCH_ACTION_PAN_UP; + minimal_conforming_touch_action |= cc::kTouchActionPanUp; else if (deltaYHint < 0) - minimal_conforming_touch_action |= TOUCH_ACTION_PAN_DOWN; + minimal_conforming_touch_action |= cc::kTouchActionPanDown; } - DCHECK(minimal_conforming_touch_action != TOUCH_ACTION_NONE); + DCHECK(minimal_conforming_touch_action != cc::kTouchActionNone); return (allowed_touch_action_ & minimal_conforming_touch_action) == 0; }
diff --git a/content/browser/renderer_host/input/touch_action_filter.h b/content/browser/renderer_host/input/touch_action_filter.h index 7296c1f..3fd52b9 100644 --- a/content/browser/renderer_host/input/touch_action_filter.h +++ b/content/browser/renderer_host/input/touch_action_filter.h
@@ -6,8 +6,8 @@ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_ #include "base/macros.h" +#include "cc/input/touch_action.h" #include "content/common/content_export.h" -#include "content/common/input/touch_action.h" namespace blink { class WebGestureEvent; @@ -31,7 +31,7 @@ // Called when a set-touch-action message is received from the renderer // for a touch start event that is currently in flight. - void OnSetTouchAction(content::TouchAction touch_action); + void OnSetTouchAction(cc::TouchAction touch_action); // Must be called at least once between when the last gesture events for the // previous touch sequence have passed through the touch action filter and the @@ -39,7 +39,7 @@ // renderer. It may be called multiple times during this interval. void ResetTouchAction(); - TouchAction allowed_touch_action() const { return allowed_touch_action_; } + cc::TouchAction allowed_touch_action() const { return allowed_touch_action_; } private: bool ShouldSuppressManipulation(const blink::WebGestureEvent&); @@ -59,7 +59,7 @@ bool allow_current_double_tap_event_; // What touch actions are currently permitted. - TouchAction allowed_touch_action_; + cc::TouchAction allowed_touch_action_; DISALLOW_COPY_AND_ASSIGN(TouchActionFilter); };
diff --git a/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/content/browser/renderer_host/input/touch_action_filter_unittest.cc index 5951b56..66253b3 100644 --- a/content/browser/renderer_host/input/touch_action_filter_unittest.cc +++ b/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -20,7 +20,7 @@ } // namespace -static void PanTest(TouchAction action, +static void PanTest(cc::TouchAction action, float scroll_x, float scroll_y, float dx, @@ -109,7 +109,7 @@ } } -static void PanTestForUnidirectionalTouchAction(TouchAction action, +static void PanTestForUnidirectionalTouchAction(cc::TouchAction action, float scroll_x, float scroll_y) { TouchActionFilter filter; @@ -192,18 +192,18 @@ filter.ResetTouchAction(); EXPECT_FALSE(filter.FilterGestureEvent(&tap)); - // TOUCH_ACTION_AUTO doesn't cause any filtering. + // cc::kTouchActionAuto doesn't cause any filtering. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update)); EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x); EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end)); - // TOUCH_ACTION_NONE filters out all scroll events, but no other events. + // cc::kTouchActionNone filters out all scroll events, but no other events. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&tap)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); @@ -221,7 +221,7 @@ // Setting touch action doesn't impact any in-progress gestures. filter.ResetTouchAction(); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_update)); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_end)); @@ -232,9 +232,9 @@ // Changing the touch action during a gesture has no effect. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x); @@ -257,9 +257,9 @@ WebGestureEvent pad_fling = SyntheticWebGestureEventBuilder::BuildFling( kFlingX, kFlingY, blink::kWebGestureDeviceTouchpad); - // TOUCH_ACTION_NONE filters out fling events. + // cc::kTouchActionNone filters out fling events. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); EXPECT_TRUE(filter.FilterGestureEvent(&fling_start)); @@ -268,7 +268,7 @@ // touchpad flings aren't filtered. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); EXPECT_FALSE(filter.FilterGestureEvent(&pad_fling)); @@ -283,9 +283,9 @@ const float kFlingX = 7; const float kFlingY = -4; - PanTest(TOUCH_ACTION_PAN_LEFT, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, - kDX, 0, kFlingX, 0); - PanTestForUnidirectionalTouchAction(TOUCH_ACTION_PAN_LEFT, kScrollX, 0); + PanTest(cc::kTouchActionPanLeft, kScrollX, kScrollY, kDX, kDY, kFlingX, + kFlingY, kDX, 0, kFlingX, 0); + PanTestForUnidirectionalTouchAction(cc::kTouchActionPanLeft, kScrollX, 0); } TEST(TouchActionFilterTest, PanRight) { @@ -296,9 +296,9 @@ const float kFlingX = 7; const float kFlingY = -4; - PanTest(TOUCH_ACTION_PAN_RIGHT, kScrollX, kScrollY, kDX, kDY, kFlingX, + PanTest(cc::kTouchActionPanRight, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, kDX, 0, kFlingX, 0); - PanTestForUnidirectionalTouchAction(TOUCH_ACTION_PAN_RIGHT, kScrollX, 0); + PanTestForUnidirectionalTouchAction(cc::kTouchActionPanRight, kScrollX, 0); } TEST(TouchActionFilterTest, PanX) { @@ -309,7 +309,7 @@ const float kFlingX = 7; const float kFlingY = -4; - PanTest(TOUCH_ACTION_PAN_X, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, + PanTest(cc::kTouchActionPanX, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, kDX, 0, kFlingX, 0); } @@ -321,9 +321,9 @@ const float kFlingX = 7; const float kFlingY = -4; - PanTest(TOUCH_ACTION_PAN_UP, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, + PanTest(cc::kTouchActionPanUp, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, 0, kDY, 0, kFlingY); - PanTestForUnidirectionalTouchAction(TOUCH_ACTION_PAN_UP, 0, kScrollY); + PanTestForUnidirectionalTouchAction(cc::kTouchActionPanUp, 0, kScrollY); } TEST(TouchActionFilterTest, PanDown) { @@ -334,9 +334,9 @@ const float kFlingX = 7; const float kFlingY = -4; - PanTest(TOUCH_ACTION_PAN_DOWN, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, - 0, kDY, 0, kFlingY); - PanTestForUnidirectionalTouchAction(TOUCH_ACTION_PAN_DOWN, 0, kScrollY); + PanTest(cc::kTouchActionPanDown, kScrollX, kScrollY, kDX, kDY, kFlingX, + kFlingY, 0, kDY, 0, kFlingY); + PanTestForUnidirectionalTouchAction(cc::kTouchActionPanDown, 0, kScrollY); } TEST(TouchActionFilterTest, PanY) { @@ -347,8 +347,8 @@ const float kFlingX = 7; const float kFlingY = -4; - PanTest(TOUCH_ACTION_PAN_Y, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, 0, - kDY, 0, kFlingY); + PanTest(cc::kTouchActionPanY, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY, + 0, kDY, 0, kFlingY); } TEST(TouchActionFilterTest, PanXY) { @@ -361,7 +361,7 @@ { // Scrolls hinted in the X axis are permitted and unmodified. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN); + filter.OnSetTouchAction(cc::kTouchActionPan); WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6, kSourceDevice); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); @@ -383,7 +383,7 @@ { // Scrolls hinted in the Y axis are permitted and unmodified. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN); + filter.OnSetTouchAction(cc::kTouchActionPan); WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); @@ -405,7 +405,7 @@ { // A two-finger gesture is not allowed. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN); + filter.OnSetTouchAction(cc::kTouchActionPan); WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice, 2); @@ -425,14 +425,15 @@ TEST(TouchActionFilterTest, BitMath) { // Verify that the simple flag mixing properties we depend on are now // trivially true. - EXPECT_EQ(TOUCH_ACTION_NONE, TOUCH_ACTION_NONE & TOUCH_ACTION_AUTO); - EXPECT_EQ(TOUCH_ACTION_NONE, TOUCH_ACTION_PAN_Y & TOUCH_ACTION_PAN_X); - EXPECT_EQ(TOUCH_ACTION_PAN, TOUCH_ACTION_AUTO & TOUCH_ACTION_PAN); - EXPECT_EQ(TOUCH_ACTION_MANIPULATION, - TOUCH_ACTION_AUTO & ~TOUCH_ACTION_DOUBLE_TAP_ZOOM); - EXPECT_EQ(TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_LEFT | TOUCH_ACTION_PAN_RIGHT); - EXPECT_EQ(TOUCH_ACTION_AUTO, - TOUCH_ACTION_MANIPULATION | TOUCH_ACTION_DOUBLE_TAP_ZOOM); + EXPECT_EQ(cc::kTouchActionNone, cc::kTouchActionNone & cc::kTouchActionAuto); + EXPECT_EQ(cc::kTouchActionNone, cc::kTouchActionPanY & cc::kTouchActionPanX); + EXPECT_EQ(cc::kTouchActionPan, cc::kTouchActionAuto & cc::kTouchActionPan); + EXPECT_EQ(cc::kTouchActionManipulation, + cc::kTouchActionAuto & ~cc::kTouchActionDoubleTapZoom); + EXPECT_EQ(cc::kTouchActionPanX, + cc::kTouchActionPanLeft | cc::kTouchActionPanRight); + EXPECT_EQ(cc::kTouchActionAuto, + cc::kTouchActionManipulation | cc::kTouchActionDoubleTapZoom); } TEST(TouchActionFilterTest, MultiTouch) { @@ -450,8 +451,8 @@ // For multiple points, the intersection is what matters. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionNone); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); @@ -461,9 +462,9 @@ // Intersection of PAN_X and PAN_Y is NONE. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN_X); - filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y); - filter.OnSetTouchAction(TOUCH_ACTION_PAN); + filter.OnSetTouchAction(cc::kTouchActionPanX); + filter.OnSetTouchAction(cc::kTouchActionPanY); + filter.OnSetTouchAction(cc::kTouchActionPan); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_update)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end)); @@ -486,7 +487,7 @@ // Pinch is allowed with touch-action: auto. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); @@ -495,7 +496,7 @@ // Pinch is not allowed with touch-action: none. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update)); @@ -507,7 +508,7 @@ // Pinch is not allowed with touch-action: pan-x pan-y. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN); + filter.OnSetTouchAction(cc::kTouchActionPan); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update)); @@ -516,7 +517,7 @@ // Pinch is allowed with touch-action: manipulation. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_MANIPULATION); + filter.OnSetTouchAction(cc::kTouchActionManipulation); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); @@ -533,16 +534,16 @@ // Pinching is only computed at GestureScrollBegin time. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end)); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end)); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end)); @@ -551,10 +552,10 @@ // Once a pinch has started, any change in state won't affect the pinch // gestures since it is computed in GestureScrollBegin. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_end)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); @@ -564,7 +565,7 @@ // Scrolling is allowed when two fingers are down. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PINCH_ZOOM); + filter.OnSetTouchAction(cc::kTouchActionPinchZoom); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_FALSE(filter.FilterGestureEvent(&pinch_update)); @@ -575,7 +576,7 @@ // gesture, so disallowed as a pinch gesture. scroll_begin.data.scroll_begin.pointer_count = 1; filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PINCH_ZOOM); + filter.OnSetTouchAction(cc::kTouchActionPinchZoom); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update)); @@ -604,7 +605,7 @@ filter.ResetTouchAction(); // Changing the touch action for the second tap doesn't effect the behaviour // of the event. - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&tap_cancel)); EXPECT_FALSE(filter.FilterGestureEvent(&tap_down)); EXPECT_FALSE(filter.FilterGestureEvent(&double_tap)); @@ -624,14 +625,14 @@ // Double tap is disabled with any touch action other than auto. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_MANIPULATION); + filter.OnSetTouchAction(cc::kTouchActionManipulation); EXPECT_FALSE(filter.FilterGestureEvent(&tap_down)); EXPECT_FALSE(filter.FilterGestureEvent(&unconfirmed_tap)); EXPECT_EQ(WebInputEvent::kGestureTap, unconfirmed_tap.GetType()); // Changing the touch action for the second tap doesn't effect the behaviour // of the event. The tap cancel will come as part of the next touch sequence. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_AUTO); + filter.OnSetTouchAction(cc::kTouchActionAuto); EXPECT_TRUE(filter.FilterGestureEvent(&tap_cancel)); EXPECT_FALSE(filter.FilterGestureEvent(&tap_down)); EXPECT_FALSE(filter.FilterGestureEvent(&double_tap)); @@ -668,7 +669,7 @@ // With touch action other than auto, tap unconfirmed is turned into tap. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&tap_down)); EXPECT_FALSE(filter.FilterGestureEvent(&unconfirmed_tap1)); EXPECT_EQ(WebInputEvent::kGestureTap, unconfirmed_tap1.GetType()); @@ -686,12 +687,12 @@ WebInputEvent::kGestureScrollEnd, kSourceDevice); filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_end)); filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&tap)); filter.ResetTouchAction(); @@ -713,7 +714,7 @@ WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build( WebInputEvent::kGestureScrollEnd, kSourceDevice); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_TRUE(filter.FilterGestureEvent(&scroll_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_begin)); EXPECT_TRUE(filter.FilterGestureEvent(&pinch_update)); @@ -746,7 +747,7 @@ // Scrolls hinted mostly in the Y axis will suppress flings with a // component solely on the X axis, converting them to a GestureScrollEnd. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN_Y); + filter.OnSetTouchAction(cc::kTouchActionPanY); WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); @@ -763,7 +764,7 @@ // Scrolls hinted mostly in the X axis will suppress flings with a // component solely on the Y axis, converting them to a GestureScrollEnd. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_PAN_X); + filter.OnSetTouchAction(cc::kTouchActionPanX); WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6, kSourceDevice); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); @@ -782,9 +783,9 @@ SyntheticWebGestureEventBuilder::BuildScrollBegin( 2, 3, blink::kWebGestureDeviceTouchpad); - // TOUCH_ACTION_NONE filters out only touchscreen scroll events. + // cc::kTouchActionNone filters out only touchscreen scroll events. filter.ResetTouchAction(); - filter.OnSetTouchAction(TOUCH_ACTION_NONE); + filter.OnSetTouchAction(cc::kTouchActionNone); EXPECT_FALSE(filter.FilterGestureEvent(&scroll_begin)); }
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index c992dd6..9f40f6c 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -28,6 +28,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "cc/input/touch_action.h" #include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/frame_navigation_entry.h" #include "content/browser/frame_host/frame_tree.h" @@ -49,7 +50,6 @@ #include "content/common/child_process_messages.h" #include "content/common/frame_messages.h" #include "content/common/input/synthetic_tap_gesture_params.h" -#include "content/common/input/touch_action.h" #include "content/common/input_messages.h" #include "content/common/renderer.mojom.h" #include "content/common/view_messages.h" @@ -5795,16 +5795,16 @@ // There's no intrinsic reason the following values can't be equal, but they // aren't at present, and if they become the same this test will need to be // updated to accommodate. - EXPECT_NE(TOUCH_ACTION_AUTO, TOUCH_ACTION_NONE); + EXPECT_NE(cc::kTouchActionAuto, cc::kTouchActionNone); - // Verify the child's input router is initially set for TOUCH_ACTION_AUTO. The - // TouchStart event will trigger TOUCH_ACTION_NONE being sent back to the + // Verify the child's input router is initially set for kTouchActionAuto. The + // TouchStart event will trigger kTouchActionNone being sent back to the // browser. RenderWidgetHostImpl* child_render_widget_host = root->child_at(0)->current_frame_host()->GetRenderWidgetHost(); InputRouterImpl* child_input_router = static_cast<InputRouterImpl*>(child_render_widget_host->input_router()); - EXPECT_EQ(TOUCH_ACTION_AUTO, + EXPECT_EQ(cc::kTouchActionAuto, child_input_router->touch_action_filter_.allowed_touch_action()); // Simulate touch event to sub-frame. @@ -5840,7 +5840,7 @@ // Verify the presence of the touch handler in the child frame correctly // propagates touch-action:none information back to the child's input router. - EXPECT_EQ(TOUCH_ACTION_NONE, + EXPECT_EQ(cc::kTouchActionNone, child_input_router->touch_action_filter_.allowed_touch_action()); } @@ -5867,17 +5867,17 @@ // There's no intrinsic reason the following values can't be equal, but they // aren't at present, and if they become the same this test will need to be // updated to accommodate. - EXPECT_NE(TOUCH_ACTION_AUTO, TOUCH_ACTION_NONE); + EXPECT_NE(cc::kTouchActionAuto, cc::kTouchActionNone); // Verify the main frame's input router is initially set for - // TOUCH_ACTION_AUTO. The - // TouchStart event will trigger TOUCH_ACTION_NONE being sent back to the + // kTouchActionAuto. The + // TouchStart event will trigger kTouchActionNone being sent back to the // browser. RenderWidgetHostImpl* render_widget_host = root->current_frame_host()->GetRenderWidgetHost(); InputRouterImpl* input_router = static_cast<InputRouterImpl*>(render_widget_host->input_router()); - EXPECT_EQ(TOUCH_ACTION_AUTO, + EXPECT_EQ(cc::kTouchActionAuto, input_router->touch_action_filter_.allowed_touch_action()); // Simulate touch event to sub-frame. @@ -5913,7 +5913,7 @@ // Verify the presence of the touch handler in the child frame correctly // propagates touch-action:none information back to the child's input router. - EXPECT_EQ(TOUCH_ACTION_NONE, + EXPECT_EQ(cc::kTouchActionNone, input_router->touch_action_filter_.allowed_touch_action()); }
diff --git a/content/child/assert_matching_enums.cc b/content/child/assert_matching_enums.cc index e4d93a7..71f371d 100644 --- a/content/child/assert_matching_enums.cc +++ b/content/child/assert_matching_enums.cc
@@ -6,14 +6,12 @@ // from Blink are valid. #include "base/macros.h" -#include "content/common/input/touch_action.h" #include "content/public/common/screen_orientation_values.h" #include "media/base/mime_util.h" #include "third_party/WebKit/public/platform/WebTextInputMode.h" #include "third_party/WebKit/public/platform/WebTextInputType.h" #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h" #include "third_party/WebKit/public/web/WebFrameSerializerCacheControlPolicy.h" -#include "third_party/WebKit/public/web/WebTouchAction.h" #include "ui/base/ime/text_input_mode.h" #include "ui/base/ime/text_input_type.h" @@ -90,20 +88,4 @@ STATIC_ASSERT_ENUM(blink::kWebTextInputTypeDateTimeField, ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD); -// Check blink::WebTouchAction and content::TouchAction is kept in sync. -STATIC_ASSERT_ENUM(blink::kWebTouchActionNone, TOUCH_ACTION_NONE); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPanLeft, TOUCH_ACTION_PAN_LEFT); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPanRight, TOUCH_ACTION_PAN_RIGHT); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPanX, TOUCH_ACTION_PAN_X); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPanUp, TOUCH_ACTION_PAN_UP); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPanDown, TOUCH_ACTION_PAN_DOWN); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPanY, TOUCH_ACTION_PAN_Y); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPan, TOUCH_ACTION_PAN); -STATIC_ASSERT_ENUM(blink::kWebTouchActionPinchZoom, TOUCH_ACTION_PINCH_ZOOM); -STATIC_ASSERT_ENUM(blink::kWebTouchActionManipulation, - TOUCH_ACTION_MANIPULATION); -STATIC_ASSERT_ENUM(blink::kWebTouchActionDoubleTapZoom, - TOUCH_ACTION_DOUBLE_TAP_ZOOM); -STATIC_ASSERT_ENUM(blink::kWebTouchActionAuto, TOUCH_ACTION_AUTO); - } // namespace content
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index d9d2104..16bd2fe 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -195,7 +195,6 @@ "input/synthetic_tap_gesture_params.h", "input/synthetic_web_input_event_builders.cc", "input/synthetic_web_input_event_builders.h", - "input/touch_action.h", "input/touch_event_stream_validator.cc", "input/touch_event_stream_validator.h", "input/web_touch_event_traits.cc",
diff --git a/content/common/input/touch_action.h b/content/common/input/touch_action.h deleted file mode 100644 index 2a00a03..0000000 --- a/content/common/input/touch_action.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2013 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 CONTENT_COMMON_INPUT_TOUCH_ACTION_H_ -#define CONTENT_COMMON_INPUT_TOUCH_ACTION_H_ - -namespace content { - -// The current touch action specifies what accelerated browser operations -// (panning and zooming) are currently permitted via touch input. -// See http://www.w3.org/TR/pointerevents/#the-touch-action-css-property. -enum TouchAction { - // No scrolling or zooming allowed. - TOUCH_ACTION_NONE = 0, - - TOUCH_ACTION_PAN_LEFT = 1 << 0, - - TOUCH_ACTION_PAN_RIGHT = 1 << 1, - - TOUCH_ACTION_PAN_X = TOUCH_ACTION_PAN_LEFT | TOUCH_ACTION_PAN_RIGHT, - - TOUCH_ACTION_PAN_UP = 1 << 2, - - TOUCH_ACTION_PAN_DOWN = 1 << 3, - - TOUCH_ACTION_PAN_Y = TOUCH_ACTION_PAN_UP | TOUCH_ACTION_PAN_DOWN, - - TOUCH_ACTION_PAN = TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y, - - TOUCH_ACTION_PINCH_ZOOM = 1 << 4, - - TOUCH_ACTION_MANIPULATION = TOUCH_ACTION_PAN | TOUCH_ACTION_PINCH_ZOOM, - - TOUCH_ACTION_DOUBLE_TAP_ZOOM = 1 << 5, - - // All actions are permitted (the default). - TOUCH_ACTION_AUTO = TOUCH_ACTION_MANIPULATION | TOUCH_ACTION_DOUBLE_TAP_ZOOM, - - TOUCH_ACTION_MAX = (1 << 6) - 1 -}; - -inline TouchAction operator| (TouchAction a, TouchAction b) -{ - return static_cast<TouchAction>(int(a) | int(b)); -} -inline TouchAction& operator|= (TouchAction& a, TouchAction b) -{ - return a = a | b; -} -inline TouchAction operator& (TouchAction a, TouchAction b) -{ - return static_cast<TouchAction>(int(a) & int(b)); -} -inline TouchAction& operator&= (TouchAction& a, TouchAction b) -{ - return a = a & b; -} - -} // namespace content - -#endif // CONTENT_COMMON_INPUT_TOUCH_ACTION_H_
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index 3f942c2b..999987f 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -8,6 +8,7 @@ #include "base/strings/string16.h" #include "build/build_config.h" +#include "cc/input/touch_action.h" #include "content/common/content_export.h" #include "content/common/content_param_traits.h" #include "content/common/edit_command.h" @@ -25,7 +26,6 @@ #include "content/common/input/synthetic_smooth_drag_gesture_params.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "content/common/input/synthetic_tap_gesture_params.h" -#include "content/common/input/touch_action.h" #include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" #include "ui/events/blink/did_overscroll_params.h" @@ -63,7 +63,7 @@ content::SyntheticPointerActionParams::Button::BUTTON_MAX) IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventDispatchType, content::InputEventDispatchType::DISPATCH_TYPE_MAX) -IPC_ENUM_TRAITS_MAX_VALUE(content::TouchAction, content::TOUCH_ACTION_MAX) +IPC_ENUM_TRAITS_MAX_VALUE(cc::TouchAction, cc::kTouchActionMax) IPC_STRUCT_TRAITS_BEGIN(ui::DidOverscrollParams) IPC_STRUCT_TRAITS_MEMBER(accumulated_overscroll) @@ -313,7 +313,7 @@ // Notifies the allowed touch actions for a new touch point. IPC_MESSAGE_ROUTED1(InputHostMsg_SetTouchAction, - content::TouchAction /* touch_action */) + cc::TouchAction /* touch_action */) // Sent by the compositor when input scroll events are dropped due to bounds // restrictions on the root scroll offset.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index c1a62e9847..7586b63 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -288,6 +288,7 @@ "pepper/fullscreen_container.h", "peripheral_content_heuristic.cc", "peripheral_content_heuristic.h", + "possibly_associated_interface_ptr.h", "presentation/presentation_connection_proxy.cc", "presentation/presentation_connection_proxy.h", "presentation/presentation_dispatcher.cc",
diff --git a/content/renderer/possibly_associated_interface_ptr.h b/content/renderer/possibly_associated_interface_ptr.h new file mode 100644 index 0000000..9e30892b --- /dev/null +++ b/content/renderer/possibly_associated_interface_ptr.h
@@ -0,0 +1,57 @@ +// Copyright 2017 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 CONTENT_RENDERER_POSSIBLY_ASSOCIATED_INTERFACE_PTR_H_ +#define CONTENT_RENDERER_POSSIBLY_ASSOCIATED_INTERFACE_PTR_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/bindings/associated_interface_ptr.h" +#include "mojo/public/cpp/bindings/interface_ptr.h" + +namespace content { + +// PossiblyAssociatedInterfacePtr<T> contains mojo::InterfacePtr<T> or +// mojo::AssociatedInterfacePtr<T>, but not both. Mojo-related functions in +// mojo::InterfacePtr<T> and mojo::AssociatedInterfacePtr<T> are not accessible, +// but a user can access the raw pointer to the interface. +template <typename T> +class PossiblyAssociatedInterfacePtr final { + public: + PossiblyAssociatedInterfacePtr() {} + PossiblyAssociatedInterfacePtr(std::nullptr_t) {} + PossiblyAssociatedInterfacePtr(mojo::InterfacePtr<T> independent_ptr) + : independent_ptr_(std::move(independent_ptr)) {} + PossiblyAssociatedInterfacePtr(mojo::AssociatedInterfacePtr<T> associated_ptr) + : associated_ptr_(std::move(associated_ptr)) {} + + PossiblyAssociatedInterfacePtr(PossiblyAssociatedInterfacePtr&& other) { + independent_ptr_ = std::move(other.independent_ptr_); + associated_ptr_ = std::move(other.associated_ptr_); + } + ~PossiblyAssociatedInterfacePtr() {} + + PossiblyAssociatedInterfacePtr& operator=( + PossiblyAssociatedInterfacePtr&& other) { + independent_ptr_ = std::move(other.independent_ptr_); + associated_ptr_ = std::move(other.associated_ptr_); + return *this; + } + + T* get() const { + return independent_ptr_ ? independent_ptr_.get() : associated_ptr_.get(); + } + T* operator->() const { return get(); } + T& operator*() const { return *get(); } + explicit operator bool() const { return get(); } + + private: + mojo::InterfacePtr<T> independent_ptr_; + mojo::AssociatedInterfacePtr<T> associated_ptr_; + + DISALLOW_COPY_AND_ASSIGN(PossiblyAssociatedInterfacePtr); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_POSSIBLY_ASSOCIATED_INTERFACE_PTR_H_
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 2194b73..192aa93ca 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -276,7 +276,7 @@ blink::WebScreenInfo GetScreenInfo() override; void SetToolTipText(const blink::WebString&, blink::WebTextDirection hint) override; - void SetTouchAction(blink::WebTouchAction touchAction) override; + void SetTouchAction(cc::TouchAction touchAction) override; void ShowUnhandledTapUIIfNeeded(const blink::WebPoint& tappedPosition, const blink::WebNode& tappedNode, bool pageChanged) override;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 7706d46..ce810c1 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -25,6 +25,7 @@ #include "base/trace_event/trace_event_synthetic_delay.h" #include "build/build_config.h" #include "cc/animation/animation_host.h" +#include "cc/input/touch_action.h" #include "cc/output/compositor_frame_sink.h" #include "cc/output/copy_output_request.h" #include "cc/scheduler/begin_frame_source.h" @@ -2246,15 +2247,13 @@ Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers)); } -void RenderWidget::SetTouchAction(blink::WebTouchAction web_touch_action) { +void RenderWidget::SetTouchAction(cc::TouchAction touch_action) { // Ignore setTouchAction calls that result from synthetic touch events (eg. // when blink is emulating touch with mouse). if (input_handler_->handling_event_type() != WebInputEvent::kTouchStart) return; - content::TouchAction content_touch_action = - static_cast<content::TouchAction>(web_touch_action); - Send(new InputHostMsg_SetTouchAction(routing_id_, content_touch_action)); + Send(new InputHostMsg_SetTouchAction(routing_id_, touch_action)); } void RenderWidget::RegisterRenderFrameProxy(RenderFrameProxy* proxy) {
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 309083cf..bbd098f 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -23,6 +23,7 @@ #include "base/observer_list.h" #include "base/time/time.h" #include "build/build_config.h" +#include "cc/input/touch_action.h" #include "cc/surfaces/local_surface_id.h" #include "content/common/content_export.h" #include "content/common/cursors/webcursor.h" @@ -51,7 +52,6 @@ #include "third_party/WebKit/public/web/WebCompositionUnderline.h" #include "third_party/WebKit/public/web/WebPopupType.h" #include "third_party/WebKit/public/web/WebTextDirection.h" -#include "third_party/WebKit/public/web/WebTouchAction.h" #include "third_party/WebKit/public/web/WebWidget.h" #include "third_party/WebKit/public/web/WebWidgetClient.h" #include "ui/base/ime/text_input_mode.h" @@ -636,7 +636,7 @@ void HasTouchEventHandlers(bool has_handlers) override; // Tell the browser about the actions permitted for a new touch point. - void SetTouchAction(blink::WebTouchAction touch_action) override; + void SetTouchAction(cc::TouchAction touch_action) override; // Sends an ACK to the browser process during the next compositor frame. void OnWaitNextFrameForTests(int routing_id);
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 18a3abf..5389c9d 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -307,28 +307,26 @@ RendererBlinkPlatformImpl::CreateURLLoader() { ChildThreadImpl* child_thread = ChildThreadImpl::current(); - mojom::URLLoaderFactory* factory = - url_loader_factory_ ? url_loader_factory_.get() - : network_service_url_loader_factory_.get(); - if (!factory && child_thread) { + if (!url_loader_factory_ && child_thread) { bool network_service_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableNetworkService); if (network_service_enabled) { - connector_->BindInterface(mojom::kNetworkServiceName, - &network_service_url_loader_factory_); - factory = network_service_url_loader_factory_.get(); + mojom::URLLoaderFactoryPtr factory_ptr; + connector_->BindInterface(mojom::kNetworkServiceName, &factory_ptr); + url_loader_factory_ = std::move(factory_ptr); } else { - child_thread->channel()->GetRemoteAssociatedInterface( - &url_loader_factory_); - factory = url_loader_factory_.get(); + mojom::URLLoaderFactoryAssociatedPtr factory_ptr; + child_thread->channel()->GetRemoteAssociatedInterface(&factory_ptr); + url_loader_factory_ = std::move(factory_ptr); } } // There may be no child thread in RenderViewTests. These tests can still use // data URLs to bypass the ResourceDispatcher. return base::MakeUnique<WebURLLoaderImpl>( - child_thread ? child_thread->resource_dispatcher() : nullptr, factory); + child_thread ? child_thread->resource_dispatcher() : nullptr, + url_loader_factory_.get()); } blink::WebThread* RendererBlinkPlatformImpl::CurrentThread() {
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 640130f..b931470c 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -19,6 +19,7 @@ #include "content/common/content_export.h" #include "content/common/url_loader_factory.mojom.h" #include "content/renderer/origin_trials/web_trial_token_validator_impl.h" +#include "content/renderer/possibly_associated_interface_ptr.h" #include "content/renderer/top_level_blame_context.h" #include "content/renderer/webpublicsuffixlist_impl.h" #include "services/ui/public/cpp/bitmap/child_shared_bitmap_manager.h" @@ -307,10 +308,7 @@ std::unique_ptr<BlinkInterfaceProviderImpl> blink_interface_provider_; - mojom::URLLoaderFactoryAssociatedPtr url_loader_factory_; - - // Only used when network service is enabled. - mojom::URLLoaderFactoryPtr network_service_url_loader_factory_; + PossiblyAssociatedInterfacePtr<mojom::URLLoaderFactory> url_loader_factory_; DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl); };
diff --git a/content/shell/browser/layout_test/layout_test_notification_manager.cc b/content/shell/browser/layout_test/layout_test_notification_manager.cc index cf078f9..791e3700 100644 --- a/content/shell/browser/layout_test/layout_test_notification_manager.cc +++ b/content/shell/browser/layout_test/layout_test_notification_manager.cc
@@ -4,187 +4,16 @@ #include "content/shell/browser/layout_test/layout_test_notification_manager.h" -#include "base/guid.h" -#include "base/strings/nullable_string16.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/desktop_notification_delegate.h" -#include "content/public/browser/notification_event_dispatcher.h" #include "content/public/browser/permission_type.h" -#include "content/public/common/persistent_notification_status.h" -#include "content/public/common/platform_notification_data.h" #include "content/shell/browser/layout_test/layout_test_browser_context.h" #include "content/shell/browser/layout_test/layout_test_content_browser_client.h" #include "content/shell/browser/layout_test/layout_test_permission_manager.h" namespace content { -namespace { -// The Web Notification layout tests don't care about the lifetime of the -// Service Worker when a notificationclick event has been dispatched. -void OnEventDispatchComplete(PersistentNotificationStatus status) {} - -} // namespace - -LayoutTestNotificationManager::LayoutTestNotificationManager() - : weak_factory_(this) {} - +LayoutTestNotificationManager::LayoutTestNotificationManager() {} LayoutTestNotificationManager::~LayoutTestNotificationManager() {} -void LayoutTestNotificationManager::DisplayNotification( - BrowserContext* browser_context, - const std::string& notification_id, - const GURL& origin, - const PlatformNotificationData& notification_data, - const NotificationResources& notification_resources, - std::unique_ptr<DesktopNotificationDelegate> delegate, - base::Closure* cancel_callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(cancel_callback); - - *cancel_callback = base::Bind(&LayoutTestNotificationManager::Close, - weak_factory_.GetWeakPtr(), notification_id); - - ReplaceNotificationIfNeeded(notification_id); - - non_persistent_notifications_[notification_id] = std::move(delegate); - non_persistent_notifications_[notification_id]->NotificationDisplayed(); - - notification_id_map_[base::UTF16ToUTF8(notification_data.title)] = - notification_id; -} - -void LayoutTestNotificationManager::DisplayPersistentNotification( - BrowserContext* browser_context, - const std::string& notification_id, - const GURL& service_worker_scope, - const GURL& origin, - const PlatformNotificationData& notification_data, - const NotificationResources& notification_resources) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - ReplaceNotificationIfNeeded(notification_id); - - PersistentNotification notification; - notification.browser_context = browser_context; - notification.origin = origin; - - persistent_notifications_[notification_id] = notification; - - notification_id_map_[base::UTF16ToUTF8(notification_data.title)] = - notification_id; -} - -void LayoutTestNotificationManager::ClosePersistentNotification( - BrowserContext* browser_context, - const std::string& notification_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - persistent_notifications_.erase(notification_id); -} - -void LayoutTestNotificationManager::GetDisplayedNotifications( - BrowserContext* browser_context, - const DisplayedNotificationsCallback& callback) { - auto displayed_notifications = base::MakeUnique<std::set<std::string>>(); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(callback, base::Passed(&displayed_notifications), - false /* supports_synchronization */)); -} - -void LayoutTestNotificationManager::SimulateClick( - const std::string& title, - int action_index, - const base::NullableString16& reply) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - const auto notification_id_iter = notification_id_map_.find(title); - if (notification_id_iter == notification_id_map_.end()) - return; - - const std::string& notification_id = notification_id_iter->second; - - const auto persistent_iter = persistent_notifications_.find(notification_id); - const auto non_persistent_iter = - non_persistent_notifications_.find(notification_id); - - if (persistent_iter != persistent_notifications_.end()) { - DCHECK(non_persistent_iter == non_persistent_notifications_.end()); - - const PersistentNotification& notification = persistent_iter->second; - NotificationEventDispatcher::GetInstance()->DispatchNotificationClickEvent( - notification.browser_context, notification_id, notification.origin, - action_index, reply, base::Bind(&OnEventDispatchComplete)); - } else if (non_persistent_iter != non_persistent_notifications_.end()) { - DCHECK_EQ(action_index, -1) << "Action buttons are only supported for " - "persistent notifications"; - - non_persistent_iter->second->NotificationClick(); - } -} - -void LayoutTestNotificationManager::SimulateClose(const std::string& title, - bool by_user) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - const auto notification_id_iter = notification_id_map_.find(title); - if (notification_id_iter == notification_id_map_.end()) - return; - - const std::string& notification_id = notification_id_iter->second; - - const auto& persistent_iter = persistent_notifications_.find(notification_id); - if (persistent_iter == persistent_notifications_.end()) - return; - - const PersistentNotification& notification = persistent_iter->second; - NotificationEventDispatcher::GetInstance()->DispatchNotificationCloseEvent( - notification.browser_context, notification_id, notification.origin, - by_user, base::Bind(&OnEventDispatchComplete)); -} - -blink::mojom::PermissionStatus -LayoutTestNotificationManager::CheckPermissionOnUIThread( - BrowserContext* browser_context, - const GURL& origin, - int render_process_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - return CheckPermission(origin); -} - -blink::mojom::PermissionStatus -LayoutTestNotificationManager::CheckPermissionOnIOThread( - ResourceContext* resource_context, - const GURL& origin, - int render_process_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - return CheckPermission(origin); -} - -void LayoutTestNotificationManager::Close(const std::string& notification_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - auto iterator = non_persistent_notifications_.find(notification_id); - if (iterator == non_persistent_notifications_.end()) - return; - - iterator->second->NotificationClosed(); -} - -void LayoutTestNotificationManager::ReplaceNotificationIfNeeded( - const std::string& notification_id) { - const auto persistent_iter = persistent_notifications_.find(notification_id); - const auto non_persistent_iter = - non_persistent_notifications_.find(notification_id); - - if (persistent_iter != persistent_notifications_.end()) { - DCHECK(non_persistent_iter == non_persistent_notifications_.end()); - persistent_notifications_.erase(persistent_iter); - } else if (non_persistent_iter != non_persistent_notifications_.end()) { - non_persistent_iter->second->NotificationClosed(); - non_persistent_notifications_.erase(non_persistent_iter); - } -} blink::mojom::PermissionStatus LayoutTestNotificationManager::CheckPermission(const GURL& origin) {
diff --git a/content/shell/browser/layout_test/layout_test_notification_manager.h b/content/shell/browser/layout_test/layout_test_notification_manager.h index 184b13e..658d0f7 100644 --- a/content/shell/browser/layout_test/layout_test_notification_manager.h +++ b/content/shell/browser/layout_test/layout_test_notification_manager.h
@@ -5,14 +5,10 @@ #ifndef CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_NOTIFICATION_MANAGER_H_ #define CONTENT_SHELL_BROWSER_LAYOUT_TEST_LAYOUT_TEST_NOTIFICATION_MANAGER_H_ -#include <stdint.h> #include <string> -#include <unordered_map> -#include "base/callback.h" #include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "content/public/browser/platform_notification_service.h" +#include "content/test/mock_platform_notification_service.h" #include "third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h" #include "url/gurl.h" @@ -22,87 +18,15 @@ namespace content { -class DesktopNotificationDelegate; -struct NotificationResources; -struct PlatformNotificationData; - // Responsible for tracking active notifications and allowed origins for the // Web Notification API when running layout tests. -class LayoutTestNotificationManager : public PlatformNotificationService { +class LayoutTestNotificationManager : public MockPlatformNotificationService { public: LayoutTestNotificationManager(); ~LayoutTestNotificationManager() override; - // Simulates a click on the notification titled |title|. |action_index| - // indicates which action was clicked, or -1 if the main notification body was - // clicked. |reply| indicates the user reply, if any. - // Must be called on the UI thread. - void SimulateClick(const std::string& title, - int action_index, - const base::NullableString16& reply); - - // Simulates the closing a notification titled |title|. Must be called on - // the UI thread. - void SimulateClose(const std::string& title, bool by_user); - - // PlatformNotificationService implementation. - blink::mojom::PermissionStatus CheckPermissionOnUIThread( - BrowserContext* browser_context, - const GURL& origin, - int render_process_id) override; - blink::mojom::PermissionStatus CheckPermissionOnIOThread( - ResourceContext* resource_context, - const GURL& origin, - int render_process_id) override; - void DisplayNotification( - BrowserContext* browser_context, - const std::string& notification_id, - const GURL& origin, - const PlatformNotificationData& notification_data, - const NotificationResources& notification_resources, - std::unique_ptr<DesktopNotificationDelegate> delegate, - base::Closure* cancel_callback) override; - void DisplayPersistentNotification( - BrowserContext* browser_context, - const std::string& notification_id, - const GURL& service_worker_scope, - const GURL& origin, - const PlatformNotificationData& notification_data, - const NotificationResources& notification_resources) override; - void ClosePersistentNotification(BrowserContext* browser_context, - const std::string& notification_id) override; - void GetDisplayedNotifications( - BrowserContext* browser_context, - const DisplayedNotificationsCallback& callback) override; - private: - // Structure to represent the information of a persistent notification. - struct PersistentNotification { - BrowserContext* browser_context = nullptr; - GURL origin; - }; - - // Closes the notification titled |title|. Must be called on the UI thread. - void Close(const std::string& title); - - // Fakes replacing the notification identified by |notification_id|. Both - // persistent and non-persistent notifications will be considered for this. - void ReplaceNotificationIfNeeded(const std::string& notification_id); - - // Checks if |origin| has permission to display notifications. May be called - // on both the IO and the UI threads. - blink::mojom::PermissionStatus CheckPermission(const GURL& origin); - - std::unordered_map<std::string, PersistentNotification> - persistent_notifications_; - std::unordered_map<std::string, std::unique_ptr<DesktopNotificationDelegate>> - non_persistent_notifications_; - - // Mapping of titles to notification ids giving test a usable identifier. - std::unordered_map<std::string, std::string> notification_id_map_; - - base::WeakPtrFactory<LayoutTestNotificationManager> weak_factory_; - + blink::mojom::PermissionStatus CheckPermission(const GURL& origin) override; DISALLOW_COPY_AND_ASSIGN(LayoutTestNotificationManager); };
diff --git a/content/shell/browser/layout_test/layout_test_permission_manager.cc b/content/shell/browser/layout_test/layout_test_permission_manager.cc index 9a211cc..8bdfb75 100644 --- a/content/shell/browser/layout_test/layout_test_permission_manager.cc +++ b/content/shell/browser/layout_test/layout_test_permission_manager.cc
@@ -15,7 +15,6 @@ #include "content/public/browser/permission_type.h" #include "content/public/browser/web_contents.h" #include "content/shell/browser/layout_test/layout_test_content_browser_client.h" -#include "content/shell/browser/layout_test/layout_test_notification_manager.h" namespace content {
diff --git a/content/shell/common/layout_test.mojom b/content/shell/common/layout_test.mojom index 81f9703..dd61553 100644 --- a/content/shell/common/layout_test.mojom +++ b/content/shell/common/layout_test.mojom
@@ -22,7 +22,7 @@ url.mojom.Url test_url; // True if pixel tests are enabled. - bool enable_pixel_dumping; + bool enable_pixel_dumping = true; // True if tests can open external URLs bool allow_external_pages;
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index b0628dc8..e3b92cc 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -252,10 +252,10 @@ BlinkTestRunner::BlinkTestRunner(RenderView* render_view) : RenderViewObserver(render_view), RenderViewObserverTracker<BlinkTestRunner>(render_view), + test_config_(mojom::ShellTestConfiguration::New()), is_main_window_(false), focus_on_next_commit_(false), - leak_detector_(new LeakDetector(this)) { -} + leak_detector_(new LeakDetector(this)) {} BlinkTestRunner::~BlinkTestRunner() { }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 869ba31..e447adf 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -169,6 +169,8 @@ "mock_leveldb_database.h", "mock_permission_manager.cc", "mock_permission_manager.h", + "mock_platform_notification_service.cc", + "mock_platform_notification_service.h", "mock_render_process.cc", "mock_render_process.h", "mock_ssl_host_state_delegate.cc",
diff --git a/docs/threading_and_tasks.md b/docs/threading_and_tasks.md index 986d7811..feae7fa 100644 --- a/docs/threading_and_tasks.md +++ b/docs/threading_and_tasks.md
@@ -75,16 +75,17 @@ base::BindOnce(&Task)); ``` -## Posting via a TaskRunner +### Posting via a TaskRunner A parallel [`TaskRunner`](https://cs.chromium.org/chromium/src/base/task_runner.h) is an alternative to calling `base::PostTask*()` directly. This is mainly useful when it isn’t known in advance whether tasks will be posted in parallel, in sequence, -or to a single-thread (ref. [Posting a Sequenced Task](#Posting-a-Sequenced- -Task), [Posting Multiple Tasks to the Same Thread](#Posting-Multiple-Tasks-to- -the-Same-Thread)). Since `TaskRunner` is the base class of `SequencedTaskRunner` -and `SingleThreadTaskRunner`, a `scoped_refptr<TaskRunner>` member can hold a +or to a single-thread (ref. +[Posting a Sequenced Task](#Posting-a-Sequenced-Task), +[Posting Multiple Tasks to the Same Thread](#Posting-Multiple-Tasks-to-the-Same-Thread)). +Since `TaskRunner` is the base class of `SequencedTaskRunner` and +`SingleThreadTaskRunner`, a `scoped_refptr<TaskRunner>` member can hold a `TaskRunner`, a `SequencedTaskRunner` or a `SingleThreadTaskRunner`. ```cpp @@ -217,13 +218,14 @@ ``` The main thread and the IO thread are already super busy. Therefore, prefer -posting to a general purpose thread when possible (ref. [Posting a Parallel -Task](#Posting-a-Parallel-Task), [Posting a Sequenced task](#Posting-a --Sequenced-Task)). Good reasons to post to the main thread are to update the UI -or access objects that are bound to it (e.g. `Profile`). A good reason to post -to the IO thread is to access the internals of components that are bound to it -(e.g. IPCs, network). Note: It is not necessary to have an explicit post task to -the IO thread to send/receive an IPC or send/receive data on the network. +posting to a general purpose thread when possible (ref. +[Posting a Parallel Task](#Posting-a-Parallel-Task), +[Posting a Sequenced task](#Posting-a-Sequenced-Task)). +Good reasons to post to the main thread are to update the UI or access objects +that are bound to it (e.g. `Profile`). A good reason to post to the IO thread is +to access the internals of components that are bound to it (e.g. IPCs, network). +Note: It is not necessary to have an explicit post task to the IO thread to +send/receive an IPC or send/receive data on the network. ### Posting to the Main Thread in a Renderer Process TODO
diff --git a/ios/chrome/app/startup/setup_debugging.mm b/ios/chrome/app/startup/setup_debugging.mm index 7410a46..24ae2994 100644 --- a/ios/chrome/app/startup/setup_debugging.mm +++ b/ios/chrome/app/startup/setup_debugging.mm
@@ -31,6 +31,8 @@ // TODO(crbug.com/720338): Add missing images. [whiteList addObject:@"glif-mic-to-dots-large_37"]; [whiteList addObject:@"glif-google-to-dots_28"]; + // TODO(crbug.com/721338): Add missing image. + [whiteList addObject:@"voice_icon_keyboard_accessory"]; // The original implementation of [UIImage imageNamed:]. // Called by the new implementation.
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm index 2110809..8652fde 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -21,7 +21,7 @@ #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" #include "ios/chrome/browser/ui/commands/ios_command_ids.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" +#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h" #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" @@ -48,7 +48,7 @@ - (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito; // Dismisses the |article|, removing it from the content service, and dismisses // the item at |indexPath| in the view controller. -- (void)dismissArticle:(ContentSuggestionsArticleItem*)article +- (void)dismissArticle:(ContentSuggestionsItem*)article atIndexPath:(NSIndexPath*)indexPath; @end @@ -134,7 +134,7 @@ [self stop]; } -- (void)displayContextMenuForArticle:(ContentSuggestionsArticleItem*)articleItem +- (void)displayContextMenuForArticle:(ContentSuggestionsItem*)articleItem atPoint:(CGPoint)touchLocation atIndexPath:(NSIndexPath*)indexPath { self.alertCoordinator = [[ActionSheetCoordinator alloc] @@ -146,9 +146,9 @@ view:self.suggestionsViewController.collectionView]; __weak ContentSuggestionsCoordinator* weakSelf = self; - GURL articleURL = articleItem.articleURL; + GURL articleURL = articleItem.URL; NSString* articleTitle = articleItem.title; - __weak ContentSuggestionsArticleItem* weakArticle = articleItem; + __weak ContentSuggestionsItem* weakArticle = articleItem; NSString* openInNewTabTitle = l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB); @@ -230,7 +230,7 @@ [self stop]; } -- (void)dismissArticle:(ContentSuggestionsArticleItem*)article +- (void)dismissArticle:(ContentSuggestionsItem*)article atIndexPath:(NSIndexPath*)indexPath { if (!article) return;
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm index 6a83d8f..cbd7a4e0 100644 --- a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm +++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
@@ -11,7 +11,6 @@ #include "components/ntp_snippets/category.h" #include "components/ntp_snippets/category_info.h" #include "components/ntp_snippets/content_suggestion.h" -#include "components/ntp_snippets/reading_list/reading_list_distillation_state_util.h" #include "components/ntp_tiles/most_visited_sites.h" #include "components/ntp_tiles/ntp_tile.h" #import "ios/chrome/browser/content_suggestions/content_suggestions_category_wrapper.h" @@ -371,13 +370,8 @@ self.sectionInformationByCategory[categoryWrapper]; if (category.IsKnownCategory(ntp_snippets::KnownCategories::READING_LIST)) { - ReadingListUIDistillationStatus status = - reading_list::UIStatusFromModelStatus( - ReadingListStateFromSuggestionState( - contentSuggestion.reading_list_suggestion_extra() - ->distilled_state)); - suggestion.readingListExtra = [ContentSuggestionReadingListExtra - extraWithDistillationStatus:status]; + suggestion.availableOffline = + contentSuggestion.reading_list_suggestion_extra()->distilled; } [contentArray addObject:suggestion];
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 527e3e4..7cacefbe 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -6,8 +6,6 @@ sources = [ "content_suggestion.h", "content_suggestion.mm", - "content_suggestion_extra_builder.h", - "content_suggestion_extra_builder.mm", "content_suggestions_collection_updater.h", "content_suggestions_collection_updater.mm", "content_suggestions_collection_utils.h", @@ -30,7 +28,6 @@ "//ios/chrome/browser/ui/content_suggestions/cells", "//ios/chrome/browser/ui/content_suggestions/identifier", "//ios/chrome/browser/ui/favicon:favicon_ui", - "//ios/chrome/browser/ui/reading_list", "//ios/chrome/browser/ui/toolbar", "//mojo/common:common_custom_types", "//ui/base", @@ -66,6 +63,9 @@ "resources/content_suggestions_no_image.png", "resources/content_suggestions_no_image@2x.png", "resources/content_suggestions_no_image@3x.png", + "resources/content_suggestions_offline.png", + "resources/content_suggestions_offline@2x.png", + "resources/content_suggestions_offline@3x.png", ] outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn index 49fc3a1..a42fb2a 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
@@ -4,14 +4,12 @@ source_set("cells") { sources = [ - "content_suggestions_article_item.h", - "content_suggestions_article_item.mm", "content_suggestions_footer_item.h", "content_suggestions_footer_item.mm", + "content_suggestions_item.h", + "content_suggestions_item.mm", "content_suggestions_most_visited_item.h", "content_suggestions_most_visited_item.mm", - "content_suggestions_reading_list_item.h", - "content_suggestions_reading_list_item.mm", "content_suggestions_text_item.h", "content_suggestions_text_item.mm", ] @@ -22,7 +20,6 @@ "//ios/chrome/browser/ui/colors", "//ios/chrome/browser/ui/content_suggestions/identifier", "//ios/chrome/browser/ui/favicon:favicon_ui", - "//ios/chrome/browser/ui/reading_list", "//ios/chrome/browser/ui/util", "//ui/base", "//url", @@ -33,8 +30,8 @@ source_set("unit_tests") { testonly = true sources = [ - "content_suggestions_article_item_unittest.mm", "content_suggestions_footer_item_unittest.mm", + "content_suggestions_item_unittest.mm", "content_suggestions_most_visited_item_unittest.mm", ] deps = [
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h deleted file mode 100644 index 3335a7a5..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2017 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 IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_ARTICLE_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_ARTICLE_ITEM_H_ - -#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" -#import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" -#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" - -namespace base { -class Time; -} - -@class ContentSuggestionsArticleItem; -@class FaviconAttributes; -@class FaviconViewNew; -class GURL; - -// Delegate for a ContentSuggestionsArticleItem. -@protocol ContentSuggestionsArticleItemDelegate - -// Loads the image associated with this item. -- (void)loadImageForArticleItem:(ContentSuggestionsArticleItem*)articleItem; - -@end - -// Item for an article in the suggestions. -@interface ContentSuggestionsArticleItem - : CollectionViewItem<ContentSuggestionIdentification> - -// Initialize an article with a |title|, a |subtitle|, an |image| and the |url| -// to the full article. |type| is the type of the item. -- (instancetype)initWithType:(NSInteger)type - title:(NSString*)title - subtitle:(NSString*)subtitle - delegate:(id<ContentSuggestionsArticleItemDelegate>)delegate - url:(const GURL&)url NS_DESIGNATED_INITIALIZER; - -- (instancetype)initWithType:(NSInteger)type NS_UNAVAILABLE; - -@property(nonatomic, copy, readonly) NSString* title; -@property(nonatomic, strong) UIImage* image; -@property(nonatomic, readonly, assign) GURL articleURL; -@property(nonatomic, copy) NSString* publisher; -@property(nonatomic, assign) base::Time publishDate; -@property(nonatomic, weak) id<ContentSuggestionsArticleItemDelegate> delegate; -// Attributes for favicon. -@property(nonatomic, strong) FaviconAttributes* attributes; - -@end - -// Corresponding cell for an article in the suggestions. -@interface ContentSuggestionsArticleCell : MDCCollectionViewCell - -@property(nonatomic, readonly, strong) UILabel* titleLabel; -@property(nonatomic, readonly, strong) UILabel* subtitleLabel; -// View for displaying the favicon. -@property(nonatomic, readonly, strong) FaviconViewNew* faviconView; - -// Sets an |image| to illustrate the article, replacing the "no image" icon. -- (void)setContentImage:(UIImage*)image; - -// Sets the publisher |name| and |date|. -- (void)setPublisherName:(NSString*)publisherName date:(base::Time)publishDate; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_ARTICLE_ITEM_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item_unittest.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item_unittest.mm deleted file mode 100644 index 37adbfea..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item_unittest.mm +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright 2017 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. - -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" - -#include "testing/gtest/include/gtest/gtest.h" -#import "third_party/ocmock/OCMock/OCMock.h" -#import "third_party/ocmock/gtest_support.h" -#include "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -// Tests that configureCell: set all the fields of the cell except the image and -// fetches the image through the delegate. -TEST(ContentSuggestionsArticleItemTest, CellIsConfiguredWithoutImage) { - // Setup. - NSString* title = @"testTitle"; - NSString* subtitle = @"testSubtitle"; - GURL url = GURL("http://chromium.org"); - id delegateMock = - OCMProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate)); - ContentSuggestionsArticleItem* item = - [[ContentSuggestionsArticleItem alloc] initWithType:0 - title:title - subtitle:subtitle - delegate:delegateMock - url:url]; - OCMExpect([delegateMock loadImageForArticleItem:item]); - ContentSuggestionsArticleCell* cell = [[[item cellClass] alloc] init]; - ASSERT_EQ([ContentSuggestionsArticleCell class], [cell class]); - ASSERT_EQ(url, item.articleURL); - ASSERT_EQ(nil, item.image); - id cellMock = OCMPartialMock(cell); - OCMExpect([cellMock setContentImage:item.image]); - - // Action. - [item configureCell:cell]; - - // Tests. - EXPECT_OCMOCK_VERIFY(cellMock); - EXPECT_EQ(title, cell.titleLabel.text); - EXPECT_EQ(subtitle, cell.subtitleLabel.text); - EXPECT_OCMOCK_VERIFY(delegateMock); -} - -// Tests that configureCell: does not call the delegate if it fetched the image -// once. -TEST(ContentSuggestionsArticleItemTest, DontFetchImageIsImageIsBeingFetched) { - // Setup. - NSString* title = @"testTitle"; - NSString* subtitle = @"testSubtitle"; - GURL url = GURL("http://chromium.org"); - id niceDelegateMock = - OCMProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate)); - ContentSuggestionsArticleItem* item = - [[ContentSuggestionsArticleItem alloc] initWithType:0 - title:title - subtitle:subtitle - delegate:niceDelegateMock - url:url]; - item.image = [[UIImage alloc] init]; - - OCMExpect([niceDelegateMock loadImageForArticleItem:item]); - ContentSuggestionsArticleCell* cell = [[[item cellClass] alloc] init]; - ASSERT_NE(nil, item.image); - [item configureCell:cell]; - ASSERT_OCMOCK_VERIFY(niceDelegateMock); - - id strictDelegateMock = - OCMStrictProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate)); - item.delegate = strictDelegateMock; - id cellMock = OCMPartialMock(cell); - OCMExpect([cellMock setContentImage:item.image]); - - // Action. - [item configureCell:cell]; - - // Tests. - EXPECT_OCMOCK_VERIFY(cellMock); - EXPECT_EQ(title, cell.titleLabel.text); - EXPECT_EQ(subtitle, cell.subtitleLabel.text); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h new file mode 100644 index 0000000..a27b4823 --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h
@@ -0,0 +1,82 @@ +// Copyright 2017 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 IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_ITEM_H_ +#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_ITEM_H_ + +#import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" +#import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" +#import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" + +namespace base { +class Time; +} + +@class ContentSuggestionsItem; +@class FaviconAttributes; +@class FaviconViewNew; +class GURL; + +// Delegate for a ContentSuggestionsItem. +@protocol ContentSuggestionsItemDelegate + +// Loads the image associated with this item. +- (void)loadImageForSuggestionItem:(ContentSuggestionsItem*)suggestionItem; + +@end + +// Item for an article in the suggestions. +@interface ContentSuggestionsItem + : CollectionViewItem<ContentSuggestionIdentification> + +// Initialize an article with a |title|, a |subtitle|, an |image| and the |url| +// to the full article. |type| is the type of the item. +- (instancetype)initWithType:(NSInteger)type + title:(NSString*)title + subtitle:(NSString*)subtitle + delegate:(id<ContentSuggestionsItemDelegate>)delegate + url:(const GURL&)url NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithType:(NSInteger)type NS_UNAVAILABLE; + +@property(nonatomic, copy, readonly) NSString* title; +@property(nonatomic, strong) UIImage* image; +@property(nonatomic, readonly, assign) GURL URL; +@property(nonatomic, copy) NSString* publisher; +@property(nonatomic, assign) base::Time publishDate; +@property(nonatomic, weak) id<ContentSuggestionsItemDelegate> delegate; +// Attributes for favicon. +@property(nonatomic, strong) FaviconAttributes* attributes; +// Whether the suggestion has an image associated. +@property(nonatomic, assign) BOOL hasImage; +// Whether the suggestion is available offline. If YES, an icon is displayed. +@property(nonatomic, assign) BOOL availableOffline; + +@end + +// Corresponding cell for an article in the suggestions. +@interface ContentSuggestionsCell : MDCCollectionViewCell + +@property(nonatomic, readonly, strong) UILabel* titleLabel; +// View for displaying the favicon. +@property(nonatomic, readonly, strong) FaviconViewNew* faviconView; +// Whether the image should be displayed. +@property(nonatomic, assign) BOOL displayImage; + +// Sets an |image| to illustrate the article, replacing the "no image" icon. +- (void)setContentImage:(UIImage*)image; + +// Sets the publisher |name| and |date| and add an icon to signal the offline +// availability if |availableOffline| is YES. +- (void)setAdditionalInformationWithPublisherName:(NSString*)publisherName + date:(base::Time)publishDate + offlineAvailability:(BOOL)availableOffline; + +// Setst the subtitle text. If |subtitle| is nil, the space taken by the +// subtitle is removed. +- (void)setSubtitleText:(NSString*)subtitle; + +@end + +#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_ITEM_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.mm similarity index 60% rename from ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.mm rename to ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.mm index 214804e..ffa7778 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" +#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" #include "base/time/time.h" #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" @@ -23,106 +23,129 @@ const CGFloat kStandardSpacing = 16; const CGFloat kSmallSpacing = 8; +// Name of the icon displayed when a suggestion is available offline. +NSString* const kOfflineIconName = @"content_suggestions_offline"; +// Size of the icon displayed when a suggestion is available offline. +const CGFloat kOfflineIconSize = 24; + // Size of the favicon view. const CGFloat kFaviconSize = 16; -// Size of the icon displayed when there is not image. +// Size of the icon displayed when there is not image but one should be +// displayed. const CGFloat kIconSize = 24; -// Name of the icon displayed when there is not image. +// Name of the icon displayed when there is not image but one should be +// displayed. NSString* const kNoImageIconName = @"content_suggestions_no_image"; // No image icon percentage of white. const CGFloat kNoImageIconWhite = 0.38; // No image background percentage of white. const CGFloat kNoImageBackgroundWhite = 0.95; -// Duration of the animation to display the image for the article. +// Duration of the animation to display the image. const CGFloat kAnimationDuration = 0.3; } -@interface ContentSuggestionsArticleItem () +@interface ContentSuggestionsItem () @property(nonatomic, copy) NSString* subtitle; // Used to check if the image has already been fetched. There is no way to -// discriminate between failed image download and nonexitent image. The article -// tries to download the image only once. +// discriminate between failed image download and nonexitent image. The +// suggestion tries to download the image only once. @property(nonatomic, assign) BOOL imageFetched; @end -#pragma mark - ContentSuggestionsArticleItem +#pragma mark - ContentSuggestionsItem -@implementation ContentSuggestionsArticleItem +@implementation ContentSuggestionsItem @synthesize title = _title; @synthesize subtitle = _subtitle; @synthesize image = _image; -@synthesize articleURL = _articleURL; +@synthesize URL = _URL; @synthesize publisher = _publisher; @synthesize publishDate = _publishDate; @synthesize suggestionIdentifier = _suggestionIdentifier; @synthesize delegate = _delegate; @synthesize imageFetched = _imageFetched; @synthesize attributes = _attributes; +@synthesize hasImage = _hasImage; +@synthesize availableOffline = _availableOffline; - (instancetype)initWithType:(NSInteger)type title:(NSString*)title subtitle:(NSString*)subtitle - delegate:(id<ContentSuggestionsArticleItemDelegate>)delegate + delegate:(id<ContentSuggestionsItemDelegate>)delegate url:(const GURL&)url { self = [super initWithType:type]; if (self) { - self.cellClass = [ContentSuggestionsArticleCell class]; + self.cellClass = [ContentSuggestionsCell class]; _title = [title copy]; _subtitle = [subtitle copy]; - _articleURL = url; + _URL = url; _delegate = delegate; } return self; } -- (void)configureCell:(ContentSuggestionsArticleCell*)cell { +- (void)configureCell:(ContentSuggestionsCell*)cell { [super configureCell:cell]; - if (!self.imageFetched) { + if (self.hasImage && !self.imageFetched) { self.imageFetched = YES; // Fetch the image. During the fetch the cell's image should still be set. - [self.delegate loadImageForArticleItem:self]; + [self.delegate loadImageForSuggestionItem:self]; } - if (self.attributes) - [cell.faviconView configureWithAttributes:self.attributes]; + [cell.faviconView configureWithAttributes:self.attributes]; cell.titleLabel.text = self.title; - cell.subtitleLabel.text = self.subtitle; + [cell setSubtitleText:self.subtitle]; + cell.displayImage = self.hasImage; [cell setContentImage:self.image]; - [cell setPublisherName:self.publisher date:self.publishDate]; + [cell setAdditionalInformationWithPublisherName:self.publisher + date:self.publishDate + offlineAvailability:self.availableOffline]; } @end -#pragma mark - ContentSuggestionsArticleCell +#pragma mark - ContentSuggestionsCell -@interface ContentSuggestionsArticleCell () +@interface ContentSuggestionsCell () -@property(nonatomic, strong) UILabel* publisherLabel; +@property(nonatomic, strong) UILabel* additionalInformationLabel; // Contains the no-image icon or the image. @property(nonatomic, strong) UIView* imageContainer; // The no-image icon displayed when there is no image. @property(nonatomic, strong) UIImageView* noImageIcon; -// Displays the image associated with this article. It is added to the +// Displays the image associated with this suggestion. It is added to the // imageContainer only if there is an image to display, hiding the no-image // icon. @property(nonatomic, strong) UIImageView* contentImageView; +// Constraint for the size of the image. +@property(nonatomic, strong) NSLayoutConstraint* imageSize; +// Constraint for the distance between the texts and the image. +@property(nonatomic, strong) NSLayoutConstraint* imageTitleSpacing; +// Constraint for the vertical distance between the title and the subtitle. +@property(nonatomic, strong) NSLayoutConstraint* titleSubtitleSpacing; +// Label for the subtitle. +@property(nonatomic, readonly, strong) UILabel* subtitleLabel; // Applies the constraints on the elements. Called in the init. - (void)applyConstraints; @end -@implementation ContentSuggestionsArticleCell +@implementation ContentSuggestionsCell @synthesize titleLabel = _titleLabel; @synthesize subtitleLabel = _subtitleLabel; @synthesize imageContainer = _imageContainer; @synthesize noImageIcon = _noImageIcon; -@synthesize publisherLabel = _publisherLabel; +@synthesize additionalInformationLabel = _additionalInformationLabel; @synthesize contentImageView = _contentImageView; @synthesize faviconView = _faviconView; +@synthesize imageSize = _imageSize; +@synthesize imageTitleSpacing = _imageTitleSpacing; +@synthesize displayImage = _displayImage; +@synthesize titleSubtitleSpacing = _titleSubtitleSpacing; - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -131,7 +154,7 @@ _subtitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _imageContainer = [[UIView alloc] initWithFrame:CGRectZero]; _noImageIcon = [[UIImageView alloc] initWithFrame:CGRectZero]; - _publisherLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _additionalInformationLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _contentImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; _faviconView = [[FaviconViewNew alloc] init]; @@ -150,14 +173,14 @@ _noImageIcon.translatesAutoresizingMaskIntoConstraints = NO; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO; - _publisherLabel.translatesAutoresizingMaskIntoConstraints = NO; + _additionalInformationLabel.translatesAutoresizingMaskIntoConstraints = NO; _contentImageView.translatesAutoresizingMaskIntoConstraints = NO; _faviconView.translatesAutoresizingMaskIntoConstraints = NO; [self.contentView addSubview:_imageContainer]; [self.contentView addSubview:_titleLabel]; [self.contentView addSubview:_subtitleLabel]; - [self.contentView addSubview:_publisherLabel]; + [self.contentView addSubview:_additionalInformationLabel]; [self.contentView addSubview:_faviconView]; [_imageContainer addSubview:_noImageIcon]; @@ -172,11 +195,11 @@ _titleLabel.font = [MDCTypography subheadFont]; _subtitleLabel.font = [MDCTypography body1Font]; - _publisherLabel.font = [MDCTypography captionFont]; + _additionalInformationLabel.font = [MDCTypography captionFont]; _faviconView.font = [[MDCTypography fontLoader] mediumFontOfSize:10]; _subtitleLabel.textColor = [[MDCPalette greyPalette] tint700]; - _publisherLabel.textColor = [[MDCPalette greyPalette] tint700]; + _additionalInformationLabel.textColor = [[MDCPalette greyPalette] tint700]; [self applyConstraints]; } @@ -200,17 +223,62 @@ }]; } -- (void)setPublisherName:(NSString*)publisherName date:(base::Time)publishDate { +- (void)setAdditionalInformationWithPublisherName:(NSString*)publisherName + date:(base::Time)publishDate + offlineAvailability:(BOOL)availableOffline { NSDate* date = [NSDate dateWithTimeIntervalSince1970:publishDate.ToDoubleT()]; NSString* dateString = [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle]; - self.publisherLabel.text = AdjustStringForLocaleDirection( - [NSString stringWithFormat:@"%@ - %@.", publisherName, dateString]); + NSString* publisherString = AdjustStringForLocaleDirection( + [NSString stringWithFormat:@"%@ - %@ ", publisherName, dateString]); + + NSMutableAttributedString* additionInformation = + [[NSMutableAttributedString alloc] initWithString:publisherString + attributes:nil]; + + if (availableOffline) { + NSTextAttachment* offlineIcon = [[NSTextAttachment alloc] init]; + offlineIcon.image = [[UIImage imageNamed:kOfflineIconName] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + offlineIcon.bounds = CGRectMake( + 0, (_additionalInformationLabel.font.xHeight - kOfflineIconSize) / 2, + kOfflineIconSize, kOfflineIconSize); + + [additionInformation + appendAttributedString:[NSAttributedString + attributedStringWithAttachment:offlineIcon]]; + } + + self.additionalInformationLabel.attributedText = additionInformation; } +- (void)setSubtitleText:(NSString*)subtitle { + self.subtitleLabel.text = subtitle; + if (subtitle.length > 0) { + self.titleSubtitleSpacing.constant = kSmallSpacing; + } else { + self.titleSubtitleSpacing.constant = 0; + } +} + +- (void)setDisplayImage:(BOOL)displayImage { + if (displayImage) { + self.imageTitleSpacing.constant = kStandardSpacing; + self.imageSize.constant = kImageSize; + self.imageContainer.hidden = NO; + } else { + self.imageTitleSpacing.constant = 0; + self.imageSize.constant = 0; + self.imageContainer.hidden = YES; + } + _displayImage = displayImage; +} + +#pragma mark - UICollectionViewCell + - (void)prepareForReuse { self.contentImageView.hidden = YES; } @@ -226,11 +294,16 @@ // changes, for instance on screen rotation. CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds); + CGFloat offset = 0; + if (self.displayImage) { + offset = kImageSize + kStandardSpacing; + } + self.titleLabel.preferredMaxLayoutWidth = - parentWidth - kImageSize - 3 * kStandardSpacing; + parentWidth - 2 * kStandardSpacing - offset; self.subtitleLabel.preferredMaxLayoutWidth = - parentWidth - kImageSize - 3 * kStandardSpacing; - self.publisherLabel.preferredMaxLayoutWidth = + parentWidth - 2 * kStandardSpacing - offset; + self.additionalInformationLabel.preferredMaxLayoutWidth = parentWidth - kFaviconSize - kSmallSpacing - 2 * kStandardSpacing; // Re-layout with the new preferred width to allow the label to adjust its @@ -241,20 +314,35 @@ #pragma mark - Private - (void)applyConstraints { + _imageSize = + [_imageContainer.heightAnchor constraintEqualToConstant:kImageSize]; + _imageTitleSpacing = [_imageContainer.leadingAnchor + constraintEqualToAnchor:_titleLabel.trailingAnchor + constant:kStandardSpacing]; + _titleSubtitleSpacing = + [_subtitleLabel.topAnchor constraintEqualToAnchor:_titleLabel.bottomAnchor + constant:kSmallSpacing]; + [NSLayoutConstraint activateConstraints:@[ - [_imageContainer.widthAnchor constraintEqualToConstant:kImageSize], - [_imageContainer.heightAnchor - constraintEqualToAnchor:_imageContainer.widthAnchor], + // Image. + _imageSize, + [_imageContainer.widthAnchor + constraintEqualToAnchor:_imageContainer.heightAnchor], [_imageContainer.topAnchor constraintEqualToAnchor:_titleLabel.topAnchor], - // Publisher. - [_publisherLabel.topAnchor + // Text. + _imageTitleSpacing, _titleSubtitleSpacing, + [_titleLabel.trailingAnchor + constraintEqualToAnchor:_subtitleLabel.trailingAnchor], + + // Additional Information. + [_additionalInformationLabel.topAnchor constraintGreaterThanOrEqualToAnchor:_imageContainer.bottomAnchor constant:kStandardSpacing], - [_publisherLabel.topAnchor + [_additionalInformationLabel.topAnchor constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor constant:kStandardSpacing], - [_publisherLabel.bottomAnchor + [_additionalInformationLabel.bottomAnchor constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor constant:-kStandardSpacing], @@ -266,7 +354,7 @@ constraintGreaterThanOrEqualToAnchor:_subtitleLabel.bottomAnchor constant:kStandardSpacing], [_faviconView.centerYAnchor - constraintEqualToAnchor:_publisherLabel.centerYAnchor], + constraintEqualToAnchor:_additionalInformationLabel.centerYAnchor], [_faviconView.bottomAnchor constraintLessThanOrEqualToAnchor:self.contentView.bottomAnchor constant:-kStandardSpacing], @@ -287,16 +375,17 @@ ApplyVisualConstraintsWithMetrics( @[ - @"H:|-(space)-[title]-(space)-[image]-(space)-|", - @"H:|-(space)-[text]-(space)-[image]", - @"V:|-(space)-[title]-[text]", - @"H:|-(space)-[favicon]-(small)-[publish]-(space)-|", + @"H:|-(space)-[title]", + @"H:[image]-(space)-|", + @"H:|-(space)-[text]", + @"V:|-(space)-[title]", + @"H:|-(space)-[favicon]-(small)-[additional]-(space)-|", ], @{ @"image" : _imageContainer, @"title" : _titleLabel, @"text" : _subtitleLabel, - @"publish" : _publisherLabel, + @"additional" : _additionalInformationLabel, @"favicon" : _faviconView, }, @{ @"space" : @(kStandardSpacing),
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item_unittest.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item_unittest.mm new file mode 100644 index 0000000..70b6647 --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item_unittest.mm
@@ -0,0 +1,121 @@ +// Copyright 2017 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. + +#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" + +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" +#include "url/gurl.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +// Tests that configureCell: sets all the fields of the cell except the image +// and fetches the image through the delegate. +TEST(ContentSuggestionsItemTest, CellIsConfiguredWithoutImage) { + // Setup. + NSString* title = @"testTitle"; + NSString* subtitle = @"testSubtitle"; + GURL url = GURL("http://chromium.org"); + NSString* publisher = @"publisherName"; + base::Time publishTime = base::Time::Now(); + id delegateMock = OCMProtocolMock(@protocol(ContentSuggestionsItemDelegate)); + ContentSuggestionsItem* item = + [[ContentSuggestionsItem alloc] initWithType:0 + title:title + subtitle:subtitle + delegate:delegateMock + url:url]; + item.hasImage = YES; + item.publisher = publisher; + item.publishDate = publishTime; + item.availableOffline = YES; + OCMExpect([delegateMock loadImageForSuggestionItem:item]); + ContentSuggestionsCell* cell = [[[item cellClass] alloc] init]; + ASSERT_EQ([ContentSuggestionsCell class], [cell class]); + ASSERT_EQ(url, item.URL); + ASSERT_EQ(nil, item.image); + id cellMock = OCMPartialMock(cell); + OCMExpect([cellMock setContentImage:item.image]); + OCMExpect([cellMock setSubtitleText:subtitle]); + OCMExpect([cellMock setAdditionalInformationWithPublisherName:publisher + date:publishTime + offlineAvailability:YES]); + + // Action. + [item configureCell:cell]; + + // Tests. + EXPECT_OCMOCK_VERIFY(cellMock); + EXPECT_EQ(title, cell.titleLabel.text); + EXPECT_OCMOCK_VERIFY(delegateMock); +} + +// Tests that configureCell: does not call the delegate if it fetched the image +// once. +TEST(ContentSuggestionsItemTest, DontFetchImageIsImageIsBeingFetched) { + // Setup. + NSString* title = @"testTitle"; + NSString* subtitle = @"testSubtitle"; + GURL url = GURL("http://chromium.org"); + id niceDelegateMock = + OCMProtocolMock(@protocol(ContentSuggestionsItemDelegate)); + ContentSuggestionsItem* item = + [[ContentSuggestionsItem alloc] initWithType:0 + title:title + subtitle:subtitle + delegate:niceDelegateMock + url:url]; + item.hasImage = YES; + item.image = [[UIImage alloc] init]; + + OCMExpect([niceDelegateMock loadImageForSuggestionItem:item]); + ContentSuggestionsCell* cell = [[[item cellClass] alloc] init]; + ASSERT_NE(nil, item.image); + [item configureCell:cell]; + ASSERT_OCMOCK_VERIFY(niceDelegateMock); + + id strictDelegateMock = + OCMStrictProtocolMock(@protocol(ContentSuggestionsItemDelegate)); + item.delegate = strictDelegateMock; + id cellMock = OCMPartialMock(cell); + OCMExpect([cellMock setContentImage:item.image]); + + // Action. + [item configureCell:cell]; + + // Tests. + EXPECT_OCMOCK_VERIFY(cellMock); + EXPECT_EQ(title, cell.titleLabel.text); +} + +// Tests that the delegate is not called when |hasImage| is set to NO. If the +// delegate is called an exception is raised. +TEST(ContentSuggestionsItemTest, NoDelegateCallWhenHasNotImage) { + // Setup. + NSString* title = @"testTitle"; + NSString* subtitle = @"testSubtitle"; + GURL url = GURL("http://chromium.org"); + // Strict mock. Raise exception if the load method is called. + id delegateMock = + OCMStrictProtocolMock(@protocol(ContentSuggestionsItemDelegate)); + ContentSuggestionsItem* item = + [[ContentSuggestionsItem alloc] initWithType:0 + title:title + subtitle:subtitle + delegate:delegateMock + url:url]; + item.hasImage = NO; + ContentSuggestionsCell* cell = [[[item cellClass] alloc] init]; + + // Action. + [item configureCell:cell]; +} + +} // namespace
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h deleted file mode 100644 index cc1dd2e8..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2017 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 IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_READING_LIST_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_READING_LIST_ITEM_H_ - -#import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" -#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" - -// Reading List item with an identifier. Do no add functionalities to this item. -@interface ContentSuggestionsReadingListItem - : ReadingListCollectionViewItem<ContentSuggestionIdentification> - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_READING_LIST_ITEM_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.mm deleted file mode 100644 index f0ccc162..0000000 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.mm +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2017 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. - -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation ContentSuggestionsReadingListItem - -@synthesize suggestionIdentifier = _suggestionIdentifier; - -@end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestion.h b/ios/chrome/browser/ui/content_suggestions/content_suggestion.h index 77a101f..0e4e7b5e 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestion.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestion.h
@@ -7,7 +7,6 @@ #import <UIKit/UIKit.h> -#import "ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.h" #import "ios/chrome/browser/ui/content_suggestions/identifier/content_suggestion_identifier.h" namespace base { @@ -41,10 +40,8 @@ @property(nonatomic, copy, nullable) NSString* publisher; // The date of publication. @property(nonatomic, assign) base::Time publishDate; - -// Extra information, only available if the suggestion is of type reading list. -@property(nonatomic, strong, nullable) - ContentSuggestionReadingListExtra* readingListExtra; +// Whether the suggestion is available offline. +@property(nonatomic, assign) BOOL availableOffline; @property(nonatomic, assign) ContentSuggestionType type;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm index 5ac7497..4b1e873 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestion.mm
@@ -19,7 +19,7 @@ @synthesize publisher = _publisher; @synthesize publishDate = _publishDate; @synthesize suggestionIdentifier = _suggestionIdentifier; -@synthesize readingListExtra = _readingListExtra; +@synthesize availableOffline = _availableOffline; @synthesize type = _type; @end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.h b/ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.h deleted file mode 100644 index d9d4ef54..0000000 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2017 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 IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTION_EXTRA_BUILDER_H_ -#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTION_EXTRA_BUILDER_H_ - -#import <Foundation/Foundation.h> - -#import "ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.h" - -// Extra information available for the ContentSuggestion of type reading list. -@interface ContentSuggestionReadingListExtra : NSObject - -+ (ContentSuggestionReadingListExtra*)extraWithDistillationStatus: - (ReadingListUIDistillationStatus)status; - -// Status of the distillation. -@property(nonatomic, assign) ReadingListUIDistillationStatus status; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTION_EXTRA_BUILDER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.mm deleted file mode 100644 index 1a34c7c..0000000 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.mm +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2017 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. - -#import "ios/chrome/browser/ui/content_suggestions/content_suggestion_extra_builder.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation ContentSuggestionReadingListExtra - -+ (ContentSuggestionReadingListExtra*)extraWithDistillationStatus: - (ReadingListUIDistillationStatus)status { - ContentSuggestionReadingListExtra* extra = - [[ContentSuggestionReadingListExtra alloc] init]; - extra.status = status; - return extra; -} - -@synthesize status = _status; - -@end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm index a682c7c0..089fa5d8 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.mm
@@ -12,10 +12,9 @@ #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.h" +#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_text_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestion.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_data_sink.h" @@ -105,7 +104,7 @@ } // namespace @interface ContentSuggestionsCollectionUpdater ()< - ContentSuggestionsArticleItemDelegate, + ContentSuggestionsItemDelegate, ContentSuggestionsDataSink> @property(nonatomic, weak) id<ContentSuggestionsDataSource> dataSource; @@ -271,8 +270,33 @@ break; } case ContentSuggestionTypeArticle: { - ContentSuggestionsArticleItem* articleItem = - [self articleItemForSuggestion:suggestion]; + ContentSuggestionsItem* articleItem = + [self suggestionItemForSuggestion:suggestion]; + + articleItem.hasImage = YES; + + __weak ContentSuggestionsItem* weakItem = articleItem; + [self fetchFaviconForItem:articleItem + withURL:articleItem.URL + callback:^void(FaviconAttributes* attributes) { + weakItem.attributes = attributes; + }]; + + __weak ContentSuggestionsCollectionUpdater* weakSelf = self; + [self.dataSource + fetchFaviconImageForSuggestion:articleItem.suggestionIdentifier + completion:^void(UIImage* favicon) { + ContentSuggestionsCollectionUpdater* + strongSelf = weakSelf; + ContentSuggestionsItem* strongItem = weakItem; + if (!strongItem || !strongSelf) + return; + + strongItem.attributes = [FaviconAttributes + attributesWithImage:favicon]; + [strongSelf.collectionViewController + reconfigureCellsForItems:@[ strongItem ]]; + }]; NSIndexPath* addedIndexPath = [self addItem:articleItem toSectionWithIdentifier:sectionIdentifier]; @@ -280,8 +304,15 @@ break; } case ContentSuggestionTypeReadingList: { - ContentSuggestionsReadingListItem* readingListItem = - [self readingListItemForSuggestion:suggestion]; + ContentSuggestionsItem* readingListItem = + [self suggestionItemForSuggestion:suggestion]; + + __weak ContentSuggestionsItem* weakItem = readingListItem; + [self fetchFaviconForItem:readingListItem + withURL:readingListItem.URL + callback:^void(FaviconAttributes* attributes) { + weakItem.attributes = attributes; + }]; NSIndexPath* addedIndexPath = [self addItem:readingListItem toSectionWithIdentifier:sectionIdentifier]; @@ -342,15 +373,15 @@ return [self addItem:item toSectionWithIdentifier:sectionIdentifier]; } -#pragma mark - ContentSuggestionsArticleItemDelegate +#pragma mark - ContentSuggestionsItemDelegate -- (void)loadImageForArticleItem:(ContentSuggestionsArticleItem*)articleItem { +- (void)loadImageForSuggestionItem:(ContentSuggestionsItem*)suggestionItem { __weak ContentSuggestionsCollectionUpdater* weakSelf = self; - __weak ContentSuggestionsArticleItem* weakArticle = articleItem; + __weak ContentSuggestionsItem* weakArticle = suggestionItem; void (^imageFetchedCallback)(UIImage*) = ^(UIImage* image) { ContentSuggestionsCollectionUpdater* strongSelf = weakSelf; - ContentSuggestionsArticleItem* strongArticle = weakArticle; + ContentSuggestionsItem* strongArticle = weakArticle; if (!strongSelf || !strongArticle) { return; } @@ -361,7 +392,7 @@ }; [self.dataSource.imageFetcher - fetchImageForSuggestion:articleItem.suggestionIdentifier + fetchImageForSuggestion:suggestionItem.suggestionIdentifier callback:imageFetchedCallback]; } @@ -455,67 +486,23 @@ return item; } -// Returns an article built with the |suggestion|. -- (ContentSuggestionsArticleItem*)articleItemForSuggestion: +// Returns a suggestion item built with the |suggestion|. +- (ContentSuggestionsItem*)suggestionItemForSuggestion: (ContentSuggestion*)suggestion { - ContentSuggestionsArticleItem* articleItem = - [[ContentSuggestionsArticleItem alloc] - initWithType:ItemTypeForContentSuggestionType(suggestion.type) - title:suggestion.title - subtitle:suggestion.text - delegate:self - url:suggestion.url]; + ContentSuggestionsItem* suggestionItem = [[ContentSuggestionsItem alloc] + initWithType:ItemTypeForContentSuggestionType(suggestion.type) + title:suggestion.title + subtitle:suggestion.text + delegate:self + url:suggestion.url]; - articleItem.publisher = suggestion.publisher; - articleItem.publishDate = suggestion.publishDate; + suggestionItem.publisher = suggestion.publisher; + suggestionItem.publishDate = suggestion.publishDate; + suggestionItem.availableOffline = suggestion.availableOffline; - articleItem.suggestionIdentifier = suggestion.suggestionIdentifier; + suggestionItem.suggestionIdentifier = suggestion.suggestionIdentifier; - __weak ContentSuggestionsArticleItem* weakItem = articleItem; - [self fetchFaviconForItem:articleItem - withURL:articleItem.articleURL - callback:^void(FaviconAttributes* attributes) { - weakItem.attributes = attributes; - }]; - - __weak ContentSuggestionsCollectionUpdater* weakSelf = self; - [self.dataSource - fetchFaviconImageForSuggestion:articleItem.suggestionIdentifier - completion:^void(UIImage* favicon) { - if (!weakItem || !weakSelf) - return; - - weakItem.attributes = - [FaviconAttributes attributesWithImage:favicon]; - [weakSelf.collectionViewController - reconfigureCellsForItems:@[ weakItem ]]; - }]; - - return articleItem; -} - -// Returns a reading list item built with the |suggestion|. -- (ContentSuggestionsReadingListItem*)readingListItemForSuggestion: - (ContentSuggestion*)suggestion { - ContentSuggestionsReadingListItem* readingListItem = - [[ContentSuggestionsReadingListItem alloc] - initWithType:ItemTypeReadingList - url:suggestion.url - distillationState:suggestion.readingListExtra.status]; - - readingListItem.title = suggestion.title; - readingListItem.subtitle = suggestion.publisher; - - readingListItem.suggestionIdentifier = suggestion.suggestionIdentifier; - - __weak ContentSuggestionsReadingListItem* weakItem = readingListItem; - [self fetchFaviconForItem:readingListItem - withURL:readingListItem.url - callback:^void(FaviconAttributes* attributes) { - weakItem.attributes = attributes; - }]; - - return readingListItem; + return suggestionItem; } // Fetches the favicon associated with the |URL|, call the |callback| with the
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h index 466424fa..e5d015a 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
@@ -5,7 +5,7 @@ #ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_COMMANDS_H_ #define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_COMMANDS_H_ -@class ContentSuggestionsArticleItem; +@class ContentSuggestionsItem; class GURL; // Commands protocol for the ContentSuggestionsViewController. @@ -16,7 +16,7 @@ // Opens the |URL|. - (void)openURL:(const GURL&)URL; // Displays a context menu for opening the |articleItem|. -- (void)displayContextMenuForArticle:(ContentSuggestionsArticleItem*)articleItem +- (void)displayContextMenuForArticle:(ContentSuggestionsItem*)articleItem atPoint:(CGPoint)touchLocation atIndexPath:(NSIndexPath*)indexPath; // Dismisses the context menu if it is displayed.
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index 0057594..ba83a32a 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -8,8 +8,7 @@ #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_reading_list_item.h" +#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestion.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_updater.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h" @@ -130,10 +129,8 @@ [self.collectionViewModel itemAtIndexPath:indexPath]; switch ([self.collectionUpdater contentSuggestionTypeForItem:item]) { case ContentSuggestionTypeReadingList: - [self openReadingListItem:item]; - break; case ContentSuggestionTypeArticle: - [self openArticle:item]; + [self openSuggestion:item]; break; case ContentSuggestionTypeMostVisited: // TODO(crbug.com/707754): Open the most visited site. @@ -184,20 +181,12 @@ #pragma mark - Private -// Opens the Reading List entry associated with |item|. |item| must be a -// ContentSuggestionsReadingListItem. -- (void)openReadingListItem:(CollectionViewItem*)item { - ContentSuggestionsReadingListItem* readingListItem = - base::mac::ObjCCastStrict<ContentSuggestionsReadingListItem>(item); - [self.suggestionCommandHandler openURL:readingListItem.url]; -} - // Opens the article associated with |item|. |item| must be a -// ContentSuggestionsArticleItem. -- (void)openArticle:(CollectionViewItem*)item { - ContentSuggestionsArticleItem* article = - base::mac::ObjCCastStrict<ContentSuggestionsArticleItem>(item); - [self.suggestionCommandHandler openURL:article.articleURL]; +// ContentSuggestionsItem. +- (void)openSuggestion:(CollectionViewItem*)item { + ContentSuggestionsItem* suggestion = + base::mac::ObjCCastStrict<ContentSuggestionsItem>(item); + [self.suggestionCommandHandler openURL:suggestion.URL]; } - (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer { @@ -224,11 +213,11 @@ return; } - ContentSuggestionsArticleItem* articleItem = - base::mac::ObjCCastStrict<ContentSuggestionsArticleItem>(touchedItem); + ContentSuggestionsItem* suggestionItem = + base::mac::ObjCCastStrict<ContentSuggestionsItem>(touchedItem); [self.suggestionCommandHandler - displayContextMenuForArticle:articleItem + displayContextMenuForArticle:suggestionItem atPoint:touchLocation atIndexPath:touchedItemIndexPath]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline.png b/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline.png new file mode 100644 index 0000000..0be17a8c --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline.png Binary files differ
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline@2x.png b/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline@2x.png new file mode 100644 index 0000000..b6c020ea --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline@3x.png b/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline@3x.png new file mode 100644 index 0000000..09bdf97d --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/content_suggestions_offline@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm index ff8a30a..924dde3 100644 --- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -25,8 +25,8 @@ #import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_text_item.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_article_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_footer_item.h" +#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" #import "ios/chrome/browser/ui/payments/cells/accepted_payment_methods_item.h" #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h" @@ -339,7 +339,7 @@ // Content Suggestions cells. [model addSectionWithIdentifier:SectionIdentifierContentSuggestionsCell]; - [model addItem:[self contentSuggestionsArticleItem] + [model addItem:[self ContentSuggestionsItem] toSectionWithIdentifier:SectionIdentifierContentSuggestionsCell]; [model addItem:[self contentSuggestionsFooterItem] toSectionWithIdentifier:SectionIdentifierContentSuggestionsCell]; @@ -724,16 +724,15 @@ return footerItem; } -- (ContentSuggestionsArticleItem*)contentSuggestionsArticleItem { - ContentSuggestionsArticleItem* articleItem = - [[ContentSuggestionsArticleItem alloc] - initWithType:ItemTypeContentSuggestions - title:@"This is an incredible article, you should read it!" - subtitle:@"Really, this is the best article I have ever seen, it " - @"is mandatory to read it! It describes how to write " - @"the best article." - delegate:nil - url:GURL()]; +- (ContentSuggestionsItem*)ContentSuggestionsItem { + ContentSuggestionsItem* articleItem = [[ContentSuggestionsItem alloc] + initWithType:ItemTypeContentSuggestions + title:@"This is an incredible article, you should read it!" + subtitle:@"Really, this is the best article I have ever seen, it " + @"is mandatory to read it! It describes how to write " + @"the best article." + delegate:nil + url:GURL()]; articleItem.publisher = @"Top Publisher.com"; return articleItem; }
diff --git a/ios/chrome/search_widget_extension/search_widget_view.mm b/ios/chrome/search_widget_extension/search_widget_view.mm index d4faa46..a878bbd0 100644 --- a/ios/chrome/search_widget_extension/search_widget_view.mm +++ b/ios/chrome/search_widget_extension/search_widget_view.mm
@@ -219,6 +219,7 @@ labelView.numberOfLines = 0; labelView.textAlignment = NSTextAlignmentCenter; labelView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; + labelView.isAccessibilityElement = NO; [labelView setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; @@ -238,6 +239,7 @@ action:actionSelector forControlEvents:UIControlEventTouchUpInside]; actionButton.translatesAutoresizingMaskIntoConstraints = NO; + actionButton.accessibilityLabel = title; [self addSubview:actionButton]; [constraints addObjectsFromArray:ui_util::CreateSameConstraints(actionButton, stack)]; @@ -274,6 +276,8 @@ self.copiedButtonView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; self.copiedButtonView.layer.cornerRadius = 5; self.copiedButtonView.translatesAutoresizingMaskIntoConstraints = NO; + self.copiedButtonView.accessibilityLabel = + NSLocalizedString(@"IDS_IOS_OPEN_COPIED_LINK", nil); [self.secondaryEffectView.contentView addSubview:self.copiedButtonView]; [self.copiedButtonView addTarget:self.target action:@selector(openCopiedURL:) @@ -366,9 +370,11 @@ self.copiedButtonView.hidden = NO; self.hairlineView.hidden = YES; self.copiedURLLabel.text = self.copiedURLString; + self.copiedURLLabel.accessibilityLabel = self.copiedURLString; self.openCopiedURLTitleLabel.alpha = 1; self.openCopiedURLTitleLabel.text = NSLocalizedString(@"IDS_IOS_OPEN_COPIED_LINK", nil); + self.openCopiedURLTitleLabel.isAccessibilityElement = NO; self.copiedURLLabel.alpha = 1; return; } @@ -377,8 +383,13 @@ self.hairlineView.hidden = NO; self.copiedURLLabel.text = NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_MESSAGE", nil); + self.copiedURLLabel.accessibilityLabel = + NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_MESSAGE", nil); self.openCopiedURLTitleLabel.text = NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_TITLE", nil); + self.openCopiedURLTitleLabel.accessibilityLabel = + NSLocalizedString(@"IDS_IOS_NO_COPIED_LINK_TITLE", nil); + self.openCopiedURLTitleLabel.isAccessibilityElement = YES; if (base::ios::IsRunningOnIOS10OrLater()) { self.copiedURLLabel.alpha = 0.5;
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index a53c7b1..f10879a 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -27404,6 +27404,26 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:1626", + "id": "build126-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 7200, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { "args": [ "power.idle_platform", "-v", @@ -39742,6 +39762,26 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "id": "build132-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 7200, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { "args": [ "power.idle_platform", "-v", @@ -45911,6 +45951,26 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0d26", + "id": "build8-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 7200, + "ignore_task_failure": false, + "io_timeout": 3600 + } + }, + { "args": [ "power.idle_platform", "-v",
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 5907bcc..25cc051 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2893,24 +2893,6 @@ ] } ], - "SpeculativeResourcePrefetchingValidation": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Prefetching", - "params": { - "mode": "prefetching" - }, - "enable_features": [ - "SpeculativeResourcePrefetching" - ] - } - ] - } - ], "StrictSecureCookies": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 2164cf72..7691886 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -5274,7 +5274,8 @@ crbug.com/591099 external/wpt/content-security-policy/media-src/media-src-redir-bug.sub.html [ Pass Timeout ] crbug.com/591099 external/wpt/content-security-policy/meta/meta-img-src.html [ Crash ] crbug.com/591099 external/wpt/content-security-policy/meta/meta-modified.html [ Crash ] -crbug.com/591099 external/wpt/content-security-policy/navigation/to-javascript-url.html [ Crash ] +crbug.com/591099 external/wpt/content-security-policy/navigation/to-javascript-url-frame-src.html [ Crash ] +crbug.com/591099 external/wpt/content-security-policy/navigation/to-javascript-url-script-src.html [ Crash ] crbug.com/591099 external/wpt/content-security-policy/script-src/script-src-1_1.html [ Crash Pass ] crbug.com/591099 external/wpt/content-security-policy/script-src/script-src-1_2.html [ Crash Pass ] crbug.com/591099 external/wpt/content-security-policy/securitypolicyviolation/img-src-redirect-upgrade-reporting.https.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations index b2d8ec6..ae22280 100644 --- a/third_party/WebKit/LayoutTests/W3CImportExpectations +++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -329,7 +329,8 @@ # external/wpt/pointerevents [ Pass ] ## Owners: chongz@chromium.org # external/wpt/pointerlock [ Pass ] -external/wpt/presentation-api [ Skip ] +## Owners: media-dev@chromium.org +# external/wpt/presentation-api [ Pass ] ## Owners: blink-network-dev@chromium.org # external/wpt/progress-events [ Pass ] external/wpt/proximity [ Skip ] @@ -346,7 +347,8 @@ external/wpt/resources/examples [ Skip ] external/wpt/resources/webidl2/README.md [ Skip ] external/wpt/resources/webidl2/test [ Skip ] -external/wpt/screen-orientation [ Skip ] +## Owners: mlamouri@chromium.org +# external/wpt/screen-orientation [ Pass ] ## Owners: mkwst@chromium.org # external/wpt/secure-contexts [ Pass ] ## Owners: dom-dev@chromium.org @@ -403,7 +405,8 @@ # external/wpt/webstorage [ Pass ] ## Owners: foolip@chromium.org,maksim.sisov@intel.com # external/wpt/webvtt [ Pass ] -external/wpt/web-nfc [ Skip ] +## Owners: alexander.shalamov@intel.com,kenneth.r.christiansen@intel.com,rijubrata.bhaumik@intel.com +# external/wpt/web-nfc [ Pass ] ## Owners: worker-dev@chromium.org # external/wpt/workers [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url-frame-src.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url-frame-src.html new file mode 100644 index 0000000..79b881c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url-frame-src.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<meta http-equiv="Content-Security-Policy" content="frame-src 'none'"> + +<body> + +<script> + var t = async_test("<iframe src='javascript:...'> not blocked by 'frame-src'"); + + var i = document.createElement('iframe'); + i.src = "javascript:window.top.t.done();"; + + document.body.appendChild(i); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url-script-src.html similarity index 100% rename from third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url.html rename to third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigation/to-javascript-url-script-src.html
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.png index 574737c..5f8b628 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.txt index e0718f9..417086f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/text-text-01-b-expected.txt
@@ -38,51 +38,51 @@ LayoutSVGInlineText {#text} at (76,38.34) size 54.33x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.33: "lengthAdjust: default" LayoutSVGContainer {g} at (2,23) size 139x22.34 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,22.00)}] - LayoutSVGContainer {g} at (3,23) size 137.69x9 - LayoutSVGText {text} at (3,23) size 64.08x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,23) size 64.08x9 + LayoutSVGContainer {g} at (3,23) size 136.98x9 + LayoutSVGText {text} at (3,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,23) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.33: "L" - chunk 1 text run 2 at (8.24,30.00) startOffset 1 endOffset 2 width 1.67: "i" - chunk 1 text run 3 at (10.82,30.00) startOffset 2 endOffset 3 width 4.33: "n" - chunk 1 text run 4 at (16.07,30.00) startOffset 3 endOffset 4 width 4.33: "e" - chunk 1 text run 5 at (21.31,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (24.56,30.00) startOffset 5 endOffset 6 width 2.33: "t" - chunk 1 text run 7 at (27.80,30.00) startOffset 6 endOffset 7 width 4.33: "o" - chunk 1 text run 8 at (33.04,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (36.29,30.00) startOffset 8 endOffset 9 width 5.33: "S" - chunk 1 text run 10 at (42.53,30.00) startOffset 9 endOffset 10 width 2.33: "t" - chunk 1 text run 11 at (45.78,30.00) startOffset 10 endOffset 11 width 2.67: "r" - chunk 1 text run 12 at (49.36,30.00) startOffset 11 endOffset 12 width 4.33: "e" - chunk 1 text run 13 at (54.60,30.00) startOffset 12 endOffset 13 width 2.33: "t" - chunk 1 text run 14 at (57.84,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.76,30.00) startOffset 14 endOffset 15 width 4.33: "h" - LayoutSVGText {text} at (75,23) size 65.69x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,23) size 65.69x9 + chunk 1 text run 2 at (8.31,30.00) startOffset 1 endOffset 2 width 1.67: "i" + chunk 1 text run 3 at (10.95,30.00) startOffset 2 endOffset 3 width 4.33: "n" + chunk 1 text run 4 at (16.26,30.00) startOffset 3 endOffset 4 width 4.33: "e" + chunk 1 text run 5 at (21.57,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (24.88,30.00) startOffset 5 endOffset 6 width 2.33: "t" + chunk 1 text run 7 at (28.19,30.00) startOffset 6 endOffset 7 width 4.33: "o" + chunk 1 text run 8 at (33.50,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (36.81,30.00) startOffset 8 endOffset 9 width 5.33: "S" + chunk 1 text run 10 at (43.12,30.00) startOffset 9 endOffset 10 width 2.33: "t" + chunk 1 text run 11 at (46.43,30.00) startOffset 10 endOffset 11 width 2.67: "r" + chunk 1 text run 12 at (50.07,30.00) startOffset 11 endOffset 12 width 4.33: "e" + chunk 1 text run 13 at (55.38,30.00) startOffset 12 endOffset 13 width 2.33: "t" + chunk 1 text run 14 at (58.69,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.67,30.00) startOffset 14 endOffset 15 width 4.33: "h" + LayoutSVGText {text} at (75,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,23) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.33: "t" - chunk 1 text run 2 at (76.64,30.00) startOffset 1 endOffset 2 width 4.33: "h" - chunk 1 text run 3 at (80.28,30.00) startOffset 2 endOffset 3 width 1.67: "i" - chunk 1 text run 4 at (81.25,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.56,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (86.20,30.00) startOffset 5 endOffset 6 width 1.67: "i" - chunk 1 text run 7 at (87.17,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.48,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (92.12,30.00) startOffset 8 endOffset 9 width 4.33: "a" - chunk 1 text run 10 at (95.76,30.00) startOffset 9 endOffset 10 width 2.33: " " - chunk 1 text run 11 at (97.40,30.00) startOffset 10 endOffset 11 width 1.67: "l" - chunk 1 text run 12 at (98.37,30.00) startOffset 11 endOffset 12 width 1.67: "i" - chunk 1 text run 13 at (99.35,30.00) startOffset 12 endOffset 13 width 4.33: "n" - chunk 1 text run 14 at (102.99,30.00) startOffset 13 endOffset 14 width 4.33: "e" - chunk 1 text run 15 at (106.63,30.00) startOffset 14 endOffset 15 width 2.33: " " - chunk 1 text run 16 at (108.27,30.00) startOffset 15 endOffset 16 width 2.33: "t" - chunk 1 text run 17 at (109.91,30.00) startOffset 16 endOffset 17 width 4.33: "o" - chunk 1 text run 18 at (113.55,30.00) startOffset 17 endOffset 18 width 2.33: " " - chunk 1 text run 19 at (115.19,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.49,30.00) startOffset 19 endOffset 20 width 4.33: "q" - chunk 1 text run 21 at (122.13,30.00) startOffset 20 endOffset 21 width 4.33: "u" - chunk 1 text run 22 at (125.77,30.00) startOffset 21 endOffset 22 width 4.33: "e" - chunk 1 text run 23 at (129.41,30.00) startOffset 22 endOffset 23 width 4.33: "e" - chunk 1 text run 24 at (133.05,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.36,30.00) startOffset 24 endOffset 25 width 4.33: "e" + chunk 1 text run 2 at (76.61,30.00) startOffset 1 endOffset 2 width 4.33: "h" + chunk 1 text run 3 at (80.22,30.00) startOffset 2 endOffset 3 width 1.67: "i" + chunk 1 text run 4 at (81.17,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.44,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (86.06,30.00) startOffset 5 endOffset 6 width 1.67: "i" + chunk 1 text run 7 at (87.00,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.28,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (91.89,30.00) startOffset 8 endOffset 9 width 4.33: "a" + chunk 1 text run 10 at (95.50,30.00) startOffset 9 endOffset 10 width 2.33: " " + chunk 1 text run 11 at (97.11,30.00) startOffset 10 endOffset 11 width 1.67: "l" + chunk 1 text run 12 at (98.06,30.00) startOffset 11 endOffset 12 width 1.67: "i" + chunk 1 text run 13 at (99.00,30.00) startOffset 12 endOffset 13 width 4.33: "n" + chunk 1 text run 14 at (102.61,30.00) startOffset 13 endOffset 14 width 4.33: "e" + chunk 1 text run 15 at (106.22,30.00) startOffset 14 endOffset 15 width 2.33: " " + chunk 1 text run 16 at (107.83,30.00) startOffset 15 endOffset 16 width 2.33: "t" + chunk 1 text run 17 at (109.44,30.00) startOffset 16 endOffset 17 width 4.33: "o" + chunk 1 text run 18 at (113.06,30.00) startOffset 17 endOffset 18 width 2.33: " " + chunk 1 text run 19 at (114.67,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.94,30.00) startOffset 19 endOffset 20 width 4.33: "q" + chunk 1 text run 21 at (121.56,30.00) startOffset 20 endOffset 21 width 4.33: "u" + chunk 1 text run 22 at (125.17,30.00) startOffset 21 endOffset 22 width 4.33: "e" + chunk 1 text run 23 at (128.78,30.00) startOffset 22 endOffset 23 width 4.33: "e" + chunk 1 text run 24 at (132.39,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.67,30.00) startOffset 24 endOffset 25 width 4.33: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00] @@ -104,51 +104,51 @@ LayoutSVGInlineText {#text} at (76,38.34) size 54.33x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.33: "lengthAdjust: default" LayoutSVGContainer {g} at (2,23) size 139x22.34 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,44.00)}] - LayoutSVGContainer {g} at (3,23) size 137.69x9 - LayoutSVGText {text} at (3,23) size 64.08x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,23) size 64.08x9 + LayoutSVGContainer {g} at (3,23) size 136.98x9 + LayoutSVGText {text} at (3,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,23) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.33: "L" - chunk 1 text run 2 at (8.24,30.00) startOffset 1 endOffset 2 width 1.67: "i" - chunk 1 text run 3 at (10.82,30.00) startOffset 2 endOffset 3 width 4.33: "n" - chunk 1 text run 4 at (16.07,30.00) startOffset 3 endOffset 4 width 4.33: "e" - chunk 1 text run 5 at (21.31,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (24.56,30.00) startOffset 5 endOffset 6 width 2.33: "t" - chunk 1 text run 7 at (27.80,30.00) startOffset 6 endOffset 7 width 4.33: "o" - chunk 1 text run 8 at (33.04,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (36.29,30.00) startOffset 8 endOffset 9 width 5.33: "S" - chunk 1 text run 10 at (42.53,30.00) startOffset 9 endOffset 10 width 2.33: "t" - chunk 1 text run 11 at (45.78,30.00) startOffset 10 endOffset 11 width 2.67: "r" - chunk 1 text run 12 at (49.36,30.00) startOffset 11 endOffset 12 width 4.33: "e" - chunk 1 text run 13 at (54.60,30.00) startOffset 12 endOffset 13 width 2.33: "t" - chunk 1 text run 14 at (57.84,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.76,30.00) startOffset 14 endOffset 15 width 4.33: "h" - LayoutSVGText {text} at (75,23) size 65.69x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,23) size 65.69x9 + chunk 1 text run 2 at (8.31,30.00) startOffset 1 endOffset 2 width 1.67: "i" + chunk 1 text run 3 at (10.95,30.00) startOffset 2 endOffset 3 width 4.33: "n" + chunk 1 text run 4 at (16.26,30.00) startOffset 3 endOffset 4 width 4.33: "e" + chunk 1 text run 5 at (21.57,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (24.88,30.00) startOffset 5 endOffset 6 width 2.33: "t" + chunk 1 text run 7 at (28.19,30.00) startOffset 6 endOffset 7 width 4.33: "o" + chunk 1 text run 8 at (33.50,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (36.81,30.00) startOffset 8 endOffset 9 width 5.33: "S" + chunk 1 text run 10 at (43.12,30.00) startOffset 9 endOffset 10 width 2.33: "t" + chunk 1 text run 11 at (46.43,30.00) startOffset 10 endOffset 11 width 2.67: "r" + chunk 1 text run 12 at (50.07,30.00) startOffset 11 endOffset 12 width 4.33: "e" + chunk 1 text run 13 at (55.38,30.00) startOffset 12 endOffset 13 width 2.33: "t" + chunk 1 text run 14 at (58.69,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.67,30.00) startOffset 14 endOffset 15 width 4.33: "h" + LayoutSVGText {text} at (75,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,23) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.33: "t" - chunk 1 text run 2 at (76.64,30.00) startOffset 1 endOffset 2 width 4.33: "h" - chunk 1 text run 3 at (80.28,30.00) startOffset 2 endOffset 3 width 1.67: "i" - chunk 1 text run 4 at (81.25,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.56,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (86.20,30.00) startOffset 5 endOffset 6 width 1.67: "i" - chunk 1 text run 7 at (87.17,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.48,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (92.12,30.00) startOffset 8 endOffset 9 width 4.33: "a" - chunk 1 text run 10 at (95.76,30.00) startOffset 9 endOffset 10 width 2.33: " " - chunk 1 text run 11 at (97.40,30.00) startOffset 10 endOffset 11 width 1.67: "l" - chunk 1 text run 12 at (98.37,30.00) startOffset 11 endOffset 12 width 1.67: "i" - chunk 1 text run 13 at (99.35,30.00) startOffset 12 endOffset 13 width 4.33: "n" - chunk 1 text run 14 at (102.99,30.00) startOffset 13 endOffset 14 width 4.33: "e" - chunk 1 text run 15 at (106.63,30.00) startOffset 14 endOffset 15 width 2.33: " " - chunk 1 text run 16 at (108.27,30.00) startOffset 15 endOffset 16 width 2.33: "t" - chunk 1 text run 17 at (109.91,30.00) startOffset 16 endOffset 17 width 4.33: "o" - chunk 1 text run 18 at (113.55,30.00) startOffset 17 endOffset 18 width 2.33: " " - chunk 1 text run 19 at (115.19,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.49,30.00) startOffset 19 endOffset 20 width 4.33: "q" - chunk 1 text run 21 at (122.13,30.00) startOffset 20 endOffset 21 width 4.33: "u" - chunk 1 text run 22 at (125.77,30.00) startOffset 21 endOffset 22 width 4.33: "e" - chunk 1 text run 23 at (129.41,30.00) startOffset 22 endOffset 23 width 4.33: "e" - chunk 1 text run 24 at (133.05,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.36,30.00) startOffset 24 endOffset 25 width 4.33: "e" + chunk 1 text run 2 at (76.61,30.00) startOffset 1 endOffset 2 width 4.33: "h" + chunk 1 text run 3 at (80.22,30.00) startOffset 2 endOffset 3 width 1.67: "i" + chunk 1 text run 4 at (81.17,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.44,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (86.06,30.00) startOffset 5 endOffset 6 width 1.67: "i" + chunk 1 text run 7 at (87.00,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.28,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (91.89,30.00) startOffset 8 endOffset 9 width 4.33: "a" + chunk 1 text run 10 at (95.50,30.00) startOffset 9 endOffset 10 width 2.33: " " + chunk 1 text run 11 at (97.11,30.00) startOffset 10 endOffset 11 width 1.67: "l" + chunk 1 text run 12 at (98.06,30.00) startOffset 11 endOffset 12 width 1.67: "i" + chunk 1 text run 13 at (99.00,30.00) startOffset 12 endOffset 13 width 4.33: "n" + chunk 1 text run 14 at (102.61,30.00) startOffset 13 endOffset 14 width 4.33: "e" + chunk 1 text run 15 at (106.22,30.00) startOffset 14 endOffset 15 width 2.33: " " + chunk 1 text run 16 at (107.83,30.00) startOffset 15 endOffset 16 width 2.33: "t" + chunk 1 text run 17 at (109.44,30.00) startOffset 16 endOffset 17 width 4.33: "o" + chunk 1 text run 18 at (113.06,30.00) startOffset 17 endOffset 18 width 2.33: " " + chunk 1 text run 19 at (114.67,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.94,30.00) startOffset 19 endOffset 20 width 4.33: "q" + chunk 1 text run 21 at (121.56,30.00) startOffset 20 endOffset 21 width 4.33: "u" + chunk 1 text run 22 at (125.17,30.00) startOffset 21 endOffset 22 width 4.33: "e" + chunk 1 text run 23 at (128.78,30.00) startOffset 22 endOffset 23 width 4.33: "e" + chunk 1 text run 24 at (132.39,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.67,30.00) startOffset 24 endOffset 25 width 4.33: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.png index 1e9f73f0..201c3e3 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.txt index 86fd394..e60504e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLayout-expected.txt
@@ -49,27 +49,27 @@ LayoutSVGText {text} at (102,140) size 246x12 contains 1 chunk(s) LayoutSVGInlineText {#text} at (102,140) size 246x12 chunk 1 (middle anchor) text run 1 at (102.00,150.00) startOffset 0 endOffset 59 width 246.00: "Letter Spacing Adjustment and Explicit Length Specification" - LayoutSVGContainer {g} at (40,159) size 111.50x38 - LayoutSVGText {text} at (40,159) size 111.50x27 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,159) size 111.50x27 + LayoutSVGContainer {g} at (40,159) size 120x38 + LayoutSVGText {text} at (40,159) size 120x27 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,159) size 120x27 chunk 1 text run 1 at (40.00,180.00) startOffset 0 endOffset 1 width 9.00: "s" - chunk 1 text run 2 at (57.50,180.00) startOffset 1 endOffset 2 width 11.00: "a" - chunk 1 text run 3 at (77.00,180.00) startOffset 2 endOffset 3 width 19.00: "m" - chunk 1 text run 4 at (104.50,180.00) startOffset 3 endOffset 4 width 12.00: "p" - chunk 1 text run 5 at (125.00,180.00) startOffset 4 endOffset 5 width 7.00: "l" - chunk 1 text run 6 at (140.50,180.00) startOffset 5 endOffset 6 width 11.00: "e" + chunk 1 text run 2 at (59.20,180.00) startOffset 1 endOffset 2 width 11.00: "a" + chunk 1 text run 3 at (80.40,180.00) startOffset 2 endOffset 3 width 19.00: "m" + chunk 1 text run 4 at (109.60,180.00) startOffset 3 endOffset 4 width 12.00: "p" + chunk 1 text run 5 at (131.80,180.00) startOffset 4 endOffset 5 width 7.00: "l" + chunk 1 text run 6 at (149.00,180.00) startOffset 5 endOffset 6 width 11.00: "e" LayoutSVGText {text} at (40,187) size 58x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,187) size 58x10 chunk 1 text run 1 at (40.00,195.00) startOffset 0 endOffset 16 width 58.00: "textLength=\"120\"" - LayoutSVGContainer {g} at (185,159) size 69.83x38 - LayoutSVGText {text} at (185,159) size 69.83x27 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (185,159) size 69.83x27 + LayoutSVGContainer {g} at (185,159) size 70x38 + LayoutSVGText {text} at (185,159) size 70x27 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (185,159) size 70x27 chunk 1 text run 1 at (185.00,180.00) startOffset 0 endOffset 1 width 9.00: "s" - chunk 1 text run 2 at (194.17,180.00) startOffset 1 endOffset 2 width 11.00: "a" - chunk 1 text run 3 at (205.33,180.00) startOffset 2 endOffset 3 width 19.00: "m" - chunk 1 text run 4 at (224.50,180.00) startOffset 3 endOffset 4 width 12.00: "p" - chunk 1 text run 5 at (236.67,180.00) startOffset 4 endOffset 5 width 7.00: "l" - chunk 1 text run 6 at (243.83,180.00) startOffset 5 endOffset 6 width 11.00: "e" + chunk 1 text run 2 at (194.20,180.00) startOffset 1 endOffset 2 width 11.00: "a" + chunk 1 text run 3 at (205.40,180.00) startOffset 2 endOffset 3 width 19.00: "m" + chunk 1 text run 4 at (224.60,180.00) startOffset 3 endOffset 4 width 12.00: "p" + chunk 1 text run 5 at (236.80,180.00) startOffset 4 endOffset 5 width 7.00: "l" + chunk 1 text run 6 at (244.00,180.00) startOffset 5 endOffset 6 width 11.00: "e" LayoutSVGText {text} at (185,187) size 54x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (185,187) size 54x10 chunk 1 text run 1 at (185.00,195.00) startOffset 0 endOffset 15 width 54.00: "textLength=\"70\"" @@ -132,75 +132,75 @@ LayoutSVGText {text} at (171.89,310) size 106.19x12 contains 1 chunk(s) LayoutSVGInlineText {#text} at (171.89,310) size 106.19x12 chunk 1 (middle anchor) text run 1 at (171.90,320.00) startOffset 0 endOffset 23 width 106.20: "Word Spacing Adjustment" - LayoutSVGContainer {g} at (40,337) size 349.42x30 - LayoutSVGText {text} at (40,337) size 349.42x17 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,337) size 349.42x17 + LayoutSVGContainer {g} at (40,337) size 350x30 + LayoutSVGText {text} at (40,337) size 350x17 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,337) size 350x17 chunk 1 text run 1 at (40.00,350.00) startOffset 0 endOffset 1 width 14.00: "W" - chunk 1 text run 2 at (54.27,350.00) startOffset 1 endOffset 2 width 4.00: "i" - chunk 1 text run 3 at (58.54,350.00) startOffset 2 endOffset 3 width 8.00: "d" - chunk 1 text run 4 at (67.12,350.00) startOffset 3 endOffset 4 width 7.00: "e" - chunk 1 text run 5 at (74.69,350.00) startOffset 4 endOffset 5 width 4.00: " " - chunk 1 text run 6 at (124.26,350.00) startOffset 5 endOffset 6 width 6.00: "s" - chunk 1 text run 7 at (130.83,350.00) startOffset 6 endOffset 7 width 7.00: "e" - chunk 1 text run 8 at (138.41,350.00) startOffset 7 endOffset 8 width 8.00: "p" - chunk 1 text run 9 at (146.98,350.00) startOffset 8 endOffset 9 width 7.00: "a" - chunk 1 text run 10 at (154.55,350.00) startOffset 9 endOffset 10 width 5.00: "r" - chunk 1 text run 11 at (160.12,350.00) startOffset 10 endOffset 11 width 7.00: "a" - chunk 1 text run 12 at (167.70,350.00) startOffset 11 endOffset 12 width 4.00: "t" - chunk 1 text run 13 at (172.27,350.00) startOffset 12 endOffset 13 width 4.00: "i" - chunk 1 text run 14 at (176.84,350.00) startOffset 13 endOffset 14 width 8.00: "o" - chunk 1 text run 15 at (185.41,350.00) startOffset 14 endOffset 15 width 8.00: "n" - chunk 1 text run 16 at (193.99,350.00) startOffset 15 endOffset 16 width 4.00: " " - chunk 1 text run 17 at (243.56,350.00) startOffset 16 endOffset 17 width 8.00: "b" - chunk 1 text run 18 at (252.13,350.00) startOffset 17 endOffset 18 width 7.00: "e" - chunk 1 text run 19 at (259.70,350.00) startOffset 18 endOffset 19 width 4.00: "t" - chunk 1 text run 20 at (264.28,350.00) startOffset 19 endOffset 20 width 11.00: "w" - chunk 1 text run 21 at (275.85,350.00) startOffset 20 endOffset 21 width 7.00: "e" - chunk 1 text run 22 at (283.42,350.00) startOffset 21 endOffset 22 width 7.00: "e" - chunk 1 text run 23 at (290.99,350.00) startOffset 22 endOffset 23 width 8.00: "n" - chunk 1 text run 24 at (299.57,350.00) startOffset 23 endOffset 24 width 4.00: " " - chunk 1 text run 25 at (349.14,350.00) startOffset 24 endOffset 25 width 11.00: "w" - chunk 1 text run 26 at (360.71,350.00) startOffset 25 endOffset 26 width 8.00: "o" - chunk 1 text run 27 at (369.28,350.00) startOffset 26 endOffset 27 width 5.00: "r" - chunk 1 text run 28 at (374.86,350.00) startOffset 27 endOffset 28 width 8.00: "d" - chunk 1 text run 29 at (383.43,350.00) startOffset 28 endOffset 29 width 6.00: "s" + chunk 1 text run 2 at (54.29,350.00) startOffset 1 endOffset 2 width 4.00: "i" + chunk 1 text run 3 at (58.59,350.00) startOffset 2 endOffset 3 width 8.00: "d" + chunk 1 text run 4 at (67.18,350.00) startOffset 3 endOffset 4 width 7.00: "e" + chunk 1 text run 5 at (74.77,350.00) startOffset 4 endOffset 5 width 4.00: " " + chunk 1 text run 6 at (124.36,350.00) startOffset 5 endOffset 6 width 6.00: "s" + chunk 1 text run 7 at (130.96,350.00) startOffset 6 endOffset 7 width 7.00: "e" + chunk 1 text run 8 at (138.55,350.00) startOffset 7 endOffset 8 width 8.00: "p" + chunk 1 text run 9 at (147.14,350.00) startOffset 8 endOffset 9 width 7.00: "a" + chunk 1 text run 10 at (154.74,350.00) startOffset 9 endOffset 10 width 5.00: "r" + chunk 1 text run 11 at (160.33,350.00) startOffset 10 endOffset 11 width 7.00: "a" + chunk 1 text run 12 at (167.92,350.00) startOffset 11 endOffset 12 width 4.00: "t" + chunk 1 text run 13 at (172.51,350.00) startOffset 12 endOffset 13 width 4.00: "i" + chunk 1 text run 14 at (177.11,350.00) startOffset 13 endOffset 14 width 8.00: "o" + chunk 1 text run 15 at (185.70,350.00) startOffset 14 endOffset 15 width 8.00: "n" + chunk 1 text run 16 at (194.29,350.00) startOffset 15 endOffset 16 width 4.00: " " + chunk 1 text run 17 at (243.89,350.00) startOffset 16 endOffset 17 width 8.00: "b" + chunk 1 text run 18 at (252.48,350.00) startOffset 17 endOffset 18 width 7.00: "e" + chunk 1 text run 19 at (260.07,350.00) startOffset 18 endOffset 19 width 4.00: "t" + chunk 1 text run 20 at (264.66,350.00) startOffset 19 endOffset 20 width 11.00: "w" + chunk 1 text run 21 at (276.26,350.00) startOffset 20 endOffset 21 width 7.00: "e" + chunk 1 text run 22 at (283.85,350.00) startOffset 21 endOffset 22 width 7.00: "e" + chunk 1 text run 23 at (291.44,350.00) startOffset 22 endOffset 23 width 8.00: "n" + chunk 1 text run 24 at (300.04,350.00) startOffset 23 endOffset 24 width 4.00: " " + chunk 1 text run 25 at (349.63,350.00) startOffset 24 endOffset 25 width 11.00: "w" + chunk 1 text run 26 at (361.22,350.00) startOffset 25 endOffset 26 width 8.00: "o" + chunk 1 text run 27 at (369.81,350.00) startOffset 26 endOffset 27 width 5.00: "r" + chunk 1 text run 28 at (375.41,350.00) startOffset 27 endOffset 28 width 8.00: "d" + chunk 1 text run 29 at (384.00,350.00) startOffset 28 endOffset 29 width 6.00: "s" LayoutSVGText {text} at (40,357) size 130x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,357) size 130x10 chunk 1 text run 1 at (40.00,365.00) startOffset 0 endOffset 35 width 130.00: "textLength=\"350\" word-spacing=\"3em\"" - LayoutSVGContainer {g} at (39,382) size 346.09x30 - LayoutSVGText {text} at (39,382) size 346.09x17 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (39,382) size 346.09x17 + LayoutSVGContainer {g} at (39,382) size 351x30 + LayoutSVGText {text} at (39,382) size 351x17 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (39,382) size 351x17 chunk 1 text run 1 at (40.00,395.00) startOffset 0 endOffset 1 width 11.00: "N" - chunk 1 text run 2 at (55.90,395.00) startOffset 1 endOffset 2 width 7.00: "a" - chunk 1 text run 3 at (67.81,395.00) startOffset 2 endOffset 3 width 5.00: "r" - chunk 1 text run 4 at (77.71,395.00) startOffset 3 endOffset 4 width 5.00: "r" - chunk 1 text run 5 at (87.61,395.00) startOffset 4 endOffset 5 width 8.00: "o" - chunk 1 text run 6 at (100.52,395.00) startOffset 5 endOffset 6 width 11.00: "w" - chunk 1 text run 7 at (116.42,395.00) startOffset 6 endOffset 7 width 4.00: " " - chunk 1 text run 8 at (120.32,395.00) startOffset 7 endOffset 8 width 6.00: "s" - chunk 1 text run 9 at (131.23,395.00) startOffset 8 endOffset 9 width 7.00: "e" - chunk 1 text run 10 at (143.13,395.00) startOffset 9 endOffset 10 width 8.00: "p" - chunk 1 text run 11 at (156.03,395.00) startOffset 10 endOffset 11 width 7.00: "a" - chunk 1 text run 12 at (167.94,395.00) startOffset 11 endOffset 12 width 5.00: "r" - chunk 1 text run 13 at (177.84,395.00) startOffset 12 endOffset 13 width 7.00: "a" - chunk 1 text run 14 at (189.74,395.00) startOffset 13 endOffset 14 width 4.00: "t" - chunk 1 text run 15 at (198.65,395.00) startOffset 14 endOffset 15 width 4.00: "i" - chunk 1 text run 16 at (207.55,395.00) startOffset 15 endOffset 16 width 8.00: "o" - chunk 1 text run 17 at (220.45,395.00) startOffset 16 endOffset 17 width 8.00: "n" - chunk 1 text run 18 at (233.35,395.00) startOffset 17 endOffset 18 width 4.00: " " - chunk 1 text run 19 at (237.26,395.00) startOffset 18 endOffset 19 width 8.00: "b" - chunk 1 text run 20 at (250.16,395.00) startOffset 19 endOffset 20 width 7.00: "e" - chunk 1 text run 21 at (262.06,395.00) startOffset 20 endOffset 21 width 4.00: "t" - chunk 1 text run 22 at (270.97,395.00) startOffset 21 endOffset 22 width 11.00: "w" - chunk 1 text run 23 at (286.87,395.00) startOffset 22 endOffset 23 width 7.00: "e" - chunk 1 text run 24 at (298.77,395.00) startOffset 23 endOffset 24 width 7.00: "e" - chunk 1 text run 25 at (310.68,395.00) startOffset 24 endOffset 25 width 8.00: "n" - chunk 1 text run 26 at (323.58,395.00) startOffset 25 endOffset 26 width 4.00: " " - chunk 1 text run 27 at (327.48,395.00) startOffset 26 endOffset 27 width 11.00: "w" - chunk 1 text run 28 at (343.39,395.00) startOffset 27 endOffset 28 width 8.00: "o" - chunk 1 text run 29 at (356.29,395.00) startOffset 28 endOffset 29 width 5.00: "r" - chunk 1 text run 30 at (366.19,395.00) startOffset 29 endOffset 30 width 8.00: "d" - chunk 1 text run 31 at (379.10,395.00) startOffset 30 endOffset 31 width 6.00: "s" + chunk 1 text run 2 at (56.07,395.00) startOffset 1 endOffset 2 width 7.00: "a" + chunk 1 text run 3 at (68.13,395.00) startOffset 2 endOffset 3 width 5.00: "r" + chunk 1 text run 4 at (78.20,395.00) startOffset 3 endOffset 4 width 5.00: "r" + chunk 1 text run 5 at (88.27,395.00) startOffset 4 endOffset 5 width 8.00: "o" + chunk 1 text run 6 at (101.33,395.00) startOffset 5 endOffset 6 width 11.00: "w" + chunk 1 text run 7 at (117.40,395.00) startOffset 6 endOffset 7 width 4.00: " " + chunk 1 text run 8 at (121.47,395.00) startOffset 7 endOffset 8 width 6.00: "s" + chunk 1 text run 9 at (132.53,395.00) startOffset 8 endOffset 9 width 7.00: "e" + chunk 1 text run 10 at (144.60,395.00) startOffset 9 endOffset 10 width 8.00: "p" + chunk 1 text run 11 at (157.67,395.00) startOffset 10 endOffset 11 width 7.00: "a" + chunk 1 text run 12 at (169.73,395.00) startOffset 11 endOffset 12 width 5.00: "r" + chunk 1 text run 13 at (179.80,395.00) startOffset 12 endOffset 13 width 7.00: "a" + chunk 1 text run 14 at (191.87,395.00) startOffset 13 endOffset 14 width 4.00: "t" + chunk 1 text run 15 at (200.93,395.00) startOffset 14 endOffset 15 width 4.00: "i" + chunk 1 text run 16 at (210.00,395.00) startOffset 15 endOffset 16 width 8.00: "o" + chunk 1 text run 17 at (223.07,395.00) startOffset 16 endOffset 17 width 8.00: "n" + chunk 1 text run 18 at (236.13,395.00) startOffset 17 endOffset 18 width 4.00: " " + chunk 1 text run 19 at (240.20,395.00) startOffset 18 endOffset 19 width 8.00: "b" + chunk 1 text run 20 at (253.27,395.00) startOffset 19 endOffset 20 width 7.00: "e" + chunk 1 text run 21 at (265.33,395.00) startOffset 20 endOffset 21 width 4.00: "t" + chunk 1 text run 22 at (274.40,395.00) startOffset 21 endOffset 22 width 11.00: "w" + chunk 1 text run 23 at (290.47,395.00) startOffset 22 endOffset 23 width 7.00: "e" + chunk 1 text run 24 at (302.53,395.00) startOffset 23 endOffset 24 width 7.00: "e" + chunk 1 text run 25 at (314.60,395.00) startOffset 24 endOffset 25 width 8.00: "n" + chunk 1 text run 26 at (327.67,395.00) startOffset 25 endOffset 26 width 4.00: " " + chunk 1 text run 27 at (331.73,395.00) startOffset 26 endOffset 27 width 11.00: "w" + chunk 1 text run 28 at (347.80,395.00) startOffset 27 endOffset 28 width 8.00: "o" + chunk 1 text run 29 at (360.87,395.00) startOffset 28 endOffset 29 width 5.00: "r" + chunk 1 text run 30 at (370.93,395.00) startOffset 29 endOffset 30 width 8.00: "d" + chunk 1 text run 31 at (384.00,395.00) startOffset 30 endOffset 31 width 6.00: "s" LayoutSVGText {text} at (40,402) size 123x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,402) size 123x10 chunk 1 text run 1 at (40.00,410.00) startOffset 0 endOffset 34 width 123.00: "textLength=\"350\" word-spacing=\"-5\""
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.png index 8c0f04f1..890a56b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.txt index 8550122f..0404a05 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textLength-expected.txt
@@ -86,13 +86,13 @@ LayoutSVGContainer {g} at (200,3) size 50x24 LayoutSVGRect {rect} at (200,5) size 50x20 [fill={[type=SOLID] [color=#DDE8FF]}] [x=200.00] [y=5.00] [width=50.00] [height=20.00] LayoutSVGPath {line} at (225,3) size 0x24 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=225.00] [y1=3.00] [x2=225.00] [y2=27.00] - LayoutSVGText {text} at (202.50,7) size 46x15 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (202.50,7) size 46x15 - chunk 1 (middle anchor) text run 1 at (202.50,19.00) startOffset 0 endOffset 1 width 8.00: "B" - chunk 1 (middle anchor) text run 2 at (215.50,19.00) startOffset 1 endOffset 2 width 5.00: "a" + LayoutSVGText {text} at (200,7) size 51x15 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (200,7) size 51x15 + chunk 1 (middle anchor) text run 1 at (200.00,19.00) startOffset 0 endOffset 1 width 8.00: "B" + chunk 1 (middle anchor) text run 2 at (214.25,19.00) startOffset 1 endOffset 2 width 5.00: "a" chunk 1 (middle anchor) text run 3 at (225.50,19.00) startOffset 2 endOffset 3 width 3.00: "t" - chunk 1 (middle anchor) text run 4 at (233.50,19.00) startOffset 3 endOffset 4 width 3.00: "i" - chunk 1 (middle anchor) text run 5 at (241.50,19.00) startOffset 4 endOffset 5 width 6.00: "k" + chunk 1 (middle anchor) text run 4 at (234.75,19.00) startOffset 3 endOffset 4 width 3.00: "i" + chunk 1 (middle anchor) text run 5 at (244.00,19.00) startOffset 4 endOffset 5 width 6.00: "k" LayoutSVGText {text} at (127,28) size 196x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (127,28) size 196x15 chunk 1 (middle anchor) text run 1 at (127.00,40.00) startOffset 0 endOffset 38 width 196.00: "textLength=\"50\" lengthAdjust=\"spacing\""
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png index 929dc4b..3dfaa5ad 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png index 929dc4b..3dfaa5ad 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.png index e8efd6f..67245c6 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.txt index b85c58f..45dba5c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-1-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 12.75x11.60 + LayoutSVGContainer {g} at (10,0.80) size 12.54x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (22.75,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=22.75] [y1=0.80] [x2=22.75] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 12.75x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=12.75] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGPath {svg:line} at (22.54,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=22.54] [y1=0.80] [x2=22.54] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 12.54x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=12.54] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (14.17,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.75,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.27,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.60,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.93,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.38,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.71,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.84,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.96,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.35,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.87,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (14.07,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.54,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.96,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.18,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.40,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.62,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.65,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.87,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.89,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.91,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.93,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.96,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.98,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 3 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.png index c2eafbb..7112a16 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.txt index 04d09084..e6cb9ed 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-2-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (30.71,0.80) size 10.73x11.60 - LayoutSVGPath {svg:line} at (30.71,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=30.71] [y1=0.80] [x2=30.71] [y2=12.40] - LayoutSVGPath {svg:line} at (41.44,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=41.44] [y1=0.80] [x2=41.44] [y2=12.40] - LayoutSVGRect {svg:rect} at (30.71,0.80) size 10.73x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=30.71] [y=0.80] [width=10.73] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGContainer {g} at (29.87,0.80) size 10.62x11.60 + LayoutSVGPath {svg:line} at (29.87,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=29.87] [y1=0.80] [x2=29.87] [y2=12.40] + LayoutSVGPath {svg:line} at (40.49,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=40.49] [y1=0.80] [x2=40.49] [y2=12.40] + LayoutSVGRect {svg:rect} at (29.87,0.80) size 10.62x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=29.87] [y=0.80] [width=10.62] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (14.17,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.75,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.27,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.60,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.93,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.38,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.71,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.84,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.96,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.35,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.87,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (14.07,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.54,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.96,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.18,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.40,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.62,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.65,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.87,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.89,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.91,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.93,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.96,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.98,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 10 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.png index 2aa4cf3..7cd115a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.txt index cfe75fe..388965c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-3-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (30.71,0.80) size 14.85x11.60 - LayoutSVGPath {svg:line} at (30.71,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=30.71] [y1=0.80] [x2=30.71] [y2=12.40] - LayoutSVGPath {svg:line} at (45.56,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=45.56] [y1=0.80] [x2=45.56] [y2=12.40] - LayoutSVGRect {svg:rect} at (30.71,0.80) size 14.85x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=30.71] [y=0.80] [width=14.85] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGContainer {g} at (29.87,0.80) size 14.64x11.60 + LayoutSVGPath {svg:line} at (29.87,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=29.87] [y1=0.80] [x2=29.87] [y2=12.40] + LayoutSVGPath {svg:line} at (44.51,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=44.51] [y1=0.80] [x2=44.51] [y2=12.40] + LayoutSVGRect {svg:rect} at (29.87,0.80) size 14.64x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=29.87] [y=0.80] [width=14.64] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (14.17,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.75,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.27,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.60,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.93,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.38,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.71,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.84,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.96,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.35,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.87,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (14.07,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.54,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.96,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.18,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.40,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.62,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.65,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.87,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.89,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.91,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.93,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.96,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.98,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.png index f714719..e90b2ca 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.txt index 7d2d735..47f92c5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-squeeze-4-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 51.47x11.60 + LayoutSVGContainer {g} at (10,0.80) size 50x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (61.47,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=61.47] [y1=0.80] [x2=61.47] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 51.47x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=51.47] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGPath {svg:line} at (60,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=60.00] [y1=0.80] [x2=60.00] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 50x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=50.00] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (14.17,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.75,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.27,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.60,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.93,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.38,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.71,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.84,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.96,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.35,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.87,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (14.07,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.54,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.96,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.18,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.40,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.62,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.65,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.87,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.89,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.91,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.93,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.96,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.98,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.png index e312e90..422ba6ff 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.txt index 162058c..062ecbf 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-1-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 35.63x11.60 + LayoutSVGContainer {g} at (10,0.80) size 36.86x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (45.63,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=45.63] [y1=0.80] [x2=45.63] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 35.63x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=35.63] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGPath {svg:line} at (46.86,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=46.86] [y1=0.80] [x2=46.86] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 36.86x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=36.86] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (21.36,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.12,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.83,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.35,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.86,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.37,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.69,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.20,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.52,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (109.03,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.46,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.97,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.69,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.77,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.94,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.06,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.98,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.90,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.82,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.47,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.19,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.11,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.63,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.28,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 4 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.png index df33b6e..a1064f6 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.txt index aa76ca3..3292e9b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-2-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (59.86,0.80) size 14.11x11.60 - LayoutSVGPath {svg:line} at (59.86,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=59.86] [y1=0.80] [x2=59.86] [y2=12.40] - LayoutSVGPath {svg:line} at (73.97,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=73.97] [y1=0.80] [x2=73.97] [y2=12.40] - LayoutSVGRect {svg:rect} at (59.86,0.80) size 14.11x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=59.86] [y=0.80] [width=14.11] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGContainer {g} at (61.90,0.80) size 14.52x11.60 + LayoutSVGPath {svg:line} at (61.90,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=61.90] [y1=0.80] [x2=61.90] [y2=12.40] + LayoutSVGPath {svg:line} at (76.42,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=76.42] [y1=0.80] [x2=76.42] [y2=12.40] + LayoutSVGRect {svg:rect} at (61.90,0.80) size 14.52x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=61.90] [y=0.80] [width=14.52] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (21.36,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.12,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.83,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.35,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.86,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.37,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.69,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.20,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.52,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (109.03,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.46,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.97,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.69,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.77,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.94,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.06,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.98,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.90,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.82,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.47,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.19,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.11,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.63,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.28,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 5 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 7 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.png index 7122225..f3b1aa1 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.txt index 2c295d3..24d4eb4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-3-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (88.20,0.80) size 24.23x11.60 - LayoutSVGPath {svg:line} at (88.20,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=88.20] [y1=0.80] [x2=88.20] [y2=12.40] - LayoutSVGPath {svg:line} at (112.43,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=112.43] [y1=0.80] [x2=112.43] [y2=12.40] - LayoutSVGRect {svg:rect} at (88.20,0.80) size 24.23x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=88.20] [y=0.80] [width=24.23] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGContainer {g} at (91.47,0.80) size 25.04x11.60 + LayoutSVGPath {svg:line} at (91.47,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=91.47] [y1=0.80] [x2=91.47] [y2=12.40] + LayoutSVGPath {svg:line} at (116.51,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=116.51] [y1=0.80] [x2=116.51] [y2=12.40] + LayoutSVGRect {svg:rect} at (91.47,0.80) size 25.04x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=91.47] [y=0.80] [width=25.04] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (21.36,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.12,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.83,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.35,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.86,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.37,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.69,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.20,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.52,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (109.03,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.46,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.97,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.69,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.77,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.94,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.06,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.98,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.90,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.82,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.47,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.19,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.11,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.63,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.28,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.png index 73a82df..f506045 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.txt index 6a7ae4c..6d0b2527 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/select-textLength-spacing-stretch-4-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 144.29x11.60 + LayoutSVGContainer {g} at (10,0.80) size 150x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (154.29,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=154.29] [y1=0.80] [x2=154.29] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 144.29x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=144.29] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGPath {svg:line} at (160,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=160.00] [y1=0.80] [x2=160.00] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 150x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=150.00] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (21.36,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.12,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.83,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.35,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.86,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.37,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.69,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.20,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.52,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (109.03,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.46,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.97,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.69,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.77,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.94,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.06,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.98,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.90,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.82,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.47,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.19,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.11,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.63,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.28,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.png index 76490a3d..9f340c8 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.txt index b1b517c6..079faa0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-selection-text-01-b-expected.txt
@@ -38,51 +38,51 @@ LayoutSVGInlineText {#text} at (76,38.41) size 55x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.80: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.81) size 139x22.59 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,22.00)}] - LayoutSVGContainer {g} at (3,22.81) size 137.69x9 - LayoutSVGText {text} at (3,22.81) size 64.06x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.81) size 64.06x9 + LayoutSVGContainer {g} at (3,22.81) size 136.98x9 + LayoutSVGText {text} at (3,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.81) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.40: "L" - chunk 1 text run 2 at (8.32,30.00) startOffset 1 endOffset 2 width 1.80: "i" - chunk 1 text run 3 at (11.04,30.00) startOffset 2 endOffset 3 width 4.40: "n" - chunk 1 text run 4 at (16.36,30.00) startOffset 3 endOffset 4 width 4.40: "e" - chunk 1 text run 5 at (21.68,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (24.80,30.00) startOffset 5 endOffset 6 width 2.20: "t" - chunk 1 text run 7 at (27.92,30.00) startOffset 6 endOffset 7 width 4.40: "o" - chunk 1 text run 8 at (33.24,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (36.36,30.00) startOffset 8 endOffset 9 width 5.40: "S" - chunk 1 text run 10 at (42.68,30.00) startOffset 9 endOffset 10 width 2.20: "t" - chunk 1 text run 11 at (45.80,30.00) startOffset 10 endOffset 11 width 2.60: "r" - chunk 1 text run 12 at (49.32,30.00) startOffset 11 endOffset 12 width 4.40: "e" - chunk 1 text run 13 at (54.64,30.00) startOffset 12 endOffset 13 width 2.20: "t" - chunk 1 text run 14 at (57.76,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.68,30.00) startOffset 14 endOffset 15 width 4.40: "h" - LayoutSVGText {text} at (75,22.81) size 65.69x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.81) size 65.69x9 + chunk 1 text run 2 at (8.39,30.00) startOffset 1 endOffset 2 width 1.80: "i" + chunk 1 text run 3 at (11.17,30.00) startOffset 2 endOffset 3 width 4.40: "n" + chunk 1 text run 4 at (16.56,30.00) startOffset 3 endOffset 4 width 4.40: "e" + chunk 1 text run 5 at (21.94,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (25.13,30.00) startOffset 5 endOffset 6 width 2.20: "t" + chunk 1 text run 7 at (28.31,30.00) startOffset 6 endOffset 7 width 4.40: "o" + chunk 1 text run 8 at (33.70,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (36.89,30.00) startOffset 8 endOffset 9 width 5.40: "S" + chunk 1 text run 10 at (43.27,30.00) startOffset 9 endOffset 10 width 2.20: "t" + chunk 1 text run 11 at (46.46,30.00) startOffset 10 endOffset 11 width 2.60: "r" + chunk 1 text run 12 at (50.04,30.00) startOffset 11 endOffset 12 width 4.40: "e" + chunk 1 text run 13 at (55.43,30.00) startOffset 12 endOffset 13 width 2.20: "t" + chunk 1 text run 14 at (58.61,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.60,30.00) startOffset 14 endOffset 15 width 4.40: "h" + LayoutSVGText {text} at (75,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.81) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.20: "t" - chunk 1 text run 2 at (76.50,30.00) startOffset 1 endOffset 2 width 4.40: "h" - chunk 1 text run 3 at (80.19,30.00) startOffset 2 endOffset 3 width 1.80: "i" - chunk 1 text run 4 at (81.29,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.58,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (86.08,30.00) startOffset 5 endOffset 6 width 1.80: "i" - chunk 1 text run 7 at (87.18,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.47,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (91.97,30.00) startOffset 8 endOffset 9 width 4.40: "a" - chunk 1 text run 10 at (95.66,30.00) startOffset 9 endOffset 10 width 2.20: " " - chunk 1 text run 11 at (97.16,30.00) startOffset 10 endOffset 11 width 1.80: "l" - chunk 1 text run 12 at (98.26,30.00) startOffset 11 endOffset 12 width 1.80: "i" - chunk 1 text run 13 at (99.35,30.00) startOffset 12 endOffset 13 width 4.40: "n" - chunk 1 text run 14 at (103.05,30.00) startOffset 13 endOffset 14 width 4.40: "e" - chunk 1 text run 15 at (106.74,30.00) startOffset 14 endOffset 15 width 2.20: " " - chunk 1 text run 16 at (108.24,30.00) startOffset 15 endOffset 16 width 2.20: "t" - chunk 1 text run 17 at (109.74,30.00) startOffset 16 endOffset 17 width 4.40: "o" - chunk 1 text run 18 at (113.43,30.00) startOffset 17 endOffset 18 width 2.20: " " - chunk 1 text run 19 at (114.93,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.22,30.00) startOffset 19 endOffset 20 width 4.40: "q" - chunk 1 text run 21 at (121.92,30.00) startOffset 20 endOffset 21 width 4.40: "u" - chunk 1 text run 22 at (125.62,30.00) startOffset 21 endOffset 22 width 4.40: "e" - chunk 1 text run 23 at (129.31,30.00) startOffset 22 endOffset 23 width 4.40: "e" - chunk 1 text run 24 at (133.01,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.30,30.00) startOffset 24 endOffset 25 width 4.40: "e" + chunk 1 text run 2 at (76.47,30.00) startOffset 1 endOffset 2 width 4.40: "h" + chunk 1 text run 3 at (80.13,30.00) startOffset 2 endOffset 3 width 1.80: "i" + chunk 1 text run 4 at (81.20,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.47,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (85.93,30.00) startOffset 5 endOffset 6 width 1.80: "i" + chunk 1 text run 7 at (87.00,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.27,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (91.73,30.00) startOffset 8 endOffset 9 width 4.40: "a" + chunk 1 text run 10 at (95.40,30.00) startOffset 9 endOffset 10 width 2.20: " " + chunk 1 text run 11 at (96.87,30.00) startOffset 10 endOffset 11 width 1.80: "l" + chunk 1 text run 12 at (97.93,30.00) startOffset 11 endOffset 12 width 1.80: "i" + chunk 1 text run 13 at (99.00,30.00) startOffset 12 endOffset 13 width 4.40: "n" + chunk 1 text run 14 at (102.67,30.00) startOffset 13 endOffset 14 width 4.40: "e" + chunk 1 text run 15 at (106.33,30.00) startOffset 14 endOffset 15 width 2.20: " " + chunk 1 text run 16 at (107.80,30.00) startOffset 15 endOffset 16 width 2.20: "t" + chunk 1 text run 17 at (109.27,30.00) startOffset 16 endOffset 17 width 4.40: "o" + chunk 1 text run 18 at (112.93,30.00) startOffset 17 endOffset 18 width 2.20: " " + chunk 1 text run 19 at (114.40,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.67,30.00) startOffset 19 endOffset 20 width 4.40: "q" + chunk 1 text run 21 at (121.33,30.00) startOffset 20 endOffset 21 width 4.40: "u" + chunk 1 text run 22 at (125.00,30.00) startOffset 21 endOffset 22 width 4.40: "e" + chunk 1 text run 23 at (128.67,30.00) startOffset 22 endOffset 23 width 4.40: "e" + chunk 1 text run 24 at (132.33,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.60,30.00) startOffset 24 endOffset 25 width 4.40: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00] @@ -104,51 +104,51 @@ LayoutSVGInlineText {#text} at (76,38.41) size 55x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.80: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.81) size 139x22.59 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,44.00)}] - LayoutSVGContainer {g} at (3,22.81) size 137.69x9 - LayoutSVGText {text} at (3,22.81) size 64.06x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.81) size 64.06x9 + LayoutSVGContainer {g} at (3,22.81) size 136.98x9 + LayoutSVGText {text} at (3,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.81) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.40: "L" - chunk 1 text run 2 at (8.32,30.00) startOffset 1 endOffset 2 width 1.80: "i" - chunk 1 text run 3 at (11.04,30.00) startOffset 2 endOffset 3 width 4.40: "n" - chunk 1 text run 4 at (16.36,30.00) startOffset 3 endOffset 4 width 4.40: "e" - chunk 1 text run 5 at (21.68,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (24.80,30.00) startOffset 5 endOffset 6 width 2.20: "t" - chunk 1 text run 7 at (27.92,30.00) startOffset 6 endOffset 7 width 4.40: "o" - chunk 1 text run 8 at (33.24,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (36.36,30.00) startOffset 8 endOffset 9 width 5.40: "S" - chunk 1 text run 10 at (42.68,30.00) startOffset 9 endOffset 10 width 2.20: "t" - chunk 1 text run 11 at (45.80,30.00) startOffset 10 endOffset 11 width 2.60: "r" - chunk 1 text run 12 at (49.32,30.00) startOffset 11 endOffset 12 width 4.40: "e" - chunk 1 text run 13 at (54.64,30.00) startOffset 12 endOffset 13 width 2.20: "t" - chunk 1 text run 14 at (57.76,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.68,30.00) startOffset 14 endOffset 15 width 4.40: "h" - LayoutSVGText {text} at (75,22.81) size 65.69x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.81) size 65.69x9 + chunk 1 text run 2 at (8.39,30.00) startOffset 1 endOffset 2 width 1.80: "i" + chunk 1 text run 3 at (11.17,30.00) startOffset 2 endOffset 3 width 4.40: "n" + chunk 1 text run 4 at (16.56,30.00) startOffset 3 endOffset 4 width 4.40: "e" + chunk 1 text run 5 at (21.94,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (25.13,30.00) startOffset 5 endOffset 6 width 2.20: "t" + chunk 1 text run 7 at (28.31,30.00) startOffset 6 endOffset 7 width 4.40: "o" + chunk 1 text run 8 at (33.70,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (36.89,30.00) startOffset 8 endOffset 9 width 5.40: "S" + chunk 1 text run 10 at (43.27,30.00) startOffset 9 endOffset 10 width 2.20: "t" + chunk 1 text run 11 at (46.46,30.00) startOffset 10 endOffset 11 width 2.60: "r" + chunk 1 text run 12 at (50.04,30.00) startOffset 11 endOffset 12 width 4.40: "e" + chunk 1 text run 13 at (55.43,30.00) startOffset 12 endOffset 13 width 2.20: "t" + chunk 1 text run 14 at (58.61,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.60,30.00) startOffset 14 endOffset 15 width 4.40: "h" + LayoutSVGText {text} at (75,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.81) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.20: "t" - chunk 1 text run 2 at (76.50,30.00) startOffset 1 endOffset 2 width 4.40: "h" - chunk 1 text run 3 at (80.19,30.00) startOffset 2 endOffset 3 width 1.80: "i" - chunk 1 text run 4 at (81.29,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.58,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (86.08,30.00) startOffset 5 endOffset 6 width 1.80: "i" - chunk 1 text run 7 at (87.18,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.47,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (91.97,30.00) startOffset 8 endOffset 9 width 4.40: "a" - chunk 1 text run 10 at (95.66,30.00) startOffset 9 endOffset 10 width 2.20: " " - chunk 1 text run 11 at (97.16,30.00) startOffset 10 endOffset 11 width 1.80: "l" - chunk 1 text run 12 at (98.26,30.00) startOffset 11 endOffset 12 width 1.80: "i" - chunk 1 text run 13 at (99.35,30.00) startOffset 12 endOffset 13 width 4.40: "n" - chunk 1 text run 14 at (103.05,30.00) startOffset 13 endOffset 14 width 4.40: "e" - chunk 1 text run 15 at (106.74,30.00) startOffset 14 endOffset 15 width 2.20: " " - chunk 1 text run 16 at (108.24,30.00) startOffset 15 endOffset 16 width 2.20: "t" - chunk 1 text run 17 at (109.74,30.00) startOffset 16 endOffset 17 width 4.40: "o" - chunk 1 text run 18 at (113.43,30.00) startOffset 17 endOffset 18 width 2.20: " " - chunk 1 text run 19 at (114.93,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.22,30.00) startOffset 19 endOffset 20 width 4.40: "q" - chunk 1 text run 21 at (121.92,30.00) startOffset 20 endOffset 21 width 4.40: "u" - chunk 1 text run 22 at (125.62,30.00) startOffset 21 endOffset 22 width 4.40: "e" - chunk 1 text run 23 at (129.31,30.00) startOffset 22 endOffset 23 width 4.40: "e" - chunk 1 text run 24 at (133.01,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.30,30.00) startOffset 24 endOffset 25 width 4.40: "e" + chunk 1 text run 2 at (76.47,30.00) startOffset 1 endOffset 2 width 4.40: "h" + chunk 1 text run 3 at (80.13,30.00) startOffset 2 endOffset 3 width 1.80: "i" + chunk 1 text run 4 at (81.20,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.47,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (85.93,30.00) startOffset 5 endOffset 6 width 1.80: "i" + chunk 1 text run 7 at (87.00,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.27,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (91.73,30.00) startOffset 8 endOffset 9 width 4.40: "a" + chunk 1 text run 10 at (95.40,30.00) startOffset 9 endOffset 10 width 2.20: " " + chunk 1 text run 11 at (96.87,30.00) startOffset 10 endOffset 11 width 1.80: "l" + chunk 1 text run 12 at (97.93,30.00) startOffset 11 endOffset 12 width 1.80: "i" + chunk 1 text run 13 at (99.00,30.00) startOffset 12 endOffset 13 width 4.40: "n" + chunk 1 text run 14 at (102.67,30.00) startOffset 13 endOffset 14 width 4.40: "e" + chunk 1 text run 15 at (106.33,30.00) startOffset 14 endOffset 15 width 2.20: " " + chunk 1 text run 16 at (107.80,30.00) startOffset 15 endOffset 16 width 2.20: "t" + chunk 1 text run 17 at (109.27,30.00) startOffset 16 endOffset 17 width 4.40: "o" + chunk 1 text run 18 at (112.93,30.00) startOffset 17 endOffset 18 width 2.20: " " + chunk 1 text run 19 at (114.40,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.67,30.00) startOffset 19 endOffset 20 width 4.40: "q" + chunk 1 text run 21 at (121.33,30.00) startOffset 20 endOffset 21 width 4.40: "u" + chunk 1 text run 22 at (125.00,30.00) startOffset 21 endOffset 22 width 4.40: "e" + chunk 1 text run 23 at (128.67,30.00) startOffset 22 endOffset 23 width 4.40: "e" + chunk 1 text run 24 at (132.33,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.60,30.00) startOffset 24 endOffset 25 width 4.40: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00]
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/svg/batik/text/textLayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/svg/batik/text/textLayout-expected.png index c15ac95..44a3a057 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/svg/batik/text/textLayout-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/svg/batik/text/textLayout-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/batik/text/textLayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/batik/text/textLayout-expected.png index c15ac95..44a3a057 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/svg/batik/text/textLayout-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/svg/batik/text/textLayout-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.png index e8eb569..2f86c70 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.txt index 7c9c0d5..948a97e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/text-text-01-b-expected.txt
@@ -38,51 +38,51 @@ LayoutSVGInlineText {#text} at (76,38.67) size 54.36x6.66 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.37: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.67) size 139x22.66 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,22.00)}] - LayoutSVGContainer {g} at (3,22.67) size 137.70x9 - LayoutSVGText {text} at (3,22.67) size 64.09x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.67) size 64.09x9 + LayoutSVGContainer {g} at (3,22.67) size 136.98x9 + LayoutSVGText {text} at (3,22.67) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.67) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.45: "L" - chunk 1 text run 2 at (8.34,30.00) startOffset 1 endOffset 2 width 1.78: "i" - chunk 1 text run 3 at (11.02,30.00) startOffset 2 endOffset 3 width 4.45: "n" - chunk 1 text run 4 at (16.36,30.00) startOffset 3 endOffset 4 width 4.45: "e" - chunk 1 text run 5 at (21.70,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (24.82,30.00) startOffset 5 endOffset 6 width 2.22: "t" - chunk 1 text run 7 at (27.94,30.00) startOffset 6 endOffset 7 width 4.45: "o" - chunk 1 text run 8 at (33.28,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (36.40,30.00) startOffset 8 endOffset 9 width 5.34: "S" - chunk 1 text run 10 at (42.63,30.00) startOffset 9 endOffset 10 width 2.22: "t" - chunk 1 text run 11 at (45.74,30.00) startOffset 10 endOffset 11 width 2.66: "r" - chunk 1 text run 12 at (49.30,30.00) startOffset 11 endOffset 12 width 4.45: "e" - chunk 1 text run 13 at (54.65,30.00) startOffset 12 endOffset 13 width 2.22: "t" - chunk 1 text run 14 at (57.76,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.66,30.00) startOffset 14 endOffset 15 width 4.45: "h" - LayoutSVGText {text} at (75,22.67) size 65.70x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.67) size 65.70x9 + chunk 1 text run 2 at (8.41,30.00) startOffset 1 endOffset 2 width 1.78: "i" + chunk 1 text run 3 at (11.14,30.00) startOffset 2 endOffset 3 width 4.45: "n" + chunk 1 text run 4 at (16.55,30.00) startOffset 3 endOffset 4 width 4.45: "e" + chunk 1 text run 5 at (21.96,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (25.14,30.00) startOffset 5 endOffset 6 width 2.22: "t" + chunk 1 text run 7 at (28.32,30.00) startOffset 6 endOffset 7 width 4.45: "o" + chunk 1 text run 8 at (33.73,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (36.91,30.00) startOffset 8 endOffset 9 width 5.34: "S" + chunk 1 text run 10 at (43.20,30.00) startOffset 9 endOffset 10 width 2.22: "t" + chunk 1 text run 11 at (46.38,30.00) startOffset 10 endOffset 11 width 2.66: "r" + chunk 1 text run 12 at (50.00,30.00) startOffset 11 endOffset 12 width 4.45: "e" + chunk 1 text run 13 at (55.41,30.00) startOffset 12 endOffset 13 width 2.22: "t" + chunk 1 text run 14 at (58.59,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.55,30.00) startOffset 14 endOffset 15 width 4.45: "h" + LayoutSVGText {text} at (75,22.67) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.67) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.22: "t" - chunk 1 text run 2 at (76.50,30.00) startOffset 1 endOffset 2 width 4.45: "h" - chunk 1 text run 3 at (80.22,30.00) startOffset 2 endOffset 3 width 1.78: "i" - chunk 1 text run 4 at (81.27,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.54,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (86.04,30.00) startOffset 5 endOffset 6 width 1.78: "i" - chunk 1 text run 7 at (87.09,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.36,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (91.86,30.00) startOffset 8 endOffset 9 width 4.45: "a" - chunk 1 text run 10 at (95.58,30.00) startOffset 9 endOffset 10 width 2.22: " " - chunk 1 text run 11 at (97.08,30.00) startOffset 10 endOffset 11 width 1.78: "l" - chunk 1 text run 12 at (98.13,30.00) startOffset 11 endOffset 12 width 1.78: "i" - chunk 1 text run 13 at (99.18,30.00) startOffset 12 endOffset 13 width 4.45: "n" - chunk 1 text run 14 at (102.90,30.00) startOffset 13 endOffset 14 width 4.45: "e" - chunk 1 text run 15 at (106.63,30.00) startOffset 14 endOffset 15 width 2.22: " " - chunk 1 text run 16 at (108.12,30.00) startOffset 15 endOffset 16 width 2.22: "t" - chunk 1 text run 17 at (109.62,30.00) startOffset 16 endOffset 17 width 4.45: "o" - chunk 1 text run 18 at (113.34,30.00) startOffset 17 endOffset 18 width 2.22: " " - chunk 1 text run 19 at (114.84,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.11,30.00) startOffset 19 endOffset 20 width 4.45: "q" - chunk 1 text run 21 at (121.84,30.00) startOffset 20 endOffset 21 width 4.45: "u" - chunk 1 text run 22 at (125.56,30.00) startOffset 21 endOffset 22 width 4.45: "e" - chunk 1 text run 23 at (129.28,30.00) startOffset 22 endOffset 23 width 4.45: "e" - chunk 1 text run 24 at (133.00,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.28,30.00) startOffset 24 endOffset 25 width 4.45: "e" + chunk 1 text run 2 at (76.47,30.00) startOffset 1 endOffset 2 width 4.45: "h" + chunk 1 text run 3 at (80.16,30.00) startOffset 2 endOffset 3 width 1.78: "i" + chunk 1 text run 4 at (81.18,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.42,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (85.89,30.00) startOffset 5 endOffset 6 width 1.78: "i" + chunk 1 text run 7 at (86.91,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.15,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (91.62,30.00) startOffset 8 endOffset 9 width 4.45: "a" + chunk 1 text run 10 at (95.31,30.00) startOffset 9 endOffset 10 width 2.22: " " + chunk 1 text run 11 at (96.78,30.00) startOffset 10 endOffset 11 width 1.78: "l" + chunk 1 text run 12 at (97.80,30.00) startOffset 11 endOffset 12 width 1.78: "i" + chunk 1 text run 13 at (98.82,30.00) startOffset 12 endOffset 13 width 4.45: "n" + chunk 1 text run 14 at (102.51,30.00) startOffset 13 endOffset 14 width 4.45: "e" + chunk 1 text run 15 at (106.20,30.00) startOffset 14 endOffset 15 width 2.22: " " + chunk 1 text run 16 at (107.67,30.00) startOffset 15 endOffset 16 width 2.22: "t" + chunk 1 text run 17 at (109.14,30.00) startOffset 16 endOffset 17 width 4.45: "o" + chunk 1 text run 18 at (112.83,30.00) startOffset 17 endOffset 18 width 2.22: " " + chunk 1 text run 19 at (114.29,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.54,30.00) startOffset 19 endOffset 20 width 4.45: "q" + chunk 1 text run 21 at (121.23,30.00) startOffset 20 endOffset 21 width 4.45: "u" + chunk 1 text run 22 at (124.92,30.00) startOffset 21 endOffset 22 width 4.45: "e" + chunk 1 text run 23 at (128.61,30.00) startOffset 22 endOffset 23 width 4.45: "e" + chunk 1 text run 24 at (132.31,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.55,30.00) startOffset 24 endOffset 25 width 4.45: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00] @@ -104,51 +104,51 @@ LayoutSVGInlineText {#text} at (76,38.67) size 54.36x6.66 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.37: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.67) size 139x22.66 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,44.00)}] - LayoutSVGContainer {g} at (3,22.67) size 137.70x9 - LayoutSVGText {text} at (3,22.67) size 64.09x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.67) size 64.09x9 + LayoutSVGContainer {g} at (3,22.67) size 136.98x9 + LayoutSVGText {text} at (3,22.67) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.67) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.45: "L" - chunk 1 text run 2 at (8.34,30.00) startOffset 1 endOffset 2 width 1.78: "i" - chunk 1 text run 3 at (11.02,30.00) startOffset 2 endOffset 3 width 4.45: "n" - chunk 1 text run 4 at (16.36,30.00) startOffset 3 endOffset 4 width 4.45: "e" - chunk 1 text run 5 at (21.70,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (24.82,30.00) startOffset 5 endOffset 6 width 2.22: "t" - chunk 1 text run 7 at (27.94,30.00) startOffset 6 endOffset 7 width 4.45: "o" - chunk 1 text run 8 at (33.28,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (36.40,30.00) startOffset 8 endOffset 9 width 5.34: "S" - chunk 1 text run 10 at (42.63,30.00) startOffset 9 endOffset 10 width 2.22: "t" - chunk 1 text run 11 at (45.74,30.00) startOffset 10 endOffset 11 width 2.66: "r" - chunk 1 text run 12 at (49.30,30.00) startOffset 11 endOffset 12 width 4.45: "e" - chunk 1 text run 13 at (54.65,30.00) startOffset 12 endOffset 13 width 2.22: "t" - chunk 1 text run 14 at (57.76,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.66,30.00) startOffset 14 endOffset 15 width 4.45: "h" - LayoutSVGText {text} at (75,22.67) size 65.70x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.67) size 65.70x9 + chunk 1 text run 2 at (8.41,30.00) startOffset 1 endOffset 2 width 1.78: "i" + chunk 1 text run 3 at (11.14,30.00) startOffset 2 endOffset 3 width 4.45: "n" + chunk 1 text run 4 at (16.55,30.00) startOffset 3 endOffset 4 width 4.45: "e" + chunk 1 text run 5 at (21.96,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (25.14,30.00) startOffset 5 endOffset 6 width 2.22: "t" + chunk 1 text run 7 at (28.32,30.00) startOffset 6 endOffset 7 width 4.45: "o" + chunk 1 text run 8 at (33.73,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (36.91,30.00) startOffset 8 endOffset 9 width 5.34: "S" + chunk 1 text run 10 at (43.20,30.00) startOffset 9 endOffset 10 width 2.22: "t" + chunk 1 text run 11 at (46.38,30.00) startOffset 10 endOffset 11 width 2.66: "r" + chunk 1 text run 12 at (50.00,30.00) startOffset 11 endOffset 12 width 4.45: "e" + chunk 1 text run 13 at (55.41,30.00) startOffset 12 endOffset 13 width 2.22: "t" + chunk 1 text run 14 at (58.59,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.55,30.00) startOffset 14 endOffset 15 width 4.45: "h" + LayoutSVGText {text} at (75,22.67) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.67) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.22: "t" - chunk 1 text run 2 at (76.50,30.00) startOffset 1 endOffset 2 width 4.45: "h" - chunk 1 text run 3 at (80.22,30.00) startOffset 2 endOffset 3 width 1.78: "i" - chunk 1 text run 4 at (81.27,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.54,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (86.04,30.00) startOffset 5 endOffset 6 width 1.78: "i" - chunk 1 text run 7 at (87.09,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.36,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (91.86,30.00) startOffset 8 endOffset 9 width 4.45: "a" - chunk 1 text run 10 at (95.58,30.00) startOffset 9 endOffset 10 width 2.22: " " - chunk 1 text run 11 at (97.08,30.00) startOffset 10 endOffset 11 width 1.78: "l" - chunk 1 text run 12 at (98.13,30.00) startOffset 11 endOffset 12 width 1.78: "i" - chunk 1 text run 13 at (99.18,30.00) startOffset 12 endOffset 13 width 4.45: "n" - chunk 1 text run 14 at (102.90,30.00) startOffset 13 endOffset 14 width 4.45: "e" - chunk 1 text run 15 at (106.63,30.00) startOffset 14 endOffset 15 width 2.22: " " - chunk 1 text run 16 at (108.12,30.00) startOffset 15 endOffset 16 width 2.22: "t" - chunk 1 text run 17 at (109.62,30.00) startOffset 16 endOffset 17 width 4.45: "o" - chunk 1 text run 18 at (113.34,30.00) startOffset 17 endOffset 18 width 2.22: " " - chunk 1 text run 19 at (114.84,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.11,30.00) startOffset 19 endOffset 20 width 4.45: "q" - chunk 1 text run 21 at (121.84,30.00) startOffset 20 endOffset 21 width 4.45: "u" - chunk 1 text run 22 at (125.56,30.00) startOffset 21 endOffset 22 width 4.45: "e" - chunk 1 text run 23 at (129.28,30.00) startOffset 22 endOffset 23 width 4.45: "e" - chunk 1 text run 24 at (133.00,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.28,30.00) startOffset 24 endOffset 25 width 4.45: "e" + chunk 1 text run 2 at (76.47,30.00) startOffset 1 endOffset 2 width 4.45: "h" + chunk 1 text run 3 at (80.16,30.00) startOffset 2 endOffset 3 width 1.78: "i" + chunk 1 text run 4 at (81.18,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.42,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (85.89,30.00) startOffset 5 endOffset 6 width 1.78: "i" + chunk 1 text run 7 at (86.91,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.15,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (91.62,30.00) startOffset 8 endOffset 9 width 4.45: "a" + chunk 1 text run 10 at (95.31,30.00) startOffset 9 endOffset 10 width 2.22: " " + chunk 1 text run 11 at (96.78,30.00) startOffset 10 endOffset 11 width 1.78: "l" + chunk 1 text run 12 at (97.80,30.00) startOffset 11 endOffset 12 width 1.78: "i" + chunk 1 text run 13 at (98.82,30.00) startOffset 12 endOffset 13 width 4.45: "n" + chunk 1 text run 14 at (102.51,30.00) startOffset 13 endOffset 14 width 4.45: "e" + chunk 1 text run 15 at (106.20,30.00) startOffset 14 endOffset 15 width 2.22: " " + chunk 1 text run 16 at (107.67,30.00) startOffset 15 endOffset 16 width 2.22: "t" + chunk 1 text run 17 at (109.14,30.00) startOffset 16 endOffset 17 width 4.45: "o" + chunk 1 text run 18 at (112.83,30.00) startOffset 17 endOffset 18 width 2.22: " " + chunk 1 text run 19 at (114.29,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.54,30.00) startOffset 19 endOffset 20 width 4.45: "q" + chunk 1 text run 21 at (121.23,30.00) startOffset 20 endOffset 21 width 4.45: "u" + chunk 1 text run 22 at (124.92,30.00) startOffset 21 endOffset 22 width 4.45: "e" + chunk 1 text run 23 at (128.61,30.00) startOffset 22 endOffset 23 width 4.45: "e" + chunk 1 text run 24 at (132.31,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.55,30.00) startOffset 24 endOffset 25 width 4.45: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.png index be020933..36a636f4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.txt index 9adc28d..e4bce52 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLayout-expected.txt
@@ -49,27 +49,27 @@ LayoutSVGText {text} at (102.80,140) size 244.38x13 contains 1 chunk(s) LayoutSVGInlineText {#text} at (102.80,140) size 244.38x13 chunk 1 (middle anchor) text run 1 at (102.81,150.00) startOffset 0 endOffset 59 width 244.39: "Letter Spacing Adjustment and Explicit Length Specification" - LayoutSVGContainer {g} at (40,158) size 111.31x39 - LayoutSVGText {text} at (40,158) size 111.31x28 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,158) size 111.31x28 + LayoutSVGContainer {g} at (40,158) size 119.98x39 + LayoutSVGText {text} at (40,158) size 119.98x28 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,158) size 119.98x28 chunk 1 text run 1 at (40.00,180.00) startOffset 0 endOffset 1 width 9.34: "s" - chunk 1 text run 2 at (58.01,180.00) startOffset 1 endOffset 2 width 10.65: "a" - chunk 1 text run 3 at (77.33,180.00) startOffset 2 endOffset 3 width 18.67: "m" - chunk 1 text run 4 at (104.67,180.00) startOffset 3 endOffset 4 width 12.00: "p" - chunk 1 text run 5 at (125.34,180.00) startOffset 4 endOffset 5 width 6.67: "l" - chunk 1 text run 6 at (140.68,180.00) startOffset 5 endOffset 6 width 10.65: "e" + chunk 1 text run 2 at (59.74,180.00) startOffset 1 endOffset 2 width 10.65: "a" + chunk 1 text run 3 at (80.80,180.00) startOffset 2 endOffset 3 width 18.67: "m" + chunk 1 text run 4 at (109.87,180.00) startOffset 3 endOffset 4 width 12.00: "p" + chunk 1 text run 5 at (132.28,180.00) startOffset 4 endOffset 5 width 6.67: "l" + chunk 1 text run 6 at (149.35,180.00) startOffset 5 endOffset 6 width 10.65: "e" LayoutSVGText {text} at (40,188) size 57.69x9 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,188) size 57.69x9 chunk 1 text run 1 at (40.00,195.00) startOffset 0 endOffset 16 width 57.70: "textLength=\"120\"" - LayoutSVGContainer {g} at (185,158) size 69.64x39 - LayoutSVGText {text} at (185,158) size 69.64x28 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (185,158) size 69.64x28 + LayoutSVGContainer {g} at (185,158) size 69.98x39 + LayoutSVGText {text} at (185,158) size 69.98x28 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (185,158) size 69.98x28 chunk 1 text run 1 at (185.00,180.00) startOffset 0 endOffset 1 width 9.34: "s" - chunk 1 text run 2 at (194.68,180.00) startOffset 1 endOffset 2 width 10.65: "a" - chunk 1 text run 3 at (205.67,180.00) startOffset 2 endOffset 3 width 18.67: "m" - chunk 1 text run 4 at (224.67,180.00) startOffset 3 endOffset 4 width 12.00: "p" - chunk 1 text run 5 at (237.01,180.00) startOffset 4 endOffset 5 width 6.67: "l" - chunk 1 text run 6 at (244.01,180.00) startOffset 5 endOffset 6 width 10.65: "e" + chunk 1 text run 2 at (194.74,180.00) startOffset 1 endOffset 2 width 10.65: "a" + chunk 1 text run 3 at (205.80,180.00) startOffset 2 endOffset 3 width 18.67: "m" + chunk 1 text run 4 at (224.87,180.00) startOffset 3 endOffset 4 width 12.00: "p" + chunk 1 text run 5 at (237.28,180.00) startOffset 4 endOffset 5 width 6.67: "l" + chunk 1 text run 6 at (244.35,180.00) startOffset 5 endOffset 6 width 10.65: "e" LayoutSVGText {text} at (185,188) size 53.69x9 contains 1 chunk(s) LayoutSVGInlineText {#text} at (185,188) size 53.69x9 chunk 1 text run 1 at (185.00,195.00) startOffset 0 endOffset 15 width 53.70: "textLength=\"70\"" @@ -132,75 +132,75 @@ LayoutSVGText {text} at (172.06,310) size 105.86x13 contains 1 chunk(s) LayoutSVGInlineText {#text} at (172.06,310) size 105.86x13 chunk 1 (middle anchor) text run 1 at (172.07,320.00) startOffset 0 endOffset 23 width 105.85: "Word Spacing Adjustment" - LayoutSVGContainer {g} at (40,337) size 349.17x30 - LayoutSVGText {text} at (40,337) size 349.17x17 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,337) size 349.17x17 + LayoutSVGContainer {g} at (40,337) size 349.98x30 + LayoutSVGText {text} at (40,337) size 349.98x17 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,337) size 349.98x17 chunk 1 text run 1 at (40.00,350.00) startOffset 0 endOffset 1 width 14.16: "W" - chunk 1 text run 2 at (54.38,350.00) startOffset 1 endOffset 2 width 4.17: "i" - chunk 1 text run 3 at (59.36,350.00) startOffset 2 endOffset 3 width 7.50: "d" - chunk 1 text run 4 at (67.67,350.00) startOffset 3 endOffset 4 width 6.66: "e" - chunk 1 text run 5 at (75.14,350.00) startOffset 4 endOffset 5 width 3.75: " " - chunk 1 text run 6 at (124.71,350.00) startOffset 5 endOffset 6 width 5.84: "s" - chunk 1 text run 7 at (131.36,350.00) startOffset 6 endOffset 7 width 6.66: "e" - chunk 1 text run 8 at (138.83,350.00) startOffset 7 endOffset 8 width 7.50: "p" - chunk 1 text run 9 at (147.14,350.00) startOffset 8 endOffset 9 width 6.66: "a" - chunk 1 text run 10 at (154.61,350.00) startOffset 9 endOffset 10 width 5.00: "r" - chunk 1 text run 11 at (160.42,350.00) startOffset 10 endOffset 11 width 6.66: "a" - chunk 1 text run 12 at (167.89,350.00) startOffset 11 endOffset 12 width 4.17: "t" - chunk 1 text run 13 at (172.87,350.00) startOffset 12 endOffset 13 width 4.17: "i" - chunk 1 text run 14 at (177.85,350.00) startOffset 13 endOffset 14 width 7.50: "o" - chunk 1 text run 15 at (186.16,350.00) startOffset 14 endOffset 15 width 7.50: "n" - chunk 1 text run 16 at (194.48,350.00) startOffset 15 endOffset 16 width 3.75: " " - chunk 1 text run 17 at (244.04,350.00) startOffset 16 endOffset 17 width 7.50: "b" - chunk 1 text run 18 at (252.35,350.00) startOffset 17 endOffset 18 width 6.66: "e" - chunk 1 text run 19 at (259.82,350.00) startOffset 18 endOffset 19 width 4.17: "t" - chunk 1 text run 20 at (264.81,350.00) startOffset 19 endOffset 20 width 10.83: "w" - chunk 1 text run 21 at (276.45,350.00) startOffset 20 endOffset 21 width 6.66: "e" - chunk 1 text run 22 at (283.92,350.00) startOffset 21 endOffset 22 width 6.66: "e" - chunk 1 text run 23 at (291.39,350.00) startOffset 22 endOffset 23 width 7.50: "n" - chunk 1 text run 24 at (299.71,350.00) startOffset 23 endOffset 24 width 3.75: " " - chunk 1 text run 25 at (349.27,350.00) startOffset 24 endOffset 25 width 10.83: "w" - chunk 1 text run 26 at (360.91,350.00) startOffset 25 endOffset 26 width 7.50: "o" - chunk 1 text run 27 at (369.23,350.00) startOffset 26 endOffset 27 width 5.00: "r" - chunk 1 text run 28 at (375.04,350.00) startOffset 27 endOffset 28 width 7.50: "d" - chunk 1 text run 29 at (383.35,350.00) startOffset 28 endOffset 29 width 5.84: "s" + chunk 1 text run 2 at (54.41,350.00) startOffset 1 endOffset 2 width 4.17: "i" + chunk 1 text run 3 at (59.42,350.00) startOffset 2 endOffset 3 width 7.50: "d" + chunk 1 text run 4 at (67.76,350.00) startOffset 3 endOffset 4 width 6.66: "e" + chunk 1 text run 5 at (75.26,350.00) startOffset 4 endOffset 5 width 3.75: " " + chunk 1 text run 6 at (124.85,350.00) startOffset 5 endOffset 6 width 5.84: "s" + chunk 1 text run 7 at (131.53,350.00) startOffset 6 endOffset 7 width 6.66: "e" + chunk 1 text run 8 at (139.03,350.00) startOffset 7 endOffset 8 width 7.50: "p" + chunk 1 text run 9 at (147.37,350.00) startOffset 8 endOffset 9 width 6.66: "a" + chunk 1 text run 10 at (154.87,350.00) startOffset 9 endOffset 10 width 5.00: "r" + chunk 1 text run 11 at (160.71,350.00) startOffset 10 endOffset 11 width 6.66: "a" + chunk 1 text run 12 at (168.21,350.00) startOffset 11 endOffset 12 width 4.17: "t" + chunk 1 text run 13 at (173.22,350.00) startOffset 12 endOffset 13 width 4.17: "i" + chunk 1 text run 14 at (178.23,350.00) startOffset 13 endOffset 14 width 7.50: "o" + chunk 1 text run 15 at (186.57,350.00) startOffset 14 endOffset 15 width 7.50: "n" + chunk 1 text run 16 at (194.91,350.00) startOffset 15 endOffset 16 width 3.75: " " + chunk 1 text run 17 at (244.51,350.00) startOffset 16 endOffset 17 width 7.50: "b" + chunk 1 text run 18 at (252.85,350.00) startOffset 17 endOffset 18 width 6.66: "e" + chunk 1 text run 19 at (260.35,350.00) startOffset 18 endOffset 19 width 4.17: "t" + chunk 1 text run 20 at (265.36,350.00) startOffset 19 endOffset 20 width 10.83: "w" + chunk 1 text run 21 at (277.03,350.00) startOffset 20 endOffset 21 width 6.66: "e" + chunk 1 text run 22 at (284.53,350.00) startOffset 21 endOffset 22 width 6.66: "e" + chunk 1 text run 23 at (292.03,350.00) startOffset 22 endOffset 23 width 7.50: "n" + chunk 1 text run 24 at (300.37,350.00) startOffset 23 endOffset 24 width 3.75: " " + chunk 1 text run 25 at (349.97,350.00) startOffset 24 endOffset 25 width 10.83: "w" + chunk 1 text run 26 at (361.64,350.00) startOffset 25 endOffset 26 width 7.50: "o" + chunk 1 text run 27 at (369.98,350.00) startOffset 26 endOffset 27 width 5.00: "r" + chunk 1 text run 28 at (375.82,350.00) startOffset 27 endOffset 28 width 7.50: "d" + chunk 1 text run 29 at (384.16,350.00) startOffset 28 endOffset 29 width 5.84: "s" LayoutSVGText {text} at (40,358) size 128.05x9 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,358) size 128.05x9 chunk 1 text run 1 at (40.00,365.00) startOffset 0 endOffset 35 width 128.06: "textLength=\"350\" word-spacing=\"3em\"" - LayoutSVGContainer {g} at (40,382) size 344.83x30 - LayoutSVGText {text} at (40,382) size 344.83x17 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,382) size 344.83x17 + LayoutSVGContainer {g} at (40,382) size 349.98x30 + LayoutSVGText {text} at (40,382) size 349.98x17 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,382) size 349.98x17 chunk 1 text run 1 at (40.00,395.00) startOffset 0 endOffset 1 width 10.83: "N" - chunk 1 text run 2 at (55.98,395.00) startOffset 1 endOffset 2 width 6.66: "a" - chunk 1 text run 3 at (67.79,395.00) startOffset 2 endOffset 3 width 5.00: "r" - chunk 1 text run 4 at (77.94,395.00) startOffset 3 endOffset 4 width 5.00: "r" - chunk 1 text run 5 at (88.08,395.00) startOffset 4 endOffset 5 width 7.50: "o" - chunk 1 text run 6 at (100.73,395.00) startOffset 5 endOffset 6 width 10.83: "w" - chunk 1 text run 7 at (116.71,395.00) startOffset 6 endOffset 7 width 3.75: " " - chunk 1 text run 8 at (120.61,395.00) startOffset 7 endOffset 8 width 5.84: "s" - chunk 1 text run 9 at (131.60,395.00) startOffset 8 endOffset 9 width 6.66: "e" - chunk 1 text run 10 at (143.41,395.00) startOffset 9 endOffset 10 width 7.50: "p" - chunk 1 text run 11 at (156.06,395.00) startOffset 10 endOffset 11 width 6.66: "a" - chunk 1 text run 12 at (167.87,395.00) startOffset 11 endOffset 12 width 5.00: "r" - chunk 1 text run 13 at (178.01,395.00) startOffset 12 endOffset 13 width 6.66: "a" - chunk 1 text run 14 at (189.82,395.00) startOffset 13 endOffset 14 width 4.17: "t" - chunk 1 text run 15 at (199.14,395.00) startOffset 14 endOffset 15 width 4.17: "i" - chunk 1 text run 16 at (208.46,395.00) startOffset 15 endOffset 16 width 7.50: "o" - chunk 1 text run 17 at (221.11,395.00) startOffset 16 endOffset 17 width 7.50: "n" - chunk 1 text run 18 at (233.76,395.00) startOffset 17 endOffset 18 width 3.75: " " - chunk 1 text run 19 at (237.66,395.00) startOffset 18 endOffset 19 width 7.50: "b" - chunk 1 text run 20 at (250.31,395.00) startOffset 19 endOffset 20 width 6.66: "e" - chunk 1 text run 21 at (262.12,395.00) startOffset 20 endOffset 21 width 4.17: "t" - chunk 1 text run 22 at (271.43,395.00) startOffset 21 endOffset 22 width 10.83: "w" - chunk 1 text run 23 at (287.42,395.00) startOffset 22 endOffset 23 width 6.66: "e" - chunk 1 text run 24 at (299.23,395.00) startOffset 23 endOffset 24 width 6.66: "e" - chunk 1 text run 25 at (311.03,395.00) startOffset 24 endOffset 25 width 7.50: "n" - chunk 1 text run 26 at (323.68,395.00) startOffset 25 endOffset 26 width 3.75: " " - chunk 1 text run 27 at (327.58,395.00) startOffset 26 endOffset 27 width 10.83: "w" - chunk 1 text run 28 at (343.57,395.00) startOffset 27 endOffset 28 width 7.50: "o" - chunk 1 text run 29 at (356.22,395.00) startOffset 28 endOffset 29 width 5.00: "r" - chunk 1 text run 30 at (366.36,395.00) startOffset 29 endOffset 30 width 7.50: "d" - chunk 1 text run 31 at (379.01,395.00) startOffset 30 endOffset 31 width 5.84: "s" + chunk 1 text run 2 at (56.15,395.00) startOffset 1 endOffset 2 width 6.66: "a" + chunk 1 text run 3 at (68.13,395.00) startOffset 2 endOffset 3 width 5.00: "r" + chunk 1 text run 4 at (78.45,395.00) startOffset 3 endOffset 4 width 5.00: "r" + chunk 1 text run 5 at (88.77,395.00) startOffset 4 endOffset 5 width 7.50: "o" + chunk 1 text run 6 at (101.59,395.00) startOffset 5 endOffset 6 width 10.83: "w" + chunk 1 text run 7 at (117.74,395.00) startOffset 6 endOffset 7 width 3.75: " " + chunk 1 text run 8 at (121.82,395.00) startOffset 7 endOffset 8 width 5.84: "s" + chunk 1 text run 9 at (132.98,395.00) startOffset 8 endOffset 9 width 6.66: "e" + chunk 1 text run 10 at (144.96,395.00) startOffset 9 endOffset 10 width 7.50: "p" + chunk 1 text run 11 at (157.78,395.00) startOffset 10 endOffset 11 width 6.66: "a" + chunk 1 text run 12 at (169.76,395.00) startOffset 11 endOffset 12 width 5.00: "r" + chunk 1 text run 13 at (180.07,395.00) startOffset 12 endOffset 13 width 6.66: "a" + chunk 1 text run 14 at (192.05,395.00) startOffset 13 endOffset 14 width 4.17: "t" + chunk 1 text run 15 at (201.54,395.00) startOffset 14 endOffset 15 width 4.17: "i" + chunk 1 text run 16 at (211.03,395.00) startOffset 15 endOffset 16 width 7.50: "o" + chunk 1 text run 17 at (223.85,395.00) startOffset 16 endOffset 17 width 7.50: "n" + chunk 1 text run 18 at (236.68,395.00) startOffset 17 endOffset 18 width 3.75: " " + chunk 1 text run 19 at (240.75,395.00) startOffset 18 endOffset 19 width 7.50: "b" + chunk 1 text run 20 at (253.57,395.00) startOffset 19 endOffset 20 width 6.66: "e" + chunk 1 text run 21 at (265.55,395.00) startOffset 20 endOffset 21 width 4.17: "t" + chunk 1 text run 22 at (275.04,395.00) startOffset 21 endOffset 22 width 10.83: "w" + chunk 1 text run 23 at (291.19,395.00) startOffset 22 endOffset 23 width 6.66: "e" + chunk 1 text run 24 at (303.17,395.00) startOffset 23 endOffset 24 width 6.66: "e" + chunk 1 text run 25 at (315.15,395.00) startOffset 24 endOffset 25 width 7.50: "n" + chunk 1 text run 26 at (327.98,395.00) startOffset 25 endOffset 26 width 3.75: " " + chunk 1 text run 27 at (332.05,395.00) startOffset 26 endOffset 27 width 10.83: "w" + chunk 1 text run 28 at (348.20,395.00) startOffset 27 endOffset 28 width 7.50: "o" + chunk 1 text run 29 at (361.02,395.00) startOffset 28 endOffset 29 width 5.00: "r" + chunk 1 text run 30 at (371.34,395.00) startOffset 29 endOffset 30 width 7.50: "d" + chunk 1 text run 31 at (384.16,395.00) startOffset 30 endOffset 31 width 5.84: "s" LayoutSVGText {text} at (40,403) size 120.94x9 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,403) size 120.94x9 chunk 1 text run 1 at (40.00,410.00) startOffset 0 endOffset 34 width 120.95: "textLength=\"350\" word-spacing=\"-5\""
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.png index b6aa487b..c6e464fd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.txt index c6b0c37..8d02ecc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textLength-expected.txt
@@ -86,13 +86,13 @@ LayoutSVGContainer {g} at (200,3) size 50x24 LayoutSVGRect {rect} at (200,5) size 50x20 [fill={[type=SOLID] [color=#DDE8FF]}] [x=200.00] [y=5.00] [width=50.00] [height=20.00] LayoutSVGPath {line} at (225,3) size 0x24 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=225.00] [y1=3.00] [x2=225.00] [y2=27.00] - LayoutSVGText {text} at (202.39,8) size 45.20x14 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (202.39,8) size 45.20x14 - chunk 1 (middle anchor) text run 1 at (202.40,19.00) startOffset 0 endOffset 1 width 8.00: "B" - chunk 1 (middle anchor) text run 2 at (215.20,19.00) startOffset 1 endOffset 2 width 5.33: "a" + LayoutSVGText {text} at (200,8) size 50x14 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (200,8) size 50x14 + chunk 1 (middle anchor) text run 1 at (200.00,19.00) startOffset 0 endOffset 1 width 8.00: "B" + chunk 1 (middle anchor) text run 2 at (214.00,19.00) startOffset 1 endOffset 2 width 5.33: "a" chunk 1 (middle anchor) text run 3 at (225.33,19.00) startOffset 2 endOffset 3 width 3.33: "t" - chunk 1 (middle anchor) text run 4 at (233.47,19.00) startOffset 3 endOffset 4 width 3.33: "i" - chunk 1 (middle anchor) text run 5 at (241.60,19.00) startOffset 4 endOffset 5 width 6.00: "k" + chunk 1 (middle anchor) text run 4 at (234.67,19.00) startOffset 3 endOffset 4 width 3.33: "i" + chunk 1 (middle anchor) text run 5 at (244.00,19.00) startOffset 4 endOffset 5 width 6.00: "k" LayoutSVGText {text} at (125.61,29) size 198.77x14 contains 1 chunk(s) LayoutSVGInlineText {#text} at (125.61,29) size 198.77x14 chunk 1 (middle anchor) text run 1 at (125.62,40.00) startOffset 0 endOffset 38 width 198.77: "textLength=\"50\" lengthAdjust=\"spacing\""
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png index 9e59513..1edf27b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png index 9e59513..1edf27b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.png index 103da34..cefdaec1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.txt new file mode 100644 index 0000000..da8cea7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-1-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (10,1) size 12.46x11.20 + LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] + LayoutSVGPath {svg:line} at (22.46,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=22.46] [y1=1.00] [x2=22.46] [y2=12.20] + LayoutSVGRect {svg:rect} at (10,1) size 12.46x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=12.46] [height=11.20] + LayoutSVGText {text} at (10,1) size 49.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 49.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (13.45,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (17.46,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.91,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (22.14,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (23.36,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (24.59,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (28.60,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (29.83,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (34.95,10.00) startOffset 9 endOffset 10 width 5.56: "q" + chunk 1 text run 11 at (38.96,10.00) startOffset 10 endOffset 11 width 5.56: "u" + chunk 1 text run 12 at (42.97,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (46.98,10.00) startOffset 12 endOffset 13 width 5.56: "e" + chunk 1 text run 14 at (50.99,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.44,10.00) startOffset 14 endOffset 15 width 5.56: "e" +selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 3 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.png index ac51162..077488e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.txt new file mode 100644 index 0000000..f8fac91e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-2-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (29.83,1) size 10.68x11.20 + LayoutSVGPath {svg:line} at (29.83,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=29.83] [y1=1.00] [x2=29.83] [y2=12.20] + LayoutSVGPath {svg:line} at (40.51,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=40.51] [y1=1.00] [x2=40.51] [y2=12.20] + LayoutSVGRect {svg:rect} at (29.83,1) size 10.68x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=29.83] [y=1.00] [width=10.68] [height=11.20] + LayoutSVGText {text} at (10,1) size 49.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 49.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (13.45,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (17.46,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.91,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (22.14,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (23.36,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (24.59,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (28.60,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (29.83,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (34.95,10.00) startOffset 9 endOffset 10 width 5.56: "q" + chunk 1 text run 11 at (38.96,10.00) startOffset 10 endOffset 11 width 5.56: "u" + chunk 1 text run 12 at (42.97,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (46.98,10.00) startOffset 12 endOffset 13 width 5.56: "e" + chunk 1 text run 14 at (50.99,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.44,10.00) startOffset 14 endOffset 15 width 5.56: "e" +selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 10 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.png index fc2a3534..d48b3e8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.txt new file mode 100644 index 0000000..b94a8ff --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-3-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (29.83,1) size 14.69x11.20 + LayoutSVGPath {svg:line} at (29.83,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=29.83] [y1=1.00] [x2=29.83] [y2=12.20] + LayoutSVGPath {svg:line} at (44.52,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=44.52] [y1=1.00] [x2=44.52] [y2=12.20] + LayoutSVGRect {svg:rect} at (29.83,1) size 14.69x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=29.83] [y=1.00] [width=14.69] [height=11.20] + LayoutSVGText {text} at (10,1) size 49.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 49.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (13.45,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (17.46,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.91,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (22.14,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (23.36,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (24.59,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (28.60,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (29.83,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (34.95,10.00) startOffset 9 endOffset 10 width 5.56: "q" + chunk 1 text run 11 at (38.96,10.00) startOffset 10 endOffset 11 width 5.56: "u" + chunk 1 text run 12 at (42.97,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (46.98,10.00) startOffset 12 endOffset 13 width 5.56: "e" + chunk 1 text run 14 at (50.99,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.44,10.00) startOffset 14 endOffset 15 width 5.56: "e" +selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.png index c49bd58..a622cd6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.txt new file mode 100644 index 0000000..018289c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-squeeze-4-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (10,1) size 50x11.20 + LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] + LayoutSVGPath {svg:line} at (60,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=60.00] [y1=1.00] [x2=60.00] [y2=12.20] + LayoutSVGRect {svg:rect} at (10,1) size 50x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=50.00] [height=11.20] + LayoutSVGText {text} at (10,1) size 49.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 49.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (13.45,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (17.46,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (20.91,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (22.14,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (23.36,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (24.59,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (28.60,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (29.83,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (34.95,10.00) startOffset 9 endOffset 10 width 5.56: "q" + chunk 1 text run 11 at (38.96,10.00) startOffset 10 endOffset 11 width 5.56: "u" + chunk 1 text run 12 at (42.97,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (46.98,10.00) startOffset 12 endOffset 13 width 5.56: "e" + chunk 1 text run 14 at (50.99,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.44,10.00) startOffset 14 endOffset 15 width 5.56: "e" +selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.png index 89764d3..8d50aa8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.txt new file mode 100644 index 0000000..036a8f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-1-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (10,1) size 36.79x11.20 + LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] + LayoutSVGPath {svg:line} at (46.79,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=46.79] [y1=1.00] [x2=46.79] [y2=12.20] + LayoutSVGRect {svg:rect} at (10,1) size 36.79x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=36.79] [height=11.20] + LayoutSVGText {text} at (10,1) size 149.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 149.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (21.15,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (32.86,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.01,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (52.94,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (61.86,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (70.79,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (82.50,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (91.43,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (104.25,10.00) startOffset 9 endOffset 10 width 2.78: "t" + chunk 1 text run 11 at (113.17,10.00) startOffset 10 endOffset 11 width 3.33: "r" + chunk 1 text run 12 at (122.65,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.78: "t" + chunk 1 text run 14 at (143.29,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.44,10.00) startOffset 14 endOffset 15 width 5.56: "h" +selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 4 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.png index 8894671..0ba412e7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.txt new file mode 100644 index 0000000..df6d37b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-2-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (61.86,1) size 14.49x11.20 + LayoutSVGPath {svg:line} at (61.86,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=61.86] [y1=1.00] [x2=61.86] [y2=12.20] + LayoutSVGPath {svg:line} at (76.35,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=76.35] [y1=1.00] [x2=76.35] [y2=12.20] + LayoutSVGRect {svg:rect} at (61.86,1) size 14.49x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=61.86] [y=1.00] [width=14.49] [height=11.20] + LayoutSVGText {text} at (10,1) size 149.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 149.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (21.15,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (32.86,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.01,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (52.94,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (61.86,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (70.79,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (82.50,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (91.43,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (104.25,10.00) startOffset 9 endOffset 10 width 2.78: "t" + chunk 1 text run 11 at (113.17,10.00) startOffset 10 endOffset 11 width 3.33: "r" + chunk 1 text run 12 at (122.65,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.78: "t" + chunk 1 text run 14 at (143.29,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.44,10.00) startOffset 14 endOffset 15 width 5.56: "h" +selection start: position 5 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 7 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.png index 88dee7a..0a0bb943 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.txt new file mode 100644 index 0000000..994d7a8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-3-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (91.43,1) size 25.08x11.20 + LayoutSVGPath {svg:line} at (91.43,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=91.43] [y1=1.00] [x2=91.43] [y2=12.20] + LayoutSVGPath {svg:line} at (116.50,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=116.50] [y1=1.00] [x2=116.50] [y2=12.20] + LayoutSVGRect {svg:rect} at (91.43,1) size 25.08x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=91.43] [y=1.00] [width=25.08] [height=11.20] + LayoutSVGText {text} at (10,1) size 149.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 149.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (21.15,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (32.86,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.01,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (52.94,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (61.86,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (70.79,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (82.50,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (91.43,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (104.25,10.00) startOffset 9 endOffset 10 width 2.78: "t" + chunk 1 text run 11 at (113.17,10.00) startOffset 10 endOffset 11 width 3.33: "r" + chunk 1 text run 12 at (122.65,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.78: "t" + chunk 1 text run 14 at (143.29,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.44,10.00) startOffset 14 endOffset 15 width 5.56: "h" +selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.png index 0b583828..de1c0b9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.txt new file mode 100644 index 0000000..1ac91a3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/select-textLength-spacing-stretch-4-expected.txt
@@ -0,0 +1,27 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutSVGRoot {svg} at (0,0) size 800x600 + LayoutSVGContainer {g} at (10,1) size 150x11.20 + LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] + LayoutSVGPath {svg:line} at (160,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=160.00] [y1=1.00] [x2=160.00] [y2=12.20] + LayoutSVGRect {svg:rect} at (10,1) size 150x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=150.00] [height=11.20] + LayoutSVGText {text} at (10,1) size 149.98x11.19 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,1) size 149.98x11.19 + chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" + chunk 1 text run 2 at (21.15,10.00) startOffset 1 endOffset 2 width 5.56: "e" + chunk 1 text run 3 at (32.86,10.00) startOffset 2 endOffset 3 width 5.00: "x" + chunk 1 text run 4 at (44.01,10.00) startOffset 3 endOffset 4 width 2.78: "t" + chunk 1 text run 5 at (52.94,10.00) startOffset 4 endOffset 5 width 2.78: " " + chunk 1 text run 6 at (61.86,10.00) startOffset 5 endOffset 6 width 2.78: "t" + chunk 1 text run 7 at (70.79,10.00) startOffset 6 endOffset 7 width 5.56: "o" + chunk 1 text run 8 at (82.50,10.00) startOffset 7 endOffset 8 width 2.78: " " + chunk 1 text run 9 at (91.43,10.00) startOffset 8 endOffset 9 width 6.67: "S" + chunk 1 text run 10 at (104.25,10.00) startOffset 9 endOffset 10 width 2.78: "t" + chunk 1 text run 11 at (113.17,10.00) startOffset 10 endOffset 11 width 3.33: "r" + chunk 1 text run 12 at (122.65,10.00) startOffset 11 endOffset 12 width 5.56: "e" + chunk 1 text run 13 at (134.36,10.00) startOffset 12 endOffset 13 width 2.78: "t" + chunk 1 text run 14 at (143.29,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.44,10.00) startOffset 14 endOffset 15 width 5.56: "h" +selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document +selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.png index c84f7c1..d2374c8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.txt index 4ff58a1..4b68434 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-selection-text-01-b-expected.txt
@@ -38,51 +38,51 @@ LayoutSVGInlineText {#text} at (76,38.61) size 54.36x6.66 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.37: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.81) size 139x22.45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,22.00)}] - LayoutSVGContainer {g} at (3,22.81) size 137.70x8.80 - LayoutSVGText {text} at (3,22.81) size 64.09x8.80 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.81) size 64.09x8.80 + LayoutSVGContainer {g} at (3,22.81) size 136.98x8.80 + LayoutSVGText {text} at (3,22.81) size 64.98x8.80 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.81) size 64.98x8.80 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.45: "L" - chunk 1 text run 2 at (8.34,30.00) startOffset 1 endOffset 2 width 1.78: "i" - chunk 1 text run 3 at (11.02,30.00) startOffset 2 endOffset 3 width 4.45: "n" - chunk 1 text run 4 at (16.36,30.00) startOffset 3 endOffset 4 width 4.45: "e" - chunk 1 text run 5 at (21.70,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (24.82,30.00) startOffset 5 endOffset 6 width 2.22: "t" - chunk 1 text run 7 at (27.94,30.00) startOffset 6 endOffset 7 width 4.45: "o" - chunk 1 text run 8 at (33.28,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (36.40,30.00) startOffset 8 endOffset 9 width 5.34: "S" - chunk 1 text run 10 at (42.63,30.00) startOffset 9 endOffset 10 width 2.22: "t" - chunk 1 text run 11 at (45.74,30.00) startOffset 10 endOffset 11 width 2.66: "r" - chunk 1 text run 12 at (49.30,30.00) startOffset 11 endOffset 12 width 4.45: "e" - chunk 1 text run 13 at (54.65,30.00) startOffset 12 endOffset 13 width 2.22: "t" - chunk 1 text run 14 at (57.76,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.66,30.00) startOffset 14 endOffset 15 width 4.45: "h" - LayoutSVGText {text} at (75,22.81) size 65.70x8.80 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.81) size 65.70x8.80 + chunk 1 text run 2 at (8.41,30.00) startOffset 1 endOffset 2 width 1.78: "i" + chunk 1 text run 3 at (11.14,30.00) startOffset 2 endOffset 3 width 4.45: "n" + chunk 1 text run 4 at (16.55,30.00) startOffset 3 endOffset 4 width 4.45: "e" + chunk 1 text run 5 at (21.96,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (25.14,30.00) startOffset 5 endOffset 6 width 2.22: "t" + chunk 1 text run 7 at (28.32,30.00) startOffset 6 endOffset 7 width 4.45: "o" + chunk 1 text run 8 at (33.73,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (36.91,30.00) startOffset 8 endOffset 9 width 5.34: "S" + chunk 1 text run 10 at (43.20,30.00) startOffset 9 endOffset 10 width 2.22: "t" + chunk 1 text run 11 at (46.38,30.00) startOffset 10 endOffset 11 width 2.66: "r" + chunk 1 text run 12 at (50.00,30.00) startOffset 11 endOffset 12 width 4.45: "e" + chunk 1 text run 13 at (55.41,30.00) startOffset 12 endOffset 13 width 2.22: "t" + chunk 1 text run 14 at (58.59,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.55,30.00) startOffset 14 endOffset 15 width 4.45: "h" + LayoutSVGText {text} at (75,22.81) size 64.98x8.80 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.81) size 64.98x8.80 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.22: "t" - chunk 1 text run 2 at (76.50,30.00) startOffset 1 endOffset 2 width 4.45: "h" - chunk 1 text run 3 at (80.22,30.00) startOffset 2 endOffset 3 width 1.78: "i" - chunk 1 text run 4 at (81.27,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.54,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (86.04,30.00) startOffset 5 endOffset 6 width 1.78: "i" - chunk 1 text run 7 at (87.09,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.36,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (91.86,30.00) startOffset 8 endOffset 9 width 4.45: "a" - chunk 1 text run 10 at (95.58,30.00) startOffset 9 endOffset 10 width 2.22: " " - chunk 1 text run 11 at (97.08,30.00) startOffset 10 endOffset 11 width 1.78: "l" - chunk 1 text run 12 at (98.13,30.00) startOffset 11 endOffset 12 width 1.78: "i" - chunk 1 text run 13 at (99.18,30.00) startOffset 12 endOffset 13 width 4.45: "n" - chunk 1 text run 14 at (102.90,30.00) startOffset 13 endOffset 14 width 4.45: "e" - chunk 1 text run 15 at (106.63,30.00) startOffset 14 endOffset 15 width 2.22: " " - chunk 1 text run 16 at (108.12,30.00) startOffset 15 endOffset 16 width 2.22: "t" - chunk 1 text run 17 at (109.62,30.00) startOffset 16 endOffset 17 width 4.45: "o" - chunk 1 text run 18 at (113.34,30.00) startOffset 17 endOffset 18 width 2.22: " " - chunk 1 text run 19 at (114.84,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.11,30.00) startOffset 19 endOffset 20 width 4.45: "q" - chunk 1 text run 21 at (121.84,30.00) startOffset 20 endOffset 21 width 4.45: "u" - chunk 1 text run 22 at (125.56,30.00) startOffset 21 endOffset 22 width 4.45: "e" - chunk 1 text run 23 at (129.28,30.00) startOffset 22 endOffset 23 width 4.45: "e" - chunk 1 text run 24 at (133.00,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.28,30.00) startOffset 24 endOffset 25 width 4.45: "e" + chunk 1 text run 2 at (76.47,30.00) startOffset 1 endOffset 2 width 4.45: "h" + chunk 1 text run 3 at (80.16,30.00) startOffset 2 endOffset 3 width 1.78: "i" + chunk 1 text run 4 at (81.18,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.42,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (85.89,30.00) startOffset 5 endOffset 6 width 1.78: "i" + chunk 1 text run 7 at (86.91,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.15,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (91.62,30.00) startOffset 8 endOffset 9 width 4.45: "a" + chunk 1 text run 10 at (95.31,30.00) startOffset 9 endOffset 10 width 2.22: " " + chunk 1 text run 11 at (96.78,30.00) startOffset 10 endOffset 11 width 1.78: "l" + chunk 1 text run 12 at (97.80,30.00) startOffset 11 endOffset 12 width 1.78: "i" + chunk 1 text run 13 at (98.82,30.00) startOffset 12 endOffset 13 width 4.45: "n" + chunk 1 text run 14 at (102.51,30.00) startOffset 13 endOffset 14 width 4.45: "e" + chunk 1 text run 15 at (106.20,30.00) startOffset 14 endOffset 15 width 2.22: " " + chunk 1 text run 16 at (107.67,30.00) startOffset 15 endOffset 16 width 2.22: "t" + chunk 1 text run 17 at (109.14,30.00) startOffset 16 endOffset 17 width 4.45: "o" + chunk 1 text run 18 at (112.83,30.00) startOffset 17 endOffset 18 width 2.22: " " + chunk 1 text run 19 at (114.29,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.54,30.00) startOffset 19 endOffset 20 width 4.45: "q" + chunk 1 text run 21 at (121.23,30.00) startOffset 20 endOffset 21 width 4.45: "u" + chunk 1 text run 22 at (124.92,30.00) startOffset 21 endOffset 22 width 4.45: "e" + chunk 1 text run 23 at (128.61,30.00) startOffset 22 endOffset 23 width 4.45: "e" + chunk 1 text run 24 at (132.31,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.55,30.00) startOffset 24 endOffset 25 width 4.45: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00] @@ -104,51 +104,51 @@ LayoutSVGInlineText {#text} at (76,38.61) size 54.36x6.66 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.37: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.81) size 139x22.45 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,44.00)}] - LayoutSVGContainer {g} at (3,22.81) size 137.70x8.80 - LayoutSVGText {text} at (3,22.81) size 64.09x8.80 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.81) size 64.09x8.80 + LayoutSVGContainer {g} at (3,22.81) size 136.98x8.80 + LayoutSVGText {text} at (3,22.81) size 64.98x8.80 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.81) size 64.98x8.80 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.45: "L" - chunk 1 text run 2 at (8.34,30.00) startOffset 1 endOffset 2 width 1.78: "i" - chunk 1 text run 3 at (11.02,30.00) startOffset 2 endOffset 3 width 4.45: "n" - chunk 1 text run 4 at (16.36,30.00) startOffset 3 endOffset 4 width 4.45: "e" - chunk 1 text run 5 at (21.70,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (24.82,30.00) startOffset 5 endOffset 6 width 2.22: "t" - chunk 1 text run 7 at (27.94,30.00) startOffset 6 endOffset 7 width 4.45: "o" - chunk 1 text run 8 at (33.28,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (36.40,30.00) startOffset 8 endOffset 9 width 5.34: "S" - chunk 1 text run 10 at (42.63,30.00) startOffset 9 endOffset 10 width 2.22: "t" - chunk 1 text run 11 at (45.74,30.00) startOffset 10 endOffset 11 width 2.66: "r" - chunk 1 text run 12 at (49.30,30.00) startOffset 11 endOffset 12 width 4.45: "e" - chunk 1 text run 13 at (54.65,30.00) startOffset 12 endOffset 13 width 2.22: "t" - chunk 1 text run 14 at (57.76,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.66,30.00) startOffset 14 endOffset 15 width 4.45: "h" - LayoutSVGText {text} at (75,22.81) size 65.70x8.80 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.81) size 65.70x8.80 + chunk 1 text run 2 at (8.41,30.00) startOffset 1 endOffset 2 width 1.78: "i" + chunk 1 text run 3 at (11.14,30.00) startOffset 2 endOffset 3 width 4.45: "n" + chunk 1 text run 4 at (16.55,30.00) startOffset 3 endOffset 4 width 4.45: "e" + chunk 1 text run 5 at (21.96,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (25.14,30.00) startOffset 5 endOffset 6 width 2.22: "t" + chunk 1 text run 7 at (28.32,30.00) startOffset 6 endOffset 7 width 4.45: "o" + chunk 1 text run 8 at (33.73,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (36.91,30.00) startOffset 8 endOffset 9 width 5.34: "S" + chunk 1 text run 10 at (43.20,30.00) startOffset 9 endOffset 10 width 2.22: "t" + chunk 1 text run 11 at (46.38,30.00) startOffset 10 endOffset 11 width 2.66: "r" + chunk 1 text run 12 at (50.00,30.00) startOffset 11 endOffset 12 width 4.45: "e" + chunk 1 text run 13 at (55.41,30.00) startOffset 12 endOffset 13 width 2.22: "t" + chunk 1 text run 14 at (58.59,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.55,30.00) startOffset 14 endOffset 15 width 4.45: "h" + LayoutSVGText {text} at (75,22.81) size 64.98x8.80 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.81) size 64.98x8.80 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.22: "t" - chunk 1 text run 2 at (76.50,30.00) startOffset 1 endOffset 2 width 4.45: "h" - chunk 1 text run 3 at (80.22,30.00) startOffset 2 endOffset 3 width 1.78: "i" - chunk 1 text run 4 at (81.27,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.54,30.00) startOffset 4 endOffset 5 width 2.22: " " - chunk 1 text run 6 at (86.04,30.00) startOffset 5 endOffset 6 width 1.78: "i" - chunk 1 text run 7 at (87.09,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.36,30.00) startOffset 7 endOffset 8 width 2.22: " " - chunk 1 text run 9 at (91.86,30.00) startOffset 8 endOffset 9 width 4.45: "a" - chunk 1 text run 10 at (95.58,30.00) startOffset 9 endOffset 10 width 2.22: " " - chunk 1 text run 11 at (97.08,30.00) startOffset 10 endOffset 11 width 1.78: "l" - chunk 1 text run 12 at (98.13,30.00) startOffset 11 endOffset 12 width 1.78: "i" - chunk 1 text run 13 at (99.18,30.00) startOffset 12 endOffset 13 width 4.45: "n" - chunk 1 text run 14 at (102.90,30.00) startOffset 13 endOffset 14 width 4.45: "e" - chunk 1 text run 15 at (106.63,30.00) startOffset 14 endOffset 15 width 2.22: " " - chunk 1 text run 16 at (108.12,30.00) startOffset 15 endOffset 16 width 2.22: "t" - chunk 1 text run 17 at (109.62,30.00) startOffset 16 endOffset 17 width 4.45: "o" - chunk 1 text run 18 at (113.34,30.00) startOffset 17 endOffset 18 width 2.22: " " - chunk 1 text run 19 at (114.84,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.11,30.00) startOffset 19 endOffset 20 width 4.45: "q" - chunk 1 text run 21 at (121.84,30.00) startOffset 20 endOffset 21 width 4.45: "u" - chunk 1 text run 22 at (125.56,30.00) startOffset 21 endOffset 22 width 4.45: "e" - chunk 1 text run 23 at (129.28,30.00) startOffset 22 endOffset 23 width 4.45: "e" - chunk 1 text run 24 at (133.00,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.28,30.00) startOffset 24 endOffset 25 width 4.45: "e" + chunk 1 text run 2 at (76.47,30.00) startOffset 1 endOffset 2 width 4.45: "h" + chunk 1 text run 3 at (80.16,30.00) startOffset 2 endOffset 3 width 1.78: "i" + chunk 1 text run 4 at (81.18,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.42,30.00) startOffset 4 endOffset 5 width 2.22: " " + chunk 1 text run 6 at (85.89,30.00) startOffset 5 endOffset 6 width 1.78: "i" + chunk 1 text run 7 at (86.91,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.15,30.00) startOffset 7 endOffset 8 width 2.22: " " + chunk 1 text run 9 at (91.62,30.00) startOffset 8 endOffset 9 width 4.45: "a" + chunk 1 text run 10 at (95.31,30.00) startOffset 9 endOffset 10 width 2.22: " " + chunk 1 text run 11 at (96.78,30.00) startOffset 10 endOffset 11 width 1.78: "l" + chunk 1 text run 12 at (97.80,30.00) startOffset 11 endOffset 12 width 1.78: "i" + chunk 1 text run 13 at (98.82,30.00) startOffset 12 endOffset 13 width 4.45: "n" + chunk 1 text run 14 at (102.51,30.00) startOffset 13 endOffset 14 width 4.45: "e" + chunk 1 text run 15 at (106.20,30.00) startOffset 14 endOffset 15 width 2.22: " " + chunk 1 text run 16 at (107.67,30.00) startOffset 15 endOffset 16 width 2.22: "t" + chunk 1 text run 17 at (109.14,30.00) startOffset 16 endOffset 17 width 4.45: "o" + chunk 1 text run 18 at (112.83,30.00) startOffset 17 endOffset 18 width 2.22: " " + chunk 1 text run 19 at (114.29,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.54,30.00) startOffset 19 endOffset 20 width 4.45: "q" + chunk 1 text run 21 at (121.23,30.00) startOffset 20 endOffset 21 width 4.45: "u" + chunk 1 text run 22 at (124.92,30.00) startOffset 21 endOffset 22 width 4.45: "e" + chunk 1 text run 23 at (128.61,30.00) startOffset 22 endOffset 23 width 4.45: "e" + chunk 1 text run 24 at (132.31,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.55,30.00) startOffset 24 endOffset 25 width 4.45: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00]
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.png index f05e936..44a2f75 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.txt index 35c6c7d..e657cd0 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/text-text-01-b-expected.txt
@@ -38,51 +38,51 @@ LayoutSVGInlineText {#text} at (76,38.34) size 54x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.00: "lengthAdjust: default" LayoutSVGContainer {g} at (2,23) size 139x22.34 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,22.00)}] - LayoutSVGContainer {g} at (3,23) size 137.75x9 - LayoutSVGText {text} at (3,23) size 64.11x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,23) size 64.11x9 + LayoutSVGContainer {g} at (3,23) size 136.98x9 + LayoutSVGText {text} at (3,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,23) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.33: "L" - chunk 1 text run 2 at (8.20,30.00) startOffset 1 endOffset 2 width 1.67: "i" - chunk 1 text run 3 at (10.73,30.00) startOffset 2 endOffset 3 width 4.67: "n" - chunk 1 text run 4 at (16.27,30.00) startOffset 3 endOffset 4 width 4.33: "e" - chunk 1 text run 5 at (21.47,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (24.67,30.00) startOffset 5 endOffset 6 width 2.33: "t" - chunk 1 text run 7 at (27.87,30.00) startOffset 6 endOffset 7 width 4.33: "o" - chunk 1 text run 8 at (33.07,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (36.27,30.00) startOffset 8 endOffset 9 width 5.33: "S" - chunk 1 text run 10 at (42.47,30.00) startOffset 9 endOffset 10 width 2.33: "t" - chunk 1 text run 11 at (45.67,30.00) startOffset 10 endOffset 11 width 2.67: "r" - chunk 1 text run 12 at (49.20,30.00) startOffset 11 endOffset 12 width 4.33: "e" - chunk 1 text run 13 at (54.40,30.00) startOffset 12 endOffset 13 width 2.33: "t" - chunk 1 text run 14 at (57.60,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.47,30.00) startOffset 14 endOffset 15 width 4.67: "h" - LayoutSVGText {text} at (75,23) size 65.75x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,23) size 65.75x9 + chunk 1 text run 2 at (8.26,30.00) startOffset 1 endOffset 2 width 1.67: "i" + chunk 1 text run 3 at (10.86,30.00) startOffset 2 endOffset 3 width 4.67: "n" + chunk 1 text run 4 at (16.45,30.00) startOffset 3 endOffset 4 width 4.33: "e" + chunk 1 text run 5 at (21.71,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (24.98,30.00) startOffset 5 endOffset 6 width 2.33: "t" + chunk 1 text run 7 at (28.24,30.00) startOffset 6 endOffset 7 width 4.33: "o" + chunk 1 text run 8 at (33.50,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (36.76,30.00) startOffset 8 endOffset 9 width 5.33: "S" + chunk 1 text run 10 at (43.02,30.00) startOffset 9 endOffset 10 width 2.33: "t" + chunk 1 text run 11 at (46.29,30.00) startOffset 10 endOffset 11 width 2.67: "r" + chunk 1 text run 12 at (49.88,30.00) startOffset 11 endOffset 12 width 4.33: "e" + chunk 1 text run 13 at (55.14,30.00) startOffset 12 endOffset 13 width 2.33: "t" + chunk 1 text run 14 at (58.40,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.33,30.00) startOffset 14 endOffset 15 width 4.67: "h" + LayoutSVGText {text} at (75,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,23) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.33: "t" - chunk 1 text run 2 at (76.57,30.00) startOffset 1 endOffset 2 width 4.67: "h" - chunk 1 text run 3 at (80.48,30.00) startOffset 2 endOffset 3 width 1.67: "i" - chunk 1 text run 4 at (81.39,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.63,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (86.20,30.00) startOffset 5 endOffset 6 width 1.67: "i" - chunk 1 text run 7 at (87.11,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.35,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (91.92,30.00) startOffset 8 endOffset 9 width 4.33: "a" - chunk 1 text run 10 at (95.49,30.00) startOffset 9 endOffset 10 width 2.33: " " - chunk 1 text run 11 at (97.07,30.00) startOffset 10 endOffset 11 width 2.00: "l" - chunk 1 text run 12 at (98.31,30.00) startOffset 11 endOffset 12 width 1.67: "i" - chunk 1 text run 13 at (99.21,30.00) startOffset 12 endOffset 13 width 4.67: "n" - chunk 1 text run 14 at (103.12,30.00) startOffset 13 endOffset 14 width 4.33: "e" - chunk 1 text run 15 at (106.69,30.00) startOffset 14 endOffset 15 width 2.33: " " - chunk 1 text run 16 at (108.27,30.00) startOffset 15 endOffset 16 width 2.33: "t" - chunk 1 text run 17 at (109.84,30.00) startOffset 16 endOffset 17 width 4.33: "o" - chunk 1 text run 18 at (113.41,30.00) startOffset 17 endOffset 18 width 2.33: " " - chunk 1 text run 19 at (114.99,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.23,30.00) startOffset 19 endOffset 20 width 4.67: "q" - chunk 1 text run 21 at (122.13,30.00) startOffset 20 endOffset 21 width 4.67: "u" - chunk 1 text run 22 at (126.04,30.00) startOffset 21 endOffset 22 width 4.33: "e" - chunk 1 text run 23 at (129.61,30.00) startOffset 22 endOffset 23 width 4.33: "e" - chunk 1 text run 24 at (133.19,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.43,30.00) startOffset 24 endOffset 25 width 4.33: "e" + chunk 1 text run 2 at (76.54,30.00) startOffset 1 endOffset 2 width 4.67: "h" + chunk 1 text run 3 at (80.42,30.00) startOffset 2 endOffset 3 width 1.67: "i" + chunk 1 text run 4 at (81.29,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.50,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (86.04,30.00) startOffset 5 endOffset 6 width 1.67: "i" + chunk 1 text run 7 at (86.92,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.12,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (91.67,30.00) startOffset 8 endOffset 9 width 4.33: "a" + chunk 1 text run 10 at (95.21,30.00) startOffset 9 endOffset 10 width 2.33: " " + chunk 1 text run 11 at (96.75,30.00) startOffset 10 endOffset 11 width 2.00: "l" + chunk 1 text run 12 at (97.96,30.00) startOffset 11 endOffset 12 width 1.67: "i" + chunk 1 text run 13 at (98.83,30.00) startOffset 12 endOffset 13 width 4.67: "n" + chunk 1 text run 14 at (102.71,30.00) startOffset 13 endOffset 14 width 4.33: "e" + chunk 1 text run 15 at (106.25,30.00) startOffset 14 endOffset 15 width 2.33: " " + chunk 1 text run 16 at (107.79,30.00) startOffset 15 endOffset 16 width 2.33: "t" + chunk 1 text run 17 at (109.33,30.00) startOffset 16 endOffset 17 width 4.33: "o" + chunk 1 text run 18 at (112.88,30.00) startOffset 17 endOffset 18 width 2.33: " " + chunk 1 text run 19 at (114.42,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.63,30.00) startOffset 19 endOffset 20 width 4.67: "q" + chunk 1 text run 21 at (121.50,30.00) startOffset 20 endOffset 21 width 4.67: "u" + chunk 1 text run 22 at (125.38,30.00) startOffset 21 endOffset 22 width 4.33: "e" + chunk 1 text run 23 at (128.92,30.00) startOffset 22 endOffset 23 width 4.33: "e" + chunk 1 text run 24 at (132.46,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.67,30.00) startOffset 24 endOffset 25 width 4.33: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00] @@ -104,51 +104,51 @@ LayoutSVGInlineText {#text} at (76,38.34) size 54x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.00: "lengthAdjust: default" LayoutSVGContainer {g} at (2,23) size 139x22.34 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,44.00)}] - LayoutSVGContainer {g} at (3,23) size 137.75x9 - LayoutSVGText {text} at (3,23) size 64.11x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,23) size 64.11x9 + LayoutSVGContainer {g} at (3,23) size 136.98x9 + LayoutSVGText {text} at (3,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,23) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.33: "L" - chunk 1 text run 2 at (8.20,30.00) startOffset 1 endOffset 2 width 1.67: "i" - chunk 1 text run 3 at (10.73,30.00) startOffset 2 endOffset 3 width 4.67: "n" - chunk 1 text run 4 at (16.27,30.00) startOffset 3 endOffset 4 width 4.33: "e" - chunk 1 text run 5 at (21.47,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (24.67,30.00) startOffset 5 endOffset 6 width 2.33: "t" - chunk 1 text run 7 at (27.87,30.00) startOffset 6 endOffset 7 width 4.33: "o" - chunk 1 text run 8 at (33.07,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (36.27,30.00) startOffset 8 endOffset 9 width 5.33: "S" - chunk 1 text run 10 at (42.47,30.00) startOffset 9 endOffset 10 width 2.33: "t" - chunk 1 text run 11 at (45.67,30.00) startOffset 10 endOffset 11 width 2.67: "r" - chunk 1 text run 12 at (49.20,30.00) startOffset 11 endOffset 12 width 4.33: "e" - chunk 1 text run 13 at (54.40,30.00) startOffset 12 endOffset 13 width 2.33: "t" - chunk 1 text run 14 at (57.60,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.47,30.00) startOffset 14 endOffset 15 width 4.67: "h" - LayoutSVGText {text} at (75,23) size 65.75x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,23) size 65.75x9 + chunk 1 text run 2 at (8.26,30.00) startOffset 1 endOffset 2 width 1.67: "i" + chunk 1 text run 3 at (10.86,30.00) startOffset 2 endOffset 3 width 4.67: "n" + chunk 1 text run 4 at (16.45,30.00) startOffset 3 endOffset 4 width 4.33: "e" + chunk 1 text run 5 at (21.71,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (24.98,30.00) startOffset 5 endOffset 6 width 2.33: "t" + chunk 1 text run 7 at (28.24,30.00) startOffset 6 endOffset 7 width 4.33: "o" + chunk 1 text run 8 at (33.50,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (36.76,30.00) startOffset 8 endOffset 9 width 5.33: "S" + chunk 1 text run 10 at (43.02,30.00) startOffset 9 endOffset 10 width 2.33: "t" + chunk 1 text run 11 at (46.29,30.00) startOffset 10 endOffset 11 width 2.67: "r" + chunk 1 text run 12 at (49.88,30.00) startOffset 11 endOffset 12 width 4.33: "e" + chunk 1 text run 13 at (55.14,30.00) startOffset 12 endOffset 13 width 2.33: "t" + chunk 1 text run 14 at (58.40,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.33,30.00) startOffset 14 endOffset 15 width 4.67: "h" + LayoutSVGText {text} at (75,23) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,23) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.33: "t" - chunk 1 text run 2 at (76.57,30.00) startOffset 1 endOffset 2 width 4.67: "h" - chunk 1 text run 3 at (80.48,30.00) startOffset 2 endOffset 3 width 1.67: "i" - chunk 1 text run 4 at (81.39,30.00) startOffset 3 endOffset 4 width 4.00: "s" - chunk 1 text run 5 at (84.63,30.00) startOffset 4 endOffset 5 width 2.33: " " - chunk 1 text run 6 at (86.20,30.00) startOffset 5 endOffset 6 width 1.67: "i" - chunk 1 text run 7 at (87.11,30.00) startOffset 6 endOffset 7 width 4.00: "s" - chunk 1 text run 8 at (90.35,30.00) startOffset 7 endOffset 8 width 2.33: " " - chunk 1 text run 9 at (91.92,30.00) startOffset 8 endOffset 9 width 4.33: "a" - chunk 1 text run 10 at (95.49,30.00) startOffset 9 endOffset 10 width 2.33: " " - chunk 1 text run 11 at (97.07,30.00) startOffset 10 endOffset 11 width 2.00: "l" - chunk 1 text run 12 at (98.31,30.00) startOffset 11 endOffset 12 width 1.67: "i" - chunk 1 text run 13 at (99.21,30.00) startOffset 12 endOffset 13 width 4.67: "n" - chunk 1 text run 14 at (103.12,30.00) startOffset 13 endOffset 14 width 4.33: "e" - chunk 1 text run 15 at (106.69,30.00) startOffset 14 endOffset 15 width 2.33: " " - chunk 1 text run 16 at (108.27,30.00) startOffset 15 endOffset 16 width 2.33: "t" - chunk 1 text run 17 at (109.84,30.00) startOffset 16 endOffset 17 width 4.33: "o" - chunk 1 text run 18 at (113.41,30.00) startOffset 17 endOffset 18 width 2.33: " " - chunk 1 text run 19 at (114.99,30.00) startOffset 18 endOffset 19 width 4.00: "s" - chunk 1 text run 20 at (118.23,30.00) startOffset 19 endOffset 20 width 4.67: "q" - chunk 1 text run 21 at (122.13,30.00) startOffset 20 endOffset 21 width 4.67: "u" - chunk 1 text run 22 at (126.04,30.00) startOffset 21 endOffset 22 width 4.33: "e" - chunk 1 text run 23 at (129.61,30.00) startOffset 22 endOffset 23 width 4.33: "e" - chunk 1 text run 24 at (133.19,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.43,30.00) startOffset 24 endOffset 25 width 4.33: "e" + chunk 1 text run 2 at (76.54,30.00) startOffset 1 endOffset 2 width 4.67: "h" + chunk 1 text run 3 at (80.42,30.00) startOffset 2 endOffset 3 width 1.67: "i" + chunk 1 text run 4 at (81.29,30.00) startOffset 3 endOffset 4 width 4.00: "s" + chunk 1 text run 5 at (84.50,30.00) startOffset 4 endOffset 5 width 2.33: " " + chunk 1 text run 6 at (86.04,30.00) startOffset 5 endOffset 6 width 1.67: "i" + chunk 1 text run 7 at (86.92,30.00) startOffset 6 endOffset 7 width 4.00: "s" + chunk 1 text run 8 at (90.12,30.00) startOffset 7 endOffset 8 width 2.33: " " + chunk 1 text run 9 at (91.67,30.00) startOffset 8 endOffset 9 width 4.33: "a" + chunk 1 text run 10 at (95.21,30.00) startOffset 9 endOffset 10 width 2.33: " " + chunk 1 text run 11 at (96.75,30.00) startOffset 10 endOffset 11 width 2.00: "l" + chunk 1 text run 12 at (97.96,30.00) startOffset 11 endOffset 12 width 1.67: "i" + chunk 1 text run 13 at (98.83,30.00) startOffset 12 endOffset 13 width 4.67: "n" + chunk 1 text run 14 at (102.71,30.00) startOffset 13 endOffset 14 width 4.33: "e" + chunk 1 text run 15 at (106.25,30.00) startOffset 14 endOffset 15 width 2.33: " " + chunk 1 text run 16 at (107.79,30.00) startOffset 15 endOffset 16 width 2.33: "t" + chunk 1 text run 17 at (109.33,30.00) startOffset 16 endOffset 17 width 4.33: "o" + chunk 1 text run 18 at (112.88,30.00) startOffset 17 endOffset 18 width 2.33: " " + chunk 1 text run 19 at (114.42,30.00) startOffset 18 endOffset 19 width 4.00: "s" + chunk 1 text run 20 at (117.63,30.00) startOffset 19 endOffset 20 width 4.67: "q" + chunk 1 text run 21 at (121.50,30.00) startOffset 20 endOffset 21 width 4.67: "u" + chunk 1 text run 22 at (125.38,30.00) startOffset 21 endOffset 22 width 4.33: "e" + chunk 1 text run 23 at (128.92,30.00) startOffset 22 endOffset 23 width 4.33: "e" + chunk 1 text run 24 at (132.46,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.67,30.00) startOffset 24 endOffset 25 width 4.33: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00]
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.png index 006c6bfb4..427c8585 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.txt index 857dbbf..e25adc1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLayout-expected.txt
@@ -49,27 +49,27 @@ LayoutSVGText {text} at (102.50,140) size 245x12 contains 1 chunk(s) LayoutSVGInlineText {#text} at (102.50,140) size 245x12 chunk 1 (middle anchor) text run 1 at (102.50,150.00) startOffset 0 endOffset 59 width 245.00: "Letter Spacing Adjustment and Explicit Length Specification" - LayoutSVGContainer {g} at (40,159) size 111.16x38 - LayoutSVGText {text} at (40,159) size 111.16x27 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,159) size 111.16x27 + LayoutSVGContainer {g} at (40,159) size 120x38 + LayoutSVGText {text} at (40,159) size 120x27 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,159) size 120x27 chunk 1 text run 1 at (40.00,180.00) startOffset 0 endOffset 1 width 9.00: "s" - chunk 1 text run 2 at (57.83,180.00) startOffset 1 endOffset 2 width 11.00: "a" - chunk 1 text run 3 at (77.67,180.00) startOffset 2 endOffset 3 width 18.00: "m" - chunk 1 text run 4 at (104.50,180.00) startOffset 3 endOffset 4 width 12.00: "p" - chunk 1 text run 5 at (125.33,180.00) startOffset 4 endOffset 5 width 6.00: "l" - chunk 1 text run 6 at (140.17,180.00) startOffset 5 endOffset 6 width 11.00: "e" + chunk 1 text run 2 at (59.60,180.00) startOffset 1 endOffset 2 width 11.00: "a" + chunk 1 text run 3 at (81.20,180.00) startOffset 2 endOffset 3 width 18.00: "m" + chunk 1 text run 4 at (109.80,180.00) startOffset 3 endOffset 4 width 12.00: "p" + chunk 1 text run 5 at (132.40,180.00) startOffset 4 endOffset 5 width 6.00: "l" + chunk 1 text run 6 at (149.00,180.00) startOffset 5 endOffset 6 width 11.00: "e" LayoutSVGText {text} at (40,187) size 59x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,187) size 59x10 chunk 1 text run 1 at (40.00,195.00) startOffset 0 endOffset 16 width 58.00: "textLength=\"120\"" - LayoutSVGContainer {g} at (185,159) size 69.50x38 - LayoutSVGText {text} at (185,159) size 69.50x27 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (185,159) size 69.50x27 + LayoutSVGContainer {g} at (185,159) size 70x38 + LayoutSVGText {text} at (185,159) size 70x27 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (185,159) size 70x27 chunk 1 text run 1 at (185.00,180.00) startOffset 0 endOffset 1 width 9.00: "s" - chunk 1 text run 2 at (194.50,180.00) startOffset 1 endOffset 2 width 11.00: "a" - chunk 1 text run 3 at (206.00,180.00) startOffset 2 endOffset 3 width 18.00: "m" - chunk 1 text run 4 at (224.50,180.00) startOffset 3 endOffset 4 width 12.00: "p" - chunk 1 text run 5 at (237.00,180.00) startOffset 4 endOffset 5 width 6.00: "l" - chunk 1 text run 6 at (243.50,180.00) startOffset 5 endOffset 6 width 11.00: "e" + chunk 1 text run 2 at (194.60,180.00) startOffset 1 endOffset 2 width 11.00: "a" + chunk 1 text run 3 at (206.20,180.00) startOffset 2 endOffset 3 width 18.00: "m" + chunk 1 text run 4 at (224.80,180.00) startOffset 3 endOffset 4 width 12.00: "p" + chunk 1 text run 5 at (237.40,180.00) startOffset 4 endOffset 5 width 6.00: "l" + chunk 1 text run 6 at (244.00,180.00) startOffset 5 endOffset 6 width 11.00: "e" LayoutSVGText {text} at (185,187) size 55x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (185,187) size 55x10 chunk 1 text run 1 at (185.00,195.00) startOffset 0 endOffset 15 width 54.00: "textLength=\"70\"" @@ -132,75 +132,75 @@ LayoutSVGText {text} at (171.39,310) size 107.19x12 contains 1 chunk(s) LayoutSVGInlineText {#text} at (171.39,310) size 107.19x12 chunk 1 (middle anchor) text run 1 at (171.40,320.00) startOffset 0 endOffset 23 width 107.20: "Word Spacing Adjustment" - LayoutSVGContainer {g} at (40,337) size 349.08x30 - LayoutSVGText {text} at (40,337) size 349.08x17 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,337) size 349.08x17 + LayoutSVGContainer {g} at (40,337) size 350x30 + LayoutSVGText {text} at (40,337) size 350x17 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,337) size 350x17 chunk 1 text run 1 at (40.00,350.00) startOffset 0 endOffset 1 width 14.00: "W" - chunk 1 text run 2 at (54.32,350.00) startOffset 1 endOffset 2 width 3.00: "i" - chunk 1 text run 3 at (58.23,350.00) startOffset 2 endOffset 3 width 7.00: "d" - chunk 1 text run 4 at (66.15,350.00) startOffset 3 endOffset 4 width 7.00: "e" - chunk 1 text run 5 at (74.07,350.00) startOffset 4 endOffset 5 width 4.00: " " - chunk 1 text run 6 at (123.99,350.00) startOffset 5 endOffset 6 width 6.00: "s" - chunk 1 text run 7 at (130.90,350.00) startOffset 6 endOffset 7 width 7.00: "e" - chunk 1 text run 8 at (138.82,350.00) startOffset 7 endOffset 8 width 7.00: "p" - chunk 1 text run 9 at (146.74,350.00) startOffset 8 endOffset 9 width 7.00: "a" - chunk 1 text run 10 at (154.65,350.00) startOffset 9 endOffset 10 width 5.00: "r" - chunk 1 text run 11 at (160.57,350.00) startOffset 10 endOffset 11 width 7.00: "a" - chunk 1 text run 12 at (168.49,350.00) startOffset 11 endOffset 12 width 4.00: "t" - chunk 1 text run 13 at (173.41,350.00) startOffset 12 endOffset 13 width 3.00: "i" - chunk 1 text run 14 at (177.32,350.00) startOffset 13 endOffset 14 width 7.00: "o" - chunk 1 text run 15 at (185.24,350.00) startOffset 14 endOffset 15 width 7.00: "n" - chunk 1 text run 16 at (193.16,350.00) startOffset 15 endOffset 16 width 4.00: " " - chunk 1 text run 17 at (243.08,350.00) startOffset 16 endOffset 17 width 7.00: "b" - chunk 1 text run 18 at (250.99,350.00) startOffset 17 endOffset 18 width 7.00: "e" - chunk 1 text run 19 at (258.91,350.00) startOffset 18 endOffset 19 width 4.00: "t" - chunk 1 text run 20 at (263.83,350.00) startOffset 19 endOffset 20 width 11.00: "w" - chunk 1 text run 21 at (275.74,350.00) startOffset 20 endOffset 21 width 7.00: "e" - chunk 1 text run 22 at (283.66,350.00) startOffset 21 endOffset 22 width 7.00: "e" - chunk 1 text run 23 at (291.58,350.00) startOffset 22 endOffset 23 width 7.00: "n" - chunk 1 text run 24 at (299.50,350.00) startOffset 23 endOffset 24 width 4.00: " " - chunk 1 text run 25 at (349.41,350.00) startOffset 24 endOffset 25 width 11.00: "w" - chunk 1 text run 26 at (361.33,350.00) startOffset 25 endOffset 26 width 7.00: "o" - chunk 1 text run 27 at (369.25,350.00) startOffset 26 endOffset 27 width 5.00: "r" - chunk 1 text run 28 at (375.17,350.00) startOffset 27 endOffset 28 width 7.00: "d" - chunk 1 text run 29 at (383.08,350.00) startOffset 28 endOffset 29 width 6.00: "s" + chunk 1 text run 2 at (54.35,350.00) startOffset 1 endOffset 2 width 3.00: "i" + chunk 1 text run 3 at (58.30,350.00) startOffset 2 endOffset 3 width 7.00: "d" + chunk 1 text run 4 at (66.25,350.00) startOffset 3 endOffset 4 width 7.00: "e" + chunk 1 text run 5 at (74.20,350.00) startOffset 4 endOffset 5 width 4.00: " " + chunk 1 text run 6 at (124.15,350.00) startOffset 5 endOffset 6 width 6.00: "s" + chunk 1 text run 7 at (131.10,350.00) startOffset 6 endOffset 7 width 7.00: "e" + chunk 1 text run 8 at (139.05,350.00) startOffset 7 endOffset 8 width 7.00: "p" + chunk 1 text run 9 at (147.00,350.00) startOffset 8 endOffset 9 width 7.00: "a" + chunk 1 text run 10 at (154.95,350.00) startOffset 9 endOffset 10 width 5.00: "r" + chunk 1 text run 11 at (160.90,350.00) startOffset 10 endOffset 11 width 7.00: "a" + chunk 1 text run 12 at (168.85,350.00) startOffset 11 endOffset 12 width 4.00: "t" + chunk 1 text run 13 at (173.80,350.00) startOffset 12 endOffset 13 width 3.00: "i" + chunk 1 text run 14 at (177.75,350.00) startOffset 13 endOffset 14 width 7.00: "o" + chunk 1 text run 15 at (185.70,350.00) startOffset 14 endOffset 15 width 7.00: "n" + chunk 1 text run 16 at (193.65,350.00) startOffset 15 endOffset 16 width 4.00: " " + chunk 1 text run 17 at (243.60,350.00) startOffset 16 endOffset 17 width 7.00: "b" + chunk 1 text run 18 at (251.55,350.00) startOffset 17 endOffset 18 width 7.00: "e" + chunk 1 text run 19 at (259.50,350.00) startOffset 18 endOffset 19 width 4.00: "t" + chunk 1 text run 20 at (264.45,350.00) startOffset 19 endOffset 20 width 11.00: "w" + chunk 1 text run 21 at (276.40,350.00) startOffset 20 endOffset 21 width 7.00: "e" + chunk 1 text run 22 at (284.35,350.00) startOffset 21 endOffset 22 width 7.00: "e" + chunk 1 text run 23 at (292.30,350.00) startOffset 22 endOffset 23 width 7.00: "n" + chunk 1 text run 24 at (300.25,350.00) startOffset 23 endOffset 24 width 4.00: " " + chunk 1 text run 25 at (350.20,350.00) startOffset 24 endOffset 25 width 11.00: "w" + chunk 1 text run 26 at (362.15,350.00) startOffset 25 endOffset 26 width 7.00: "o" + chunk 1 text run 27 at (370.10,350.00) startOffset 26 endOffset 27 width 5.00: "r" + chunk 1 text run 28 at (376.05,350.00) startOffset 27 endOffset 28 width 7.00: "d" + chunk 1 text run 29 at (384.00,350.00) startOffset 28 endOffset 29 width 6.00: "s" LayoutSVGText {text} at (40,357) size 132x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,357) size 132x10 chunk 1 text run 1 at (40.00,365.00) startOffset 0 endOffset 35 width 131.00: "textLength=\"350\" word-spacing=\"3em\"" - LayoutSVGContainer {g} at (40,382) size 344.80x30 - LayoutSVGText {text} at (40,382) size 344.80x17 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (40,382) size 344.80x17 + LayoutSVGContainer {g} at (40,382) size 350x30 + LayoutSVGText {text} at (40,382) size 350x17 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (40,382) size 350x17 chunk 1 text run 1 at (40.00,395.00) startOffset 0 endOffset 1 width 11.00: "N" - chunk 1 text run 2 at (56.19,395.00) startOffset 1 endOffset 2 width 7.00: "a" - chunk 1 text run 3 at (68.39,395.00) startOffset 2 endOffset 3 width 5.00: "r" - chunk 1 text run 4 at (78.58,395.00) startOffset 3 endOffset 4 width 5.00: "r" - chunk 1 text run 5 at (88.77,395.00) startOffset 4 endOffset 5 width 7.00: "o" - chunk 1 text run 6 at (100.97,395.00) startOffset 5 endOffset 6 width 11.00: "w" - chunk 1 text run 7 at (117.16,395.00) startOffset 6 endOffset 7 width 4.00: " " - chunk 1 text run 8 at (121.35,395.00) startOffset 7 endOffset 8 width 6.00: "s" - chunk 1 text run 9 at (132.55,395.00) startOffset 8 endOffset 9 width 7.00: "e" - chunk 1 text run 10 at (144.74,395.00) startOffset 9 endOffset 10 width 7.00: "p" - chunk 1 text run 11 at (156.94,395.00) startOffset 10 endOffset 11 width 7.00: "a" - chunk 1 text run 12 at (169.13,395.00) startOffset 11 endOffset 12 width 5.00: "r" - chunk 1 text run 13 at (179.32,395.00) startOffset 12 endOffset 13 width 7.00: "a" - chunk 1 text run 14 at (191.52,395.00) startOffset 13 endOffset 14 width 4.00: "t" - chunk 1 text run 15 at (200.71,395.00) startOffset 14 endOffset 15 width 3.00: "i" - chunk 1 text run 16 at (208.90,395.00) startOffset 15 endOffset 16 width 7.00: "o" - chunk 1 text run 17 at (221.10,395.00) startOffset 16 endOffset 17 width 7.00: "n" - chunk 1 text run 18 at (233.29,395.00) startOffset 17 endOffset 18 width 4.00: " " - chunk 1 text run 19 at (237.48,395.00) startOffset 18 endOffset 19 width 7.00: "b" - chunk 1 text run 20 at (249.68,395.00) startOffset 19 endOffset 20 width 7.00: "e" - chunk 1 text run 21 at (261.87,395.00) startOffset 20 endOffset 21 width 4.00: "t" - chunk 1 text run 22 at (271.06,395.00) startOffset 21 endOffset 22 width 11.00: "w" - chunk 1 text run 23 at (287.26,395.00) startOffset 22 endOffset 23 width 7.00: "e" - chunk 1 text run 24 at (299.45,395.00) startOffset 23 endOffset 24 width 7.00: "e" - chunk 1 text run 25 at (311.65,395.00) startOffset 24 endOffset 25 width 7.00: "n" - chunk 1 text run 26 at (323.84,395.00) startOffset 25 endOffset 26 width 4.00: " " - chunk 1 text run 27 at (328.03,395.00) startOffset 26 endOffset 27 width 11.00: "w" - chunk 1 text run 28 at (344.23,395.00) startOffset 27 endOffset 28 width 7.00: "o" - chunk 1 text run 29 at (356.42,395.00) startOffset 28 endOffset 29 width 5.00: "r" - chunk 1 text run 30 at (366.61,395.00) startOffset 29 endOffset 30 width 7.00: "d" - chunk 1 text run 31 at (378.81,395.00) startOffset 30 endOffset 31 width 6.00: "s" + chunk 1 text run 2 at (56.37,395.00) startOffset 1 endOffset 2 width 7.00: "a" + chunk 1 text run 3 at (68.73,395.00) startOffset 2 endOffset 3 width 5.00: "r" + chunk 1 text run 4 at (79.10,395.00) startOffset 3 endOffset 4 width 5.00: "r" + chunk 1 text run 5 at (89.47,395.00) startOffset 4 endOffset 5 width 7.00: "o" + chunk 1 text run 6 at (101.83,395.00) startOffset 5 endOffset 6 width 11.00: "w" + chunk 1 text run 7 at (118.20,395.00) startOffset 6 endOffset 7 width 4.00: " " + chunk 1 text run 8 at (122.57,395.00) startOffset 7 endOffset 8 width 6.00: "s" + chunk 1 text run 9 at (133.93,395.00) startOffset 8 endOffset 9 width 7.00: "e" + chunk 1 text run 10 at (146.30,395.00) startOffset 9 endOffset 10 width 7.00: "p" + chunk 1 text run 11 at (158.67,395.00) startOffset 10 endOffset 11 width 7.00: "a" + chunk 1 text run 12 at (171.03,395.00) startOffset 11 endOffset 12 width 5.00: "r" + chunk 1 text run 13 at (181.40,395.00) startOffset 12 endOffset 13 width 7.00: "a" + chunk 1 text run 14 at (193.77,395.00) startOffset 13 endOffset 14 width 4.00: "t" + chunk 1 text run 15 at (203.13,395.00) startOffset 14 endOffset 15 width 3.00: "i" + chunk 1 text run 16 at (211.50,395.00) startOffset 15 endOffset 16 width 7.00: "o" + chunk 1 text run 17 at (223.87,395.00) startOffset 16 endOffset 17 width 7.00: "n" + chunk 1 text run 18 at (236.23,395.00) startOffset 17 endOffset 18 width 4.00: " " + chunk 1 text run 19 at (240.60,395.00) startOffset 18 endOffset 19 width 7.00: "b" + chunk 1 text run 20 at (252.97,395.00) startOffset 19 endOffset 20 width 7.00: "e" + chunk 1 text run 21 at (265.33,395.00) startOffset 20 endOffset 21 width 4.00: "t" + chunk 1 text run 22 at (274.70,395.00) startOffset 21 endOffset 22 width 11.00: "w" + chunk 1 text run 23 at (291.07,395.00) startOffset 22 endOffset 23 width 7.00: "e" + chunk 1 text run 24 at (303.43,395.00) startOffset 23 endOffset 24 width 7.00: "e" + chunk 1 text run 25 at (315.80,395.00) startOffset 24 endOffset 25 width 7.00: "n" + chunk 1 text run 26 at (328.17,395.00) startOffset 25 endOffset 26 width 4.00: " " + chunk 1 text run 27 at (332.53,395.00) startOffset 26 endOffset 27 width 11.00: "w" + chunk 1 text run 28 at (348.90,395.00) startOffset 27 endOffset 28 width 7.00: "o" + chunk 1 text run 29 at (361.27,395.00) startOffset 28 endOffset 29 width 5.00: "r" + chunk 1 text run 30 at (371.63,395.00) startOffset 29 endOffset 30 width 7.00: "d" + chunk 1 text run 31 at (384.00,395.00) startOffset 30 endOffset 31 width 6.00: "s" LayoutSVGText {text} at (40,402) size 124x10 contains 1 chunk(s) LayoutSVGInlineText {#text} at (40,402) size 124x10 chunk 1 text run 1 at (40.00,410.00) startOffset 0 endOffset 34 width 123.00: "textLength=\"350\" word-spacing=\"-5\""
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.png index 003f3e99..3355928 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.txt index a2a9f36..140107a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textLength-expected.txt
@@ -86,13 +86,13 @@ LayoutSVGContainer {g} at (200,3) size 50x24 LayoutSVGRect {rect} at (200,5) size 50x20 [fill={[type=SOLID] [color=#DDE8FF]}] [x=200.00] [y=5.00] [width=50.00] [height=20.00] LayoutSVGPath {line} at (225,3) size 0x24 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=225.00] [y1=3.00] [x2=225.00] [y2=27.00] - LayoutSVGText {text} at (202.39,7) size 45.20x15 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (202.39,7) size 45.20x15 - chunk 1 (middle anchor) text run 1 at (202.40,19.00) startOffset 0 endOffset 1 width 8.00: "B" - chunk 1 (middle anchor) text run 2 at (215.20,19.00) startOffset 1 endOffset 2 width 5.00: "a" + LayoutSVGText {text} at (200,7) size 50x15 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (200,7) size 50x15 + chunk 1 (middle anchor) text run 1 at (200.00,19.00) startOffset 0 endOffset 1 width 8.00: "B" + chunk 1 (middle anchor) text run 2 at (214.00,19.00) startOffset 1 endOffset 2 width 5.00: "a" chunk 1 (middle anchor) text run 3 at (225.00,19.00) startOffset 2 endOffset 3 width 4.00: "t" - chunk 1 (middle anchor) text run 4 at (233.80,19.00) startOffset 3 endOffset 4 width 3.00: "i" - chunk 1 (middle anchor) text run 5 at (241.60,19.00) startOffset 4 endOffset 5 width 6.00: "k" + chunk 1 (middle anchor) text run 4 at (235.00,19.00) startOffset 3 endOffset 4 width 3.00: "i" + chunk 1 (middle anchor) text run 5 at (244.00,19.00) startOffset 4 endOffset 5 width 6.00: "k" LayoutSVGText {text} at (126,28) size 198x15 contains 1 chunk(s) LayoutSVGInlineText {#text} at (126,28) size 198x15 chunk 1 (middle anchor) text run 1 at (126.00,40.00) startOffset 0 endOffset 38 width 198.00: "textLength=\"50\" lengthAdjust=\"spacing\""
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png index ad53fc1..32cf8c8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-dom-textLength-attr-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png index ad53fc1..32cf8c8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/dynamic-updates/SVGTextElement-svgdom-textLength-prop-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.png index 292809a..842400f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.txt index bdc8d679..7f3bc5c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-1-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 12.57x11.60 + LayoutSVGContainer {g} at (10,0.80) size 12.36x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (22.57,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=22.57] [y1=0.80] [x2=22.57] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 12.57x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=12.57] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGPath {svg:line} at (22.36,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=22.36] [y1=0.80] [x2=22.36] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 12.36x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=12.36] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (13.63,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.77,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (21.11,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.45,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.79,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.13,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.28,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.62,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.76,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.90,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.04,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.18,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.32,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.86,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (13.53,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.56,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (20.80,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.04,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.27,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.51,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.78,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.82,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.85,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.89,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.93,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.96,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 3 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.png index e143989..50d7ec0c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.txt index ea296682..6940dee 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-2-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (30.62,0.80) size 10.74x11.60 - LayoutSVGPath {svg:line} at (30.62,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=30.62] [y1=0.80] [x2=30.62] [y2=12.40] - LayoutSVGPath {svg:line} at (41.36,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=41.36] [y1=0.80] [x2=41.36] [y2=12.40] - LayoutSVGRect {svg:rect} at (30.62,0.80) size 10.74x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=30.62] [y=0.80] [width=10.74] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGContainer {g} at (29.78,0.80) size 10.64x11.60 + LayoutSVGPath {svg:line} at (29.78,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=29.78] [y1=0.80] [x2=29.78] [y2=12.40] + LayoutSVGPath {svg:line} at (40.42,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=40.42] [y1=0.80] [x2=40.42] [y2=12.40] + LayoutSVGRect {svg:rect} at (29.78,0.80) size 10.64x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=29.78] [y=0.80] [width=10.64] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (13.63,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.77,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (21.11,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.45,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.79,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.13,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.28,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.62,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.76,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.90,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.04,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.18,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.32,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.86,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (13.53,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.56,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (20.80,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.04,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.27,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.51,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.78,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.82,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.85,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.89,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.93,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.96,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 10 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.png index 651a521..74d1777 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.txt index 409bf17..5e4020ac 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-3-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (30.62,0.80) size 14.88x11.60 - LayoutSVGPath {svg:line} at (30.62,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=30.62] [y1=0.80] [x2=30.62] [y2=12.40] - LayoutSVGPath {svg:line} at (45.50,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=45.50] [y1=0.80] [x2=45.50] [y2=12.40] - LayoutSVGRect {svg:rect} at (30.62,0.80) size 14.88x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=30.62] [y=0.80] [width=14.88] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGContainer {g} at (29.78,0.80) size 14.67x11.60 + LayoutSVGPath {svg:line} at (29.78,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=29.78] [y1=0.80] [x2=29.78] [y2=12.40] + LayoutSVGPath {svg:line} at (44.45,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=44.45] [y1=0.80] [x2=44.45] [y2=12.40] + LayoutSVGRect {svg:rect} at (29.78,0.80) size 14.67x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=29.78] [y=0.80] [width=14.67] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (13.63,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.77,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (21.11,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.45,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.79,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.13,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.28,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.62,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.76,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.90,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.04,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.18,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.32,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.86,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (13.53,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.56,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (20.80,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.04,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.27,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.51,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.78,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.82,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.85,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.89,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.93,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.96,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.png index 9a60ac8..78cdbf9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.txt index b028905..22df01d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-squeeze-4-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 51.46x11.60 + LayoutSVGContainer {g} at (10,0.80) size 50x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (61.46,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=61.46] [y1=0.80] [x2=61.46] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 51.46x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=51.46] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 51.45x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 51.45x11.39 + LayoutSVGPath {svg:line} at (60,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=60.00] [y1=0.80] [x2=60.00] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 50x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=50.00] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 49.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 49.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (13.63,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (17.77,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (21.11,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (22.45,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (23.79,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (25.13,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (29.28,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (30.62,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (35.76,10.00) startOffset 9 endOffset 10 width 5.60: "q" - chunk 1 text run 11 at (39.90,10.00) startOffset 10 endOffset 11 width 5.60: "u" - chunk 1 text run 12 at (44.04,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (48.18,10.00) startOffset 12 endOffset 13 width 5.60: "e" - chunk 1 text run 14 at (52.32,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.86,10.00) startOffset 14 endOffset 15 width 5.60: "e" + chunk 1 text run 2 at (13.53,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (17.56,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (20.80,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (22.04,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (23.27,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (24.51,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (28.55,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (29.78,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (34.82,10.00) startOffset 9 endOffset 10 width 5.60: "q" + chunk 1 text run 11 at (38.85,10.00) startOffset 10 endOffset 11 width 5.60: "u" + chunk 1 text run 12 at (42.89,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (46.93,10.00) startOffset 12 endOffset 13 width 5.60: "e" + chunk 1 text run 14 at (50.96,10.00) startOffset 13 endOffset 14 width 5.00: "z" + chunk 1 text run 15 at (54.40,10.00) startOffset 14 endOffset 15 width 5.60: "e" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.png index f715cbfb..427f82fcb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.txt index 9f442451..651eab0 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-1-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 35.47x11.60 + LayoutSVGContainer {g} at (10,0.80) size 36.70x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (45.47,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=45.47] [y1=0.80] [x2=45.47] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 35.47x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=35.47] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGPath {svg:line} at (46.70,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=46.70] [y1=0.80] [x2=46.70] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 36.70x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=36.70] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (20.82,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.15,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (42.67,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.20,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.73,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.58,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.11,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.44,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (108.96,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.42,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.95,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.67,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.23,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.96,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (43.90,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.84,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.77,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.71,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.45,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.38,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.12,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.05,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.59,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.33,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.26,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 4 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.png index 5e52314..051c64f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.txt index dbf82e5..dbee057 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-2-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (59.73,0.80) size 14.13x11.60 - LayoutSVGPath {svg:line} at (59.73,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=59.73] [y1=0.80] [x2=59.73] [y2=12.40] - LayoutSVGPath {svg:line} at (73.85,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=73.85] [y1=0.80] [x2=73.85] [y2=12.40] - LayoutSVGRect {svg:rect} at (59.73,0.80) size 14.13x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=59.73] [y=0.80] [width=14.13] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGContainer {g} at (61.77,0.80) size 14.54x11.60 + LayoutSVGPath {svg:line} at (61.77,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=61.77] [y1=0.80] [x2=61.77] [y2=12.40] + LayoutSVGPath {svg:line} at (76.31,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=76.31] [y1=0.80] [x2=76.31] [y2=12.40] + LayoutSVGRect {svg:rect} at (61.77,0.80) size 14.54x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=61.77] [y=0.80] [width=14.54] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (20.82,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.15,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (42.67,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.20,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.73,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.58,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.11,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.44,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (108.96,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.42,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.95,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.67,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.23,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.96,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (43.90,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.84,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.77,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.71,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.45,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.38,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.12,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.05,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.59,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.33,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.26,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 5 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 7 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.png index 1a1d3b13..7310636 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.txt index 813898b..51e49aea 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-3-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (88.11,0.80) size 24.25x11.60 - LayoutSVGPath {svg:line} at (88.11,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=88.11] [y1=0.80] [x2=88.11] [y2=12.40] - LayoutSVGPath {svg:line} at (112.36,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=112.36] [y1=0.80] [x2=112.36] [y2=12.40] - LayoutSVGRect {svg:rect} at (88.11,0.80) size 24.25x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=88.11] [y=0.80] [width=24.25] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGContainer {g} at (91.38,0.80) size 25.07x11.60 + LayoutSVGPath {svg:line} at (91.38,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=91.38] [y1=0.80] [x2=91.38] [y2=12.40] + LayoutSVGPath {svg:line} at (116.45,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=116.45] [y1=0.80] [x2=116.45] [y2=12.40] + LayoutSVGRect {svg:rect} at (91.38,0.80) size 25.07x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=91.38] [y=0.80] [width=25.07] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (20.82,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.15,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (42.67,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.20,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.73,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.58,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.11,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.44,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (108.96,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.42,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.95,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.67,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.23,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.96,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (43.90,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.84,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.77,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.71,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.45,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.38,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.12,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.05,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.59,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.33,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.26,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.png index e4aa8b9..c3416b91 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.txt index 52c97ec..29fbac5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/select-textLength-spacing-stretch-4-expected.txt
@@ -2,26 +2,26 @@ LayoutView at (0,0) size 800x600 layer at (0,0) size 800x600 LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,0.80) size 144.27x11.60 + LayoutSVGContainer {g} at (10,0.80) size 150x11.60 LayoutSVGPath {svg:line} at (10,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=0.80] [x2=10.00] [y2=12.40] - LayoutSVGPath {svg:line} at (154.27,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=154.27] [y1=0.80] [x2=154.27] [y2=12.40] - LayoutSVGRect {svg:rect} at (10,0.80) size 144.27x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=144.27] [height=11.40] - LayoutSVGText {text} at (10,0.81) size 144.27x11.39 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,0.81) size 144.27x11.39 + LayoutSVGPath {svg:line} at (160,0.80) size 0x11.60 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=160.00] [y1=0.80] [x2=160.00] [y2=12.40] + LayoutSVGRect {svg:rect} at (10,0.80) size 150x11.40 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=0.80] [width=150.00] [height=11.40] + LayoutSVGText {text} at (10,0.81) size 149.98x11.39 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (10,0.81) size 149.98x11.39 chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.20: "T" - chunk 1 text run 2 at (20.82,10.00) startOffset 1 endOffset 2 width 5.60: "e" - chunk 1 text run 3 at (32.15,10.00) startOffset 2 endOffset 3 width 4.80: "x" - chunk 1 text run 4 at (42.67,10.00) startOffset 3 endOffset 4 width 2.80: "t" - chunk 1 text run 5 at (51.20,10.00) startOffset 4 endOffset 5 width 2.80: " " - chunk 1 text run 6 at (59.73,10.00) startOffset 5 endOffset 6 width 2.80: "t" - chunk 1 text run 7 at (68.25,10.00) startOffset 6 endOffset 7 width 5.60: "o" - chunk 1 text run 8 at (79.58,10.00) startOffset 7 endOffset 8 width 2.80: " " - chunk 1 text run 9 at (88.11,10.00) startOffset 8 endOffset 9 width 6.60: "S" - chunk 1 text run 10 at (100.44,10.00) startOffset 9 endOffset 10 width 2.80: "t" - chunk 1 text run 11 at (108.96,10.00) startOffset 10 endOffset 11 width 3.40: "r" - chunk 1 text run 12 at (118.09,10.00) startOffset 11 endOffset 12 width 5.60: "e" - chunk 1 text run 13 at (129.42,10.00) startOffset 12 endOffset 13 width 2.80: "t" - chunk 1 text run 14 at (137.95,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.67,10.00) startOffset 14 endOffset 15 width 5.60: "h" + chunk 1 text run 2 at (21.23,10.00) startOffset 1 endOffset 2 width 5.60: "e" + chunk 1 text run 3 at (32.96,10.00) startOffset 2 endOffset 3 width 4.80: "x" + chunk 1 text run 4 at (43.90,10.00) startOffset 3 endOffset 4 width 2.80: "t" + chunk 1 text run 5 at (52.84,10.00) startOffset 4 endOffset 5 width 2.80: " " + chunk 1 text run 6 at (61.77,10.00) startOffset 5 endOffset 6 width 2.80: "t" + chunk 1 text run 7 at (70.71,10.00) startOffset 6 endOffset 7 width 5.60: "o" + chunk 1 text run 8 at (82.45,10.00) startOffset 7 endOffset 8 width 2.80: " " + chunk 1 text run 9 at (91.38,10.00) startOffset 8 endOffset 9 width 6.60: "S" + chunk 1 text run 10 at (104.12,10.00) startOffset 9 endOffset 10 width 2.80: "t" + chunk 1 text run 11 at (113.05,10.00) startOffset 10 endOffset 11 width 3.40: "r" + chunk 1 text run 12 at (122.59,10.00) startOffset 11 endOffset 12 width 5.60: "e" + chunk 1 text run 13 at (134.33,10.00) startOffset 12 endOffset 13 width 2.80: "t" + chunk 1 text run 14 at (143.26,10.00) startOffset 13 endOffset 14 width 5.00: "c" + chunk 1 text run 15 at (154.40,10.00) startOffset 14 endOffset 15 width 5.60: "h" selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.png index 35db3cd..f09077f2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.txt index a4e00521..d3b44ae 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-selection-text-01-b-expected.txt
@@ -38,51 +38,51 @@ LayoutSVGInlineText {#text} at (76,38.41) size 54x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.00: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.81) size 139x22.59 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,22.00)}] - LayoutSVGContainer {g} at (3,22.81) size 137.61x9 - LayoutSVGText {text} at (3,22.81) size 64.02x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.81) size 64.02x9 + LayoutSVGContainer {g} at (3,22.81) size 136.98x9 + LayoutSVGText {text} at (3,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.81) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.40: "L" - chunk 1 text run 2 at (8.36,30.00) startOffset 1 endOffset 2 width 1.60: "i" - chunk 1 text run 3 at (10.92,30.00) startOffset 2 endOffset 3 width 4.20: "n" - chunk 1 text run 4 at (16.08,30.00) startOffset 3 endOffset 4 width 4.40: "e" - chunk 1 text run 5 at (21.44,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (24.60,30.00) startOffset 5 endOffset 6 width 2.20: "t" - chunk 1 text run 7 at (27.76,30.00) startOffset 6 endOffset 7 width 4.40: "o" - chunk 1 text run 8 at (33.12,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (36.28,30.00) startOffset 8 endOffset 9 width 5.40: "S" - chunk 1 text run 10 at (42.64,30.00) startOffset 9 endOffset 10 width 2.20: "t" - chunk 1 text run 11 at (45.80,30.00) startOffset 10 endOffset 11 width 2.60: "r" - chunk 1 text run 12 at (49.36,30.00) startOffset 11 endOffset 12 width 4.40: "e" - chunk 1 text run 13 at (54.72,30.00) startOffset 12 endOffset 13 width 2.20: "t" - chunk 1 text run 14 at (57.88,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.84,30.00) startOffset 14 endOffset 15 width 4.20: "h" - LayoutSVGText {text} at (75,22.81) size 65.61x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.81) size 65.61x9 + chunk 1 text run 2 at (8.43,30.00) startOffset 1 endOffset 2 width 1.60: "i" + chunk 1 text run 3 at (11.06,30.00) startOffset 2 endOffset 3 width 4.20: "n" + chunk 1 text run 4 at (16.29,30.00) startOffset 3 endOffset 4 width 4.40: "e" + chunk 1 text run 5 at (21.71,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (24.94,30.00) startOffset 5 endOffset 6 width 2.20: "t" + chunk 1 text run 7 at (28.17,30.00) startOffset 6 endOffset 7 width 4.40: "o" + chunk 1 text run 8 at (33.60,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (36.83,30.00) startOffset 8 endOffset 9 width 5.40: "S" + chunk 1 text run 10 at (43.26,30.00) startOffset 9 endOffset 10 width 2.20: "t" + chunk 1 text run 11 at (46.49,30.00) startOffset 10 endOffset 11 width 2.60: "r" + chunk 1 text run 12 at (50.11,30.00) startOffset 11 endOffset 12 width 4.40: "e" + chunk 1 text run 13 at (55.54,30.00) startOffset 12 endOffset 13 width 2.20: "t" + chunk 1 text run 14 at (58.77,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.80,30.00) startOffset 14 endOffset 15 width 4.20: "h" + LayoutSVGText {text} at (75,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.81) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.20: "t" - chunk 1 text run 2 at (76.58,30.00) startOffset 1 endOffset 2 width 4.20: "h" - chunk 1 text run 3 at (80.15,30.00) startOffset 2 endOffset 3 width 1.60: "i" - chunk 1 text run 4 at (81.13,30.00) startOffset 3 endOffset 4 width 3.80: "s" - chunk 1 text run 5 at (84.30,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (85.88,30.00) startOffset 5 endOffset 6 width 1.60: "i" - chunk 1 text run 7 at (86.86,30.00) startOffset 6 endOffset 7 width 3.80: "s" - chunk 1 text run 8 at (90.03,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (91.61,30.00) startOffset 8 endOffset 9 width 4.40: "a" - chunk 1 text run 10 at (95.38,30.00) startOffset 9 endOffset 10 width 2.20: " " - chunk 1 text run 11 at (96.96,30.00) startOffset 10 endOffset 11 width 1.60: "l" - chunk 1 text run 12 at (97.94,30.00) startOffset 11 endOffset 12 width 1.60: "i" - chunk 1 text run 13 at (98.91,30.00) startOffset 12 endOffset 13 width 4.20: "n" - chunk 1 text run 14 at (102.49,30.00) startOffset 13 endOffset 14 width 4.40: "e" - chunk 1 text run 15 at (106.26,30.00) startOffset 14 endOffset 15 width 2.20: " " - chunk 1 text run 16 at (107.84,30.00) startOffset 15 endOffset 16 width 2.20: "t" - chunk 1 text run 17 at (109.42,30.00) startOffset 16 endOffset 17 width 4.40: "o" - chunk 1 text run 18 at (113.19,30.00) startOffset 17 endOffset 18 width 2.20: " " - chunk 1 text run 19 at (114.77,30.00) startOffset 18 endOffset 19 width 3.80: "s" - chunk 1 text run 20 at (117.94,30.00) startOffset 19 endOffset 20 width 4.40: "q" - chunk 1 text run 21 at (121.72,30.00) startOffset 20 endOffset 21 width 4.20: "u" - chunk 1 text run 22 at (125.30,30.00) startOffset 21 endOffset 22 width 4.40: "e" - chunk 1 text run 23 at (129.07,30.00) startOffset 22 endOffset 23 width 4.40: "e" - chunk 1 text run 24 at (132.85,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.22,30.00) startOffset 24 endOffset 25 width 4.40: "e" + chunk 1 text run 2 at (76.55,30.00) startOffset 1 endOffset 2 width 4.20: "h" + chunk 1 text run 3 at (80.10,30.00) startOffset 2 endOffset 3 width 1.60: "i" + chunk 1 text run 4 at (81.05,30.00) startOffset 3 endOffset 4 width 3.80: "s" + chunk 1 text run 5 at (84.20,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (85.75,30.00) startOffset 5 endOffset 6 width 1.60: "i" + chunk 1 text run 7 at (86.70,30.00) startOffset 6 endOffset 7 width 3.80: "s" + chunk 1 text run 8 at (89.85,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (91.40,30.00) startOffset 8 endOffset 9 width 4.40: "a" + chunk 1 text run 10 at (95.15,30.00) startOffset 9 endOffset 10 width 2.20: " " + chunk 1 text run 11 at (96.70,30.00) startOffset 10 endOffset 11 width 1.60: "l" + chunk 1 text run 12 at (97.65,30.00) startOffset 11 endOffset 12 width 1.60: "i" + chunk 1 text run 13 at (98.60,30.00) startOffset 12 endOffset 13 width 4.20: "n" + chunk 1 text run 14 at (102.15,30.00) startOffset 13 endOffset 14 width 4.40: "e" + chunk 1 text run 15 at (105.90,30.00) startOffset 14 endOffset 15 width 2.20: " " + chunk 1 text run 16 at (107.45,30.00) startOffset 15 endOffset 16 width 2.20: "t" + chunk 1 text run 17 at (109.00,30.00) startOffset 16 endOffset 17 width 4.40: "o" + chunk 1 text run 18 at (112.75,30.00) startOffset 17 endOffset 18 width 2.20: " " + chunk 1 text run 19 at (114.30,30.00) startOffset 18 endOffset 19 width 3.80: "s" + chunk 1 text run 20 at (117.45,30.00) startOffset 19 endOffset 20 width 4.40: "q" + chunk 1 text run 21 at (121.20,30.00) startOffset 20 endOffset 21 width 4.20: "u" + chunk 1 text run 22 at (124.75,30.00) startOffset 21 endOffset 22 width 4.40: "e" + chunk 1 text run 23 at (128.50,30.00) startOffset 22 endOffset 23 width 4.40: "e" + chunk 1 text run 24 at (132.25,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.60,30.00) startOffset 24 endOffset 25 width 4.40: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00] @@ -104,51 +104,51 @@ LayoutSVGInlineText {#text} at (76,38.41) size 54x7 chunk 1 text run 1 at (76.00,44.00) startOffset 0 endOffset 21 width 54.00: "lengthAdjust: default" LayoutSVGContainer {g} at (2,22.81) size 139x22.59 [transform={m=((1.00,0.00)(0.00,1.00)) t=(0.00,44.00)}] - LayoutSVGContainer {g} at (3,22.81) size 137.61x9 - LayoutSVGText {text} at (3,22.81) size 64.02x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (3,22.81) size 64.02x9 + LayoutSVGContainer {g} at (3,22.81) size 136.98x9 + LayoutSVGText {text} at (3,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (3,22.81) size 64.98x9 chunk 1 text run 1 at (3.00,30.00) startOffset 0 endOffset 1 width 4.40: "L" - chunk 1 text run 2 at (8.36,30.00) startOffset 1 endOffset 2 width 1.60: "i" - chunk 1 text run 3 at (10.92,30.00) startOffset 2 endOffset 3 width 4.20: "n" - chunk 1 text run 4 at (16.08,30.00) startOffset 3 endOffset 4 width 4.40: "e" - chunk 1 text run 5 at (21.44,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (24.60,30.00) startOffset 5 endOffset 6 width 2.20: "t" - chunk 1 text run 7 at (27.76,30.00) startOffset 6 endOffset 7 width 4.40: "o" - chunk 1 text run 8 at (33.12,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (36.28,30.00) startOffset 8 endOffset 9 width 5.40: "S" - chunk 1 text run 10 at (42.64,30.00) startOffset 9 endOffset 10 width 2.20: "t" - chunk 1 text run 11 at (45.80,30.00) startOffset 10 endOffset 11 width 2.60: "r" - chunk 1 text run 12 at (49.36,30.00) startOffset 11 endOffset 12 width 4.40: "e" - chunk 1 text run 13 at (54.72,30.00) startOffset 12 endOffset 13 width 2.20: "t" - chunk 1 text run 14 at (57.88,30.00) startOffset 13 endOffset 14 width 4.00: "c" - chunk 1 text run 15 at (62.84,30.00) startOffset 14 endOffset 15 width 4.20: "h" - LayoutSVGText {text} at (75,22.81) size 65.61x9 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (75,22.81) size 65.61x9 + chunk 1 text run 2 at (8.43,30.00) startOffset 1 endOffset 2 width 1.60: "i" + chunk 1 text run 3 at (11.06,30.00) startOffset 2 endOffset 3 width 4.20: "n" + chunk 1 text run 4 at (16.29,30.00) startOffset 3 endOffset 4 width 4.40: "e" + chunk 1 text run 5 at (21.71,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (24.94,30.00) startOffset 5 endOffset 6 width 2.20: "t" + chunk 1 text run 7 at (28.17,30.00) startOffset 6 endOffset 7 width 4.40: "o" + chunk 1 text run 8 at (33.60,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (36.83,30.00) startOffset 8 endOffset 9 width 5.40: "S" + chunk 1 text run 10 at (43.26,30.00) startOffset 9 endOffset 10 width 2.20: "t" + chunk 1 text run 11 at (46.49,30.00) startOffset 10 endOffset 11 width 2.60: "r" + chunk 1 text run 12 at (50.11,30.00) startOffset 11 endOffset 12 width 4.40: "e" + chunk 1 text run 13 at (55.54,30.00) startOffset 12 endOffset 13 width 2.20: "t" + chunk 1 text run 14 at (58.77,30.00) startOffset 13 endOffset 14 width 4.00: "c" + chunk 1 text run 15 at (63.80,30.00) startOffset 14 endOffset 15 width 4.20: "h" + LayoutSVGText {text} at (75,22.81) size 64.98x9 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (75,22.81) size 64.98x9 chunk 1 text run 1 at (75.00,30.00) startOffset 0 endOffset 1 width 2.20: "t" - chunk 1 text run 2 at (76.58,30.00) startOffset 1 endOffset 2 width 4.20: "h" - chunk 1 text run 3 at (80.15,30.00) startOffset 2 endOffset 3 width 1.60: "i" - chunk 1 text run 4 at (81.13,30.00) startOffset 3 endOffset 4 width 3.80: "s" - chunk 1 text run 5 at (84.30,30.00) startOffset 4 endOffset 5 width 2.20: " " - chunk 1 text run 6 at (85.88,30.00) startOffset 5 endOffset 6 width 1.60: "i" - chunk 1 text run 7 at (86.86,30.00) startOffset 6 endOffset 7 width 3.80: "s" - chunk 1 text run 8 at (90.03,30.00) startOffset 7 endOffset 8 width 2.20: " " - chunk 1 text run 9 at (91.61,30.00) startOffset 8 endOffset 9 width 4.40: "a" - chunk 1 text run 10 at (95.38,30.00) startOffset 9 endOffset 10 width 2.20: " " - chunk 1 text run 11 at (96.96,30.00) startOffset 10 endOffset 11 width 1.60: "l" - chunk 1 text run 12 at (97.94,30.00) startOffset 11 endOffset 12 width 1.60: "i" - chunk 1 text run 13 at (98.91,30.00) startOffset 12 endOffset 13 width 4.20: "n" - chunk 1 text run 14 at (102.49,30.00) startOffset 13 endOffset 14 width 4.40: "e" - chunk 1 text run 15 at (106.26,30.00) startOffset 14 endOffset 15 width 2.20: " " - chunk 1 text run 16 at (107.84,30.00) startOffset 15 endOffset 16 width 2.20: "t" - chunk 1 text run 17 at (109.42,30.00) startOffset 16 endOffset 17 width 4.40: "o" - chunk 1 text run 18 at (113.19,30.00) startOffset 17 endOffset 18 width 2.20: " " - chunk 1 text run 19 at (114.77,30.00) startOffset 18 endOffset 19 width 3.80: "s" - chunk 1 text run 20 at (117.94,30.00) startOffset 19 endOffset 20 width 4.40: "q" - chunk 1 text run 21 at (121.72,30.00) startOffset 20 endOffset 21 width 4.20: "u" - chunk 1 text run 22 at (125.30,30.00) startOffset 21 endOffset 22 width 4.40: "e" - chunk 1 text run 23 at (129.07,30.00) startOffset 22 endOffset 23 width 4.40: "e" - chunk 1 text run 24 at (132.85,30.00) startOffset 23 endOffset 24 width 4.00: "z" - chunk 1 text run 25 at (136.22,30.00) startOffset 24 endOffset 25 width 4.40: "e" + chunk 1 text run 2 at (76.55,30.00) startOffset 1 endOffset 2 width 4.20: "h" + chunk 1 text run 3 at (80.10,30.00) startOffset 2 endOffset 3 width 1.60: "i" + chunk 1 text run 4 at (81.05,30.00) startOffset 3 endOffset 4 width 3.80: "s" + chunk 1 text run 5 at (84.20,30.00) startOffset 4 endOffset 5 width 2.20: " " + chunk 1 text run 6 at (85.75,30.00) startOffset 5 endOffset 6 width 1.60: "i" + chunk 1 text run 7 at (86.70,30.00) startOffset 6 endOffset 7 width 3.80: "s" + chunk 1 text run 8 at (89.85,30.00) startOffset 7 endOffset 8 width 2.20: " " + chunk 1 text run 9 at (91.40,30.00) startOffset 8 endOffset 9 width 4.40: "a" + chunk 1 text run 10 at (95.15,30.00) startOffset 9 endOffset 10 width 2.20: " " + chunk 1 text run 11 at (96.70,30.00) startOffset 10 endOffset 11 width 1.60: "l" + chunk 1 text run 12 at (97.65,30.00) startOffset 11 endOffset 12 width 1.60: "i" + chunk 1 text run 13 at (98.60,30.00) startOffset 12 endOffset 13 width 4.20: "n" + chunk 1 text run 14 at (102.15,30.00) startOffset 13 endOffset 14 width 4.40: "e" + chunk 1 text run 15 at (105.90,30.00) startOffset 14 endOffset 15 width 2.20: " " + chunk 1 text run 16 at (107.45,30.00) startOffset 15 endOffset 16 width 2.20: "t" + chunk 1 text run 17 at (109.00,30.00) startOffset 16 endOffset 17 width 4.40: "o" + chunk 1 text run 18 at (112.75,30.00) startOffset 17 endOffset 18 width 2.20: " " + chunk 1 text run 19 at (114.30,30.00) startOffset 18 endOffset 19 width 3.80: "s" + chunk 1 text run 20 at (117.45,30.00) startOffset 19 endOffset 20 width 4.40: "q" + chunk 1 text run 21 at (121.20,30.00) startOffset 20 endOffset 21 width 4.20: "u" + chunk 1 text run 22 at (124.75,30.00) startOffset 21 endOffset 22 width 4.40: "e" + chunk 1 text run 23 at (128.50,30.00) startOffset 22 endOffset 23 width 4.40: "e" + chunk 1 text run 24 at (132.25,30.00) startOffset 23 endOffset 24 width 4.00: "z" + chunk 1 text run 25 at (135.60,30.00) startOffset 24 endOffset 25 width 4.40: "e" LayoutSVGContainer {g} at (2,32) size 139x4 LayoutSVGPath {line} at (2,32) size 67x0 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=69.00] [y2=32.00] LayoutSVGPath {line} at (2,32) size 0x4 [stroke={[type=SOLID] [color=#FF0000]}] [fill={[type=SOLID] [color=#000000]}] [x1=2.00] [y1=32.00] [x2=2.00] [y2=36.00]
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-1-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-1-expected.txt deleted file mode 100644 index 6c2aad8..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-1-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,1) size 12.67x11.20 - LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] - LayoutSVGPath {svg:line} at (22.67,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=22.67] [y1=1.00] [x2=22.67] [y2=12.20] - LayoutSVGRect {svg:rect} at (10,1) size 12.67x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=12.67] [height=11.20] - LayoutSVGText {text} at (10,1) size 51.42x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 51.42x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (13.55,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (17.67,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.22,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (22.55,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (23.88,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (25.21,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (29.32,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (30.66,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (35.88,10.00) startOffset 9 endOffset 10 width 5.56: "q" - chunk 1 text run 11 at (39.99,10.00) startOffset 10 endOffset 11 width 5.56: "u" - chunk 1 text run 12 at (44.11,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.56: "e" - chunk 1 text run 14 at (52.33,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.89,10.00) startOffset 14 endOffset 15 width 5.56: "e" -selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 3 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-2-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-2-expected.txt deleted file mode 100644 index 05280375..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-2-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (30.66,1) size 10.78x11.20 - LayoutSVGPath {svg:line} at (30.66,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=30.66] [y1=1.00] [x2=30.66] [y2=12.20] - LayoutSVGPath {svg:line} at (41.44,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=41.44] [y1=1.00] [x2=41.44] [y2=12.20] - LayoutSVGRect {svg:rect} at (30.66,1) size 10.78x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=30.66] [y=1.00] [width=10.78] [height=11.20] - LayoutSVGText {text} at (10,1) size 51.42x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 51.42x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (13.55,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (17.67,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.22,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (22.55,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (23.88,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (25.21,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (29.32,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (30.66,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (35.88,10.00) startOffset 9 endOffset 10 width 5.56: "q" - chunk 1 text run 11 at (39.99,10.00) startOffset 10 endOffset 11 width 5.56: "u" - chunk 1 text run 12 at (44.11,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.56: "e" - chunk 1 text run 14 at (52.33,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.89,10.00) startOffset 14 endOffset 15 width 5.56: "e" -selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 10 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-3-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-3-expected.txt deleted file mode 100644 index ad981b6..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-3-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (30.66,1) size 14.90x11.20 - LayoutSVGPath {svg:line} at (30.66,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=30.66] [y1=1.00] [x2=30.66] [y2=12.20] - LayoutSVGPath {svg:line} at (45.55,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=45.55] [y1=1.00] [x2=45.55] [y2=12.20] - LayoutSVGRect {svg:rect} at (30.66,1) size 14.90x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=30.66] [y=1.00] [width=14.90] [height=11.20] - LayoutSVGText {text} at (10,1) size 51.42x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 51.42x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (13.55,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (17.67,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.22,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (22.55,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (23.88,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (25.21,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (29.32,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (30.66,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (35.88,10.00) startOffset 9 endOffset 10 width 5.56: "q" - chunk 1 text run 11 at (39.99,10.00) startOffset 10 endOffset 11 width 5.56: "u" - chunk 1 text run 12 at (44.11,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.56: "e" - chunk 1 text run 14 at (52.33,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.89,10.00) startOffset 14 endOffset 15 width 5.56: "e" -selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-4-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-4-expected.txt deleted file mode 100644 index 29dbc34..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-squeeze-4-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,1) size 51.45x11.20 - LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] - LayoutSVGPath {svg:line} at (61.45,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=61.45] [y1=1.00] [x2=61.45] [y2=12.20] - LayoutSVGRect {svg:rect} at (10,1) size 51.45x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=51.45] [height=11.20] - LayoutSVGText {text} at (10,1) size 51.42x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 51.42x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (13.55,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (17.67,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (21.22,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (22.55,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (23.88,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (25.21,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (29.32,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (30.66,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (35.88,10.00) startOffset 9 endOffset 10 width 5.56: "q" - chunk 1 text run 11 at (39.99,10.00) startOffset 10 endOffset 11 width 5.56: "u" - chunk 1 text run 12 at (44.11,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (48.22,10.00) startOffset 12 endOffset 13 width 5.56: "e" - chunk 1 text run 14 at (52.33,10.00) startOffset 13 endOffset 14 width 5.00: "z" - chunk 1 text run 15 at (55.89,10.00) startOffset 14 endOffset 15 width 5.56: "e" -selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-1-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-1-expected.txt deleted file mode 100644 index f96c30a..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-1-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,1) size 35.56x11.20 - LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] - LayoutSVGPath {svg:line} at (45.56,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=45.56] [y1=1.00] [x2=45.56] [y2=12.20] - LayoutSVGRect {svg:rect} at (10,1) size 35.56x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=35.56] [height=11.20] - LayoutSVGText {text} at (10,1) size 144.23x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 144.23x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (20.74,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (32.04,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.78,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (51.30,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (59.81,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (68.33,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (79.63,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (88.15,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (100.56,10.00) startOffset 9 endOffset 10 width 2.78: "t" - chunk 1 text run 11 at (109.07,10.00) startOffset 10 endOffset 11 width 3.33: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (129.44,10.00) startOffset 12 endOffset 13 width 2.78: "t" - chunk 1 text run 14 at (137.96,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.70,10.00) startOffset 14 endOffset 15 width 5.56: "h" -selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 4 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-2-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-2-expected.txt deleted file mode 100644 index 20bace8..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-2-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (59.81,1) size 14.08x11.20 - LayoutSVGPath {svg:line} at (59.81,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=59.81] [y1=1.00] [x2=59.81] [y2=12.20] - LayoutSVGPath {svg:line} at (73.89,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=73.89] [y1=1.00] [x2=73.89] [y2=12.20] - LayoutSVGRect {svg:rect} at (59.81,1) size 14.08x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=59.81] [y=1.00] [width=14.08] [height=11.20] - LayoutSVGText {text} at (10,1) size 144.23x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 144.23x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (20.74,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (32.04,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.78,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (51.30,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (59.81,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (68.33,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (79.63,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (88.15,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (100.56,10.00) startOffset 9 endOffset 10 width 2.78: "t" - chunk 1 text run 11 at (109.07,10.00) startOffset 10 endOffset 11 width 3.33: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (129.44,10.00) startOffset 12 endOffset 13 width 2.78: "t" - chunk 1 text run 14 at (137.96,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.70,10.00) startOffset 14 endOffset 15 width 5.56: "h" -selection start: position 5 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 7 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-3-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-3-expected.txt deleted file mode 100644 index 8f7fb82..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-3-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (88.15,1) size 24.26x11.20 - LayoutSVGPath {svg:line} at (88.15,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=88.15] [y1=1.00] [x2=88.15] [y2=12.20] - LayoutSVGPath {svg:line} at (112.40,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=112.40] [y1=1.00] [x2=112.40] [y2=12.20] - LayoutSVGRect {svg:rect} at (88.15,1) size 24.26x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=88.15] [y=1.00] [width=24.26] [height=11.20] - LayoutSVGText {text} at (10,1) size 144.23x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 144.23x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (20.74,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (32.04,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.78,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (51.30,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (59.81,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (68.33,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (79.63,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (88.15,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (100.56,10.00) startOffset 9 endOffset 10 width 2.78: "t" - chunk 1 text run 11 at (109.07,10.00) startOffset 10 endOffset 11 width 3.33: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (129.44,10.00) startOffset 12 endOffset 13 width 2.78: "t" - chunk 1 text run 14 at (137.96,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.70,10.00) startOffset 14 endOffset 15 width 5.56: "h" -selection start: position 8 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 11 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-4-expected.txt b/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-4-expected.txt deleted file mode 100644 index b7878f0..0000000 --- a/third_party/WebKit/LayoutTests/svg/text/select-textLength-spacing-stretch-4-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutSVGRoot {svg} at (0,0) size 800x600 - LayoutSVGContainer {g} at (10,1) size 144.26x11.20 - LayoutSVGPath {svg:line} at (10,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=10.00] [y1=1.00] [x2=10.00] [y2=12.20] - LayoutSVGPath {svg:line} at (154.26,1) size 0x11.20 [stroke={[type=SOLID] [color=#008000]}] [fill={[type=SOLID] [color=#000000]}] [x1=154.26] [y1=1.00] [x2=154.26] [y2=12.20] - LayoutSVGRect {svg:rect} at (10,1) size 144.26x11.20 [fill={[type=SOLID] [color=#FF0000] [opacity=0.40]}] [x=10.00] [y=1.00] [width=144.26] [height=11.20] - LayoutSVGText {text} at (10,1) size 144.23x11.19 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (10,1) size 144.23x11.19 - chunk 1 text run 1 at (10.00,10.00) startOffset 0 endOffset 1 width 6.11: "T" - chunk 1 text run 2 at (20.74,10.00) startOffset 1 endOffset 2 width 5.56: "e" - chunk 1 text run 3 at (32.04,10.00) startOffset 2 endOffset 3 width 5.00: "x" - chunk 1 text run 4 at (42.78,10.00) startOffset 3 endOffset 4 width 2.78: "t" - chunk 1 text run 5 at (51.30,10.00) startOffset 4 endOffset 5 width 2.78: " " - chunk 1 text run 6 at (59.81,10.00) startOffset 5 endOffset 6 width 2.78: "t" - chunk 1 text run 7 at (68.33,10.00) startOffset 6 endOffset 7 width 5.56: "o" - chunk 1 text run 8 at (79.63,10.00) startOffset 7 endOffset 8 width 2.78: " " - chunk 1 text run 9 at (88.15,10.00) startOffset 8 endOffset 9 width 6.67: "S" - chunk 1 text run 10 at (100.56,10.00) startOffset 9 endOffset 10 width 2.78: "t" - chunk 1 text run 11 at (109.07,10.00) startOffset 10 endOffset 11 width 3.33: "r" - chunk 1 text run 12 at (118.14,10.00) startOffset 11 endOffset 12 width 5.56: "e" - chunk 1 text run 13 at (129.44,10.00) startOffset 12 endOffset 13 width 2.78: "t" - chunk 1 text run 14 at (137.96,10.00) startOffset 13 endOffset 14 width 5.00: "c" - chunk 1 text run 15 at (148.70,10.00) startOffset 14 endOffset 15 width 5.56: "h" -selection start: position 0 of child 0 {#text} of child 5 {text} of child 0 {svg} of document -selection end: position 15 of child 0 {#text} of child 5 {text} of child 0 {svg} of document
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp index 87424b9..3d4eea28 100644 --- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueSerializerTest.cpp
@@ -524,7 +524,7 @@ OffscreenCanvas* new_canvas = V8OffscreenCanvas::toImpl(result.As<v8::Object>()); EXPECT_EQ(IntSize(10, 7), new_canvas->Size()); - EXPECT_EQ(519, new_canvas->PlaceholderCanvasId()); + EXPECT_EQ(519u, new_canvas->PlaceholderCanvasId()); EXPECT_TRUE(canvas->IsNeutered()); EXPECT_FALSE(new_canvas->IsNeutered()); }
diff --git a/third_party/WebKit/Source/core/css/CSSFontSelector.cpp b/third_party/WebKit/Source/core/css/CSSFontSelector.cpp index 35460d3..4ac4e17 100644 --- a/third_party/WebKit/Source/core/css/CSSFontSelector.cpp +++ b/third_party/WebKit/Source/core/css/CSSFontSelector.cpp
@@ -34,6 +34,7 @@ #include "core/dom/Document.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" +#include "core/frame/UseCounter.h" #include "core/loader/FrameLoader.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/fonts/FontCache.h" @@ -173,6 +174,11 @@ FontCacheInvalidated(); } +void CSSFontSelector::ReportNotDefGlyph() const { + DCHECK(document_); + UseCounter::Count(document_, UseCounter::kFontShapingNotDefGlyphObserved); +} + DEFINE_TRACE(CSSFontSelector) { visitor->Trace(document_); visitor->Trace(font_face_cache_);
diff --git a/third_party/WebKit/Source/core/css/CSSFontSelector.h b/third_party/WebKit/Source/core/css/CSSFontSelector.h index 03c4f1e..2be3c5b 100644 --- a/third_party/WebKit/Source/core/css/CSSFontSelector.h +++ b/third_party/WebKit/Source/core/css/CSSFontSelector.h
@@ -50,6 +50,8 @@ unsigned Version() const override { return font_face_cache_.Version(); } + void ReportNotDefGlyph() const override; + PassRefPtr<FontData> GetFontData(const FontDescription&, const AtomicString&) override; void WillUseFontData(const FontDescription&,
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h index 788258b..0fe64a7 100644 --- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h +++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -46,6 +46,7 @@ #include "platform/fonts/FontSmoothingMode.h" #include "platform/fonts/TextRenderingMode.h" #include "platform/graphics/GraphicsTypes.h" +#include "platform/graphics/TouchAction.h" #include "platform/scroll/ScrollableArea.h" #include "platform/text/TextRun.h" #include "platform/text/WritingMode.h" @@ -2974,31 +2975,31 @@ inline TouchAction CSSIdentifierValue::ConvertTo() const { switch (value_id_) { case CSSValueNone: - return kTouchActionNone; + return TouchAction::kTouchActionNone; case CSSValueAuto: - return kTouchActionAuto; + return TouchAction::kTouchActionAuto; case CSSValuePanLeft: - return kTouchActionPanLeft; + return TouchAction::kTouchActionPanLeft; case CSSValuePanRight: - return kTouchActionPanRight; + return TouchAction::kTouchActionPanRight; case CSSValuePanX: - return kTouchActionPanX; + return TouchAction::kTouchActionPanX; case CSSValuePanUp: - return kTouchActionPanUp; + return TouchAction::kTouchActionPanUp; case CSSValuePanDown: - return kTouchActionPanDown; + return TouchAction::kTouchActionPanDown; case CSSValuePanY: - return kTouchActionPanY; + return TouchAction::kTouchActionPanY; case CSSValueManipulation: - return kTouchActionManipulation; + return TouchAction::kTouchActionManipulation; case CSSValuePinchZoom: - return kTouchActionPinchZoom; + return TouchAction::kTouchActionPinchZoom; default: break; } NOTREACHED(); - return kTouchActionNone; + return TouchAction::kTouchActionNone; } template <>
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index 7f007488..6c129182 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -656,6 +656,10 @@ name: "border-bottom-color", custom_all: true, interpolable: true, + field_template: "storage_only", + field_type_path: "platform/graphics/Color", + default_value: "0", + field_group: "surround", }, { name: "border-bottom-left-radius", @@ -744,6 +748,10 @@ name: "border-left-color", custom_all: true, interpolable: true, + field_template: "storage_only", + field_type_path: "platform/graphics/Color", + default_value: "0", + field_group: "surround", }, { name: "border-left-style", @@ -770,6 +778,10 @@ name: "border-right-color", custom_all: true, interpolable: true, + field_template: "storage_only", + field_type_path: "platform/graphics/Color", + default_value: "0", + field_group: "surround", }, { name: "border-right-style", @@ -796,6 +808,10 @@ name: "border-top-color", custom_all: true, interpolable: true, + field_template: "storage_only", + field_type_path: "platform/graphics/Color", + default_value: "0", + field_group: "surround", }, { name: "border-top-left-radius",
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp index 9d4e5c14..1daf561 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp +++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -1181,27 +1181,30 @@ static CSSValue* TouchActionFlagsToCSSValue(TouchAction touch_action) { CSSValueList* list = CSSValueList::CreateSpaceSeparated(); - if (touch_action == kTouchActionAuto) { + if (touch_action == TouchAction::kTouchActionAuto) { list->Append(*CSSIdentifierValue::Create(CSSValueAuto)); - } else if (touch_action == kTouchActionNone) { + } else if (touch_action == TouchAction::kTouchActionNone) { list->Append(*CSSIdentifierValue::Create(CSSValueNone)); - } else if (touch_action == kTouchActionManipulation) { + } else if (touch_action == TouchAction::kTouchActionManipulation) { list->Append(*CSSIdentifierValue::Create(CSSValueManipulation)); } else { - if ((touch_action & kTouchActionPanX) == kTouchActionPanX) + if ((touch_action & TouchAction::kTouchActionPanX) == + TouchAction::kTouchActionPanX) list->Append(*CSSIdentifierValue::Create(CSSValuePanX)); - else if (touch_action & kTouchActionPanLeft) + else if (touch_action & TouchAction::kTouchActionPanLeft) list->Append(*CSSIdentifierValue::Create(CSSValuePanLeft)); - else if (touch_action & kTouchActionPanRight) + else if (touch_action & TouchAction::kTouchActionPanRight) list->Append(*CSSIdentifierValue::Create(CSSValuePanRight)); - if ((touch_action & kTouchActionPanY) == kTouchActionPanY) + if ((touch_action & TouchAction::kTouchActionPanY) == + TouchAction::kTouchActionPanY) list->Append(*CSSIdentifierValue::Create(CSSValuePanY)); - else if (touch_action & kTouchActionPanUp) + else if (touch_action & TouchAction::kTouchActionPanUp) list->Append(*CSSIdentifierValue::Create(CSSValuePanUp)); - else if (touch_action & kTouchActionPanDown) + else if (touch_action & TouchAction::kTouchActionPanDown) list->Append(*CSSIdentifierValue::Create(CSSValuePanDown)); - if ((touch_action & kTouchActionPinchZoom) == kTouchActionPinchZoom) + if ((touch_action & TouchAction::kTouchActionPinchZoom) == + TouchAction::kTouchActionPinchZoom) list->Append(*CSSIdentifierValue::Create(CSSValuePinchZoom)); }
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 b/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 index 827674e..e40c8d0 100644 --- a/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5 +++ b/third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5
@@ -23,6 +23,34 @@ has_custom_compare_and_copy: true, }, { + name: "BorderLeftColorIsCurrentColor", + field_template: "primitive", + default_value: "true", + type_name: "bool", + field_group: "surround", + }, + { + name: "BorderRightColorIsCurrentColor", + field_template: "primitive", + default_value: "true", + type_name: "bool", + field_group: "surround", + }, + { + name: "BorderTopColorIsCurrentColor", + field_template: "primitive", + default_value: "true", + type_name: "bool", + field_group: "surround", + }, + { + name: "BorderBottomColorIsCurrentColor", + field_template: "primitive", + default_value: "true", + type_name: "bool", + field_group: "surround", + }, + { name: "OriginalDisplay", field_template: "keyword", default_value: "inline",
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp index 64a30c8..329a5db9 100644 --- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp +++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -1957,6 +1957,7 @@ const CachedUAStyle* cached_ua_style = state.GetCachedUAStyle(); return cached_ua_style && (cached_ua_style->border != state.Style()->Border() || + !cached_ua_style->BorderColorEquals(*state.Style()) || (cached_ua_style->border_left_width != state.Style()->BorderLeftWidth() || cached_ua_style->border_right_width !=
diff --git a/third_party/WebKit/Source/core/dom/DOMNodeIds.cpp b/third_party/WebKit/Source/core/dom/DOMNodeIds.cpp index c638646..1a3dfa1 100644 --- a/third_party/WebKit/Source/core/dom/DOMNodeIds.cpp +++ b/third_party/WebKit/Source/core/dom/DOMNodeIds.cpp
@@ -8,16 +8,16 @@ namespace blink { -DEFINE_WEAK_IDENTIFIER_MAP(Node); +DEFINE_WEAK_IDENTIFIER_MAP(Node, DOMNodeId); // static -int DOMNodeIds::IdForNode(Node* node) { - return WeakIdentifierMap<Node>::Identifier(node); +DOMNodeId DOMNodeIds::IdForNode(Node* node) { + return WeakIdentifierMap<Node, DOMNodeId>::Identifier(node); } // static -Node* DOMNodeIds::NodeForId(int id) { - return WeakIdentifierMap<Node>::Lookup(id); +Node* DOMNodeIds::NodeForId(DOMNodeId id) { + return WeakIdentifierMap<Node, DOMNodeId>::Lookup(id); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/DOMNodeIds.h b/third_party/WebKit/Source/core/dom/DOMNodeIds.h index 15bb91f..2985a15 100644 --- a/third_party/WebKit/Source/core/dom/DOMNodeIds.h +++ b/third_party/WebKit/Source/core/dom/DOMNodeIds.h
@@ -12,14 +12,18 @@ namespace blink { -DECLARE_WEAK_IDENTIFIER_MAP(Node); +using DOMNodeId = uint64_t; + +DECLARE_WEAK_IDENTIFIER_MAP(Node, DOMNodeId); + +static const DOMNodeId kInvalidDOMNodeId = 0; class CORE_EXPORT DOMNodeIds { STATIC_ONLY(DOMNodeIds); public: - static int IdForNode(Node*); - static Node* NodeForId(int id); + static DOMNodeId IdForNode(Node*); + static Node* NodeForId(DOMNodeId); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp index 4bf5773..03d6eed 100644 --- a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp
@@ -112,12 +112,13 @@ BLINK_FROM_HERE, WTF::Bind(&internal::IdleRequestCallbackWrapper::IdleTaskFired, callback_wrapper)); - if (timeout_millis > 0) + if (timeout_millis > 0) { scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, WTF::Bind(&internal::IdleRequestCallbackWrapper::TimeoutFired, callback_wrapper), - timeout_millis); + TimeDelta::FromMilliseconds(timeout_millis)); + } TRACE_EVENT_INSTANT1("devtools.timeline", "RequestIdleCallback", TRACE_EVENT_SCOPE_THREAD, "data", InspectorIdleCallbackRequestEvent::Data(
diff --git a/third_party/WebKit/Source/core/events/TouchEvent.cpp b/third_party/WebKit/Source/core/events/TouchEvent.cpp index e4e7768..48120738 100644 --- a/third_party/WebKit/Source/core/events/TouchEvent.cpp +++ b/third_party/WebKit/Source/core/events/TouchEvent.cpp
@@ -200,7 +200,7 @@ TouchEvent::TouchEvent() : default_prevented_before_current_target_(false), - current_touch_action_(kTouchActionAuto) {} + current_touch_action_(TouchAction::kTouchActionAuto) {} TouchEvent::TouchEvent(const WebTouchEvent& event, TouchList* touches, @@ -236,7 +236,7 @@ touches_(TouchList::Create(initializer.touches())), target_touches_(TouchList::Create(initializer.targetTouches())), changed_touches_(TouchList::Create(initializer.changedTouches())), - current_touch_action_(kTouchActionAuto) {} + current_touch_action_(TouchAction::kTouchActionAuto) {} TouchEvent::~TouchEvent() {} @@ -296,7 +296,7 @@ // Only enable the warning when the current touch action is auto because // an author may use touch action but call preventDefault for interop with // browsers that don't support touch-action. - if (current_touch_action_ == kTouchActionAuto) { + if (current_touch_action_ == TouchAction::kTouchActionAuto) { message_source = kInterventionMessageSource; warning_message = "Unable to preventDefault inside passive event listener due to " @@ -318,7 +318,7 @@ if ((type() == EventTypeNames::touchstart || type() == EventTypeNames::touchmove) && view() && view()->GetFrame() && - current_touch_action_ == kTouchActionAuto) { + current_touch_action_ == TouchAction::kTouchActionAuto) { switch (HandlingPassive()) { case PassiveMode::kNotPassiveDefault: UseCounter::Count(view()->GetFrame(),
diff --git a/third_party/WebKit/Source/core/events/TouchEvent.h b/third_party/WebKit/Source/core/events/TouchEvent.h index dd88224..ecdf706b 100644 --- a/third_party/WebKit/Source/core/events/TouchEvent.h +++ b/third_party/WebKit/Source/core/events/TouchEvent.h
@@ -32,6 +32,7 @@ #include "core/events/EventDispatchMediator.h" #include "core/events/TouchEventInit.h" #include "core/events/UIEventWithKeyState.h" +#include "platform/graphics/TouchAction.h" #include "public/platform/WebTouchEvent.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/events/TouchEventTest.cpp b/third_party/WebKit/Source/core/events/TouchEventTest.cpp index e3e6ab8..779ece0 100644 --- a/third_party/WebKit/Source/core/events/TouchEventTest.cpp +++ b/third_party/WebKit/Source/core/events/TouchEventTest.cpp
@@ -65,7 +65,8 @@ WebTouchEvent web_touch_event(WebInputEvent::kTouchStart, 0, 0); web_touch_event.dispatch_type = dispatch_type; return TouchEvent::Create(web_touch_event, nullptr, nullptr, nullptr, - "touchstart", &Window(), kTouchActionAuto); + "touchstart", &Window(), + TouchAction::kTouchActionAuto); } private:
diff --git a/third_party/WebKit/Source/core/exported/BUILD.gn b/third_party/WebKit/Source/core/exported/BUILD.gn index 3ecd359..b92241b 100644 --- a/third_party/WebKit/Source/core/exported/BUILD.gn +++ b/third_party/WebKit/Source/core/exported/BUILD.gn
@@ -13,8 +13,21 @@ "WebAssociatedURLLoaderImpl.cpp", "WebAssociatedURLLoaderImpl.h", "WebBlob.cpp", + "WebCSSParser.cpp", + "WebColorSuggestion.cpp", + "WebCustomElement.cpp", + "WebDOMActivityLogger.cpp", + "WebDOMEvent.cpp", "WebDataSourceImpl.cpp", "WebDataSourceImpl.h", + "WebDateTimeSuggestion.cpp", + "WebFileChooserCompletionImpl.cpp", + "WebFileChooserCompletionImpl.h", + "WebHeap.cpp", + "WebImageCache.cpp", + "WebImageDecoder.cpp", "WebViewBase.h", ] + + defines = [ "BLINK_IMPLEMENTATION=1" ] }
diff --git a/third_party/WebKit/Source/web/WebCSSParser.cpp b/third_party/WebKit/Source/core/exported/WebCSSParser.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebCSSParser.cpp rename to third_party/WebKit/Source/core/exported/WebCSSParser.cpp
diff --git a/third_party/WebKit/Source/web/WebColorSuggestion.cpp b/third_party/WebKit/Source/core/exported/WebColorSuggestion.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebColorSuggestion.cpp rename to third_party/WebKit/Source/core/exported/WebColorSuggestion.cpp
diff --git a/third_party/WebKit/Source/web/WebCustomElement.cpp b/third_party/WebKit/Source/core/exported/WebCustomElement.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebCustomElement.cpp rename to third_party/WebKit/Source/core/exported/WebCustomElement.cpp
diff --git a/third_party/WebKit/Source/web/WebDOMActivityLogger.cpp b/third_party/WebKit/Source/core/exported/WebDOMActivityLogger.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebDOMActivityLogger.cpp rename to third_party/WebKit/Source/core/exported/WebDOMActivityLogger.cpp
diff --git a/third_party/WebKit/Source/web/WebDOMEvent.cpp b/third_party/WebKit/Source/core/exported/WebDOMEvent.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebDOMEvent.cpp rename to third_party/WebKit/Source/core/exported/WebDOMEvent.cpp
diff --git a/third_party/WebKit/Source/web/WebDateTimeSuggestion.cpp b/third_party/WebKit/Source/core/exported/WebDateTimeSuggestion.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebDateTimeSuggestion.cpp rename to third_party/WebKit/Source/core/exported/WebDateTimeSuggestion.cpp
diff --git a/third_party/WebKit/Source/web/WebFileChooserCompletionImpl.cpp b/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.cpp similarity index 97% rename from third_party/WebKit/Source/web/WebFileChooserCompletionImpl.cpp rename to third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.cpp index 07721ca..473d653 100644 --- a/third_party/WebKit/Source/web/WebFileChooserCompletionImpl.cpp +++ b/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.cpp
@@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "web/WebFileChooserCompletionImpl.h" +#include "core/exported/WebFileChooserCompletionImpl.h" #include "platform/FileMetadata.h" #include "platform/wtf/DateMath.h"
diff --git a/third_party/WebKit/Source/web/WebFileChooserCompletionImpl.h b/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h similarity index 93% rename from third_party/WebKit/Source/web/WebFileChooserCompletionImpl.h rename to third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h index a2b4796..16cf432 100644 --- a/third_party/WebKit/Source/web/WebFileChooserCompletionImpl.h +++ b/third_party/WebKit/Source/core/exported/WebFileChooserCompletionImpl.h
@@ -31,6 +31,7 @@ #ifndef WebFileChooserCompletionImpl_h #define WebFileChooserCompletionImpl_h +#include "core/CoreExport.h" #include "platform/FileChooser.h" #include "platform/wtf/PassRefPtr.h" #include "public/platform/WebString.h" @@ -39,7 +40,8 @@ namespace blink { -class WebFileChooserCompletionImpl final : public WebFileChooserCompletion { +class CORE_EXPORT WebFileChooserCompletionImpl final + : public NON_EXPORTED_BASE(WebFileChooserCompletion) { public: explicit WebFileChooserCompletionImpl(PassRefPtr<FileChooser>); ~WebFileChooserCompletionImpl() override;
diff --git a/third_party/WebKit/Source/web/WebHeap.cpp b/third_party/WebKit/Source/core/exported/WebHeap.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebHeap.cpp rename to third_party/WebKit/Source/core/exported/WebHeap.cpp
diff --git a/third_party/WebKit/Source/web/WebImageCache.cpp b/third_party/WebKit/Source/core/exported/WebImageCache.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebImageCache.cpp rename to third_party/WebKit/Source/core/exported/WebImageCache.cpp
diff --git a/third_party/WebKit/Source/web/WebImageDecoder.cpp b/third_party/WebKit/Source/core/exported/WebImageDecoder.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebImageDecoder.cpp rename to third_party/WebKit/Source/core/exported/WebImageDecoder.cpp
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 53e007a..08b6961 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1579,6 +1579,7 @@ kGATTServerDisconnectedEvent = 1970, kAnchorClickDispatchForNonConnectedNode = 1971, kHTMLParseErrorNestedForm = 1972, + kFontShapingNotDefGlyphObserved = 1973, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp index c7e6464..0250b79 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreator.cpp
@@ -613,7 +613,8 @@ std::unique_ptr<WTF::Closure> task, double delay_ms) { TaskRunnerHelper::Get(TaskType::kCanvasBlobSerialization, document_) - ->PostDelayedTask(location, std::move(task), delay_ms); + ->PostDelayedTask(location, std::move(task), + TimeDelta::FromMillisecondsD(delay_ms)); } DEFINE_TRACE(CanvasAsyncBlobCreator) {
diff --git a/third_party/WebKit/Source/core/input/TouchActionUtil.cpp b/third_party/WebKit/Source/core/input/TouchActionUtil.cpp index 5b43186..e482126c 100644 --- a/third_party/WebKit/Source/core/input/TouchActionUtil.cpp +++ b/third_party/WebKit/Source/core/input/TouchActionUtil.cpp
@@ -50,8 +50,8 @@ // prohibited actions at or below the element that supports them. // I.e. pan-related actions are considered up to the nearest scroller, // and zoom related actions are considered up to the root. - TouchAction effective_touch_action = kTouchActionAuto; - TouchAction handled_touch_actions = kTouchActionNone; + TouchAction effective_touch_action = TouchAction::kTouchActionAuto; + TouchAction handled_touch_actions = TouchAction::kTouchActionNone; for (const Node* cur_node = &node; cur_node; cur_node = ParentNodeAcrossFrames(cur_node)) { if (LayoutObject* layout_object = cur_node->GetLayoutObject()) { @@ -59,7 +59,7 @@ TouchAction action = layout_object->Style()->GetTouchAction(); action |= handled_touch_actions; effective_touch_action &= action; - if (effective_touch_action == kTouchActionNone) + if (effective_touch_action == TouchAction::kTouchActionNone) break; } @@ -68,7 +68,7 @@ if ((layout_object->IsBox() && ToLayoutBox(layout_object)->ScrollsOverflow()) || layout_object->IsLayoutView()) - handled_touch_actions |= kTouchActionPan; + handled_touch_actions |= TouchAction::kTouchActionPan; } } return effective_touch_action;
diff --git a/third_party/WebKit/Source/core/input/TouchActionUtil.h b/third_party/WebKit/Source/core/input/TouchActionUtil.h index 1104e6de..682dad22 100644 --- a/third_party/WebKit/Source/core/input/TouchActionUtil.h +++ b/third_party/WebKit/Source/core/input/TouchActionUtil.h
@@ -6,7 +6,7 @@ #define TouchActionUtil_h #include "core/CoreExport.h" -#include "core/style/ComputedStyleConstants.h" +#include "platform/graphics/TouchAction.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/input/TouchEventManager.cpp b/third_party/WebKit/Source/core/input/TouchEventManager.cpp index fa285af..7505b62 100644 --- a/third_party/WebKit/Source/core/input/TouchEventManager.cpp +++ b/third_party/WebKit/Source/core/input/TouchEventManager.cpp
@@ -107,7 +107,7 @@ region_for_touch_id_.clear(); touch_pressed_ = false; suppressing_touchmoves_within_slop_ = false; - current_touch_action_ = kTouchActionAuto; + current_touch_action_ = TouchAction::kTouchActionAuto; } DEFINE_TRACE(TouchEventManager) { @@ -197,7 +197,7 @@ if (all_touches_released) { touch_sequence_document_.Clear(); - current_touch_action_ = kTouchActionAuto; + current_touch_action_ = TouchAction::kTouchActionAuto; } WebInputEventResult event_result = WebInputEventResult::kNotHandled; @@ -369,7 +369,7 @@ TouchAction effective_touch_action = TouchActionUtil::ComputeEffectiveTouchAction(*touch_info.touch_node); - if (effective_touch_action != kTouchActionAuto) { + if (effective_touch_action != TouchAction::kTouchActionAuto) { frame_->GetPage()->GetChromeClient().SetTouchAction( frame_, effective_touch_action);
diff --git a/third_party/WebKit/Source/core/input/TouchEventManager.h b/third_party/WebKit/Source/core/input/TouchEventManager.h index d791b49..dc8654b 100644 --- a/third_party/WebKit/Source/core/input/TouchEventManager.h +++ b/third_party/WebKit/Source/core/input/TouchEventManager.h
@@ -7,6 +7,7 @@ #include "core/CoreExport.h" #include "core/events/PointerEventFactory.h" +#include "platform/graphics/TouchAction.h" #include "platform/wtf/Allocator.h" #include "platform/wtf/HashMap.h" #include "public/platform/WebInputEventResult.h"
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp index 3239bc4..408cf60 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -85,6 +85,7 @@ #include "platform/RuntimeEnabledFeatures.h" #include "platform/geometry/TransformState.h" #include "platform/graphics/GraphicsLayer.h" +#include "platform/graphics/TouchAction.h" #include "platform/graphics/paint/PropertyTreeState.h" #include "platform/instrumentation/tracing/TracedValue.h" #include "platform/wtf/allocator/Partitions.h" @@ -1817,13 +1818,13 @@ // handler will have already been added for its parent so ignore it. // TODO: Remove this blocking event handler; crbug.com/318381 TouchAction old_touch_action = - style_ ? style_->GetTouchAction() : kTouchActionAuto; + style_ ? style_->GetTouchAction() : TouchAction::kTouchActionAuto; if (GetNode() && !GetNode()->IsTextNode() && - (old_touch_action == kTouchActionAuto) != - (new_style.GetTouchAction() == kTouchActionAuto)) { + (old_touch_action == TouchAction::kTouchActionAuto) != + (new_style.GetTouchAction() == TouchAction::kTouchActionAuto)) { EventHandlerRegistry& registry = GetDocument().GetPage()->GetEventHandlerRegistry(); - if (new_style.GetTouchAction() != kTouchActionAuto) + if (new_style.GetTouchAction() != TouchAction::kTouchActionAuto) registry.DidAddEventHandler( *GetNode(), EventHandlerRegistry::kTouchStartOrMoveEventBlocking); else @@ -2645,7 +2646,7 @@ // m_style is null in cases of partial construction. Any handler we added // previously may have already been removed by the Document independently. if (GetNode() && !GetNode()->IsTextNode() && style_ && - style_->GetTouchAction() != kTouchActionAuto) { + style_->GetTouchAction() != TouchAction::kTouchActionAuto) { EventHandlerRegistry& registry = GetDocument().GetPage()->GetEventHandlerRegistry(); if (registry
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.cpp b/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.cpp index b8c5b92..fa7d7eec 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.cpp
@@ -18,6 +18,7 @@ if (!table.ShouldCollapseBorders()) return; if (old_style.Border() != table_part.StyleRef().Border() || + !old_style.BorderColorEquals(table_part.StyleRef()) || !old_style.RadiiEqual(table_part.StyleRef()) || !old_style.BorderSizeEquals(table_part.StyleRef()) || (diff.TextDecorationOrColorChanged() &&
diff --git a/third_party/WebKit/Source/core/layout/LayoutTheme.cpp b/third_party/WebKit/Source/core/layout/LayoutTheme.cpp index b002429..1733121 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTheme.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTheme.cpp
@@ -50,6 +50,7 @@ #include "platform/RuntimeEnabledFeatures.h" #include "platform/Theme.h" #include "platform/fonts/FontSelector.h" +#include "platform/graphics/TouchAction.h" #include "platform/text/PlatformLocale.h" #include "platform/text/StringTruncator.h" #include "platform/wtf/text/StringBuilder.h" @@ -626,10 +627,10 @@ if (e && (e->ShadowPseudoId() == "-webkit-media-slider-container" || e->ShadowPseudoId() == "-webkit-slider-container")) { if (style.Appearance() == kSliderVerticalPart) { - style.SetTouchAction(kTouchActionPanX); + style.SetTouchAction(TouchAction::kTouchActionPanX); style.SetAppearance(kNoControlPart); } else { - style.SetTouchAction(kTouchActionPanY); + style.SetTouchAction(TouchAction::kTouchActionPanY); style.SetAppearance(kNoControlPart); } }
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp index 2aa34f7..59387e98 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGTextChunkBuilder.cpp
@@ -208,8 +208,11 @@ if (process_text_length) { float chunk_length = length_accumulator.length(); if (length_adjust == kSVGLengthAdjustSpacing) { - float text_length_shift = (desired_text_length - chunk_length) / - length_accumulator.NumCharacters(); + float text_length_shift = 0; + if (length_accumulator.NumCharacters() > 1) { + text_length_shift = desired_text_length - chunk_length; + text_length_shift /= length_accumulator.NumCharacters() - 1; + } unsigned at_character = 0; for (auto box_iter = box_start; box_iter != box_end; ++box_iter) { Vector<SVGTextFragment>& fragments = (*box_iter)->TextFragments();
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index 12cef19..e4ab2936 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -45,6 +45,7 @@ #include "platform/geometry/FloatPoint.h" #include "platform/geometry/FloatRect.h" #include "platform/geometry/IntRect.h" +#include "platform/graphics/TouchAction.h" #include "platform/heap/Handle.h" #include "platform/loader/fetch/ResourceError.h" #include "platform/text/TextCheckerClient.h"
diff --git a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp index 7d0935f..8a42169 100644 --- a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp +++ b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
@@ -540,7 +540,7 @@ BLINK_FROM_HERE, WTF::Bind(&NavigationScheduler::NavigateTask, WrapWeakPersistent(this)), - redirect_->Delay() * 1000.0); + TimeDelta::FromSecondsD(redirect_->Delay())); probe::frameScheduledNavigation(frame_, redirect_->Delay()); }
diff --git a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h index 3d5b782..30ffc96 100644 --- a/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h +++ b/third_party/WebKit/Source/core/offscreencanvas/OffscreenCanvas.h
@@ -7,6 +7,7 @@ #include <memory> #include "bindings/core/v8/ScriptPromise.h" +#include "core/dom/DOMNodeIds.h" #include "core/events/EventTarget.h" #include "core/html/HTMLCanvasElement.h" #include "core/html/canvas/CanvasImageSource.h" @@ -59,12 +60,12 @@ const IntSize& Size() const override { return size_; } void SetSize(const IntSize&); - void SetPlaceholderCanvasId(int canvas_id) { + void SetPlaceholderCanvasId(DOMNodeId canvas_id) { placeholder_canvas_id_ = canvas_id; } - int PlaceholderCanvasId() const { return placeholder_canvas_id_; } + DOMNodeId PlaceholderCanvasId() const { return placeholder_canvas_id_; } bool HasPlaceholderCanvas() { - return placeholder_canvas_id_ != kNoPlaceholderCanvas; + return placeholder_canvas_id_ != kInvalidDOMNodeId; } bool IsNeutered() const { return is_neutered_; } void SetNeutered(); @@ -166,11 +167,7 @@ Member<CanvasRenderingContext> context_; WeakMember<ExecutionContext> execution_context_; - enum { - kNoPlaceholderCanvas = -1, // DOMNodeIds starts from 0, using -1 to - // indicate no associated canvas element. - }; - int placeholder_canvas_id_ = kNoPlaceholderCanvas; + DOMNodeId placeholder_canvas_id_ = kInvalidDOMNodeId; IntSize size_; bool is_neutered_ = false;
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 48e803a2..c709d97 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -35,6 +35,7 @@ #include "platform/Cursor.h" #include "platform/PlatformChromeClient.h" #include "platform/PopupMenu.h" +#include "platform/graphics/TouchAction.h" #include "platform/heap/Handle.h" #include "platform/scroll/ScrollTypes.h" #include "platform/wtf/Forward.h"
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollState.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollState.cpp index 12053e2f..eb27f48 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollState.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollState.cpp
@@ -93,10 +93,11 @@ } Element* ScrollState::CurrentNativeScrollingElement() const { - uint64_t element_id = data_->current_native_scrolling_element().primaryId; - if (element_id == 0) + DOMNodeId dom_node_id = DomNodeIdFromCompositorElementId( + data_->current_native_scrolling_element()); + if (dom_node_id == kInvalidDOMNodeId) return nullptr; - return ElementForId(element_id); + return ElementForId(dom_node_id); } void ScrollState::SetCurrentNativeScrollingElement(Element* element) {
diff --git a/third_party/WebKit/Source/core/style/BUILD.gn b/third_party/WebKit/Source/core/style/BUILD.gn index 03386c9..4083c27 100644 --- a/third_party/WebKit/Source/core/style/BUILD.gn +++ b/third_party/WebKit/Source/core/style/BUILD.gn
@@ -12,12 +12,12 @@ "AppliedTextDecoration.h", "BasicShapes.cpp", "BasicShapes.h", - "BorderColorAndStyle.h", "BorderData.h", "BorderEdge.cpp", "BorderEdge.h", "BorderImageLength.h", "BorderImageLengthBox.h", + "BorderStyle.h", "BorderValue.h", "CachedUAStyle.h", "ClipPathOperation.cpp", @@ -56,7 +56,6 @@ "ShadowData.h", "ShadowList.cpp", "ShadowList.h", - "StyleBoxData.h", "StyleContentAlignmentData.h", "StyleDeprecatedFlexibleBoxData.cpp", "StyleDeprecatedFlexibleBoxData.h",
diff --git a/third_party/WebKit/Source/core/style/BorderData.h b/third_party/WebKit/Source/core/style/BorderData.h index c6d1888..8bf5a6e7 100644 --- a/third_party/WebKit/Source/core/style/BorderData.h +++ b/third_party/WebKit/Source/core/style/BorderData.h
@@ -25,7 +25,7 @@ #ifndef BorderData_h #define BorderData_h -#include "core/style/BorderColorAndStyle.h" +#include "core/style/BorderStyle.h" #include "core/style/NinePieceImage.h" #include "platform/LengthSize.h" #include "platform/geometry/IntRect.h" @@ -47,13 +47,6 @@ bool HasBorderFill() const { return image_.HasImage() && image_.Fill(); } - bool HasBorderColorReferencingCurrentColor() const { - return (left_.NonZero() && left_.GetColor().IsCurrentColor()) || - (right_.NonZero() && right_.GetColor().IsCurrentColor()) || - (top_.NonZero() && top_.GetColor().IsCurrentColor()) || - (bottom_.NonZero() && bottom_.GetColor().IsCurrentColor()); - } - bool operator==(const BorderData& o) const { return left_ == o.left_ && right_ == o.right_ && top_ == o.top_ && bottom_ == o.bottom_ && image_ == o.image_; @@ -71,18 +64,18 @@ bool operator!=(const BorderData& o) const { return !(*this == o); } - const BorderColorAndStyle& Left() const { return left_; } - const BorderColorAndStyle& Right() const { return right_; } - const BorderColorAndStyle& Top() const { return top_; } - const BorderColorAndStyle& Bottom() const { return bottom_; } + const BorderStyle& Left() const { return left_; } + const BorderStyle& Right() const { return right_; } + const BorderStyle& Top() const { return top_; } + const BorderStyle& Bottom() const { return bottom_; } const NinePieceImage& GetImage() const { return image_; } private: - BorderColorAndStyle left_; - BorderColorAndStyle right_; - BorderColorAndStyle top_; - BorderColorAndStyle bottom_; + BorderStyle left_; + BorderStyle right_; + BorderStyle top_; + BorderStyle bottom_; NinePieceImage image_; };
diff --git a/third_party/WebKit/Source/core/style/BorderColorAndStyle.h b/third_party/WebKit/Source/core/style/BorderStyle.h similarity index 63% rename from third_party/WebKit/Source/core/style/BorderColorAndStyle.h rename to third_party/WebKit/Source/core/style/BorderStyle.h index 757254f2..b243bca0 100644 --- a/third_party/WebKit/Source/core/style/BorderColorAndStyle.h +++ b/third_party/WebKit/Source/core/style/BorderStyle.h
@@ -22,8 +22,8 @@ * */ -#ifndef BorderColorAndStyle_h -#define BorderColorAndStyle_h +#ifndef BorderStyle_h +#define BorderStyle_h #include "core/css/StyleColor.h" #include "core/style/ComputedStyleConstants.h" @@ -32,31 +32,20 @@ namespace blink { -class BorderColorAndStyle { +class BorderStyle { DISALLOW_NEW(); friend class ComputedStyle; public: - BorderColorAndStyle() - : color_(0), - color_is_current_color_(true), - style_(kBorderStyleNone), - is_auto_(kOutlineIsAutoOff) {} + BorderStyle() : style_(kBorderStyleNone), is_auto_(kOutlineIsAutoOff) {} bool NonZero() const { return (style_ != kBorderStyleNone); } - bool IsTransparent() const { - return !color_is_current_color_ && !color_.Alpha(); - } - - bool operator==(const BorderColorAndStyle& o) const { - return style_ == o.style_ && color_ == o.color_ && - color_is_current_color_ == o.color_is_current_color_; - } + bool operator==(const BorderStyle& o) const { return style_ == o.style_; } // The default width is 3px, but if the style is none we compute a value of 0 // (in ComputedStyle itself) - bool VisuallyEqual(const BorderColorAndStyle& o) const { + bool VisuallyEqual(const BorderStyle& o) const { if (style_ == kBorderStyleNone && o.style_ == kBorderStyleNone) return true; if (style_ == kBorderStyleHidden && o.style_ == kBorderStyleHidden) @@ -64,17 +53,7 @@ return *this == o; } - bool operator!=(const BorderColorAndStyle& o) const { return !(*this == o); } - - void SetColor(const StyleColor& color) { - color_ = color.Resolve(Color()); - color_is_current_color_ = color.IsCurrentColor(); - } - - StyleColor GetColor() const { - return color_is_current_color_ ? StyleColor::CurrentColor() - : StyleColor(color_); - } + bool operator!=(const BorderStyle& o) const { return !(*this == o); } EBorderStyle Style() const { return static_cast<EBorderStyle>(style_); } void SetStyle(EBorderStyle style) { style_ = style; } @@ -82,15 +61,7 @@ OutlineIsAuto IsAuto() const { return static_cast<OutlineIsAuto>(is_auto_); } void SetIsAuto(OutlineIsAuto is_auto) { is_auto_ = is_auto; } - bool ColorIsCurrentColor() const { return color_is_current_color_; } - void SetColorIsCurrentColor(bool color_is_current_color) { - color_is_current_color_ = static_cast<unsigned>(color_is_current_color); - } - protected: - Color color_; - unsigned color_is_current_color_ : 1; - unsigned style_ : 4; // EBorderStyle // This is only used by OutlineValue but moved here to keep the bits packed. @@ -99,4 +70,4 @@ } // namespace blink -#endif // BorderColorAndStyle_h +#endif // BorderStyle_h
diff --git a/third_party/WebKit/Source/core/style/BorderValue.h b/third_party/WebKit/Source/core/style/BorderValue.h index 0c71ba0..2682ced9 100644 --- a/third_party/WebKit/Source/core/style/BorderValue.h +++ b/third_party/WebKit/Source/core/style/BorderValue.h
@@ -26,7 +26,7 @@ #define BorderValue_h #include "core/css/StyleColor.h" -#include "core/style/BorderColorAndStyle.h" +#include "core/style/BorderStyle.h" #include "core/style/ComputedStyleConstants.h" #include "platform/graphics/Color.h" #include "platform/wtf/Allocator.h" @@ -46,9 +46,8 @@ SetWidth(3); } - BorderValue(const BorderColorAndStyle& data, float width) { - SetColor(data.GetColor()); - SetColorIsCurrentColor(ColorIsCurrentColor()); + BorderValue(const BorderStyle& data, const StyleColor& color, float width) { + SetColor(color.Resolve(Color())); SetStyle(data.Style()); SetIsAuto(data.IsAuto()); SetWidth(width);
diff --git a/third_party/WebKit/Source/core/style/CachedUAStyle.h b/third_party/WebKit/Source/core/style/CachedUAStyle.h index 1f8c095..07504a6d 100644 --- a/third_party/WebKit/Source/core/style/CachedUAStyle.h +++ b/third_party/WebKit/Source/core/style/CachedUAStyle.h
@@ -25,6 +25,7 @@ #include <memory> #include "core/style/ComputedStyle.h" +#include "platform/graphics/Color.h" #include "platform/wtf/Allocator.h" #include "platform/wtf/Noncopyable.h" #include "platform/wtf/PtrUtil.h" @@ -38,17 +39,41 @@ class CachedUAStyle { USING_FAST_MALLOC(CachedUAStyle); WTF_MAKE_NONCOPYABLE(CachedUAStyle); + friend class ComputedStyle; public: static std::unique_ptr<CachedUAStyle> Create(const ComputedStyle* style) { return WTF::WrapUnique(new CachedUAStyle(style)); } + bool BorderColorEquals(const ComputedStyle& other) const { + return (border_left_color == other.BorderLeftColorInternal() && + border_right_color == other.BorderRightColorInternal() && + border_top_color == other.BorderTopColorInternal() && + border_bottom_color == other.BorderBottomColorInternal()) && + (border_left_color_is_current_color == + other.BorderLeftColorIsCurrentColor() && + border_right_color_is_current_color == + other.BorderRightColorIsCurrentColor() && + border_top_color_is_current_color == + other.BorderTopColorIsCurrentColor() && + border_bottom_color_is_current_color == + other.BorderBottomColorIsCurrentColor()); + } + BorderData border; LengthSize top_left_; LengthSize top_right_; LengthSize bottom_left_; LengthSize bottom_right_; + Color border_left_color; + Color border_right_color; + Color border_top_color; + Color border_bottom_color; + bool border_left_color_is_current_color; + bool border_right_color_is_current_color; + bool border_top_color_is_current_color; + bool border_bottom_color_is_current_color; float border_left_width; float border_right_width; float border_top_width; @@ -63,6 +88,18 @@ top_right_(style->BorderTopRightRadius()), bottom_left_(style->BorderBottomLeftRadius()), bottom_right_(style->BorderBottomRightRadius()), + border_left_color(style->BorderLeftColorInternal()), + border_right_color(style->BorderRightColorInternal()), + border_top_color(style->BorderTopColorInternal()), + border_bottom_color(style->BorderBottomColorInternal()), + border_left_color_is_current_color( + style->BorderLeftColorIsCurrentColor()), + border_right_color_is_current_color( + style->BorderRightColorIsCurrentColor()), + border_top_color_is_current_color( + style->BorderTopColorIsCurrentColor()), + border_bottom_color_is_current_color( + style->BorderBottomColorIsCurrentColor()), border_left_width(style->BorderLeftWidth()), border_right_width(style->BorderRightWidth()), border_top_width(style->BorderTopWidth()),
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.cpp b/third_party/WebKit/Source/core/style/ComputedStyle.cpp index 21d6407d..6990044f 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.cpp +++ b/third_party/WebKit/Source/core/style/ComputedStyle.cpp
@@ -887,7 +887,8 @@ PrintColorAdjust() != other.PrintColorAdjust() || InsideLink() != other.InsideLink() || !Border().VisuallyEqual(other.Border()) || !RadiiEqual(other) || - !BorderSizeEquals(other) || *background_data_ != *other.background_data_) + !BorderColorVisuallyEquals(other) || !BorderSizeEquals(other) || + *background_data_ != *other.background_data_) return true; if (rare_inherited_data_.Get() != other.rare_inherited_data_.Get()) {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h index efa91d1..77a3e50 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyle.h +++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -37,7 +37,6 @@ #include "core/style/LineClampValue.h" #include "core/style/NinePieceImage.h" #include "core/style/SVGComputedStyle.h" -#include "core/style/StyleBoxData.h" #include "core/style/StyleContentAlignmentData.h" #include "core/style/StyleDeprecatedFlexibleBoxData.h" #include "core/style/StyleDifference.h" @@ -65,6 +64,7 @@ #include "platform/geometry/FloatRoundedRect.h" #include "platform/geometry/LayoutRectOutsets.h" #include "platform/graphics/Color.h" +#include "platform/graphics/TouchAction.h" #include "platform/scroll/ScrollTypes.h" #include "platform/text/TextDirection.h" #include "platform/text/UnicodeBidi.h" @@ -180,6 +180,58 @@ friend class StyleResolverState; friend class StyleResolver; + private: + class StyleBoxData : public RefCountedCopyable<StyleBoxData> { + public: + static PassRefPtr<StyleBoxData> Create() { + return AdoptRef(new StyleBoxData); + } + PassRefPtr<StyleBoxData> Copy() const { + return AdoptRef(new StyleBoxData(*this)); + } + + bool operator==(const StyleBoxData& other) const { + return width_ == other.width_ && height_ == other.height_ && + min_width_ == other.min_width_ && max_width_ == other.max_width_ && + min_height_ == other.min_height_ && + max_height_ == other.max_height_ && + vertical_align_length_ == other.vertical_align_length_ && + z_index_ == other.z_index_ && + has_auto_z_index_ == other.has_auto_z_index_ && + box_sizing_ == other.box_sizing_ && + box_decoration_break_ == other.box_decoration_break_; + } + bool operator!=(const StyleBoxData& o) const { return !(*this == o); } + + Length width_; + Length height_; + Length min_width_; + Length max_width_; + Length min_height_; + Length max_height_; + Length vertical_align_length_; + int z_index_; + unsigned has_auto_z_index_ : 1; + unsigned box_sizing_ : 1; // EBoxSizing + unsigned box_decoration_break_ : 1; // EBoxDecorationBreak + + private: + StyleBoxData() + : width_(Length()), + height_(Length()), + min_width_(Length()), + max_width_(Length(kMaxSizeNone)), + min_height_(Length()), + max_height_(Length(kMaxSizeNone)), + z_index_(0), + has_auto_z_index_(static_cast<unsigned>(true)), + box_sizing_(static_cast<unsigned>(EBoxSizing::kContentBox)), + box_decoration_break_( + static_cast<unsigned>(EBoxDecorationBreak::kSlice)) {} + + StyleBoxData(const StyleBoxData&) = default; + }; + protected: // non-inherited attributes DataRef<StyleBoxData> box_data_; @@ -560,23 +612,35 @@ // Border color properties. // border-left-color - void SetBorderLeftColor(const StyleColor& v) { - SET_BORDERVALUE_COLOR(surround_data_, border_.left_, v); + void SetBorderLeftColor(const StyleColor& color) { + if (!compareEqual(BorderLeftColor(), color)) { + SetBorderLeftColorInternal(color.Resolve(Color())); + SetBorderLeftColorIsCurrentColor(color.IsCurrentColor()); + } } // border-right-color - void SetBorderRightColor(const StyleColor& v) { - SET_BORDERVALUE_COLOR(surround_data_, border_.right_, v); + void SetBorderRightColor(const StyleColor& color) { + if (!compareEqual(BorderRightColor(), color)) { + SetBorderRightColorInternal(color.Resolve(Color())); + SetBorderRightColorIsCurrentColor(color.IsCurrentColor()); + } } // border-top-color - void SetBorderTopColor(const StyleColor& v) { - SET_BORDERVALUE_COLOR(surround_data_, border_.top_, v); + void SetBorderTopColor(const StyleColor& color) { + if (!compareEqual(BorderTopColor(), color)) { + SetBorderTopColorInternal(color.Resolve(Color())); + SetBorderTopColorIsCurrentColor(color.IsCurrentColor()); + } } // border-bottom-color - void SetBorderBottomColor(const StyleColor& v) { - SET_BORDERVALUE_COLOR(surround_data_, border_.bottom_, v); + void SetBorderBottomColor(const StyleColor& color) { + if (!compareEqual(BorderBottomColor(), color)) { + SetBorderBottomColorInternal(color.Resolve(Color())); + SetBorderBottomColorIsCurrentColor(color.IsCurrentColor()); + } } // box-shadow (aka -webkit-box-shadow) @@ -1532,7 +1596,9 @@ } // touch-action - static TouchAction InitialTouchAction() { return kTouchActionAuto; } + static TouchAction InitialTouchAction() { + return TouchAction::kTouchActionAuto; + } TouchAction GetTouchAction() const { return static_cast<TouchAction>(rare_non_inherited_data_->touch_action_); } @@ -2845,16 +2911,20 @@ void SetBorderImageSlicesFill(bool); const BorderData& Border() const { return surround_data_->border_; } const BorderValue BorderLeft() const { - return BorderValue(surround_data_->border_.Left(), BorderLeftWidth()); + return BorderValue(surround_data_->border_.Left(), BorderLeftColor(), + BorderLeftWidth()); } const BorderValue BorderRight() const { - return BorderValue(surround_data_->border_.Right(), BorderRightWidth()); + return BorderValue(surround_data_->border_.Right(), BorderRightColor(), + BorderRightWidth()); } const BorderValue BorderTop() const { - return BorderValue(surround_data_->border_.Top(), BorderTopWidth()); + return BorderValue(surround_data_->border_.Top(), BorderTopColor(), + BorderTopWidth()); } const BorderValue BorderBottom() const { - return BorderValue(surround_data_->border_.Bottom(), BorderBottomWidth()); + return BorderValue(surround_data_->border_.Bottom(), BorderBottomColor(), + BorderBottomWidth()); } bool BorderSizeEquals(const ComputedStyle& o) const { return BorderWidthEquals(BorderLeftWidth(), o.BorderLeftWidth()) && @@ -2891,7 +2961,10 @@ return false; } bool HasBorderColorReferencingCurrentColor() const { - return Border().HasBorderColorReferencingCurrentColor(); + return (BorderLeft().NonZero() && BorderLeftColor().IsCurrentColor()) || + (BorderRight().NonZero() && BorderRightColor().IsCurrentColor()) || + (BorderTop().NonZero() && BorderTopColor().IsCurrentColor()) || + (BorderBottom().NonZero() && BorderBottomColor().IsCurrentColor()); } bool RadiiEqual(const ComputedStyle& o) const { @@ -2901,6 +2974,43 @@ BorderBottomRightRadius() == o.BorderBottomRightRadius(); } + bool BorderColorEquals(const ComputedStyle& o) const { + return (BorderLeftColorInternal() == o.BorderLeftColorInternal() && + BorderRightColorInternal() == o.BorderRightColorInternal() && + BorderTopColorInternal() == o.BorderTopColorInternal() && + BorderBottomColorInternal() == o.BorderBottomColorInternal()) && + (BorderLeftColorIsCurrentColor() == + o.BorderLeftColorIsCurrentColor() && + BorderRightColorIsCurrentColor() == + o.BorderRightColorIsCurrentColor() && + BorderTopColorIsCurrentColor() == + o.BorderTopColorIsCurrentColor() && + BorderBottomColorIsCurrentColor() == + o.BorderBottomColorIsCurrentColor()); + } + + bool BorderColorVisuallyEquals(const ComputedStyle& o) const { + if ((BorderLeftStyle() == kBorderStyleNone && + o.BorderLeftStyle() == kBorderStyleNone) && + (BorderRightStyle() == kBorderStyleNone && + o.BorderRightStyle() == kBorderStyleNone) && + (BorderTopStyle() == kBorderStyleNone && + o.BorderTopStyle() == kBorderStyleNone) && + (BorderBottomStyle() == kBorderStyleNone && + o.BorderBottomStyle() == kBorderStyleNone)) + return true; + if ((BorderLeftStyle() == kBorderStyleHidden && + o.BorderLeftStyle() == kBorderStyleHidden) && + (BorderRightStyle() == kBorderStyleHidden && + o.BorderRightStyle() == kBorderStyleHidden) && + (BorderTopStyle() == kBorderStyleHidden && + o.BorderTopStyle() == kBorderStyleHidden) && + (BorderBottomStyle() == kBorderStyleHidden && + o.BorderBottomStyle() == kBorderStyleHidden)) + return true; + return BorderColorEquals(o); + } + void ResetBorder() { ResetBorderImage(); ResetBorderTop(); @@ -2912,21 +3022,30 @@ ResetBorderBottomLeftRadius(); ResetBorderBottomRightRadius(); } + void ResetBorderTop() { - SET_VAR(surround_data_, border_.top_, BorderColorAndStyle()); + SET_VAR(surround_data_, border_.top_, BorderStyle()); SetBorderTopWidth(3); + SetBorderTopColorInternal(0); + SetBorderTopColorInternal(true); } void ResetBorderRight() { - SET_VAR(surround_data_, border_.right_, BorderColorAndStyle()); + SET_VAR(surround_data_, border_.right_, BorderStyle()); SetBorderRightWidth(3); + SetBorderRightColorInternal(0); + SetBorderRightColorInternal(true); } void ResetBorderBottom() { - SET_VAR(surround_data_, border_.bottom_, BorderColorAndStyle()); + SET_VAR(surround_data_, border_.bottom_, BorderStyle()); SetBorderBottomWidth(3); + SetBorderBottomColorInternal(0); + SetBorderBottomColorInternal(true); } void ResetBorderLeft() { - SET_VAR(surround_data_, border_.left_, BorderColorAndStyle()); + SET_VAR(surround_data_, border_.left_, BorderStyle()); SetBorderLeftWidth(3); + SetBorderLeftColorInternal(0); + SetBorderLeftColorInternal(true); } void ResetBorderImage() { SET_VAR(surround_data_, border_.image_, NinePieceImage()); @@ -3488,17 +3607,26 @@ // Color accessors are all private to make sure callers use // VisitedDependentColor instead to access them. StyleColor BorderLeftColor() const { - return surround_data_->border_.Left().GetColor(); + return BorderLeftColorIsCurrentColor() + ? StyleColor::CurrentColor() + : StyleColor(BorderLeftColorInternal()); } StyleColor BorderRightColor() const { - return surround_data_->border_.Right().GetColor(); + return BorderRightColorIsCurrentColor() + ? StyleColor::CurrentColor() + : StyleColor(BorderRightColorInternal()); } StyleColor BorderTopColor() const { - return surround_data_->border_.Top().GetColor(); + return BorderTopColorIsCurrentColor() + ? StyleColor::CurrentColor() + : StyleColor(BorderTopColorInternal()); } StyleColor BorderBottomColor() const { - return surround_data_->border_.Bottom().GetColor(); + return BorderBottomColorIsCurrentColor() + ? StyleColor::CurrentColor() + : StyleColor(BorderBottomColorInternal()); } + StyleColor BackgroundColor() const { return background_data_->background_color_; }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h index 8fd1c06..f8bae4d 100644 --- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h +++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -381,34 +381,6 @@ kDraggableRegionNoDrag }; -static const size_t kTouchActionBits = 6; -enum TouchAction { - kTouchActionNone = 0x0, - kTouchActionPanLeft = 0x1, - kTouchActionPanRight = 0x2, - kTouchActionPanX = kTouchActionPanLeft | kTouchActionPanRight, - kTouchActionPanUp = 0x4, - kTouchActionPanDown = 0x8, - kTouchActionPanY = kTouchActionPanUp | kTouchActionPanDown, - kTouchActionPan = kTouchActionPanX | kTouchActionPanY, - kTouchActionPinchZoom = 0x10, - kTouchActionManipulation = kTouchActionPan | kTouchActionPinchZoom, - kTouchActionDoubleTapZoom = 0x20, - kTouchActionAuto = kTouchActionManipulation | kTouchActionDoubleTapZoom -}; -inline TouchAction operator|(TouchAction a, TouchAction b) { - return static_cast<TouchAction>(int(a) | int(b)); -} -inline TouchAction& operator|=(TouchAction& a, TouchAction b) { - return a = a | b; -} -inline TouchAction operator&(TouchAction a, TouchAction b) { - return static_cast<TouchAction>(int(a) & int(b)); -} -inline TouchAction& operator&=(TouchAction& a, TouchAction b) { - return a = a & b; -} - enum EIsolation { kIsolationAuto, kIsolationIsolate }; static const size_t kContainmentBits = 4;
diff --git a/third_party/WebKit/Source/core/style/StyleBoxData.h b/third_party/WebKit/Source/core/style/StyleBoxData.h deleted file mode 100644 index 4017dbb..0000000 --- a/third_party/WebKit/Source/core/style/StyleBoxData.h +++ /dev/null
@@ -1,98 +0,0 @@ -/* - * Copyright (C) 2000 Lars Knoll (knoll@kde.org) - * (C) 2000 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef StyleBoxData_h -#define StyleBoxData_h - -#include "core/CoreExport.h" -#include "core/style/ComputedStyleConstants.h" -#include "platform/Length.h" -#include "platform/wtf/PassRefPtr.h" -#include "platform/wtf/RefCounted.h" - -namespace blink { - -// TODO(sashab): Move this into a private class on ComputedStyle, and remove -// all methods on it, merging them into copy/creation methods on ComputedStyle -// instead. Keep the allocation logic, only allocating a new object if needed. -class CORE_EXPORT StyleBoxData : public RefCountedCopyable<StyleBoxData> { - public: - static PassRefPtr<StyleBoxData> Create() { - return AdoptRef(new StyleBoxData); - } - PassRefPtr<StyleBoxData> Copy() const { - return AdoptRef(new StyleBoxData(*this)); - } - - bool operator==(const StyleBoxData& other) const { - return width_ == other.width_ && height_ == other.height_ && - min_width_ == other.min_width_ && max_width_ == other.max_width_ && - min_height_ == other.min_height_ && - max_height_ == other.max_height_ && - vertical_align_length_ == other.vertical_align_length_ && - z_index_ == other.z_index_ && - has_auto_z_index_ == other.has_auto_z_index_ && - box_sizing_ == other.box_sizing_ && - box_decoration_break_ == other.box_decoration_break_; - } - bool operator!=(const StyleBoxData& o) const { return !(*this == o); } - - private: - friend class ComputedStyle; - - StyleBoxData() - : width_(Length()), - height_(Length()), - min_width_(Length()), - max_width_(Length(kMaxSizeNone)), - min_height_(Length()), - max_height_(Length(kMaxSizeNone)), - z_index_(0), - has_auto_z_index_(static_cast<unsigned>(true)), - box_sizing_(static_cast<unsigned>(EBoxSizing::kContentBox)), - box_decoration_break_( - static_cast<unsigned>(EBoxDecorationBreak::kSlice)) {} - - StyleBoxData(const StyleBoxData&) = default; - - Length width_; - Length height_; - - Length min_width_; - Length max_width_; - - Length min_height_; - Length max_height_; - - Length vertical_align_length_; - - int z_index_; - unsigned has_auto_z_index_ : 1; - unsigned box_sizing_ : 1; // EBoxSizing - unsigned box_decoration_break_ : 1; // EBoxDecorationBreak -}; - -} // namespace blink - -#endif // StyleBoxData_h
diff --git a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h index d3e1605..2b7cf9ab 100644 --- a/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h +++ b/third_party/WebKit/Source/core/style/StyleRareNonInheritedData.h
@@ -42,6 +42,7 @@ #include "core/style/StyleScrollSnapData.h" #include "core/style/StyleSelfAlignmentData.h" #include "platform/LengthPoint.h" +#include "platform/graphics/TouchAction.h" #include "platform/wtf/PassRefPtr.h" #include "platform/wtf/RefCounted.h" #include "platform/wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp index 8bb8859..e35a0aa7 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -348,7 +348,8 @@ BLINK_FROM_HERE, WTF::Bind(&WorkerThread::MayForciblyTerminateExecution, WTF::Unretained(this)), - forcible_termination_delay_in_ms_); + TimeDelta::FromMilliseconds( + forcible_termination_delay_in_ms_)); break; } }
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js index 134d55d2..2b2ce62e 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
@@ -226,7 +226,8 @@ SDK.CSSMetadata._distanceProperties = new Set([ 'background-position', 'border-spacing', 'bottom', 'font-size', 'height', 'left', 'letter-spacing', 'max-height', - 'max-width', 'min-height', 'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing' + 'max-width', 'min-height', 'min-width', 'right', 'text-indent', 'top', 'width', 'word-spacing', 'grid-row-gap', + 'grid-column-gap' ]); SDK.CSSMetadata._bezierAwareProperties = new Set([ @@ -705,6 +706,21 @@ ] }, 'caret-color': {values: ['auto']}, + 'grid-template-columns': {values: ['none']}, + 'grid-template-rows': {values: ['none']}, + 'grid-template-areas': {values: ['none']}, + 'grid-template': {values: ['none']}, + 'grid-auto-columns': {values: ['auto']}, + 'grid-auto-rows': {values: ['auto']}, + 'grid-auto-flow': {values: ['row', 'column', 'dense']}, + 'grid': {values: ['none']}, + 'grid-row-start': {values: ['auto']}, + 'grid-column-start': {values: ['auto']}, + 'grid-row-end': {values: ['auto']}, + 'grid-column-end': {values: ['auto']}, + 'grid-row': {values: ['auto']}, + 'grid-column': {values: ['auto']}, + 'grid-area': {values: ['auto']}, }; // Weight of CSS properties based on their usage from https://www.chromestatus.com/metrics/css/popularity
diff --git a/third_party/WebKit/Source/devtools/scripts/build/generate_devtools_grd.py b/third_party/WebKit/Source/devtools/scripts/build/generate_devtools_grd.py index 5fd837e7..6794459 100755 --- a/third_party/WebKit/Source/devtools/scripts/build/generate_devtools_grd.py +++ b/third_party/WebKit/Source/devtools/scripts/build/generate_devtools_grd.py
@@ -53,7 +53,9 @@ <output filename="devtools_resources.pak" type="data_package" /> </outputs> <release seq="1"> - <includes></includes> + <includes> + <include name="COMPRESSED_PROTOCOL_JSON" file="${compressed_protocol_file}" use_base_dir="false" type="BINDATA" /> + </includes> </release> </grit> '''
diff --git a/third_party/WebKit/Source/modules/BUILD.gn b/third_party/WebKit/Source/modules/BUILD.gn index 6c79dba..0f8a89f 100644 --- a/third_party/WebKit/Source/modules/BUILD.gn +++ b/third_party/WebKit/Source/modules/BUILD.gn
@@ -117,6 +117,7 @@ "//third_party/WebKit/Source/modules/encoding", "//third_party/WebKit/Source/modules/encryptedmedia", "//third_party/WebKit/Source/modules/eventsource", + "//third_party/WebKit/Source/modules/exported", "//third_party/WebKit/Source/modules/fetch", "//third_party/WebKit/Source/modules/filesystem", "//third_party/WebKit/Source/modules/gamepad",
diff --git a/third_party/WebKit/Source/modules/DEPS b/third_party/WebKit/Source/modules/DEPS index 9f2ddf77..3a37149 100644 --- a/third_party/WebKit/Source/modules/DEPS +++ b/third_party/WebKit/Source/modules/DEPS
@@ -4,5 +4,6 @@ "+modules", "+platform", "+public/platform", + "+public/web", "-web", ]
diff --git a/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModuleTest.cpp b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModuleTest.cpp index 50ab0381..9a004d5 100644 --- a/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModuleTest.cpp +++ b/third_party/WebKit/Source/modules/canvas/HTMLCanvasElementModuleTest.cpp
@@ -50,7 +50,7 @@ NonThrowableExceptionState exception_state; OffscreenCanvas* offscreen_canvas = TransferControlToOffscreen(exception_state); - int canvas_id = offscreen_canvas->PlaceholderCanvasId(); + DOMNodeId canvas_id = offscreen_canvas->PlaceholderCanvasId(); EXPECT_EQ(canvas_id, DOMNodeIds::IdForNode(&(CanvasElement()))); }
diff --git a/third_party/WebKit/Source/modules/exported/BUILD.gn b/third_party/WebKit/Source/modules/exported/BUILD.gn new file mode 100644 index 0000000..b23096d --- /dev/null +++ b/third_party/WebKit/Source/modules/exported/BUILD.gn
@@ -0,0 +1,15 @@ +# Copyright 2017 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. +import("//third_party/WebKit/Source/modules/modules.gni") + +blink_modules_sources("exported") { + sources = [ + "WebCryptoNormalize.cpp", + "WebDOMFileSystem.cpp", + "WebDOMMediaStreamTrack.cpp", + "WebDatabase.cpp", + ] + + defines = [ "BLINK_MODULES_IMPLEMENTATION=1" ] +}
diff --git a/third_party/WebKit/Source/web/WebCryptoNormalize.cpp b/third_party/WebKit/Source/modules/exported/WebCryptoNormalize.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebCryptoNormalize.cpp rename to third_party/WebKit/Source/modules/exported/WebCryptoNormalize.cpp
diff --git a/third_party/WebKit/Source/web/WebDOMFileSystem.cpp b/third_party/WebKit/Source/modules/exported/WebDOMFileSystem.cpp similarity index 98% rename from third_party/WebKit/Source/web/WebDOMFileSystem.cpp rename to third_party/WebKit/Source/modules/exported/WebDOMFileSystem.cpp index 0b13c00..a5b49fb 100644 --- a/third_party/WebKit/Source/web/WebDOMFileSystem.cpp +++ b/third_party/WebKit/Source/modules/exported/WebDOMFileSystem.cpp
@@ -132,9 +132,10 @@ DCHECK(creation_context->CreationContext() == isolate->GetCurrentContext()); if (!private_.Get()) return v8::Local<v8::Value>(); - if (entry_type == kEntryTypeDirectory) + if (entry_type == kEntryTypeDirectory) { return ToV8(DirectoryEntry::Create(private_.Get(), path), isolate->GetCurrentContext()->Global(), isolate); + } DCHECK_EQ(entry_type, kEntryTypeFile); return ToV8(FileEntry::Create(private_.Get(), path), isolate->GetCurrentContext()->Global(), isolate);
diff --git a/third_party/WebKit/Source/web/WebDOMMediaStreamTrack.cpp b/third_party/WebKit/Source/modules/exported/WebDOMMediaStreamTrack.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebDOMMediaStreamTrack.cpp rename to third_party/WebKit/Source/modules/exported/WebDOMMediaStreamTrack.cpp
diff --git a/third_party/WebKit/Source/web/WebDatabase.cpp b/third_party/WebKit/Source/modules/exported/WebDatabase.cpp similarity index 100% rename from third_party/WebKit/Source/web/WebDatabase.cpp rename to third_party/WebKit/Source/modules/exported/WebDatabase.cpp
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 28ce7df..59f8d8d 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -955,6 +955,7 @@ "graphics/StrokeData.cpp", "graphics/StrokeData.h", "graphics/TextureHolder.h", + "graphics/TouchAction.h", "graphics/UnacceleratedImageBufferSurface.cpp", "graphics/UnacceleratedImageBufferSurface.h", "graphics/UnacceleratedStaticBitmapImage.cpp", @@ -1840,6 +1841,7 @@ "geometry/LayoutRectTest.cpp", "geometry/RegionTest.cpp", "graphics/BitmapImageTest.cpp", + "graphics/CompositorElementIdTest.cpp", "graphics/CompositorMutableStateTest.cpp", "graphics/CompositorMutatorClientTest.cpp", "graphics/ContiguousContainerTest.cpp",
diff --git a/third_party/WebKit/Source/platform/Timer.cpp b/third_party/WebKit/Source/platform/Timer.cpp index 5f543f0..a1612d50 100644 --- a/third_party/WebKit/Source/platform/Timer.cpp +++ b/third_party/WebKit/Source/platform/Timer.cpp
@@ -137,11 +137,10 @@ // Cancel any previously posted task. weak_ptr_factory_.RevokeAll(); - double delay_ms = 1000.0 * delay; - TimerTaskRunner()->PostDelayedTask( + TimerTaskRunner()->ToSingleThreadTaskRunner()->PostDelayedTask( location_, base::Bind(&TimerBase::RunInternal, weak_ptr_factory_.CreateWeakPtr()), - delay_ms); + TimeDelta::FromSecondsD(delay)); } }
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.cpp b/third_party/WebKit/Source/platform/WebTaskRunner.cpp index 8bd0ea3..8bdfe57 100644 --- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp +++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
@@ -127,10 +127,9 @@ void WebTaskRunner::PostDelayedTask(const WebTraceLocation& location, std::unique_ptr<CrossThreadClosure> task, - long long delay_ms) { + TimeDelta delay) { ToSingleThreadTaskRunner()->PostDelayedTask( - location, base::Bind(&RunCrossThreadClosure, base::Passed(&task)), - base::TimeDelta::FromMilliseconds(delay_ms)); + location, base::Bind(&RunCrossThreadClosure, base::Passed(&task)), delay); } void WebTaskRunner::PostTask(const WebTraceLocation& location, @@ -141,10 +140,9 @@ void WebTaskRunner::PostDelayedTask(const WebTraceLocation& location, std::unique_ptr<WTF::Closure> task, - long long delay_ms) { + TimeDelta delay) { ToSingleThreadTaskRunner()->PostDelayedTask( - location, ConvertToBaseCallback(std::move(task)), - base::TimeDelta::FromMilliseconds(delay_ms)); + location, ConvertToBaseCallback(std::move(task)), delay); } TaskHandle WebTaskRunner::PostCancellableTask( @@ -161,14 +159,14 @@ TaskHandle WebTaskRunner::PostDelayedCancellableTask( const WebTraceLocation& location, std::unique_ptr<WTF::Closure> task, - long long delay_ms) { + TimeDelta delay) { DCHECK(RunsTasksOnCurrentThread()); RefPtr<TaskHandle::Runner> runner = AdoptRef(new TaskHandle::Runner(std::move(task))); PostDelayedTask(location, WTF::Bind(&TaskHandle::Runner::Run, runner->AsWeakPtr(), TaskHandle(runner)), - delay_ms); + delay); return TaskHandle(runner); }
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h index c5c19f8..19f8690 100644 --- a/third_party/WebKit/Source/platform/WebTaskRunner.h +++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -10,6 +10,7 @@ #include "platform/wtf/Compiler.h" #include "platform/wtf/Functional.h" #include "platform/wtf/RefCounted.h" +#include "platform/wtf/Time.h" #include "platform/wtf/WeakPtr.h" #include "public/platform/WebCommon.h" #include "public/platform/WebTraceLocation.h" @@ -59,12 +60,6 @@ class BLINK_PLATFORM_EXPORT WebTaskRunner : public ThreadSafeRefCounted<WebTaskRunner> { public: - // Schedule a task to be run after |delayMs| on the the associated WebThread. - // Can be called from any thread. - virtual void PostDelayedTask(const WebTraceLocation&, - base::OnceClosure, - double delay_ms) = 0; - // Drepecated: favor RunsTasksInCurrentSequence(). // TODO(http://crbug.com/665062): mass redirect callers and remove this. bool RunsTasksOnCurrentThread(); @@ -101,13 +96,13 @@ void PostTask(const WebTraceLocation&, std::unique_ptr<CrossThreadClosure>); void PostDelayedTask(const WebTraceLocation&, std::unique_ptr<CrossThreadClosure>, - long long delay_ms); + TimeDelta delay); // For same-thread posting. Must be called from the associated WebThread. void PostTask(const WebTraceLocation&, std::unique_ptr<WTF::Closure>); void PostDelayedTask(const WebTraceLocation&, std::unique_ptr<WTF::Closure>, - long long delay_ms); + TimeDelta delay); // For same-thread cancellable task posting. Returns a TaskHandle object for // cancellation. @@ -116,7 +111,7 @@ WARN_UNUSED_RESULT TaskHandle PostDelayedCancellableTask(const WebTraceLocation&, std::unique_ptr<WTF::Closure>, - long long delay_ms); + TimeDelta delay); protected: friend ThreadSafeRefCounted<WebTaskRunner>;
diff --git a/third_party/WebKit/Source/platform/WebTaskRunnerTest.cpp b/third_party/WebKit/Source/platform/WebTaskRunnerTest.cpp index bcd7da6d..8010a7b 100644 --- a/third_party/WebKit/Source/platform/WebTaskRunnerTest.cpp +++ b/third_party/WebKit/Source/platform/WebTaskRunnerTest.cpp
@@ -53,7 +53,8 @@ count = 0; handle = task_runner->PostDelayedCancellableTask( - BLINK_FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)), 1); + BLINK_FROM_HERE, WTF::Bind(&Increment, WTF::Unretained(&count)), + TimeDelta::FromMilliseconds(1)); EXPECT_EQ(0, count); EXPECT_TRUE(handle.IsActive()); task_runner->RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h index 6a6273e..a0d01e2a 100644 --- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h +++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -40,9 +40,9 @@ void PostDelayedTask(const WebTraceLocation& location, std::unique_ptr<WTF::Closure> task, - long long delay_ms) { + TimeDelta delay) { thread_->GetWebTaskRunner()->PostDelayedTask(location, std::move(task), - delay_ms); + delay); } void PostTask(const WebTraceLocation& location, @@ -52,9 +52,9 @@ void PostDelayedTask(const WebTraceLocation& location, std::unique_ptr<CrossThreadClosure> task, - long long delay_ms) { + TimeDelta delay) { thread_->GetWebTaskRunner()->PostDelayedTask(location, std::move(task), - delay_ms); + delay); } bool IsCurrentThread() const { return thread_->IsCurrentThread(); }
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp index 4090ee5..6f21f47 100644 --- a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp +++ b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
@@ -62,10 +62,10 @@ RunTask(); if (elapsed_ms_ < duration_ms_) { client_thread_->GetWebTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - CrossThreadBind(&FIFOClient::RunTaskOnOwnThread, - CrossThreadUnretained(this)), - interval_with_jitter); + BLINK_FROM_HERE, + CrossThreadBind(&FIFOClient::RunTaskOnOwnThread, + CrossThreadUnretained(this)), + TimeDelta::FromMillisecondsD(interval_with_jitter)); } else { Stop(counter_); done_event_->Signal();
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp index f3356b8..d9722fa6 100644 --- a/third_party/WebKit/Source/platform/fonts/Font.cpp +++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -411,6 +411,16 @@ return !platform_data.HasSpaceInLigaturesOrKerning(features); }; +void Font::ReportNotDefGlyph() const { + FontSelector* fontSelector = font_fallback_list_->GetFontSelector(); + // We have a few non-DOM usages of Font code, for example in DragImage::Create + // and in EmbeddedObjectPainter::paintReplaced. In those cases, we can't + // retrieve a font selector as our connection to a Document object to report + // UseCounter metrics, and thus we cannot report notdef glyphs. + if (fontSelector) + fontSelector->ReportNotDefGlyph(); +} + void Font::WillUseFontData(const String& text) const { const FontFamily& family = GetFontDescription().Family(); if (font_fallback_list_ && font_fallback_list_->GetFontSelector() &&
diff --git a/third_party/WebKit/Source/platform/fonts/Font.h b/third_party/WebKit/Source/platform/fonts/Font.h index 3de99eb..30618c0 100644 --- a/third_party/WebKit/Source/platform/fonts/Font.h +++ b/third_party/WebKit/Source/platform/fonts/Font.h
@@ -197,6 +197,8 @@ shape_word_by_word_computed_ = true; } + void ReportNotDefGlyph() const; + private: enum ForTextEmphasisOrNot { kNotForTextEmphasis, kForTextEmphasis };
diff --git a/third_party/WebKit/Source/platform/fonts/FontSelector.h b/third_party/WebKit/Source/platform/fonts/FontSelector.h index e7acdf22..a789926 100644 --- a/third_party/WebKit/Source/platform/fonts/FontSelector.h +++ b/third_party/WebKit/Source/platform/fonts/FontSelector.h
@@ -54,6 +54,8 @@ const FontDataForRangeSet&) = 0; virtual unsigned Version() const = 0; + + virtual void ReportNotDefGlyph() const = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp index 9ea5db3b2..8ceb11b 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -150,7 +150,7 @@ } // namespace -bool HarfBuzzShaper::ExtractShapeResults( +void HarfBuzzShaper::ExtractShapeResults( RangeData* range_data, bool& font_cycle_queued, const HolesQueueItem& current_queue_item, @@ -171,10 +171,8 @@ unsigned last_change_position = 0; - if (!num_glyphs) { - DLOG(ERROR) << "HarfBuzz returned empty glyph buffer after shaping."; - return false; - } + if (!num_glyphs) + return; for (unsigned glyph_index = 0; glyph_index <= num_glyphs; ++glyph_index) { // Iterating by clusters, check for when the state switches from shaped @@ -191,7 +189,7 @@ } else { // We can only call the current cluster fully shapped, if // all characters that are part of it are shaped, so update - // currentClusterResult to Shaped only if the previous + // currentClusterResult to kShaped only if the previous // characters have been shaped, too. current_cluster_result = current_cluster_result == kShaped ? kShaped : kNotDef; @@ -203,8 +201,8 @@ current_cluster_result = glyph_info[glyph_index].codepoint == 0 ? kNotDef : kShaped; } else { - // The code below operates on the "flanks"/changes between NotDef - // and Shaped. In order to keep the code below from explictly + // The code below operates on the "flanks"/changes between kNotDef + // and kShaped. In order to keep the code below from explictly // dealing with character indices and run end, we explicitly // terminate the cluster/run here by setting the result value to the // opposite of what it was, leading to atChange turning true. @@ -286,10 +284,10 @@ start_index, num_glyphs_to_insert, num_characters); shape_result->InsertRun(WTF::WrapUnique(run), last_change_position, num_glyphs_to_insert, range_data->buffer); + range_data->font->ReportNotDefGlyph(); } last_change_position = glyph_index; } - return true; } static inline const SimpleFontData* FontDataAdjustedForOrientation( @@ -676,11 +674,9 @@ direction, language)) DLOG(ERROR) << "Shaping range failed."; - if (!ExtractShapeResults(range_data, font_cycle_queued, current_queue_item, - direction_and_small_caps_adjusted_font, - segment.script, !fallback_iterator->HasNext(), - result)) - DLOG(ERROR) << "Shape result extraction failed."; + ExtractShapeResults(range_data, font_cycle_queued, current_queue_item, + direction_and_small_caps_adjusted_font, segment.script, + !fallback_iterator->HasNext(), result); hb_buffer_reset(range_data->buffer); }
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.h b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.h index dd7c39c..126d250 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.h +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.h
@@ -80,7 +80,7 @@ RunSegmenter::RunSegmenterRange, ShapeResult*) const; - bool ExtractShapeResults(RangeData*, + void ExtractShapeResults(RangeData*, bool& font_cycle_queued, const HolesQueueItem&, const SimpleFontData*,
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp b/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp index eeb495f..eec2d113 100644 --- a/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp +++ b/third_party/WebKit/Source/platform/graphics/CompositorElementId.cpp
@@ -7,9 +7,27 @@ namespace blink { CompositorElementId CreateCompositorElementId( - int dom_node_id, + DOMNodeId dom_node_id, CompositorSubElementId sub_element_id) { - return CompositorElementId(dom_node_id, static_cast<int>(sub_element_id)); + DCHECK(dom_node_id > 0 && + dom_node_id < std::numeric_limits<DOMNodeId>::max() / + static_cast<unsigned>( + CompositorSubElementId::kNumSubElementTypes)); + cc::ElementIdType id = + dom_node_id << 2; // Shift to make room for sub_element_id enum bits. + id += static_cast<uint64_t>(sub_element_id); + return CompositorElementId(id); +} + +DOMNodeId DomNodeIdFromCompositorElementId(CompositorElementId element_id) { + return element_id.id_ >> 2; +} + +CompositorSubElementId SubElementIdFromCompositorElementId( + CompositorElementId element_id) { + return static_cast<CompositorSubElementId>( + element_id.id_ % + static_cast<unsigned>(CompositorSubElementId::kNumSubElementTypes)); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorElementId.h b/third_party/WebKit/Source/platform/graphics/CompositorElementId.h index 7a17e46..df39549 100644 --- a/third_party/WebKit/Source/platform/graphics/CompositorElementId.h +++ b/third_party/WebKit/Source/platform/graphics/CompositorElementId.h
@@ -17,36 +17,43 @@ kPrimary, kScroll, kViewport, - kLinkHighlight + kLinkHighlight, + // A sentinel to indicate how many enum values there are. + kNumSubElementTypes }; using CompositorElementId = cc::ElementId; +using DOMNodeId = uint64_t; CompositorElementId PLATFORM_EXPORT -CreateCompositorElementId(int dom_node_id, CompositorSubElementId); + CreateCompositorElementId(DOMNodeId, CompositorSubElementId); // Note cc::ElementId has a hash function already implemented via // ElementIdHash::operator(). However for consistency's sake we choose to use // Blink's hash functions with Blink specific data structures. struct CompositorElementIdHash { - static unsigned GetHash(const CompositorElementId& p) { - return WTF::HashInts(p.primaryId, p.secondaryId); + static unsigned GetHash(const CompositorElementId& key) { + return WTF::HashInt(static_cast<cc::ElementIdType>(key.id_)); } static bool Equal(const CompositorElementId& a, const CompositorElementId& b) { - return a.primaryId == b.primaryId && a.secondaryId == b.secondaryId; + return a.id_ == b.id_; } static const bool safe_to_compare_to_empty_or_deleted = true; }; +DOMNodeId PLATFORM_EXPORT DomNodeIdFromCompositorElementId(CompositorElementId); +CompositorSubElementId PLATFORM_EXPORT + SubElementIdFromCompositorElementId(CompositorElementId); + struct CompositorElementIdHashTraits : WTF::GenericHashTraits<CompositorElementId> { - static CompositorElementId EmptyValue() { return CompositorElementId(); } + static CompositorElementId EmptyValue() { return CompositorElementId(1); } static void ConstructDeletedValue(CompositorElementId& slot, bool) { - slot = CompositorElementId(-1, -1); + slot = CompositorElementId(); } static bool IsDeletedValue(CompositorElementId value) { - return value == CompositorElementId(-1, -1); + return value == CompositorElementId(); } };
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorElementIdTest.cpp b/third_party/WebKit/Source/platform/graphics/CompositorElementIdTest.cpp new file mode 100644 index 0000000..e0e812b --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/CompositorElementIdTest.cpp
@@ -0,0 +1,32 @@ +// Copyright 2016 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 "platform/graphics/CompositorElementId.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class CompositorElementIdTest : public ::testing::Test {}; + +TEST_F(CompositorElementIdTest, EncodeDecode) { + CompositorElementId element_id = + CreateCompositorElementId(1, CompositorSubElementId::kPrimary); + EXPECT_EQ(1u, DomNodeIdFromCompositorElementId(element_id)); + EXPECT_EQ(CompositorSubElementId::kPrimary, + SubElementIdFromCompositorElementId(element_id)); + + element_id = + CreateCompositorElementId(1, CompositorSubElementId::kLinkHighlight); + EXPECT_EQ(1u, DomNodeIdFromCompositorElementId(element_id)); + EXPECT_EQ(CompositorSubElementId::kLinkHighlight, + SubElementIdFromCompositorElementId(element_id)); + + element_id = CreateCompositorElementId(23, CompositorSubElementId::kScroll); + EXPECT_EQ(23u, DomNodeIdFromCompositorElementId(element_id)); + EXPECT_EQ(CompositorSubElementId::kScroll, + SubElementIdFromCompositorElementId(element_id)); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp index 28b1a68..d5a6d73 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -127,7 +127,7 @@ host.AddTimeline(*compositor_timeline); compositor_timeline->PlayerAttached(player); - platform_layer_->SetElementId(CompositorElementId(platform_layer_->Id(), 0)); + platform_layer_->SetElementId(CompositorElementId(platform_layer_->Id())); player.CompositorPlayer()->AttachElement(platform_layer_->GetElementId()); ASSERT_TRUE(player.CompositorPlayer()->IsElementAttached());
diff --git a/third_party/WebKit/Source/platform/graphics/TouchAction.h b/third_party/WebKit/Source/platform/graphics/TouchAction.h new file mode 100644 index 0000000..8d4b91a --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/TouchAction.h
@@ -0,0 +1,17 @@ +// Copyright 2017 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 TouchAction_h +#define TouchAction_h + +#include "cc/input/touch_action.h" + +namespace blink { + +const size_t kTouchActionBits = cc::kTouchActionBits; +using TouchAction = cc::TouchAction; + +} // namespace blink + +#endif // TouchAction_h
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index 2c13bd2..614331c 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -714,8 +714,7 @@ TEST_F(PaintArtifactCompositorTestWithPropertyTrees, OneScrollNode) { FakeScrollClient scroll_client; - CompositorElementId expected_compositor_element_id = - CompositorElementId(2, 0); + CompositorElementId expected_compositor_element_id = CompositorElementId(2); RefPtr<TransformPaintPropertyNode> scroll_translation = TransformPaintPropertyNode::CreateScrollTranslation( TransformPaintPropertyNode::Root(), @@ -823,8 +822,7 @@ RefPtr<EffectPaintPropertyNode> effect = CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5); - CompositorElementId expected_compositor_element_id_a = - CompositorElementId(2, 0); + CompositorElementId expected_compositor_element_id_a = CompositorElementId(2); RefPtr<TransformPaintPropertyNode> scroll_translation_a = TransformPaintPropertyNode::CreateScrollTranslation( TransformPaintPropertyNode::Root(), @@ -835,8 +833,7 @@ MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, nullptr); - CompositorElementId expected_compositor_element_id_b = - CompositorElementId(3, 0); + CompositorElementId expected_compositor_element_id_b = CompositorElementId(3); RefPtr<TransformPaintPropertyNode> scroll_translation_b = TransformPaintPropertyNode::CreateScrollTranslation( scroll_translation_a, TransformationMatrix().Translate(37, 41), @@ -1644,7 +1641,7 @@ } PassRefPtr<EffectPaintPropertyNode> CreateSampleEffectNodeWithElementId() { - CompositorElementId expected_compositor_element_id(2, 0); + CompositorElementId expected_compositor_element_id(2); float opacity = 2.0 / 255.0; return EffectPaintPropertyNode::Create( EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), @@ -1655,7 +1652,7 @@ PassRefPtr<TransformPaintPropertyNode> CreateSampleTransformNodeWithElementId() { - CompositorElementId expected_compositor_element_id(3, 0); + CompositorElementId expected_compositor_element_id(3); return TransformPaintPropertyNode::Create( TransformPaintPropertyNode::Root(), TransformationMatrix().Rotate(90), FloatPoint3D(100, 100, 0), false, 0, kCompositingReason3DTransform,
diff --git a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.cpp b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.cpp index 8ee5702..85bfced 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.cpp
@@ -36,12 +36,12 @@ String EffectPaintPropertyNode::ToString() const { return String::Format( "parent=%p localTransformSpace=%p outputClip=%p opacity=%f filter=%s " - "blendMode=%s directCompositingReasons=%s compositorElementId=(%d, %d) " + "blendMode=%s directCompositingReasons=%s compositorElementId=%lu " "paintOffset=%s", parent_.Get(), local_transform_space_.Get(), output_clip_.Get(), opacity_, filter_.ToString().Ascii().data(), SkBlendMode_Name(blend_mode_), CompositingReasonsAsString(direct_compositing_reasons_).Ascii().data(), - compositor_element_id_.primaryId, compositor_element_id_.secondaryId, + static_cast<unsigned long>(compositor_element_id_.id_), paint_offset_.ToString().Ascii().data()); }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeStateTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeStateTest.cpp index 6b1e01d..a6e320c4 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeStateTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PropertyTreeStateTest.cpp
@@ -196,8 +196,7 @@ } TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnTransformNode) { - CompositorElementId expected_compositor_element_id = - CompositorElementId(2, 0); + CompositorElementId expected_compositor_element_id = CompositorElementId(2); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), TransformationMatrix(), FloatPoint3D(), @@ -210,8 +209,7 @@ } TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnEffectNode) { - CompositorElementId expected_compositor_element_id = - CompositorElementId(2, 0); + CompositorElementId expected_compositor_element_id = CompositorElementId(2); RefPtr<EffectPaintPropertyNode> effect = EffectPaintPropertyNode::Create( EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), kColorFilterNone, @@ -224,8 +222,7 @@ } TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnMultipleNodes) { - CompositorElementId expected_compositor_element_id = - CompositorElementId(2, 0); + CompositorElementId expected_compositor_element_id = CompositorElementId(2); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), TransformationMatrix(), FloatPoint3D(), @@ -243,8 +240,8 @@ } TEST_F(PropertyTreeStateTest, CompositorElementIdWithDifferingElementIds) { - CompositorElementId first_compositor_element_id = CompositorElementId(2, 0); - CompositorElementId second_compositor_element_id = CompositorElementId(3, 0); + CompositorElementId first_compositor_element_id = CompositorElementId(2); + CompositorElementId second_compositor_element_id = CompositorElementId(3); RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), TransformationMatrix(), FloatPoint3D(),
diff --git a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp index 6260949..ab43c96a 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/TransformPaintPropertyNode.cpp
@@ -39,12 +39,12 @@ auto transform = String::Format( "parent=%p transform=%s origin=%s flattensInheritedTransform=%s " "renderingContextId=%x directCompositingReasons=%s " - "compositorElementId=(%d, %d)", + "compositorElementId=%lu", parent_.Get(), matrix_.ToString().Ascii().data(), origin_.ToString().Ascii().data(), flattens_inherited_transform_ ? "yes" : "no", rendering_context_id_, CompositingReasonsAsString(direct_compositing_reasons_).Ascii().data(), - compositor_element_id_.primaryId, compositor_element_id_.secondaryId); + static_cast<unsigned long>(compositor_element_id_.id_)); if (scroll_) return transform + " scroll=" + scroll_->ToString(); return transform;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm index b8d8d3a..614af9a 100644 --- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm +++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -1040,7 +1040,7 @@ BLINK_FROM_HERE, WTF::Bind(&ScrollAnimatorMac::InitialScrollbarPaintTask, WrapWeakPersistent(this)), - 1); + TimeDelta::FromMilliseconds(1)); } bool ScrollAnimatorMac::ScrollbarPaintTimerIsActive() const {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc index cf084fe..01fb90e 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
@@ -21,15 +21,6 @@ return AdoptRef(new WebTaskRunnerImpl(std::move(task_queue))); } -void WebTaskRunnerImpl::PostDelayedTask(const WebTraceLocation& location, - base::OnceClosure task, - double delay_ms) { - DCHECK_GE(delay_ms, 0.0) << location.function_name() << " " - << location.file_name(); - task_queue_->PostDelayedTask(location, std::move(task), - base::TimeDelta::FromMillisecondsD(delay_ms)); -} - bool WebTaskRunnerImpl::RunsTasksInCurrentSequence() { return task_queue_->RunsTasksInCurrentSequence(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h index e4080262..d5ac48b 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
@@ -23,9 +23,6 @@ static RefPtr<WebTaskRunnerImpl> Create(scoped_refptr<TaskQueue> task_queue); // WebTaskRunner implementation: - void PostDelayedTask(const WebTraceLocation&, - base::OnceClosure, - double delay_ms) override; bool RunsTasksInCurrentSequence() override; double VirtualTimeSeconds() const override; double MonotonicallyIncreasingVirtualTimeSeconds() const override;
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc index 1d271154..5781866 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -151,8 +151,8 @@ thread_->PostIdleTask(BLINK_FROM_HERE, task.release()); // We need to post a wake-up task or idle work will never happen. - thread_->GetWebTaskRunner()->PostDelayedTask(BLINK_FROM_HERE, - WTF::Bind([] {}), 50ll); + thread_->GetWebTaskRunner()->PostDelayedTask( + BLINK_FROM_HERE, WTF::Bind([] {}), TimeDelta::FromMilliseconds(50)); completion.Wait(); } @@ -188,7 +188,8 @@ BLINK_FROM_HERE, WTF::Bind(&MockTask::Run, WTF::Unretained(&task))); thread_->GetWebTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, - WTF::Bind(&MockTask::Run, WTF::Unretained(&delayed_task)), 50ll); + WTF::Bind(&MockTask::Run, WTF::Unretained(&delayed_task)), + TimeDelta::FromMilliseconds(50)); thread_.reset(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc index 2cc3b00..0d2c1fb 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -3757,8 +3757,10 @@ scheduler_->TimerTaskQueue()->PostTask(FROM_HERE, base::Bind(NullTask)); - web_frame_scheduler->LoadingTaskRunner()->PostDelayedTask( - FROM_HERE, base::Bind(NullTask), 10); + web_frame_scheduler->LoadingTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask(FROM_HERE, base::Bind(NullTask), + TimeDelta::FromMilliseconds(10)); std::unique_ptr<base::trace_event::ConvertableToTraceFormat> value = scheduler_->AsValue(base::TimeTicks());
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc index bd0fafa8..ab04a98 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
@@ -73,7 +73,7 @@ WebTaskRunner* task_runner_ptr = task_runner.Get(); task_runner_ptr->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(std::move(task_runner), run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); } void IncrementCounter(int* counter) { @@ -89,7 +89,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -103,7 +103,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -125,7 +125,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -140,7 +140,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -155,7 +155,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1, run_count); @@ -169,7 +169,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -193,7 +193,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc index 500c89a5..fefee3e 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl.cc
@@ -268,8 +268,7 @@ std::unique_ptr<WTF::Closure> budget_exhausted_callback) { virtual_time_budget_expired_task_handle_ = virtual_time_control_task_queue_->PostDelayedCancellableTask( - BLINK_FROM_HERE, std::move(budget_exhausted_callback), - budget.InMilliseconds()); + BLINK_FROM_HERE, std::move(budget_exhausted_callback), budget); } void WebViewSchedulerImpl::AudioStateChanged(bool is_audio_playing) {
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc index 6acf0cb..8bdac8155 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
@@ -95,7 +95,7 @@ blink::WebTaskRunner* task_runner_ptr = task_runner.Get(); task_runner_ptr->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(std::move(task_runner), run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); } } // namespace @@ -107,7 +107,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -121,7 +121,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -157,7 +157,7 @@ timer_task_runner->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -188,7 +188,7 @@ web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->LoadingTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); // Loading tasks should not be throttled @@ -211,11 +211,11 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count1), - 1.0); + TimeDelta::FromMilliseconds(1)); web_frame_scheduler2->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler2->TimerTaskRunner(), &run_count2), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count1); @@ -261,21 +261,21 @@ MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 2.0); + TimeDelta::FromMilliseconds(2)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 20.0); + TimeDelta::FromMilliseconds(20)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 200.0); + TimeDelta::FromMilliseconds(200)); mock_task_runner_->RunUntilIdle(); @@ -302,21 +302,21 @@ MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->LoadingTaskRunner(), &real_times, &virtual_times_ms), - 2.0); + TimeDelta::FromMilliseconds(2)); web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->LoadingTaskRunner(), &real_times, &virtual_times_ms), - 20.0); + TimeDelta::FromMilliseconds(20)); web_frame_scheduler_->LoadingTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->LoadingTaskRunner(), &real_times, &virtual_times_ms), - 200.0); + TimeDelta::FromMilliseconds(200)); mock_task_runner_->RunUntilIdle(); @@ -337,7 +337,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunTasksWhile(mock_task_runner_->TaskRunCountBelow(2000)); // Virtual time means page visibility is ignored. @@ -379,14 +379,14 @@ WTF::Bind(&DelayedRunOrderTask, 1, WTF::Passed(web_frame_scheduler_->TimerTaskRunner()), WTF::Unretained(&run_order)), - 2.0); + TimeDelta::FromMilliseconds(2)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, WTF::Bind(&DelayedRunOrderTask, 3, WTF::Passed(web_frame_scheduler_->TimerTaskRunner()), WTF::Unretained(&run_order)), - 4.0); + TimeDelta::FromMilliseconds(4)); mock_task_runner_->RunUntilIdle(); @@ -409,14 +409,14 @@ WTF::Bind(&DelayedRunOrderTask, 1, WTF::Passed(web_frame_scheduler_->TimerTaskRunner()), WTF::Unretained(&run_order)), - 2.0); + TimeDelta::FromMilliseconds(2)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, WTF::Bind(&DelayedRunOrderTask, 3, WTF::Passed(web_frame_scheduler_->TimerTaskRunner()), WTF::Unretained(&run_order)), - 4.0); + TimeDelta::FromMilliseconds(4)); mock_task_runner_->RunUntilIdle(); @@ -440,7 +440,7 @@ web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeRepeatingTask(web_frame_scheduler_->TimerTaskRunner(), &run_count), - 1.0); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1000, run_count); @@ -457,7 +457,7 @@ web_frame_scheduler->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, WTF::Bind(&RunOrderTask, 1, WTF::Unretained(&run_order)), - 1); + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilIdle(); EXPECT_TRUE(run_order.empty()); @@ -482,7 +482,8 @@ WebFrameSchedulerImpl* web_frame_scheduler = web_view_scheduler_->CreateWebFrameSchedulerImpl(nullptr).release(); web_frame_scheduler->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, MakeDeletionTask(web_frame_scheduler), 1); + BLINK_FROM_HERE, MakeDeletionTask(web_frame_scheduler), + TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilIdle(); } @@ -507,13 +508,15 @@ int run_count = 0; timer_task_runner->PostDelayedTask( - BLINK_FROM_HERE, MakeRepeatingTask(timer_task_runner, &run_count), 1.0); + BLINK_FROM_HERE, MakeRepeatingTask(timer_task_runner, &run_count), + TimeDelta::FromMilliseconds(1)); // Note this will run at time t = 10s since we start at time t = 5000us, and // it will prevent further tasks from running (i.e. the RepeatingTask) by // deleting the WebFrameScheduler. - timer_task_runner->PostDelayedTask( - BLINK_FROM_HERE, MakeDeletionTask(web_frame_scheduler), 9990.0); + timer_task_runner->PostDelayedTask(BLINK_FROM_HERE, + MakeDeletionTask(web_frame_scheduler), + TimeDelta::FromMilliseconds(9990)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(100)); EXPECT_EQ(10, run_count); @@ -613,7 +616,7 @@ web_view_scheduler_->CreateWebFrameSchedulerImpl(nullptr); web_frame_scheduler->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, WTF::Bind(&RunOrderTask, 1, WTF::Unretained(&run_order)), - 0); + TimeDelta()); web_view_scheduler_->SetVirtualTimePolicy(VirtualTimePolicy::PAUSE); web_view_scheduler_->EnableVirtualTime(); @@ -643,28 +646,28 @@ MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 1.0); + TimeDelta::FromMilliseconds(1)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 2.0); + TimeDelta::FromMilliseconds(2)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 5.0); + TimeDelta::FromMilliseconds(5)); web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( BLINK_FROM_HERE, MakeVirtualTimeRecorderTask(clock_.get(), web_frame_scheduler_->TimerTaskRunner(), &real_times, &virtual_times_ms), - 7.0); + TimeDelta::FromMilliseconds(7)); web_view_scheduler_->GrantVirtualTimeBudget( base::TimeDelta::FromMilliseconds(5), @@ -725,12 +728,18 @@ mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(2500)); - web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - 1); - web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - 1); + web_frame_scheduler_->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); + web_frame_scheduler_->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(3500)); @@ -745,12 +754,18 @@ mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(11500)); - web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - 1); - web_frame_scheduler_->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), - 1); + web_frame_scheduler_->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); + web_frame_scheduler_->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilIdle(); @@ -784,9 +799,12 @@ base::TimeDelta::FromMilliseconds(20500)); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler1->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + web_frame_scheduler1->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -804,9 +822,12 @@ websocket_connection = web_frame_scheduler1->OnActiveConnectionCreated(); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler1->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + web_frame_scheduler1->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -823,9 +844,12 @@ run_times.clear(); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler2->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + web_frame_scheduler2->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -847,9 +871,12 @@ base::TimeDelta::FromMilliseconds(70500)); for (size_t i = 0; i < 3; ++i) { - web_frame_scheduler1->TimerTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, - base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), 1); + web_frame_scheduler1->TimerTaskRunner() + ->ToSingleThreadTaskRunner() + ->PostDelayedTask( + BLINK_FROM_HERE, + base::Bind(&ExpensiveTestTask, clock_.get(), &run_times), + TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc index d4509f8..663af1a 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
@@ -82,13 +82,6 @@ data_->time_ = new_time; } -void FakeWebTaskRunner::PostDelayedTask(const WebTraceLocation&, - base::OnceClosure closure, - double delay_ms) { - data_->PostTask(std::move(closure), - base::TimeDelta::FromMillisecondsD(delay_ms)); -} - bool FakeWebTaskRunner::RunsTasksInCurrentSequence() { return true; }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h index 888657f..b62fb0ef 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
@@ -25,9 +25,6 @@ void SetTime(double new_time); // WebTaskRunner implementation: - void PostDelayedTask(const WebTraceLocation&, - base::OnceClosure, - double) override; bool RunsTasksInCurrentSequence() override; double VirtualTimeSeconds() const override; double MonotonicallyIncreasingVirtualTimeSeconds() const override;
diff --git a/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp index 5d4d0d3..d2fa1de 100644 --- a/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp +++ b/third_party/WebKit/Source/platform/testing/FontTestHelpers.cpp
@@ -46,6 +46,7 @@ unsigned Version() const override { return 0; } void FontCacheInvalidated() override {} + void ReportNotDefGlyph() const override{}; private: TestFontSelector(PassRefPtr<FontCustomPlatformData> custom_platform_data)
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp index eafb280..d0e10b6 100644 --- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp +++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -68,7 +68,8 @@ void RunDelayedTasks(double delay_ms) { Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, WTF::Bind(&ExitRunLoop), delay_ms); + BLINK_FROM_HERE, WTF::Bind(&ExitRunLoop), + TimeDelta::FromMillisecondsD(delay_ms)); EnterRunLoop(); }
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/bignum-dtoa.cc b/third_party/WebKit/Source/platform/wtf/dtoa/bignum-dtoa.cc index 4c377d0..d33f20b2 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/bignum-dtoa.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/bignum-dtoa.cc
@@ -27,631 +27,653 @@ #include "bignum-dtoa.h" +#include <math.h> #include "bignum.h" #include "double.h" -#include <math.h> namespace WTF { namespace double_conversion { - static int NormalizedExponent(uint64_t significand, int exponent) { - DCHECK_NE(significand, 0u); - while ((significand & Double::kHiddenBit) == 0) { - significand = significand << 1; - exponent = exponent - 1; - } - return exponent; +static int NormalizedExponent(uint64_t significand, int exponent) { + DCHECK_NE(significand, 0u); + while ((significand & Double::kHiddenBit) == 0) { + significand = significand << 1; + exponent = exponent - 1; + } + return exponent; +} + +// Forward declarations: +// Returns an estimation of k such that 10^(k-1) <= v < 10^k. +static int EstimatePower(int exponent); +// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator +// and denominator. +static void InitialScaledStartValues(double v, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus); +// Multiplies numerator/denominator so that its values lies in the range 1-10. +// Returns decimal_point s.t. +// v = numerator'/denominator' * 10^(decimal_point-1) +// where numerator' and denominator' are the values of numerator and +// denominator after the call to this function. +static void FixupMultiply10(int estimated_power, + bool is_even, + int* decimal_point, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus); +// Generates digits from the left to the right and stops when the generated +// digits yield the shortest decimal representation of v. +static void GenerateShortestDigits(Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus, + bool is_even, + Vector<char> buffer, + int* length); +// Generates 'requested_digits' after the decimal point. +static void BignumToFixed(int requested_digits, + int* decimal_point, + Bignum* numerator, + Bignum* denominator, + Vector<char>(buffer), + int* length); +// Generates 'count' digits of numerator/denominator. +// Once 'count' digits have been produced rounds the result depending on the +// remainder (remainders of exactly .5 round upwards). Might update the +// decimal_point when rounding up (for example for 0.9999). +static void GenerateCountedDigits(int count, + int* decimal_point, + Bignum* numerator, + Bignum* denominator, + Vector<char>(buffer), + int* length); + +void BignumDtoa(double v, + BignumDtoaMode mode, + int requested_digits, + Vector<char> buffer, + int* length, + int* decimal_point) { + DCHECK_GT(v, 0); + DCHECK(!Double(v).IsSpecial()); + uint64_t significand = Double(v).Significand(); + bool is_even = (significand & 1) == 0; + int exponent = Double(v).Exponent(); + int normalized_exponent = NormalizedExponent(significand, exponent); + // estimated_power might be too low by 1. + int estimated_power = EstimatePower(normalized_exponent); + + // Shortcut for Fixed. + // The requested digits correspond to the digits after the point. If the + // number is much too small, then there is no need in trying to get any + // digits. + if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) { + buffer[0] = '\0'; + *length = 0; + // Set decimal-point to -requested_digits. This is what Gay does. + // Note that it should not have any effect anyways since the string is + // empty. + *decimal_point = -requested_digits; + return; + } + + Bignum numerator; + Bignum denominator; + Bignum delta_minus; + Bignum delta_plus; + // Make sure the bignum can grow large enough. The smallest double equals + // 4e-324. In this case the denominator needs fewer than 324*4 binary digits. + // The maximum double is 1.7976931348623157e308 which needs fewer than + // 308*4 binary digits. + DCHECK_GE(Bignum::kMaxSignificantBits, 324 * 4); + bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST); + InitialScaledStartValues(v, estimated_power, need_boundary_deltas, &numerator, + &denominator, &delta_minus, &delta_plus); + // We now have v = (numerator / denominator) * 10^estimated_power. + FixupMultiply10(estimated_power, is_even, decimal_point, &numerator, + &denominator, &delta_minus, &delta_plus); + // We now have v = (numerator / denominator) * 10^(decimal_point-1), and + // 1 <= (numerator + delta_plus) / denominator < 10 + switch (mode) { + case BIGNUM_DTOA_SHORTEST: + GenerateShortestDigits(&numerator, &denominator, &delta_minus, + &delta_plus, is_even, buffer, length); + break; + case BIGNUM_DTOA_FIXED: + BignumToFixed(requested_digits, decimal_point, &numerator, &denominator, + buffer, length); + break; + case BIGNUM_DTOA_PRECISION: + GenerateCountedDigits(requested_digits, decimal_point, &numerator, + &denominator, buffer, length); + break; + default: + UNREACHABLE(); + } + buffer[*length] = '\0'; +} + +// The procedure starts generating digits from the left to the right and stops +// when the generated digits yield the shortest decimal representation of v. A +// decimal representation of v is a number lying closer to v than to any other +// double, so it converts to v when read. +// +// This is true if d, the decimal representation, is between m- and m+, the +// upper and lower boundaries. d must be strictly between them if !is_even. +// m- := (numerator - delta_minus) / denominator +// m+ := (numerator + delta_plus) / denominator +// +// Precondition: 0 <= (numerator+delta_plus) / denominator < 10. +// If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit +// will be produced. This should be the standard precondition. +static void GenerateShortestDigits(Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus, + bool is_even, + Vector<char> buffer, + int* length) { + // Small optimization: if delta_minus and delta_plus are the same just reuse + // one of the two bignums. + if (Bignum::Equal(*delta_minus, *delta_plus)) { + delta_plus = delta_minus; + } + *length = 0; + while (true) { + uint16_t digit; + digit = numerator->DivideModuloIntBignum(*denominator); + DCHECK_LE(digit, 9u); // digit is a uint16_t and therefore always positive. + // digit = numerator / denominator (integer division). + // numerator = numerator % denominator. + buffer[(*length)++] = static_cast<char>(digit + '0'); + + // Can we stop already? + // If the remainder of the division is less than the distance to the lower + // boundary we can stop. In this case we simply round down (discarding the + // remainder). + // Similarly we test if we can round up (using the upper boundary). + bool in_delta_room_minus; + bool in_delta_room_plus; + if (is_even) { + in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus); + } else { + in_delta_room_minus = Bignum::Less(*numerator, *delta_minus); } - - - // Forward declarations: - // Returns an estimation of k such that 10^(k-1) <= v < 10^k. - static int EstimatePower(int exponent); - // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator - // and denominator. - static void InitialScaledStartValues(double v, - int estimated_power, - bool need_boundary_deltas, - Bignum* numerator, - Bignum* denominator, - Bignum* delta_minus, - Bignum* delta_plus); - // Multiplies numerator/denominator so that its values lies in the range 1-10. - // Returns decimal_point s.t. - // v = numerator'/denominator' * 10^(decimal_point-1) - // where numerator' and denominator' are the values of numerator and - // denominator after the call to this function. - static void FixupMultiply10(int estimated_power, bool is_even, - int* decimal_point, - Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus); - // Generates digits from the left to the right and stops when the generated - // digits yield the shortest decimal representation of v. - static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus, - bool is_even, - Vector<char> buffer, int* length); - // Generates 'requested_digits' after the decimal point. - static void BignumToFixed(int requested_digits, int* decimal_point, - Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length); - // Generates 'count' digits of numerator/denominator. - // Once 'count' digits have been produced rounds the result depending on the - // remainder (remainders of exactly .5 round upwards). Might update the - // decimal_point when rounding up (for example for 0.9999). - static void GenerateCountedDigits(int count, int* decimal_point, - Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length); - - - void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, - Vector<char> buffer, int* length, int* decimal_point) { - DCHECK_GT(v, 0); - DCHECK(!Double(v).IsSpecial()); - uint64_t significand = Double(v).Significand(); - bool is_even = (significand & 1) == 0; - int exponent = Double(v).Exponent(); - int normalized_exponent = NormalizedExponent(significand, exponent); - // estimated_power might be too low by 1. - int estimated_power = EstimatePower(normalized_exponent); - - // Shortcut for Fixed. - // The requested digits correspond to the digits after the point. If the - // number is much too small, then there is no need in trying to get any - // digits. - if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) { - buffer[0] = '\0'; - *length = 0; - // Set decimal-point to -requested_digits. This is what Gay does. - // Note that it should not have any effect anyways since the string is - // empty. - *decimal_point = -requested_digits; - return; - } - - Bignum numerator; - Bignum denominator; - Bignum delta_minus; - Bignum delta_plus; - // Make sure the bignum can grow large enough. The smallest double equals - // 4e-324. In this case the denominator needs fewer than 324*4 binary digits. - // The maximum double is 1.7976931348623157e308 which needs fewer than - // 308*4 binary digits. - DCHECK_GE(Bignum::kMaxSignificantBits, 324*4); - bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST); - InitialScaledStartValues(v, estimated_power, need_boundary_deltas, - &numerator, &denominator, - &delta_minus, &delta_plus); - // We now have v = (numerator / denominator) * 10^estimated_power. - FixupMultiply10(estimated_power, is_even, decimal_point, - &numerator, &denominator, - &delta_minus, &delta_plus); - // We now have v = (numerator / denominator) * 10^(decimal_point-1), and - // 1 <= (numerator + delta_plus) / denominator < 10 - switch (mode) { - case BIGNUM_DTOA_SHORTEST: - GenerateShortestDigits(&numerator, &denominator, - &delta_minus, &delta_plus, - is_even, buffer, length); - break; - case BIGNUM_DTOA_FIXED: - BignumToFixed(requested_digits, decimal_point, - &numerator, &denominator, - buffer, length); - break; - case BIGNUM_DTOA_PRECISION: - GenerateCountedDigits(requested_digits, decimal_point, - &numerator, &denominator, - buffer, length); - break; - default: - UNREACHABLE(); - } - buffer[*length] = '\0'; + if (is_even) { + in_delta_room_plus = + Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; + } else { + in_delta_room_plus = + Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; } + if (!in_delta_room_minus && !in_delta_room_plus) { + // Prepare for next iteration. + numerator->Times10(); + delta_minus->Times10(); + // We optimized delta_plus to be equal to delta_minus (if they share the + // same value). So don't multiply delta_plus if they point to the same + // object. + if (delta_minus != delta_plus) { + delta_plus->Times10(); + } + } else if (in_delta_room_minus && in_delta_room_plus) { + // Let's see if 2*numerator < denominator. + // If yes, then the next digit would be < 5 and we can round down. + int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator); + if (compare < 0) { + // Remaining digits are less than .5. -> Round down (== do nothing). + } else if (compare > 0) { + // Remaining digits are more than .5 of denominator. -> Round up. + // Note that the last digit could not be a '9' as otherwise the whole + // loop would have stopped earlier. + // We still have an assert here in case the preconditions were not + // satisfied. + DCHECK_NE(buffer[(*length) - 1], '9'); + buffer[(*length) - 1]++; + } else { + // Halfway case. + // TODO(floitsch): need a way to solve half-way cases. + // For now let's round towards even (since this is what Gay seems to + // do). - - // The procedure starts generating digits from the left to the right and stops - // when the generated digits yield the shortest decimal representation of v. A - // decimal representation of v is a number lying closer to v than to any other - // double, so it converts to v when read. - // - // This is true if d, the decimal representation, is between m- and m+, the - // upper and lower boundaries. d must be strictly between them if !is_even. - // m- := (numerator - delta_minus) / denominator - // m+ := (numerator + delta_plus) / denominator - // - // Precondition: 0 <= (numerator+delta_plus) / denominator < 10. - // If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit - // will be produced. This should be the standard precondition. - static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus, - bool is_even, - Vector<char> buffer, int* length) { - // Small optimization: if delta_minus and delta_plus are the same just reuse - // one of the two bignums. - if (Bignum::Equal(*delta_minus, *delta_plus)) { - delta_plus = delta_minus; - } - *length = 0; - while (true) { - uint16_t digit; - digit = numerator->DivideModuloIntBignum(*denominator); - DCHECK_LE(digit, 9u); // digit is a uint16_t and therefore always positive. - // digit = numerator / denominator (integer division). - // numerator = numerator % denominator. - buffer[(*length)++] = static_cast<char>(digit + '0'); - - // Can we stop already? - // If the remainder of the division is less than the distance to the lower - // boundary we can stop. In this case we simply round down (discarding the - // remainder). - // Similarly we test if we can round up (using the upper boundary). - bool in_delta_room_minus; - bool in_delta_room_plus; - if (is_even) { - in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus); - } else { - in_delta_room_minus = Bignum::Less(*numerator, *delta_minus); - } - if (is_even) { - in_delta_room_plus = - Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; - } else { - in_delta_room_plus = - Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; - } - if (!in_delta_room_minus && !in_delta_room_plus) { - // Prepare for next iteration. - numerator->Times10(); - delta_minus->Times10(); - // We optimized delta_plus to be equal to delta_minus (if they share the - // same value). So don't multiply delta_plus if they point to the same - // object. - if (delta_minus != delta_plus) { - delta_plus->Times10(); - } - } else if (in_delta_room_minus && in_delta_room_plus) { - // Let's see if 2*numerator < denominator. - // If yes, then the next digit would be < 5 and we can round down. - int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator); - if (compare < 0) { - // Remaining digits are less than .5. -> Round down (== do nothing). - } else if (compare > 0) { - // Remaining digits are more than .5 of denominator. -> Round up. - // Note that the last digit could not be a '9' as otherwise the whole - // loop would have stopped earlier. - // We still have an assert here in case the preconditions were not - // satisfied. - DCHECK_NE(buffer[(*length) - 1], '9'); - buffer[(*length) - 1]++; - } else { - // Halfway case. - // TODO(floitsch): need a way to solve half-way cases. - // For now let's round towards even (since this is what Gay seems to - // do). - - if ((buffer[(*length) - 1] - '0') % 2 == 0) { - // Round down => Do nothing. - } else { - DCHECK_NE(buffer[(*length) - 1], '9'); - buffer[(*length) - 1]++; - } - } - return; - } else if (in_delta_room_minus) { - // Round down (== do nothing). - return; - } else { // in_delta_room_plus - // Round up. - // Note again that the last digit could not be '9' since this would have - // stopped the loop earlier. - // We still have an ASSERT here, in case the preconditions were not - // satisfied. - DCHECK_NE(buffer[(*length) -1], '9'); - buffer[(*length) - 1]++; - return; - } - } - } - - - // Let v = numerator / denominator < 10. - // Then we generate 'count' digits of d = x.xxxxx... (without the decimal point) - // from left to right. Once 'count' digits have been produced we decide wether - // to round up or down. Remainders of exactly .5 round upwards. Numbers such - // as 9.999999 propagate a carry all the way, and change the - // exponent (decimal_point), when rounding upwards. - static void GenerateCountedDigits(int count, int* decimal_point, - Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length) { - DCHECK_GE(count, 0); - for (int i = 0; i < count - 1; ++i) { - uint16_t digit; - digit = numerator->DivideModuloIntBignum(*denominator); - DCHECK_LE(digit, 9u); // digit is a uint16_t and therefore always positive. - // digit = numerator / denominator (integer division). - // numerator = numerator % denominator. - buffer[i] = static_cast<char>(digit + '0'); - // Prepare for next iteration. - numerator->Times10(); - } - // Generate the last digit. - uint16_t digit; - digit = numerator->DivideModuloIntBignum(*denominator); - if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { - digit++; - } - buffer[count - 1] = static_cast<char>(digit + '0'); - // Correct bad digits (in case we had a sequence of '9's). Propagate the - // carry until we hat a non-'9' or til we reach the first digit. - for (int i = count - 1; i > 0; --i) { - if (buffer[i] != '0' + 10) break; - buffer[i] = '0'; - buffer[i - 1]++; - } - if (buffer[0] == '0' + 10) { - // Propagate a carry past the top place. - buffer[0] = '1'; - (*decimal_point)++; - } - *length = count; - } - - - // Generates 'requested_digits' after the decimal point. It might omit - // trailing '0's. If the input number is too small then no digits at all are - // generated (ex.: 2 fixed digits for 0.00001). - // - // Input verifies: 1 <= (numerator + delta) / denominator < 10. - static void BignumToFixed(int requested_digits, int* decimal_point, - Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length) { - // Note that we have to look at more than just the requested_digits, since - // a number could be rounded up. Example: v=0.5 with requested_digits=0. - // Even though the power of v equals 0 we can't just stop here. - if (-(*decimal_point) > requested_digits) { - // The number is definitively too small. - // Ex: 0.001 with requested_digits == 1. - // Set decimal-point to -requested_digits. This is what Gay does. - // Note that it should not have any effect anyways since the string is - // empty. - *decimal_point = -requested_digits; - *length = 0; - return; - } else if (-(*decimal_point) == requested_digits) { - // We only need to verify if the number rounds down or up. - // Ex: 0.04 and 0.06 with requested_digits == 1. - DCHECK_EQ(*decimal_point, -requested_digits); - // Initially the fraction lies in range (1, 10]. Multiply the denominator - // by 10 so that we can compare more easily. - denominator->Times10(); - if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { - // If the fraction is >= 0.5 then we have to include the rounded - // digit. - buffer[0] = '1'; - *length = 1; - (*decimal_point)++; - } else { - // Note that we caught most of similar cases earlier. - *length = 0; - } - return; + if ((buffer[(*length) - 1] - '0') % 2 == 0) { + // Round down => Do nothing. } else { - // The requested digits correspond to the digits after the point. - // The variable 'needed_digits' includes the digits before the point. - int needed_digits = (*decimal_point) + requested_digits; - GenerateCountedDigits(needed_digits, decimal_point, - numerator, denominator, - buffer, length); + DCHECK_NE(buffer[(*length) - 1], '9'); + buffer[(*length) - 1]++; } + } + return; + } else if (in_delta_room_minus) { + // Round down (== do nothing). + return; + } else { // in_delta_room_plus + // Round up. + // Note again that the last digit could not be '9' since this would have + // stopped the loop earlier. + // We still have an ASSERT here, in case the preconditions were not + // satisfied. + DCHECK_NE(buffer[(*length) - 1], '9'); + buffer[(*length) - 1]++; + return; } + } +} +// Let v = numerator / denominator < 10. +// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point) +// from left to right. Once 'count' digits have been produced we decide wether +// to round up or down. Remainders of exactly .5 round upwards. Numbers such +// as 9.999999 propagate a carry all the way, and change the +// exponent (decimal_point), when rounding upwards. +static void GenerateCountedDigits(int count, + int* decimal_point, + Bignum* numerator, + Bignum* denominator, + Vector<char>(buffer), + int* length) { + DCHECK_GE(count, 0); + for (int i = 0; i < count - 1; ++i) { + uint16_t digit; + digit = numerator->DivideModuloIntBignum(*denominator); + DCHECK_LE(digit, 9u); // digit is a uint16_t and therefore always positive. + // digit = numerator / denominator (integer division). + // numerator = numerator % denominator. + buffer[i] = static_cast<char>(digit + '0'); + // Prepare for next iteration. + numerator->Times10(); + } + // Generate the last digit. + uint16_t digit; + digit = numerator->DivideModuloIntBignum(*denominator); + if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { + digit++; + } + buffer[count - 1] = static_cast<char>(digit + '0'); + // Correct bad digits (in case we had a sequence of '9's). Propagate the + // carry until we hat a non-'9' or til we reach the first digit. + for (int i = count - 1; i > 0; --i) { + if (buffer[i] != '0' + 10) + break; + buffer[i] = '0'; + buffer[i - 1]++; + } + if (buffer[0] == '0' + 10) { + // Propagate a carry past the top place. + buffer[0] = '1'; + (*decimal_point)++; + } + *length = count; +} - // Returns an estimation of k such that 10^(k-1) <= v < 10^k where - // v = f * 2^exponent and 2^52 <= f < 2^53. - // v is hence a normalized double with the given exponent. The output is an - // approximation for the exponent of the decimal approimation .digits * 10^k. - // - // The result might undershoot by 1 in which case 10^k <= v < 10^k+1. - // Note: this property holds for v's upper boundary m+ too. - // 10^k <= m+ < 10^k+1. - // (see explanation below). - // - // Examples: - // EstimatePower(0) => 16 - // EstimatePower(-52) => 0 - // - // Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0. - static int EstimatePower(int exponent) { - // This function estimates log10 of v where v = f*2^e (with e == exponent). - // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)). - // Note that f is bounded by its container size. Let p = 53 (the double's - // significand size). Then 2^(p-1) <= f < 2^p. - // - // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close - // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)). - // The computed number undershoots by less than 0.631 (when we compute log3 - // and not log10). - // - // Optimization: since we only need an approximated result this computation - // can be performed on 64 bit integers. On x86/x64 architecture the speedup is - // not really measurable, though. - // - // Since we want to avoid overshooting we decrement by 1e10 so that - // floating-point imprecisions don't affect us. - // - // Explanation for v's boundary m+: the computation takes advantage of - // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement - // (even for denormals where the delta can be much more important). - - const double kK1Log10 = 0.30102999566398114; // 1/lg(10) - - // For doubles len(f) == 53 (don't forget the hidden bit). - const int kSignificandSize = 53; - double estimate = - ceil((exponent + kSignificandSize - 1) * kK1Log10 - 1e-10); - return static_cast<int>(estimate); +// Generates 'requested_digits' after the decimal point. It might omit +// trailing '0's. If the input number is too small then no digits at all are +// generated (ex.: 2 fixed digits for 0.00001). +// +// Input verifies: 1 <= (numerator + delta) / denominator < 10. +static void BignumToFixed(int requested_digits, + int* decimal_point, + Bignum* numerator, + Bignum* denominator, + Vector<char>(buffer), + int* length) { + // Note that we have to look at more than just the requested_digits, since + // a number could be rounded up. Example: v=0.5 with requested_digits=0. + // Even though the power of v equals 0 we can't just stop here. + if (-(*decimal_point) > requested_digits) { + // The number is definitively too small. + // Ex: 0.001 with requested_digits == 1. + // Set decimal-point to -requested_digits. This is what Gay does. + // Note that it should not have any effect anyways since the string is + // empty. + *decimal_point = -requested_digits; + *length = 0; + return; + } else if (-(*decimal_point) == requested_digits) { + // We only need to verify if the number rounds down or up. + // Ex: 0.04 and 0.06 with requested_digits == 1. + DCHECK_EQ(*decimal_point, -requested_digits); + // Initially the fraction lies in range (1, 10]. Multiply the denominator + // by 10 so that we can compare more easily. + denominator->Times10(); + if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { + // If the fraction is >= 0.5 then we have to include the rounded + // digit. + buffer[0] = '1'; + *length = 1; + (*decimal_point)++; + } else { + // Note that we caught most of similar cases earlier. + *length = 0; } + return; + } else { + // The requested digits correspond to the digits after the point. + // The variable 'needed_digits' includes the digits before the point. + int needed_digits = (*decimal_point) + requested_digits; + GenerateCountedDigits(needed_digits, decimal_point, numerator, denominator, + buffer, length); + } +} +// Returns an estimation of k such that 10^(k-1) <= v < 10^k where +// v = f * 2^exponent and 2^52 <= f < 2^53. +// v is hence a normalized double with the given exponent. The output is an +// approximation for the exponent of the decimal approimation .digits * 10^k. +// +// The result might undershoot by 1 in which case 10^k <= v < 10^k+1. +// Note: this property holds for v's upper boundary m+ too. +// 10^k <= m+ < 10^k+1. +// (see explanation below). +// +// Examples: +// EstimatePower(0) => 16 +// EstimatePower(-52) => 0 +// +// Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0. +static int EstimatePower(int exponent) { + // This function estimates log10 of v where v = f*2^e (with e == exponent). + // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)). + // Note that f is bounded by its container size. Let p = 53 (the double's + // significand size). Then 2^(p-1) <= f < 2^p. + // + // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close + // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)). + // The computed number undershoots by less than 0.631 (when we compute log3 + // and not log10). + // + // Optimization: since we only need an approximated result this computation + // can be performed on 64 bit integers. On x86/x64 architecture the speedup is + // not really measurable, though. + // + // Since we want to avoid overshooting we decrement by 1e10 so that + // floating-point imprecisions don't affect us. + // + // Explanation for v's boundary m+: the computation takes advantage of + // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement + // (even for denormals where the delta can be much more important). - // See comments for InitialScaledStartValues. - static void InitialScaledStartValuesPositiveExponent( - double v, int estimated_power, bool need_boundary_deltas, - Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus) { - // A positive exponent implies a positive power. - DCHECK_GE(estimated_power, 0); - // Since the estimated_power is positive we simply multiply the denominator - // by 10^estimated_power. + const double kK1Log10 = 0.30102999566398114; // 1/lg(10) - // numerator = v. - numerator->AssignUInt64(Double(v).Significand()); - numerator->ShiftLeft(Double(v).Exponent()); - // denominator = 10^estimated_power. - denominator->AssignPowerUInt16(10, estimated_power); + // For doubles len(f) == 53 (don't forget the hidden bit). + const int kSignificandSize = 53; + double estimate = ceil((exponent + kSignificandSize - 1) * kK1Log10 - 1e-10); + return static_cast<int>(estimate); +} - if (need_boundary_deltas) { - // Introduce a common denominator so that the deltas to the boundaries are - // integers. - denominator->ShiftLeft(1); - numerator->ShiftLeft(1); - // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common - // denominator (of 2) delta_plus equals 2^e. - delta_plus->AssignUInt16(1); - delta_plus->ShiftLeft(Double(v).Exponent()); - // Same for delta_minus (with adjustments below if f == 2^p-1). - delta_minus->AssignUInt16(1); - delta_minus->ShiftLeft(Double(v).Exponent()); +// See comments for InitialScaledStartValues. +static void InitialScaledStartValuesPositiveExponent(double v, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus) { + // A positive exponent implies a positive power. + DCHECK_GE(estimated_power, 0); + // Since the estimated_power is positive we simply multiply the denominator + // by 10^estimated_power. - // If the significand (without the hidden bit) is 0, then the lower - // boundary is closer than just half a ulp (unit in the last place). - // There is only one exception: if the next lower number is a denormal then - // the distance is 1 ulp. This cannot be the case for exponent >= 0 (but we - // have to test it in the other function where exponent < 0). - uint64_t v_bits = Double(v).AsUint64(); - if ((v_bits & Double::kSignificandMask) == 0) { - // The lower boundary is closer at half the distance of "normal" numbers. - // Increase the common denominator and adapt all but the delta_minus. - denominator->ShiftLeft(1); // *2 - numerator->ShiftLeft(1); // *2 - delta_plus->ShiftLeft(1); // *2 - } - } + // numerator = v. + numerator->AssignUInt64(Double(v).Significand()); + numerator->ShiftLeft(Double(v).Exponent()); + // denominator = 10^estimated_power. + denominator->AssignPowerUInt16(10, estimated_power); + + if (need_boundary_deltas) { + // Introduce a common denominator so that the deltas to the boundaries are + // integers. + denominator->ShiftLeft(1); + numerator->ShiftLeft(1); + // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common + // denominator (of 2) delta_plus equals 2^e. + delta_plus->AssignUInt16(1); + delta_plus->ShiftLeft(Double(v).Exponent()); + // Same for delta_minus (with adjustments below if f == 2^p-1). + delta_minus->AssignUInt16(1); + delta_minus->ShiftLeft(Double(v).Exponent()); + + // If the significand (without the hidden bit) is 0, then the lower + // boundary is closer than just half a ulp (unit in the last place). + // There is only one exception: if the next lower number is a denormal then + // the distance is 1 ulp. This cannot be the case for exponent >= 0 (but we + // have to test it in the other function where exponent < 0). + uint64_t v_bits = Double(v).AsUint64(); + if ((v_bits & Double::kSignificandMask) == 0) { + // The lower boundary is closer at half the distance of "normal" numbers. + // Increase the common denominator and adapt all but the delta_minus. + denominator->ShiftLeft(1); // *2 + numerator->ShiftLeft(1); // *2 + delta_plus->ShiftLeft(1); // *2 } + } +} +// See comments for InitialScaledStartValues +static void InitialScaledStartValuesNegativeExponentPositivePower( + double v, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus) { + uint64_t significand = Double(v).Significand(); + int exponent = Double(v).Exponent(); + // v = f * 2^e with e < 0, and with estimated_power >= 0. + // This means that e is close to 0 (have a look at how estimated_power is + // computed). - // See comments for InitialScaledStartValues - static void InitialScaledStartValuesNegativeExponentPositivePower( - double v, int estimated_power, bool need_boundary_deltas, - Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus) { - uint64_t significand = Double(v).Significand(); - int exponent = Double(v).Exponent(); - // v = f * 2^e with e < 0, and with estimated_power >= 0. - // This means that e is close to 0 (have a look at how estimated_power is - // computed). + // numerator = significand + // since v = significand * 2^exponent this is equivalent to + // numerator = v * / 2^-exponent + numerator->AssignUInt64(significand); + // denominator = 10^estimated_power * 2^-exponent (with exponent < 0) + denominator->AssignPowerUInt16(10, estimated_power); + denominator->ShiftLeft(-exponent); - // numerator = significand - // since v = significand * 2^exponent this is equivalent to - // numerator = v * / 2^-exponent - numerator->AssignUInt64(significand); - // denominator = 10^estimated_power * 2^-exponent (with exponent < 0) - denominator->AssignPowerUInt16(10, estimated_power); - denominator->ShiftLeft(-exponent); + if (need_boundary_deltas) { + // Introduce a common denominator so that the deltas to the boundaries are + // integers. + denominator->ShiftLeft(1); + numerator->ShiftLeft(1); + // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common + // denominator (of 2) delta_plus equals 2^e. + // Given that the denominator already includes v's exponent the distance + // to the boundaries is simply 1. + delta_plus->AssignUInt16(1); + // Same for delta_minus (with adjustments below if f == 2^p-1). + delta_minus->AssignUInt16(1); - if (need_boundary_deltas) { - // Introduce a common denominator so that the deltas to the boundaries are - // integers. - denominator->ShiftLeft(1); - numerator->ShiftLeft(1); - // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common - // denominator (of 2) delta_plus equals 2^e. - // Given that the denominator already includes v's exponent the distance - // to the boundaries is simply 1. - delta_plus->AssignUInt16(1); - // Same for delta_minus (with adjustments below if f == 2^p-1). - delta_minus->AssignUInt16(1); - - // If the significand (without the hidden bit) is 0, then the lower - // boundary is closer than just one ulp (unit in the last place). - // There is only one exception: if the next lower number is a denormal - // then the distance is 1 ulp. Since the exponent is close to zero - // (otherwise estimated_power would have been negative) this cannot happen - // here either. - uint64_t v_bits = Double(v).AsUint64(); - if ((v_bits & Double::kSignificandMask) == 0) { - // The lower boundary is closer at half the distance of "normal" numbers. - // Increase the denominator and adapt all but the delta_minus. - denominator->ShiftLeft(1); // *2 - numerator->ShiftLeft(1); // *2 - delta_plus->ShiftLeft(1); // *2 - } - } + // If the significand (without the hidden bit) is 0, then the lower + // boundary is closer than just one ulp (unit in the last place). + // There is only one exception: if the next lower number is a denormal + // then the distance is 1 ulp. Since the exponent is close to zero + // (otherwise estimated_power would have been negative) this cannot happen + // here either. + uint64_t v_bits = Double(v).AsUint64(); + if ((v_bits & Double::kSignificandMask) == 0) { + // The lower boundary is closer at half the distance of "normal" numbers. + // Increase the denominator and adapt all but the delta_minus. + denominator->ShiftLeft(1); // *2 + numerator->ShiftLeft(1); // *2 + delta_plus->ShiftLeft(1); // *2 } + } +} +// See comments for InitialScaledStartValues +static void InitialScaledStartValuesNegativeExponentNegativePower( + double v, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus) { + const uint64_t kMinimalNormalizedExponent = + UINT64_2PART_C(0x00100000, 00000000); + uint64_t significand = Double(v).Significand(); + int exponent = Double(v).Exponent(); + // Instead of multiplying the denominator with 10^estimated_power we + // multiply all values (numerator and deltas) by 10^-estimated_power. - // See comments for InitialScaledStartValues - static void InitialScaledStartValuesNegativeExponentNegativePower( - double v, int estimated_power, bool need_boundary_deltas, - Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus) { - const uint64_t kMinimalNormalizedExponent = - UINT64_2PART_C(0x00100000, 00000000); - uint64_t significand = Double(v).Significand(); - int exponent = Double(v).Exponent(); - // Instead of multiplying the denominator with 10^estimated_power we - // multiply all values (numerator and deltas) by 10^-estimated_power. + // Use numerator as temporary container for power_ten. + Bignum* power_ten = numerator; + power_ten->AssignPowerUInt16(10, -estimated_power); - // Use numerator as temporary container for power_ten. - Bignum* power_ten = numerator; - power_ten->AssignPowerUInt16(10, -estimated_power); + if (need_boundary_deltas) { + // Since power_ten == numerator we must make a copy of 10^estimated_power + // before we complete the computation of the numerator. + // delta_plus = delta_minus = 10^estimated_power + delta_plus->AssignBignum(*power_ten); + delta_minus->AssignBignum(*power_ten); + } - if (need_boundary_deltas) { - // Since power_ten == numerator we must make a copy of 10^estimated_power - // before we complete the computation of the numerator. - // delta_plus = delta_minus = 10^estimated_power - delta_plus->AssignBignum(*power_ten); - delta_minus->AssignBignum(*power_ten); - } + // numerator = significand * 2 * 10^-estimated_power + // since v = significand * 2^exponent this is equivalent to + // numerator = v * 10^-estimated_power * 2 * 2^-exponent. + // Remember: numerator has been abused as power_ten. So no need to assign it + // to itself. + DCHECK_EQ(numerator, power_ten); + numerator->MultiplyByUInt64(significand); - // numerator = significand * 2 * 10^-estimated_power - // since v = significand * 2^exponent this is equivalent to - // numerator = v * 10^-estimated_power * 2 * 2^-exponent. - // Remember: numerator has been abused as power_ten. So no need to assign it - // to itself. - DCHECK_EQ(numerator, power_ten); - numerator->MultiplyByUInt64(significand); + // denominator = 2 * 2^-exponent with exponent < 0. + denominator->AssignUInt16(1); + denominator->ShiftLeft(-exponent); - // denominator = 2 * 2^-exponent with exponent < 0. - denominator->AssignUInt16(1); - denominator->ShiftLeft(-exponent); + if (need_boundary_deltas) { + // Introduce a common denominator so that the deltas to the boundaries are + // integers. + numerator->ShiftLeft(1); + denominator->ShiftLeft(1); + // With this shift the boundaries have their correct value, since + // delta_plus = 10^-estimated_power, and + // delta_minus = 10^-estimated_power. + // These assignments have been done earlier. - if (need_boundary_deltas) { - // Introduce a common denominator so that the deltas to the boundaries are - // integers. - numerator->ShiftLeft(1); - denominator->ShiftLeft(1); - // With this shift the boundaries have their correct value, since - // delta_plus = 10^-estimated_power, and - // delta_minus = 10^-estimated_power. - // These assignments have been done earlier. - - // The special case where the lower boundary is twice as close. - // This time we have to look out for the exception too. - uint64_t v_bits = Double(v).AsUint64(); - if ((v_bits & Double::kSignificandMask) == 0 && - // The only exception where a significand == 0 has its boundaries at - // "normal" distances: - (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent) { - numerator->ShiftLeft(1); // *2 - denominator->ShiftLeft(1); // *2 - delta_plus->ShiftLeft(1); // *2 - } - } + // The special case where the lower boundary is twice as close. + // This time we have to look out for the exception too. + uint64_t v_bits = Double(v).AsUint64(); + if ((v_bits & Double::kSignificandMask) == 0 && + // The only exception where a significand == 0 has its boundaries at + // "normal" distances: + (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent) { + numerator->ShiftLeft(1); // *2 + denominator->ShiftLeft(1); // *2 + delta_plus->ShiftLeft(1); // *2 } + } +} +// Let v = significand * 2^exponent. +// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator +// and denominator. The functions GenerateShortestDigits and +// GenerateCountedDigits will then convert this ratio to its decimal +// representation d, with the required accuracy. +// Then d * 10^estimated_power is the representation of v. +// (Note: the fraction and the estimated_power might get adjusted before +// generating the decimal representation.) +// +// The initial start values consist of: +// - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power. +// - a scaled (common) denominator. +// optionally (used by GenerateShortestDigits to decide if it has the shortest +// decimal converting back to v): +// - v - m-: the distance to the lower boundary. +// - m+ - v: the distance to the upper boundary. +// +// v, m+, m-, and therefore v - m- and m+ - v all share the same denominator. +// +// Let ep == estimated_power, then the returned values will satisfy: +// v / 10^ep = numerator / denominator. +// v's boundarys m- and m+: +// m- / 10^ep == v / 10^ep - delta_minus / denominator +// m+ / 10^ep == v / 10^ep + delta_plus / denominator +// Or in other words: +// m- == v - delta_minus * 10^ep / denominator; +// m+ == v + delta_plus * 10^ep / denominator; +// +// Since 10^(k-1) <= v < 10^k (with k == estimated_power) +// or 10^k <= v < 10^(k+1) +// we then have 0.1 <= numerator/denominator < 1 +// or 1 <= numerator/denominator < 10 +// +// It is then easy to kickstart the digit-generation routine. +// +// The boundary-deltas are only filled if need_boundary_deltas is set. +static void InitialScaledStartValues(double v, + int estimated_power, + bool need_boundary_deltas, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus) { + if (Double(v).Exponent() >= 0) { + InitialScaledStartValuesPositiveExponent( + v, estimated_power, need_boundary_deltas, numerator, denominator, + delta_minus, delta_plus); + } else if (estimated_power >= 0) { + InitialScaledStartValuesNegativeExponentPositivePower( + v, estimated_power, need_boundary_deltas, numerator, denominator, + delta_minus, delta_plus); + } else { + InitialScaledStartValuesNegativeExponentNegativePower( + v, estimated_power, need_boundary_deltas, numerator, denominator, + delta_minus, delta_plus); + } +} - // Let v = significand * 2^exponent. - // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator - // and denominator. The functions GenerateShortestDigits and - // GenerateCountedDigits will then convert this ratio to its decimal - // representation d, with the required accuracy. - // Then d * 10^estimated_power is the representation of v. - // (Note: the fraction and the estimated_power might get adjusted before - // generating the decimal representation.) - // - // The initial start values consist of: - // - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power. - // - a scaled (common) denominator. - // optionally (used by GenerateShortestDigits to decide if it has the shortest - // decimal converting back to v): - // - v - m-: the distance to the lower boundary. - // - m+ - v: the distance to the upper boundary. - // - // v, m+, m-, and therefore v - m- and m+ - v all share the same denominator. - // - // Let ep == estimated_power, then the returned values will satisfy: - // v / 10^ep = numerator / denominator. - // v's boundarys m- and m+: - // m- / 10^ep == v / 10^ep - delta_minus / denominator - // m+ / 10^ep == v / 10^ep + delta_plus / denominator - // Or in other words: - // m- == v - delta_minus * 10^ep / denominator; - // m+ == v + delta_plus * 10^ep / denominator; - // - // Since 10^(k-1) <= v < 10^k (with k == estimated_power) - // or 10^k <= v < 10^(k+1) - // we then have 0.1 <= numerator/denominator < 1 - // or 1 <= numerator/denominator < 10 - // - // It is then easy to kickstart the digit-generation routine. - // - // The boundary-deltas are only filled if need_boundary_deltas is set. - static void InitialScaledStartValues(double v, - int estimated_power, - bool need_boundary_deltas, - Bignum* numerator, - Bignum* denominator, - Bignum* delta_minus, - Bignum* delta_plus) { - if (Double(v).Exponent() >= 0) { - InitialScaledStartValuesPositiveExponent( - v, estimated_power, need_boundary_deltas, - numerator, denominator, delta_minus, delta_plus); - } else if (estimated_power >= 0) { - InitialScaledStartValuesNegativeExponentPositivePower( - v, estimated_power, need_boundary_deltas, - numerator, denominator, delta_minus, delta_plus); - } else { - InitialScaledStartValuesNegativeExponentNegativePower( - v, estimated_power, need_boundary_deltas, - numerator, denominator, delta_minus, delta_plus); - } +// This routine multiplies numerator/denominator so that its values lies in the +// range 1-10. That is after a call to this function we have: +// 1 <= (numerator + delta_plus) /denominator < 10. +// Let numerator the input before modification and numerator' the argument +// after modification, then the output-parameter decimal_point is such that +// numerator / denominator * 10^estimated_power == +// numerator' / denominator' * 10^(decimal_point - 1) +// In some cases estimated_power was too low, and this is already the case. We +// then simply adjust the power so that 10^(k-1) <= v < 10^k (with k == +// estimated_power) but do not touch the numerator or denominator. +// Otherwise the routine multiplies the numerator and the deltas by 10. +static void FixupMultiply10(int estimated_power, + bool is_even, + int* decimal_point, + Bignum* numerator, + Bignum* denominator, + Bignum* delta_minus, + Bignum* delta_plus) { + bool in_range; + if (is_even) { + // For IEEE doubles half-way cases (in decimal system numbers ending with 5) + // are rounded to the closest floating-point number with even significand. + in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; + } else { + in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; + } + if (in_range) { + // Since numerator + delta_plus >= denominator we already have + // 1 <= numerator/denominator < 10. Simply update the estimated_power. + *decimal_point = estimated_power + 1; + } else { + *decimal_point = estimated_power; + numerator->Times10(); + if (Bignum::Equal(*delta_minus, *delta_plus)) { + delta_minus->Times10(); + delta_plus->AssignBignum(*delta_minus); + } else { + delta_minus->Times10(); + delta_plus->Times10(); } - - - // This routine multiplies numerator/denominator so that its values lies in the - // range 1-10. That is after a call to this function we have: - // 1 <= (numerator + delta_plus) /denominator < 10. - // Let numerator the input before modification and numerator' the argument - // after modification, then the output-parameter decimal_point is such that - // numerator / denominator * 10^estimated_power == - // numerator' / denominator' * 10^(decimal_point - 1) - // In some cases estimated_power was too low, and this is already the case. We - // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k == - // estimated_power) but do not touch the numerator or denominator. - // Otherwise the routine multiplies the numerator and the deltas by 10. - static void FixupMultiply10(int estimated_power, bool is_even, - int* decimal_point, - Bignum* numerator, Bignum* denominator, - Bignum* delta_minus, Bignum* delta_plus) { - bool in_range; - if (is_even) { - // For IEEE doubles half-way cases (in decimal system numbers ending with 5) - // are rounded to the closest floating-point number with even significand. - in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; - } else { - in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; - } - if (in_range) { - // Since numerator + delta_plus >= denominator we already have - // 1 <= numerator/denominator < 10. Simply update the estimated_power. - *decimal_point = estimated_power + 1; - } else { - *decimal_point = estimated_power; - numerator->Times10(); - if (Bignum::Equal(*delta_minus, *delta_plus)) { - delta_minus->Times10(); - delta_plus->AssignBignum(*delta_minus); - } else { - delta_minus->Times10(); - delta_plus->Times10(); - } - } - } + } +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/bignum.cc b/third_party/WebKit/Source/platform/wtf/dtoa/bignum.cc index b551709..c0daf31b 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/bignum.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/bignum.cc
@@ -33,745 +33,738 @@ namespace double_conversion { - Bignum::Bignum() +Bignum::Bignum() : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) { - for (int i = 0; i < kBigitCapacity; ++i) { - bigits_[i] = 0; - } + for (int i = 0; i < kBigitCapacity; ++i) { + bigits_[i] = 0; + } +} + +template <typename S> +static int BitSize(S value) { + return 8 * sizeof(value); +} + +// Guaranteed to lie in one Bigit. +void Bignum::AssignUInt16(uint16_t value) { + DCHECK_GE(kBigitSize, BitSize(value)); + Zero(); + if (value == 0) + return; + + EnsureCapacity(1); + bigits_[0] = value; + used_digits_ = 1; +} + +void Bignum::AssignUInt64(uint64_t value) { + const int kUInt64Size = 64; + + Zero(); + if (value == 0) + return; + + int needed_bigits = kUInt64Size / kBigitSize + 1; + EnsureCapacity(needed_bigits); + for (int i = 0; i < needed_bigits; ++i) { + bigits_[i] = (uint32_t)value & kBigitMask; + value = value >> kBigitSize; + } + used_digits_ = needed_bigits; + Clamp(); +} + +void Bignum::AssignBignum(const Bignum& other) { + exponent_ = other.exponent_; + for (int i = 0; i < other.used_digits_; ++i) { + bigits_[i] = other.bigits_[i]; + } + // Clear the excess digits (if there were any). + for (int i = other.used_digits_; i < used_digits_; ++i) { + bigits_[i] = 0; + } + used_digits_ = other.used_digits_; +} + +static uint64_t ReadUInt64(Vector<const char> buffer, + int from, + int digits_to_read) { + uint64_t result = 0; + for (int i = from; i < from + digits_to_read; ++i) { + int digit = buffer[i] - '0'; + DCHECK_LE(0, digit); + DCHECK_LE(digit, 9); + result = result * 10 + digit; + } + return result; +} + +void Bignum::AssignDecimalString(Vector<const char> value) { + // 2^64 = 18446744073709551616 > 10^19 + const int kMaxUint64DecimalDigits = 19; + Zero(); + int length = value.length(); + int pos = 0; + // Let's just say that each digit needs 4 bits. + while (length >= kMaxUint64DecimalDigits) { + uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits); + pos += kMaxUint64DecimalDigits; + length -= kMaxUint64DecimalDigits; + MultiplyByPowerOfTen(kMaxUint64DecimalDigits); + AddUInt64(digits); + } + uint64_t digits = ReadUInt64(value, pos, length); + MultiplyByPowerOfTen(length); + AddUInt64(digits); + Clamp(); +} + +static int HexCharValue(char c) { + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return 10 + c - 'a'; + if ('A' <= c && c <= 'F') + return 10 + c - 'A'; + UNREACHABLE(); + return 0; // To make compiler happy. +} + +void Bignum::AssignHexString(Vector<const char> value) { + Zero(); + int length = value.length(); + + int needed_bigits = length * 4 / kBigitSize + 1; + EnsureCapacity(needed_bigits); + int string_index = length - 1; + for (int i = 0; i < needed_bigits - 1; ++i) { + // These bigits are guaranteed to be "full". + Chunk current_bigit = 0; + for (int j = 0; j < kBigitSize / 4; j++) { + current_bigit += HexCharValue(value[string_index--]) << (j * 4); } + bigits_[i] = current_bigit; + } + used_digits_ = needed_bigits - 1; + Chunk most_significant_bigit = 0; // Could be = 0; + for (int j = 0; j <= string_index; ++j) { + most_significant_bigit <<= 4; + most_significant_bigit += HexCharValue(value[j]); + } + if (most_significant_bigit != 0) { + bigits_[used_digits_] = most_significant_bigit; + used_digits_++; + } + Clamp(); +} - template<typename S> - static int BitSize(S value) { - return 8 * sizeof(value); - } +void Bignum::AddUInt64(uint64_t operand) { + if (operand == 0) + return; + Bignum other; + other.AssignUInt64(operand); + AddBignum(other); +} - // Guaranteed to lie in one Bigit. - void Bignum::AssignUInt16(uint16_t value) { - DCHECK_GE(kBigitSize, BitSize(value)); - Zero(); - if (value == 0) return; +void Bignum::AddBignum(const Bignum& other) { + DCHECK(IsClamped()); + DCHECK(other.IsClamped()); - EnsureCapacity(1); - bigits_[0] = value; - used_digits_ = 1; - } + // If this has a greater exponent than other append zero-bigits to this. + // After this call exponent_ <= other.exponent_. + Align(other); + // There are two possibilities: + // aaaaaaaaaaa 0000 (where the 0s represent a's exponent) + // bbbbb 00000000 + // ---------------- + // ccccccccccc 0000 + // or + // aaaaaaaaaa 0000 + // bbbbbbbbb 0000000 + // ----------------- + // cccccccccccc 0000 + // In both cases we might need a carry bigit. - void Bignum::AssignUInt64(uint64_t value) { - const int kUInt64Size = 64; + EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_); + Chunk carry = 0; + int bigit_pos = other.exponent_ - exponent_; + DCHECK_GE(bigit_pos, 0); + for (int i = 0; i < other.used_digits_; ++i) { + Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry; + bigits_[bigit_pos] = sum & kBigitMask; + carry = sum >> kBigitSize; + bigit_pos++; + } - Zero(); - if (value == 0) return; + while (carry != 0) { + Chunk sum = bigits_[bigit_pos] + carry; + bigits_[bigit_pos] = sum & kBigitMask; + carry = sum >> kBigitSize; + bigit_pos++; + } + used_digits_ = Max(bigit_pos, used_digits_); + DCHECK(IsClamped()); +} - int needed_bigits = kUInt64Size / kBigitSize + 1; - EnsureCapacity(needed_bigits); - for (int i = 0; i < needed_bigits; ++i) { - bigits_[i] = (uint32_t)value & kBigitMask; - value = value >> kBigitSize; - } - used_digits_ = needed_bigits; - Clamp(); - } +void Bignum::SubtractBignum(const Bignum& other) { + DCHECK(IsClamped()); + DCHECK(other.IsClamped()); + // We require this to be bigger than other. + DCHECK(LessEqual(other, *this)); + Align(other); - void Bignum::AssignBignum(const Bignum& other) { - exponent_ = other.exponent_; - for (int i = 0; i < other.used_digits_; ++i) { - bigits_[i] = other.bigits_[i]; - } - // Clear the excess digits (if there were any). - for (int i = other.used_digits_; i < used_digits_; ++i) { - bigits_[i] = 0; - } - used_digits_ = other.used_digits_; - } + int offset = other.exponent_ - exponent_; + Chunk borrow = 0; + int i; + for (i = 0; i < other.used_digits_; ++i) { + DCHECK((borrow == 0) || (borrow == 1)); + Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow; + bigits_[i + offset] = difference & kBigitMask; + borrow = difference >> (kChunkSize - 1); + } + while (borrow != 0) { + Chunk difference = bigits_[i + offset] - borrow; + bigits_[i + offset] = difference & kBigitMask; + borrow = difference >> (kChunkSize - 1); + ++i; + } + Clamp(); +} +void Bignum::ShiftLeft(int shift_amount) { + if (used_digits_ == 0) + return; + exponent_ += shift_amount / kBigitSize; + int local_shift = shift_amount % kBigitSize; + EnsureCapacity(used_digits_ + 1); + BigitsShiftLeft(local_shift); +} - static uint64_t ReadUInt64(Vector<const char> buffer, - int from, - int digits_to_read) { - uint64_t result = 0; - for (int i = from; i < from + digits_to_read; ++i) { - int digit = buffer[i] - '0'; - DCHECK_LE(0, digit); - DCHECK_LE(digit, 9); - result = result * 10 + digit; - } - return result; - } +void Bignum::MultiplyByUInt32(uint32_t factor) { + if (factor == 1) + return; + if (factor == 0) { + Zero(); + return; + } + if (used_digits_ == 0) + return; + // The product of a bigit with the factor is of size kBigitSize + 32. + // Assert that this number + 1 (for the carry) fits into double chunk. + DCHECK_GE(kDoubleChunkSize, kBigitSize + 32 + 1); + DoubleChunk carry = 0; + for (int i = 0; i < used_digits_; ++i) { + DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry; + bigits_[i] = static_cast<Chunk>(product & kBigitMask); + carry = (product >> kBigitSize); + } + while (carry != 0) { + EnsureCapacity(used_digits_ + 1); + bigits_[used_digits_] = (uint32_t)carry & kBigitMask; + used_digits_++; + carry >>= kBigitSize; + } +} - void Bignum::AssignDecimalString(Vector<const char> value) { - // 2^64 = 18446744073709551616 > 10^19 - const int kMaxUint64DecimalDigits = 19; - Zero(); - int length = value.length(); - int pos = 0; - // Let's just say that each digit needs 4 bits. - while (length >= kMaxUint64DecimalDigits) { - uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits); - pos += kMaxUint64DecimalDigits; - length -= kMaxUint64DecimalDigits; - MultiplyByPowerOfTen(kMaxUint64DecimalDigits); - AddUInt64(digits); - } - uint64_t digits = ReadUInt64(value, pos, length); - MultiplyByPowerOfTen(length); - AddUInt64(digits); - Clamp(); - } - - - static int HexCharValue(char c) { - if ('0' <= c && c <= '9') return c - '0'; - if ('a' <= c && c <= 'f') return 10 + c - 'a'; - if ('A' <= c && c <= 'F') return 10 + c - 'A'; - UNREACHABLE(); - return 0; // To make compiler happy. - } - - - void Bignum::AssignHexString(Vector<const char> value) { - Zero(); - int length = value.length(); - - int needed_bigits = length * 4 / kBigitSize + 1; - EnsureCapacity(needed_bigits); - int string_index = length - 1; - for (int i = 0; i < needed_bigits - 1; ++i) { - // These bigits are guaranteed to be "full". - Chunk current_bigit = 0; - for (int j = 0; j < kBigitSize / 4; j++) { - current_bigit += HexCharValue(value[string_index--]) << (j * 4); - } - bigits_[i] = current_bigit; - } - used_digits_ = needed_bigits - 1; - - Chunk most_significant_bigit = 0; // Could be = 0; - for (int j = 0; j <= string_index; ++j) { - most_significant_bigit <<= 4; - most_significant_bigit += HexCharValue(value[j]); - } - if (most_significant_bigit != 0) { - bigits_[used_digits_] = most_significant_bigit; - used_digits_++; - } - Clamp(); - } - - - void Bignum::AddUInt64(uint64_t operand) { - if (operand == 0) return; - Bignum other; - other.AssignUInt64(operand); - AddBignum(other); - } - - - void Bignum::AddBignum(const Bignum& other) { - DCHECK(IsClamped()); - DCHECK(other.IsClamped()); - - // If this has a greater exponent than other append zero-bigits to this. - // After this call exponent_ <= other.exponent_. - Align(other); - - // There are two possibilities: - // aaaaaaaaaaa 0000 (where the 0s represent a's exponent) - // bbbbb 00000000 - // ---------------- - // ccccccccccc 0000 - // or - // aaaaaaaaaa 0000 - // bbbbbbbbb 0000000 - // ----------------- - // cccccccccccc 0000 - // In both cases we might need a carry bigit. - - EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_); - Chunk carry = 0; - int bigit_pos = other.exponent_ - exponent_; - DCHECK_GE(bigit_pos, 0); - for (int i = 0; i < other.used_digits_; ++i) { - Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry; - bigits_[bigit_pos] = sum & kBigitMask; - carry = sum >> kBigitSize; - bigit_pos++; - } - - while (carry != 0) { - Chunk sum = bigits_[bigit_pos] + carry; - bigits_[bigit_pos] = sum & kBigitMask; - carry = sum >> kBigitSize; - bigit_pos++; - } - used_digits_ = Max(bigit_pos, used_digits_); - DCHECK(IsClamped()); - } - - - void Bignum::SubtractBignum(const Bignum& other) { - DCHECK(IsClamped()); - DCHECK(other.IsClamped()); - // We require this to be bigger than other. - DCHECK(LessEqual(other, *this)); - - Align(other); - - int offset = other.exponent_ - exponent_; - Chunk borrow = 0; - int i; - for (i = 0; i < other.used_digits_; ++i) { - DCHECK((borrow == 0) || (borrow == 1)); - Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow; - bigits_[i + offset] = difference & kBigitMask; - borrow = difference >> (kChunkSize - 1); - } - while (borrow != 0) { - Chunk difference = bigits_[i + offset] - borrow; - bigits_[i + offset] = difference & kBigitMask; - borrow = difference >> (kChunkSize - 1); - ++i; - } - Clamp(); - } - - - void Bignum::ShiftLeft(int shift_amount) { - if (used_digits_ == 0) return; - exponent_ += shift_amount / kBigitSize; - int local_shift = shift_amount % kBigitSize; - EnsureCapacity(used_digits_ + 1); - BigitsShiftLeft(local_shift); - } - - - void Bignum::MultiplyByUInt32(uint32_t factor) { - if (factor == 1) return; - if (factor == 0) { - Zero(); - return; - } - if (used_digits_ == 0) return; - - // The product of a bigit with the factor is of size kBigitSize + 32. - // Assert that this number + 1 (for the carry) fits into double chunk. - DCHECK_GE(kDoubleChunkSize, kBigitSize + 32 + 1); - DoubleChunk carry = 0; - for (int i = 0; i < used_digits_; ++i) { - DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry; - bigits_[i] = static_cast<Chunk>(product & kBigitMask); - carry = (product >> kBigitSize); - } - while (carry != 0) { - EnsureCapacity(used_digits_ + 1); - bigits_[used_digits_] = (uint32_t)carry & kBigitMask; - used_digits_++; - carry >>= kBigitSize; - } - } - - - void Bignum::MultiplyByUInt64(uint64_t factor) { - if (factor == 1) return; - if (factor == 0) { - Zero(); - return; - } - DCHECK_LT(kBigitSize, 32); - uint64_t carry = 0; - uint64_t low = factor & 0xFFFFFFFF; - uint64_t high = factor >> 32; - for (int i = 0; i < used_digits_; ++i) { - uint64_t product_low = low * bigits_[i]; - uint64_t product_high = high * bigits_[i]; - uint64_t tmp = (carry & kBigitMask) + product_low; - bigits_[i] = (uint32_t)tmp & kBigitMask; - carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + +void Bignum::MultiplyByUInt64(uint64_t factor) { + if (factor == 1) + return; + if (factor == 0) { + Zero(); + return; + } + DCHECK_LT(kBigitSize, 32); + uint64_t carry = 0; + uint64_t low = factor & 0xFFFFFFFF; + uint64_t high = factor >> 32; + for (int i = 0; i < used_digits_; ++i) { + uint64_t product_low = low * bigits_[i]; + uint64_t product_high = high * bigits_[i]; + uint64_t tmp = (carry & kBigitMask) + product_low; + bigits_[i] = (uint32_t)tmp & kBigitMask; + carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + (product_high << (32 - kBigitSize)); - } - while (carry != 0) { - EnsureCapacity(used_digits_ + 1); - bigits_[used_digits_] = (uint32_t)carry & kBigitMask; - used_digits_++; - carry >>= kBigitSize; - } + } + while (carry != 0) { + EnsureCapacity(used_digits_ + 1); + bigits_[used_digits_] = (uint32_t)carry & kBigitMask; + used_digits_++; + carry >>= kBigitSize; + } +} + +void Bignum::MultiplyByPowerOfTen(int exponent) { + const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d); + const uint16_t kFive1 = 5; + const uint16_t kFive2 = kFive1 * 5; + const uint16_t kFive3 = kFive2 * 5; + const uint16_t kFive4 = kFive3 * 5; + const uint16_t kFive5 = kFive4 * 5; + const uint16_t kFive6 = kFive5 * 5; + const uint32_t kFive7 = kFive6 * 5; + const uint32_t kFive8 = kFive7 * 5; + const uint32_t kFive9 = kFive8 * 5; + const uint32_t kFive10 = kFive9 * 5; + const uint32_t kFive11 = kFive10 * 5; + const uint32_t kFive12 = kFive11 * 5; + const uint32_t kFive13 = kFive12 * 5; + const uint32_t kFive1_to_12[] = {kFive1, kFive2, kFive3, kFive4, + kFive5, kFive6, kFive7, kFive8, + kFive9, kFive10, kFive11, kFive12}; + + DCHECK_GE(exponent, 0); + if (exponent == 0) + return; + if (used_digits_ == 0) + return; + + // We shift by exponent at the end just before returning. + int remaining_exponent = exponent; + while (remaining_exponent >= 27) { + MultiplyByUInt64(kFive27); + remaining_exponent -= 27; + } + while (remaining_exponent >= 13) { + MultiplyByUInt32(kFive13); + remaining_exponent -= 13; + } + if (remaining_exponent > 0) { + MultiplyByUInt32(kFive1_to_12[remaining_exponent - 1]); + } + ShiftLeft(exponent); +} + +void Bignum::Square() { + DCHECK(IsClamped()); + int product_length = 2 * used_digits_; + EnsureCapacity(product_length); + + // Comba multiplication: compute each column separately. + // Example: r = a2a1a0 * b2b1b0. + // r = 1 * a0b0 + + // 10 * (a1b0 + a0b1) + + // 100 * (a2b0 + a1b1 + a0b2) + + // 1000 * (a2b1 + a1b2) + + // 10000 * a2b2 + // + // In the worst case we have to accumulate nb-digits products of + // digit*digit. + // + // Assert that the additional number of bits in a DoubleChunk are enough + // to sum up used_digits of Bigit*Bigit. + if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) { + UNIMPLEMENTED(); + } + DoubleChunk accumulator = 0; + // First shift the digits so we don't overwrite them. + int copy_offset = used_digits_; + for (int i = 0; i < used_digits_; ++i) { + bigits_[copy_offset + i] = bigits_[i]; + } + // We have two loops to avoid some 'if's in the loop. + for (int i = 0; i < used_digits_; ++i) { + // Process temporary digit i with power i. + // The sum of the two indices must be equal to i. + int bigit_index1 = i; + int bigit_index2 = 0; + // Sum all of the sub-products. + while (bigit_index1 >= 0) { + Chunk chunk1 = bigits_[copy_offset + bigit_index1]; + Chunk chunk2 = bigits_[copy_offset + bigit_index2]; + accumulator += static_cast<DoubleChunk>(chunk1) * chunk2; + bigit_index1--; + bigit_index2++; } - - - void Bignum::MultiplyByPowerOfTen(int exponent) { - const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d); - const uint16_t kFive1 = 5; - const uint16_t kFive2 = kFive1 * 5; - const uint16_t kFive3 = kFive2 * 5; - const uint16_t kFive4 = kFive3 * 5; - const uint16_t kFive5 = kFive4 * 5; - const uint16_t kFive6 = kFive5 * 5; - const uint32_t kFive7 = kFive6 * 5; - const uint32_t kFive8 = kFive7 * 5; - const uint32_t kFive9 = kFive8 * 5; - const uint32_t kFive10 = kFive9 * 5; - const uint32_t kFive11 = kFive10 * 5; - const uint32_t kFive12 = kFive11 * 5; - const uint32_t kFive13 = kFive12 * 5; - const uint32_t kFive1_to_12[] = - { kFive1, kFive2, kFive3, kFive4, kFive5, kFive6, - kFive7, kFive8, kFive9, kFive10, kFive11, kFive12 }; - - DCHECK_GE(exponent, 0); - if (exponent == 0) return; - if (used_digits_ == 0) return; - - // We shift by exponent at the end just before returning. - int remaining_exponent = exponent; - while (remaining_exponent >= 27) { - MultiplyByUInt64(kFive27); - remaining_exponent -= 27; - } - while (remaining_exponent >= 13) { - MultiplyByUInt32(kFive13); - remaining_exponent -= 13; - } - if (remaining_exponent > 0) { - MultiplyByUInt32(kFive1_to_12[remaining_exponent - 1]); - } - ShiftLeft(exponent); + bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask; + accumulator >>= kBigitSize; + } + for (int i = used_digits_; i < product_length; ++i) { + int bigit_index1 = used_digits_ - 1; + int bigit_index2 = i - bigit_index1; + // Invariant: sum of both indices is again equal to i. + // Inner loop runs 0 times on last iteration, emptying accumulator. + while (bigit_index2 < used_digits_) { + Chunk chunk1 = bigits_[copy_offset + bigit_index1]; + Chunk chunk2 = bigits_[copy_offset + bigit_index2]; + accumulator += static_cast<DoubleChunk>(chunk1) * chunk2; + bigit_index1--; + bigit_index2++; } + // The overwritten bigits_[i] will never be read in further loop iterations, + // because bigit_index1 and bigit_index2 are always greater + // than i - used_digits_. + bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask; + accumulator >>= kBigitSize; + } + // Since the result was guaranteed to lie inside the number the + // accumulator must be 0 now. + DCHECK_EQ(accumulator, 0u); + // Don't forget to update the used_digits and the exponent. + used_digits_ = product_length; + exponent_ *= 2; + Clamp(); +} - void Bignum::Square() { - DCHECK(IsClamped()); - int product_length = 2 * used_digits_; - EnsureCapacity(product_length); +void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) { + DCHECK_NE(base, 0); + DCHECK_GE(power_exponent, 0); + if (power_exponent == 0) { + AssignUInt16(1); + return; + } + Zero(); + int shifts = 0; + // We expect base to be in range 2-32, and most often to be 10. + // It does not make much sense to implement different algorithms for counting + // the bits. + while ((base & 1) == 0) { + base >>= 1; + shifts++; + } + int bit_size = 0; + int tmp_base = base; + while (tmp_base != 0) { + tmp_base >>= 1; + bit_size++; + } + int final_size = bit_size * power_exponent; + // 1 extra bigit for the shifting, and one for rounded final_size. + EnsureCapacity(final_size / kBigitSize + 2); - // Comba multiplication: compute each column separately. - // Example: r = a2a1a0 * b2b1b0. - // r = 1 * a0b0 + - // 10 * (a1b0 + a0b1) + - // 100 * (a2b0 + a1b1 + a0b2) + - // 1000 * (a2b1 + a1b2) + - // 10000 * a2b2 - // - // In the worst case we have to accumulate nb-digits products of - // digit*digit. - // - // Assert that the additional number of bits in a DoubleChunk are enough - // to sum up used_digits of Bigit*Bigit. - if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) { - UNIMPLEMENTED(); - } - DoubleChunk accumulator = 0; - // First shift the digits so we don't overwrite them. - int copy_offset = used_digits_; - for (int i = 0; i < used_digits_; ++i) { - bigits_[copy_offset + i] = bigits_[i]; - } - // We have two loops to avoid some 'if's in the loop. - for (int i = 0; i < used_digits_; ++i) { - // Process temporary digit i with power i. - // The sum of the two indices must be equal to i. - int bigit_index1 = i; - int bigit_index2 = 0; - // Sum all of the sub-products. - while (bigit_index1 >= 0) { - Chunk chunk1 = bigits_[copy_offset + bigit_index1]; - Chunk chunk2 = bigits_[copy_offset + bigit_index2]; - accumulator += static_cast<DoubleChunk>(chunk1) * chunk2; - bigit_index1--; - bigit_index2++; - } - bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask; - accumulator >>= kBigitSize; - } - for (int i = used_digits_; i < product_length; ++i) { - int bigit_index1 = used_digits_ - 1; - int bigit_index2 = i - bigit_index1; - // Invariant: sum of both indices is again equal to i. - // Inner loop runs 0 times on last iteration, emptying accumulator. - while (bigit_index2 < used_digits_) { - Chunk chunk1 = bigits_[copy_offset + bigit_index1]; - Chunk chunk2 = bigits_[copy_offset + bigit_index2]; - accumulator += static_cast<DoubleChunk>(chunk1) * chunk2; - bigit_index1--; - bigit_index2++; - } - // The overwritten bigits_[i] will never be read in further loop iterations, - // because bigit_index1 and bigit_index2 are always greater - // than i - used_digits_. - bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask; - accumulator >>= kBigitSize; - } - // Since the result was guaranteed to lie inside the number the - // accumulator must be 0 now. - DCHECK_EQ(accumulator, 0u); + // Left to Right exponentiation. + int mask = 1; + while (power_exponent >= mask) + mask <<= 1; - // Don't forget to update the used_digits and the exponent. - used_digits_ = product_length; - exponent_ *= 2; - Clamp(); + // The mask is now pointing to the bit above the most significant 1-bit of + // power_exponent. + // Get rid of first 1-bit; + mask >>= 2; + uint64_t this_value = base; + + bool delayed_multipliciation = false; + const uint64_t max_32bits = 0xFFFFFFFF; + while (mask != 0 && this_value <= max_32bits) { + this_value = this_value * this_value; + // Verify that there is enough space in this_value to perform the + // multiplication. The first bit_size bits must be 0. + if ((power_exponent & mask) != 0) { + uint64_t base_bits_mask = + ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1); + bool high_bits_zero = (this_value & base_bits_mask) == 0; + if (high_bits_zero) { + this_value *= base; + } else { + delayed_multipliciation = true; + } } + mask >>= 1; + } + AssignUInt64(this_value); + if (delayed_multipliciation) { + MultiplyByUInt32(base); + } - - void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) { - DCHECK_NE(base, 0); - DCHECK_GE(power_exponent, 0); - if (power_exponent == 0) { - AssignUInt16(1); - return; - } - Zero(); - int shifts = 0; - // We expect base to be in range 2-32, and most often to be 10. - // It does not make much sense to implement different algorithms for counting - // the bits. - while ((base & 1) == 0) { - base >>= 1; - shifts++; - } - int bit_size = 0; - int tmp_base = base; - while (tmp_base != 0) { - tmp_base >>= 1; - bit_size++; - } - int final_size = bit_size * power_exponent; - // 1 extra bigit for the shifting, and one for rounded final_size. - EnsureCapacity(final_size / kBigitSize + 2); - - // Left to Right exponentiation. - int mask = 1; - while (power_exponent >= mask) mask <<= 1; - - // The mask is now pointing to the bit above the most significant 1-bit of - // power_exponent. - // Get rid of first 1-bit; - mask >>= 2; - uint64_t this_value = base; - - bool delayed_multipliciation = false; - const uint64_t max_32bits = 0xFFFFFFFF; - while (mask != 0 && this_value <= max_32bits) { - this_value = this_value * this_value; - // Verify that there is enough space in this_value to perform the - // multiplication. The first bit_size bits must be 0. - if ((power_exponent & mask) != 0) { - uint64_t base_bits_mask = - ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1); - bool high_bits_zero = (this_value & base_bits_mask) == 0; - if (high_bits_zero) { - this_value *= base; - } else { - delayed_multipliciation = true; - } - } - mask >>= 1; - } - AssignUInt64(this_value); - if (delayed_multipliciation) { - MultiplyByUInt32(base); - } - - // Now do the same thing as a bignum. - while (mask != 0) { - Square(); - if ((power_exponent & mask) != 0) { - MultiplyByUInt32(base); - } - mask >>= 1; - } - - // And finally add the saved shifts. - ShiftLeft(shifts * power_exponent); + // Now do the same thing as a bignum. + while (mask != 0) { + Square(); + if ((power_exponent & mask) != 0) { + MultiplyByUInt32(base); } + mask >>= 1; + } + // And finally add the saved shifts. + ShiftLeft(shifts * power_exponent); +} - // Precondition: this/other < 16bit. - uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) { - DCHECK(IsClamped()); - DCHECK(other.IsClamped()); - DCHECK_GT(other.used_digits_, 0); +// Precondition: this/other < 16bit. +uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) { + DCHECK(IsClamped()); + DCHECK(other.IsClamped()); + DCHECK_GT(other.used_digits_, 0); - // Easy case: if we have less digits than the divisor than the result is - // 0. Note: this handles the case where this == 0, too. - if (BigitLength() < other.BigitLength()) { - return 0; - } + // Easy case: if we have less digits than the divisor than the result is + // 0. Note: this handles the case where this == 0, too. + if (BigitLength() < other.BigitLength()) { + return 0; + } - Align(other); + Align(other); - uint16_t result = 0; + uint16_t result = 0; - // Start by removing multiples of 'other' until both numbers have the same - // number of digits. - while (BigitLength() > other.BigitLength()) { - // This naive approach is extremely inefficient if the this divided other - // might be big. This function is implemented for doubleToString where - // the result should be small (less than 10). - DCHECK_GE(other.bigits_[other.used_digits_ - 1], ((1u << kBigitSize) / 16)); - // Remove the multiples of the first digit. - // Example this = 23 and other equals 9. -> Remove 2 multiples. - result += static_cast<uint16_t>(bigits_[used_digits_ - 1]); - SubtractTimes(other, bigits_[used_digits_ - 1]); - } + // Start by removing multiples of 'other' until both numbers have the same + // number of digits. + while (BigitLength() > other.BigitLength()) { + // This naive approach is extremely inefficient if the this divided other + // might be big. This function is implemented for doubleToString where + // the result should be small (less than 10). + DCHECK_GE(other.bigits_[other.used_digits_ - 1], ((1u << kBigitSize) / 16)); + // Remove the multiples of the first digit. + // Example this = 23 and other equals 9. -> Remove 2 multiples. + result += static_cast<uint16_t>(bigits_[used_digits_ - 1]); + SubtractTimes(other, bigits_[used_digits_ - 1]); + } - DCHECK_EQ(BigitLength(), other.BigitLength()); + DCHECK_EQ(BigitLength(), other.BigitLength()); - // Both bignums are at the same length now. - // Since other has more than 0 digits we know that the access to - // bigits_[used_digits_ - 1] is safe. - Chunk this_bigit = bigits_[used_digits_ - 1]; - Chunk other_bigit = other.bigits_[other.used_digits_ - 1]; + // Both bignums are at the same length now. + // Since other has more than 0 digits we know that the access to + // bigits_[used_digits_ - 1] is safe. + Chunk this_bigit = bigits_[used_digits_ - 1]; + Chunk other_bigit = other.bigits_[other.used_digits_ - 1]; - if (other.used_digits_ == 1) { - // Shortcut for easy (and common) case. - uint16_t quotient = static_cast<uint16_t>(this_bigit / other_bigit); - bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient; - result += quotient; - Clamp(); - return result; - } + if (other.used_digits_ == 1) { + // Shortcut for easy (and common) case. + uint16_t quotient = static_cast<uint16_t>(this_bigit / other_bigit); + bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient; + result += quotient; + Clamp(); + return result; + } - uint16_t division_estimate = static_cast<uint16_t>(this_bigit / (other_bigit + 1)); - result += division_estimate; - SubtractTimes(other, division_estimate); + uint16_t division_estimate = + static_cast<uint16_t>(this_bigit / (other_bigit + 1)); + result += division_estimate; + SubtractTimes(other, division_estimate); - if (other_bigit * (division_estimate + 1) > this_bigit) { - // No need to even try to subtract. Even if other's remaining digits were 0 - // another subtraction would be too much. - return result; - } + if (other_bigit * (division_estimate + 1) > this_bigit) { + // No need to even try to subtract. Even if other's remaining digits were 0 + // another subtraction would be too much. + return result; + } - while (LessEqual(other, *this)) { - SubtractBignum(other); - result++; - } - return result; + while (LessEqual(other, *this)) { + SubtractBignum(other); + result++; + } + return result; +} + +template <typename S> +static int SizeInHexChars(S number) { + DCHECK_GT(number, 0u); + int result = 0; + while (number != 0) { + number >>= 4; + result++; + } + return result; +} + +static char HexCharOfValue(uint8_t value) { + DCHECK_LE(0, value); + DCHECK_LE(value, 16); + if (value < 10) + return value + '0'; + return value - 10 + 'A'; +} + +bool Bignum::ToHexString(char* buffer, int buffer_size) const { + DCHECK(IsClamped()); + // Each bigit must be printable as separate hex-character. + DCHECK_EQ(kBigitSize % 4, 0); + const int kHexCharsPerBigit = kBigitSize / 4; + + if (used_digits_ == 0) { + if (buffer_size < 2) + return false; + buffer[0] = '0'; + buffer[1] = '\0'; + return true; + } + // We add 1 for the terminating '\0' character. + int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit + + SizeInHexChars(bigits_[used_digits_ - 1]) + 1; + if (needed_chars > buffer_size) + return false; + int string_index = needed_chars - 1; + buffer[string_index--] = '\0'; + for (int i = 0; i < exponent_; ++i) { + for (int j = 0; j < kHexCharsPerBigit; ++j) { + buffer[string_index--] = '0'; } - - - template<typename S> - static int SizeInHexChars(S number) { - DCHECK_GT(number, 0u); - int result = 0; - while (number != 0) { - number >>= 4; - result++; - } - return result; + } + for (int i = 0; i < used_digits_ - 1; ++i) { + Chunk current_bigit = bigits_[i]; + for (int j = 0; j < kHexCharsPerBigit; ++j) { + buffer[string_index--] = HexCharOfValue(current_bigit & 0xF); + current_bigit >>= 4; } + } + // And finally the last bigit. + Chunk most_significant_bigit = bigits_[used_digits_ - 1]; + while (most_significant_bigit != 0) { + buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF); + most_significant_bigit >>= 4; + } + return true; +} +Bignum::Chunk Bignum::BigitAt(int index) const { + if (index >= BigitLength()) + return 0; + if (index < exponent_) + return 0; + return bigits_[index - exponent_]; +} - static char HexCharOfValue(uint8_t value) { - DCHECK_LE(0, value); - DCHECK_LE(value, 16); - if (value < 10) return value + '0'; - return value - 10 + 'A'; - } +int Bignum::Compare(const Bignum& a, const Bignum& b) { + DCHECK(a.IsClamped()); + DCHECK(b.IsClamped()); + int bigit_length_a = a.BigitLength(); + int bigit_length_b = b.BigitLength(); + if (bigit_length_a < bigit_length_b) + return -1; + if (bigit_length_a > bigit_length_b) + return +1; + for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); --i) { + Chunk bigit_a = a.BigitAt(i); + Chunk bigit_b = b.BigitAt(i); + if (bigit_a < bigit_b) + return -1; + if (bigit_a > bigit_b) + return +1; + // Otherwise they are equal up to this digit. Try the next digit. + } + return 0; +} +int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) { + DCHECK(a.IsClamped()); + DCHECK(b.IsClamped()); + DCHECK(c.IsClamped()); + if (a.BigitLength() < b.BigitLength()) { + return PlusCompare(b, a, c); + } + if (a.BigitLength() + 1 < c.BigitLength()) + return -1; + if (a.BigitLength() > c.BigitLength()) + return +1; + // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than + // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one + // of 'a'. + if (a.exponent_ >= b.BigitLength() && a.BigitLength() < c.BigitLength()) { + return -1; + } - bool Bignum::ToHexString(char* buffer, int buffer_size) const { - DCHECK(IsClamped()); - // Each bigit must be printable as separate hex-character. - DCHECK_EQ(kBigitSize % 4, 0); - const int kHexCharsPerBigit = kBigitSize / 4; - - if (used_digits_ == 0) { - if (buffer_size < 2) - return false; - buffer[0] = '0'; - buffer[1] = '\0'; - return true; - } - // We add 1 for the terminating '\0' character. - int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit + - SizeInHexChars(bigits_[used_digits_ - 1]) + 1; - if (needed_chars > buffer_size) return false; - int string_index = needed_chars - 1; - buffer[string_index--] = '\0'; - for (int i = 0; i < exponent_; ++i) { - for (int j = 0; j < kHexCharsPerBigit; ++j) { - buffer[string_index--] = '0'; - } - } - for (int i = 0; i < used_digits_ - 1; ++i) { - Chunk current_bigit = bigits_[i]; - for (int j = 0; j < kHexCharsPerBigit; ++j) { - buffer[string_index--] = HexCharOfValue(current_bigit & 0xF); - current_bigit >>= 4; - } - } - // And finally the last bigit. - Chunk most_significant_bigit = bigits_[used_digits_ - 1]; - while (most_significant_bigit != 0) { - buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF); - most_significant_bigit >>= 4; - } - return true; - } - - - Bignum::Chunk Bignum::BigitAt(int index) const { - if (index >= BigitLength()) return 0; - if (index < exponent_) return 0; - return bigits_[index - exponent_]; - } - - - int Bignum::Compare(const Bignum& a, const Bignum& b) { - DCHECK(a.IsClamped()); - DCHECK(b.IsClamped()); - int bigit_length_a = a.BigitLength(); - int bigit_length_b = b.BigitLength(); - if (bigit_length_a < bigit_length_b) + Chunk borrow = 0; + // Starting at min_exponent all digits are == 0. So no need to compare them. + int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_); + for (int i = c.BigitLength() - 1; i >= min_exponent; --i) { + Chunk chunk_a = a.BigitAt(i); + Chunk chunk_b = b.BigitAt(i); + Chunk chunk_c = c.BigitAt(i); + Chunk sum = chunk_a + chunk_b; + if (sum > chunk_c + borrow) { + return +1; + } else { + borrow = chunk_c + borrow - sum; + if (borrow > 1) return -1; - if (bigit_length_a > bigit_length_b) - return +1; - for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); - --i) { - Chunk bigit_a = a.BigitAt(i); - Chunk bigit_b = b.BigitAt(i); - if (bigit_a < bigit_b) - return -1; - if (bigit_a > bigit_b) - return +1; - // Otherwise they are equal up to this digit. Try the next digit. - } - return 0; + borrow <<= kBigitSize; } + } + if (borrow == 0) + return 0; + return -1; +} +void Bignum::Clamp() { + while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) { + used_digits_--; + } + if (used_digits_ == 0) { + // Zero. + exponent_ = 0; + } +} - int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) { - DCHECK(a.IsClamped()); - DCHECK(b.IsClamped()); - DCHECK(c.IsClamped()); - if (a.BigitLength() < b.BigitLength()) { - return PlusCompare(b, a, c); - } - if (a.BigitLength() + 1 < c.BigitLength()) return -1; - if (a.BigitLength() > c.BigitLength()) return +1; - // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than - // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one - // of 'a'. - if (a.exponent_ >= b.BigitLength() && a.BigitLength() < c.BigitLength()) { - return -1; - } +bool Bignum::IsClamped() const { + return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0; +} - Chunk borrow = 0; - // Starting at min_exponent all digits are == 0. So no need to compare them. - int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_); - for (int i = c.BigitLength() - 1; i >= min_exponent; --i) { - Chunk chunk_a = a.BigitAt(i); - Chunk chunk_b = b.BigitAt(i); - Chunk chunk_c = c.BigitAt(i); - Chunk sum = chunk_a + chunk_b; - if (sum > chunk_c + borrow) { - return +1; - } else { - borrow = chunk_c + borrow - sum; - if (borrow > 1) return -1; - borrow <<= kBigitSize; - } - } - if (borrow == 0) return 0; - return -1; +void Bignum::Zero() { + for (int i = 0; i < used_digits_; ++i) { + bigits_[i] = 0; + } + used_digits_ = 0; + exponent_ = 0; +} + +void Bignum::Align(const Bignum& other) { + if (exponent_ > other.exponent_) { + // If "X" represents a "hidden" digit (by the exponent) then we are in the + // following case (a == this, b == other): + // a: aaaaaaXXXX or a: aaaaaXXX + // b: bbbbbbX b: bbbbbbbbXX + // We replace some of the hidden digits (X) of a with 0 digits. + // a: aaaaaa000X or a: aaaaa0XX + int zero_digits = exponent_ - other.exponent_; + EnsureCapacity(used_digits_ + zero_digits); + for (int i = used_digits_ - 1; i >= 0; --i) { + bigits_[i + zero_digits] = bigits_[i]; } - - - void Bignum::Clamp() { - while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) { - used_digits_--; - } - if (used_digits_ == 0) { - // Zero. - exponent_ = 0; - } + for (int i = 0; i < zero_digits; ++i) { + bigits_[i] = 0; } + used_digits_ += zero_digits; + exponent_ -= zero_digits; + DCHECK_GE(used_digits_, 0); + DCHECK_GE(exponent_, 0); + } +} +void Bignum::BigitsShiftLeft(int shift_amount) { + DCHECK_LT(shift_amount, kBigitSize); + DCHECK_GE(shift_amount, 0); + Chunk carry = 0; + for (int i = 0; i < used_digits_; ++i) { + Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount); + bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask; + carry = new_carry; + } + if (carry != 0) { + bigits_[used_digits_] = carry; + used_digits_++; + } +} - bool Bignum::IsClamped() const { - return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0; +void Bignum::SubtractTimes(const Bignum& other, int factor) { + DCHECK_LE(exponent_, other.exponent_); + if (factor < 3) { + for (int i = 0; i < factor; ++i) { + SubtractBignum(other); } - - - void Bignum::Zero() { - for (int i = 0; i < used_digits_; ++i) { - bigits_[i] = 0; - } - used_digits_ = 0; - exponent_ = 0; - } - - - void Bignum::Align(const Bignum& other) { - if (exponent_ > other.exponent_) { - // If "X" represents a "hidden" digit (by the exponent) then we are in the - // following case (a == this, b == other): - // a: aaaaaaXXXX or a: aaaaaXXX - // b: bbbbbbX b: bbbbbbbbXX - // We replace some of the hidden digits (X) of a with 0 digits. - // a: aaaaaa000X or a: aaaaa0XX - int zero_digits = exponent_ - other.exponent_; - EnsureCapacity(used_digits_ + zero_digits); - for (int i = used_digits_ - 1; i >= 0; --i) { - bigits_[i + zero_digits] = bigits_[i]; - } - for (int i = 0; i < zero_digits; ++i) { - bigits_[i] = 0; - } - used_digits_ += zero_digits; - exponent_ -= zero_digits; - DCHECK_GE(used_digits_, 0); - DCHECK_GE(exponent_, 0); - } - } - - - void Bignum::BigitsShiftLeft(int shift_amount) { - DCHECK_LT(shift_amount, kBigitSize); - DCHECK_GE(shift_amount, 0); - Chunk carry = 0; - for (int i = 0; i < used_digits_; ++i) { - Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount); - bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask; - carry = new_carry; - } - if (carry != 0) { - bigits_[used_digits_] = carry; - used_digits_++; - } - } - - - void Bignum::SubtractTimes(const Bignum& other, int factor) { - DCHECK_LE(exponent_, other.exponent_); - if (factor < 3) { - for (int i = 0; i < factor; ++i) { - SubtractBignum(other); - } - return; - } - Chunk borrow = 0; - int exponent_diff = other.exponent_ - exponent_; - for (int i = 0; i < other.used_digits_; ++i) { - DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i]; - DoubleChunk remove = borrow + product; - Chunk difference = bigits_[i + exponent_diff] - ((uint32_t)remove & kBigitMask); - bigits_[i + exponent_diff] = difference & kBigitMask; - borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) + - (remove >> kBigitSize)); - } - for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) { - if (borrow == 0) return; - Chunk difference = bigits_[i] - borrow; - bigits_[i] = difference & kBigitMask; - borrow = difference >> (kChunkSize - 1); - } - Clamp(); - } - + return; + } + Chunk borrow = 0; + int exponent_diff = other.exponent_ - exponent_; + for (int i = 0; i < other.used_digits_; ++i) { + DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i]; + DoubleChunk remove = borrow + product; + Chunk difference = + bigits_[i + exponent_diff] - ((uint32_t)remove & kBigitMask); + bigits_[i + exponent_diff] = difference & kBigitMask; + borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) + + (remove >> kBigitSize)); + } + for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) { + if (borrow == 0) + return; + Chunk difference = bigits_[i] - borrow; + bigits_[i] = difference & kBigitMask; + borrow = difference >> (kChunkSize - 1); + } + Clamp(); +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/cached-powers.cc b/third_party/WebKit/Source/platform/wtf/dtoa/cached-powers.cc index 8ce1c869..e019a93 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/cached-powers.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/cached-powers.cc
@@ -27,175 +27,177 @@ #include "cached-powers.h" -#include "utils.h" -#include <stdarg.h> #include <limits.h> #include <math.h> +#include <stdarg.h> +#include "utils.h" namespace WTF { namespace double_conversion { - struct CachedPower { - uint64_t significand; - int16_t binary_exponent; - int16_t decimal_exponent; - }; +struct CachedPower { + uint64_t significand; + int16_t binary_exponent; + int16_t decimal_exponent; +}; - static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) - static const CachedPower kCachedPowers[] = { - {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348}, - {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340}, - {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332}, - {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324}, - {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316}, - {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308}, - {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300}, - {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292}, - {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284}, - {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276}, - {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268}, - {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260}, - {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252}, - {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244}, - {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236}, - {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228}, - {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220}, - {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212}, - {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204}, - {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196}, - {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188}, - {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180}, - {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172}, - {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164}, - {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156}, - {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148}, - {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140}, - {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132}, - {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124}, - {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116}, - {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108}, - {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100}, - {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92}, - {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84}, - {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76}, - {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68}, - {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60}, - {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52}, - {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44}, - {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36}, - {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28}, - {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20}, - {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12}, - {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4}, - {UINT64_2PART_C(0x9c400000, 00000000), -50, 4}, - {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12}, - {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20}, - {UINT64_2PART_C(0x813f3978, f8940984), 30, 28}, - {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36}, - {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44}, - {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52}, - {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60}, - {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68}, - {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76}, - {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84}, - {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92}, - {UINT64_2PART_C(0x924d692c, a61be758), 269, 100}, - {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108}, - {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116}, - {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124}, - {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132}, - {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140}, - {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148}, - {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156}, - {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164}, - {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172}, - {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180}, - {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188}, - {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196}, - {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204}, - {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212}, - {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220}, - {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228}, - {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236}, - {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244}, - {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252}, - {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260}, - {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268}, - {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276}, - {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284}, - {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292}, - {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300}, - {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308}, - {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316}, - {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324}, - {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332}, - {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340}, - }; - static const int kCachedPowersOffset = 348; // -kCachedPowers[0].decimal_exponent +static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) +static const CachedPower kCachedPowers[] = { + {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348}, + {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340}, + {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332}, + {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324}, + {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316}, + {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308}, + {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300}, + {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292}, + {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284}, + {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276}, + {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268}, + {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260}, + {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252}, + {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244}, + {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236}, + {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228}, + {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220}, + {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212}, + {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204}, + {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196}, + {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188}, + {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180}, + {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172}, + {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164}, + {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156}, + {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148}, + {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140}, + {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132}, + {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124}, + {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116}, + {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108}, + {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100}, + {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92}, + {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84}, + {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76}, + {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68}, + {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60}, + {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52}, + {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44}, + {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36}, + {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28}, + {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20}, + {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12}, + {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4}, + {UINT64_2PART_C(0x9c400000, 00000000), -50, 4}, + {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12}, + {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20}, + {UINT64_2PART_C(0x813f3978, f8940984), 30, 28}, + {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36}, + {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44}, + {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52}, + {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60}, + {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68}, + {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76}, + {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84}, + {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92}, + {UINT64_2PART_C(0x924d692c, a61be758), 269, 100}, + {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108}, + {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116}, + {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124}, + {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132}, + {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140}, + {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148}, + {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156}, + {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164}, + {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172}, + {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180}, + {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188}, + {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196}, + {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204}, + {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212}, + {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220}, + {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228}, + {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236}, + {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244}, + {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252}, + {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260}, + {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268}, + {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276}, + {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284}, + {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292}, + {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300}, + {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308}, + {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316}, + {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324}, + {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332}, + {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340}, +}; +static const int kCachedPowersOffset = + 348; // -kCachedPowers[0].decimal_exponent - const int PowersOfTenCache::kDecimalExponentDistance = 8; // kCachedPowers[1].decimal_exponent - kCachedPowers[0].decimal_exponent - const int PowersOfTenCache::kMinDecimalExponent = -348; // kCachedPowers[0].decimal_exponent - const int PowersOfTenCache::kMaxDecimalExponent = 340; // kCachedPowers[kCachedPowersLength - 1].decimal_exponent +const int PowersOfTenCache::kDecimalExponentDistance = + 8; // kCachedPowers[1].decimal_exponent - kCachedPowers[0].decimal_exponent +const int PowersOfTenCache::kMinDecimalExponent = + -348; // kCachedPowers[0].decimal_exponent +const int PowersOfTenCache::kMaxDecimalExponent = + 340; // kCachedPowers[kCachedPowersLength - 1].decimal_exponent #if DCHECK_IS_ON() - static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers); +static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers); - // Check that the static constants match the values in kCachedPowers. - static void ValidateStaticConstants() { - DCHECK_EQ(kCachedPowersOffset, -kCachedPowers[0].decimal_exponent); - DCHECK_EQ(PowersOfTenCache::kDecimalExponentDistance, - (kCachedPowers[1].decimal_exponent - - kCachedPowers[0].decimal_exponent)); - DCHECK_EQ(PowersOfTenCache::kMinDecimalExponent, - kCachedPowers[0].decimal_exponent); - DCHECK_EQ(PowersOfTenCache::kMaxDecimalExponent, - kCachedPowers[kCachedPowersLength - 1].decimal_exponent); - } +// Check that the static constants match the values in kCachedPowers. +static void ValidateStaticConstants() { + DCHECK_EQ(kCachedPowersOffset, -kCachedPowers[0].decimal_exponent); + DCHECK_EQ( + PowersOfTenCache::kDecimalExponentDistance, + (kCachedPowers[1].decimal_exponent - kCachedPowers[0].decimal_exponent)); + DCHECK_EQ(PowersOfTenCache::kMinDecimalExponent, + kCachedPowers[0].decimal_exponent); + DCHECK_EQ(PowersOfTenCache::kMaxDecimalExponent, + kCachedPowers[kCachedPowersLength - 1].decimal_exponent); +} #endif - void PowersOfTenCache::GetCachedPowerForBinaryExponentRange( - int min_exponent, - int max_exponent, - DiyFp* power, - int* decimal_exponent) { +void PowersOfTenCache::GetCachedPowerForBinaryExponentRange( + int min_exponent, + int max_exponent, + DiyFp* power, + int* decimal_exponent) { #if DCHECK_IS_ON() - ValidateStaticConstants(); + ValidateStaticConstants(); #endif - const int kQ = DiyFp::kSignificandSize; - double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10); - int foo = kCachedPowersOffset; - int index = - (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1; - DCHECK_LE(0, index); + const int kQ = DiyFp::kSignificandSize; + double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10); + int foo = kCachedPowersOffset; + int index = (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1; + DCHECK_LE(0, index); #if DCHECK_IS_ON() - DCHECK_LT(index, kCachedPowersLength); + DCHECK_LT(index, kCachedPowersLength); #endif - CachedPower cached_power = kCachedPowers[index]; - DCHECK_LE(min_exponent, cached_power.binary_exponent); - DCHECK_LE(cached_power.binary_exponent, max_exponent); - *decimal_exponent = cached_power.decimal_exponent; - *power = DiyFp(cached_power.significand, cached_power.binary_exponent); - } + CachedPower cached_power = kCachedPowers[index]; + DCHECK_LE(min_exponent, cached_power.binary_exponent); + DCHECK_LE(cached_power.binary_exponent, max_exponent); + *decimal_exponent = cached_power.decimal_exponent; + *power = DiyFp(cached_power.significand, cached_power.binary_exponent); +} - - void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent, - DiyFp* power, - int* found_exponent) { - DCHECK_LE(kMinDecimalExponent, requested_exponent); - DCHECK_LT(requested_exponent, kMaxDecimalExponent + kDecimalExponentDistance); +void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent, + DiyFp* power, + int* found_exponent) { + DCHECK_LE(kMinDecimalExponent, requested_exponent); + DCHECK_LT(requested_exponent, kMaxDecimalExponent + kDecimalExponentDistance); #if DCHECK_IS_ON() - ValidateStaticConstants(); + ValidateStaticConstants(); #endif - int index = - (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; - CachedPower cached_power = kCachedPowers[index]; - *power = DiyFp(cached_power.significand, cached_power.binary_exponent); - *found_exponent = cached_power.decimal_exponent; - DCHECK_LE(*found_exponent, requested_exponent); - DCHECK_LT(requested_exponent, *found_exponent + kDecimalExponentDistance); - } + int index = + (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; + CachedPower cached_power = kCachedPowers[index]; + *power = DiyFp(cached_power.significand, cached_power.binary_exponent); + *found_exponent = cached_power.decimal_exponent; + DCHECK_LE(*found_exponent, requested_exponent); + DCHECK_LT(requested_exponent, *found_exponent + kDecimalExponentDistance); +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/diy-fp.cc b/third_party/WebKit/Source/platform/wtf/dtoa/diy-fp.cc index b2f4601..2789ce2 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/diy-fp.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/diy-fp.cc
@@ -33,29 +33,29 @@ namespace double_conversion { - void DiyFp::Multiply(const DiyFp& other) { - // Simply "emulates" a 128 bit multiplication. - // However: the resulting number only contains 64 bits. The least - // significant 64 bits are only used for rounding the most significant 64 - // bits. - const uint64_t kM32 = 0xFFFFFFFFU; - uint64_t a = f_ >> 32; - uint64_t b = f_ & kM32; - uint64_t c = other.f_ >> 32; - uint64_t d = other.f_ & kM32; - uint64_t ac = a * c; - uint64_t bc = b * c; - uint64_t ad = a * d; - uint64_t bd = b * d; - uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); - // By adding 1U << 31 to tmp we round the final result. - // Halfway cases will be round up. - tmp += 1U << 31; - uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); - e_ += other.e_ + 64; - f_ = result_f; - } +void DiyFp::Multiply(const DiyFp& other) { + // Simply "emulates" a 128 bit multiplication. + // However: the resulting number only contains 64 bits. The least + // significant 64 bits are only used for rounding the most significant 64 + // bits. + const uint64_t kM32 = 0xFFFFFFFFU; + uint64_t a = f_ >> 32; + uint64_t b = f_ & kM32; + uint64_t c = other.f_ >> 32; + uint64_t d = other.f_ & kM32; + uint64_t ac = a * c; + uint64_t bc = b * c; + uint64_t ad = a * d; + uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); + // By adding 1U << 31 to tmp we round the final result. + // Halfway cases will be round up. + tmp += 1U << 31; + uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + e_ += other.e_ + 64; + f_ = result_f; +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/double-conversion.cc b/third_party/WebKit/Source/platform/wtf/dtoa/double-conversion.cc index 110acd0..90e8a32 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/double-conversion.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/double-conversion.cc
@@ -27,578 +27,569 @@ #include "double-conversion.h" +#include <limits.h> +#include <math.h> #include "bignum-dtoa.h" #include "double.h" #include "fast-dtoa.h" #include "fixed-dtoa.h" #include "strtod.h" #include "utils.h" -#include <limits.h> -#include <math.h> namespace WTF { namespace double_conversion { - const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { - int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; - static DoubleToStringConverter converter(flags, - "Infinity", - "NaN", - 'e', - -6, 21, - 6, 0); - return converter; +const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { + int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; + static DoubleToStringConverter converter(flags, "Infinity", "NaN", 'e', -6, + 21, 6, 0); + return converter; +} + +bool DoubleToStringConverter::HandleSpecialValues( + double value, + StringBuilder* result_builder) const { + Double double_inspect(value); + if (double_inspect.IsInfinite()) { + if (infinity_symbol_ == NULL) + return false; + if (value < 0) { + result_builder->AddCharacter('-'); } + result_builder->AddString(infinity_symbol_); + return true; + } + if (double_inspect.IsNan()) { + if (nan_symbol_ == NULL) + return false; + result_builder->AddString(nan_symbol_); + return true; + } + return false; +} - - bool DoubleToStringConverter::HandleSpecialValues( - double value, - StringBuilder* result_builder) const { - Double double_inspect(value); - if (double_inspect.IsInfinite()) { - if (infinity_symbol_ == NULL) return false; - if (value < 0) { - result_builder->AddCharacter('-'); - } - result_builder->AddString(infinity_symbol_); - return true; - } - if (double_inspect.IsNan()) { - if (nan_symbol_ == NULL) return false; - result_builder->AddString(nan_symbol_); - return true; - } - return false; +void DoubleToStringConverter::CreateExponentialRepresentation( + const char* decimal_digits, + int length, + int exponent, + StringBuilder* result_builder) const { + DCHECK_NE(length, 0); + result_builder->AddCharacter(decimal_digits[0]); + if (length != 1) { + result_builder->AddCharacter('.'); + result_builder->AddSubstring(&decimal_digits[1], length - 1); + } + result_builder->AddCharacter(exponent_character_); + if (exponent < 0) { + result_builder->AddCharacter('-'); + exponent = -exponent; + } else { + if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) { + result_builder->AddCharacter('+'); } + } + if (exponent == 0) { + result_builder->AddCharacter('0'); + return; + } + DCHECK_LT(exponent, 1e4); + const int kMaxExponentLength = 5; + char buffer[kMaxExponentLength + 1]; + int first_char_pos = kMaxExponentLength; + buffer[first_char_pos] = '\0'; + while (exponent > 0) { + buffer[--first_char_pos] = '0' + (exponent % 10); + exponent /= 10; + } + result_builder->AddSubstring(&buffer[first_char_pos], + kMaxExponentLength - first_char_pos); +} - - void DoubleToStringConverter::CreateExponentialRepresentation( - const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const { - DCHECK_NE(length, 0); - result_builder->AddCharacter(decimal_digits[0]); - if (length != 1) { - result_builder->AddCharacter('.'); - result_builder->AddSubstring(&decimal_digits[1], length-1); - } - result_builder->AddCharacter(exponent_character_); - if (exponent < 0) { - result_builder->AddCharacter('-'); - exponent = -exponent; - } else { - if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) { - result_builder->AddCharacter('+'); - } - } - if (exponent == 0) { - result_builder->AddCharacter('0'); - return; - } - DCHECK_LT(exponent, 1e4); - const int kMaxExponentLength = 5; - char buffer[kMaxExponentLength + 1]; - int first_char_pos = kMaxExponentLength; - buffer[first_char_pos] = '\0'; - while (exponent > 0) { - buffer[--first_char_pos] = '0' + (exponent % 10); - exponent /= 10; - } - result_builder->AddSubstring(&buffer[first_char_pos], - kMaxExponentLength - first_char_pos); +void DoubleToStringConverter::CreateDecimalRepresentation( + const char* decimal_digits, + int length, + int decimal_point, + int digits_after_point, + StringBuilder* result_builder) const { + // Create a representation that is padded with zeros if needed. + if (decimal_point <= 0) { + // "0.00000decimal_rep". + result_builder->AddCharacter('0'); + if (digits_after_point > 0) { + result_builder->AddCharacter('.'); + result_builder->AddPadding('0', -decimal_point); + DCHECK_LE(length, digits_after_point - (-decimal_point)); + result_builder->AddSubstring(decimal_digits, length); + int remaining_digits = digits_after_point - (-decimal_point) - length; + result_builder->AddPadding('0', remaining_digits); } - - - void DoubleToStringConverter::CreateDecimalRepresentation( - const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const { - // Create a representation that is padded with zeros if needed. - if (decimal_point <= 0) { - // "0.00000decimal_rep". - result_builder->AddCharacter('0'); - if (digits_after_point > 0) { - result_builder->AddCharacter('.'); - result_builder->AddPadding('0', -decimal_point); - DCHECK_LE(length, digits_after_point - (-decimal_point)); - result_builder->AddSubstring(decimal_digits, length); - int remaining_digits = digits_after_point - (-decimal_point) - length; - result_builder->AddPadding('0', remaining_digits); - } - } else if (decimal_point >= length) { - // "decimal_rep0000.00000" or "decimal_rep.0000" - result_builder->AddSubstring(decimal_digits, length); - result_builder->AddPadding('0', decimal_point - length); - if (digits_after_point > 0) { - result_builder->AddCharacter('.'); - result_builder->AddPadding('0', digits_after_point); - } - } else { - // "decima.l_rep000" - DCHECK_GT(digits_after_point, 0); - result_builder->AddSubstring(decimal_digits, decimal_point); - result_builder->AddCharacter('.'); - DCHECK_LE(length - decimal_point, digits_after_point); - result_builder->AddSubstring(&decimal_digits[decimal_point], - length - decimal_point); - int remaining_digits = digits_after_point - (length - decimal_point); - result_builder->AddPadding('0', remaining_digits); - } - if (digits_after_point == 0) { - if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { - result_builder->AddCharacter('.'); - } - if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { - result_builder->AddCharacter('0'); - } - } + } else if (decimal_point >= length) { + // "decimal_rep0000.00000" or "decimal_rep.0000" + result_builder->AddSubstring(decimal_digits, length); + result_builder->AddPadding('0', decimal_point - length); + if (digits_after_point > 0) { + result_builder->AddCharacter('.'); + result_builder->AddPadding('0', digits_after_point); } - - - bool DoubleToStringConverter::ToShortest(double value, - StringBuilder* result_builder) const { - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } - - int decimal_point; - bool sign; - const int kDecimalRepCapacity = kBase10MaximalLength + 1; - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - - DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - - bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } - - int exponent = decimal_point - 1; - if ((decimal_in_shortest_low_ <= exponent) && - (exponent < decimal_in_shortest_high_)) { - CreateDecimalRepresentation(decimal_rep, decimal_rep_length, - decimal_point, - Max(0, decimal_rep_length - decimal_point), - result_builder); - } else { - CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, - result_builder); - } - return true; + } else { + // "decima.l_rep000" + DCHECK_GT(digits_after_point, 0); + result_builder->AddSubstring(decimal_digits, decimal_point); + result_builder->AddCharacter('.'); + DCHECK_LE(length - decimal_point, digits_after_point); + result_builder->AddSubstring(&decimal_digits[decimal_point], + length - decimal_point); + int remaining_digits = digits_after_point - (length - decimal_point); + result_builder->AddPadding('0', remaining_digits); + } + if (digits_after_point == 0) { + if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { + result_builder->AddCharacter('.'); } + if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { + result_builder->AddCharacter('0'); + } + } +} +bool DoubleToStringConverter::ToShortest(double value, + StringBuilder* result_builder) const { + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } - bool DoubleToStringConverter::ToFixed(double value, - int requested_digits, + int decimal_point; + bool sign; + const int kDecimalRepCapacity = kBase10MaximalLength + 1; + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; + + DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity, &sign, + &decimal_rep_length, &decimal_point); + + bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + int exponent = decimal_point - 1; + if ((decimal_in_shortest_low_ <= exponent) && + (exponent < decimal_in_shortest_high_)) { + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, + Max(0, decimal_rep_length - decimal_point), + result_builder); + } else { + CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, + result_builder); + } + return true; +} + +bool DoubleToStringConverter::ToFixed(double value, + int requested_digits, + StringBuilder* result_builder) const { + DCHECK_EQ(kMaxFixedDigitsBeforePoint, 60); + const double kFirstNonFixed = 1e60; + + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } + + if (requested_digits > kMaxFixedDigitsAfterPoint) + return false; + if (value >= kFirstNonFixed || value <= -kFirstNonFixed) + return false; + + // Find a sufficiently precise decimal representation of n. + int decimal_point; + bool sign; + // Add space for the '\0' byte. + const int kDecimalRepCapacity = + kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; + DoubleToAscii(value, FIXED, requested_digits, decimal_rep, + kDecimalRepCapacity, &sign, &decimal_rep_length, + &decimal_point); + + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, + requested_digits, result_builder); + return true; +} + +bool DoubleToStringConverter::ToExponential( + double value, + int requested_digits, + StringBuilder* result_builder) const { + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } + + if (requested_digits < -1) + return false; + if (requested_digits > kMaxExponentialDigits) + return false; + + int decimal_point; + bool sign; + // Add space for digit before the decimal point and the '\0' character. + const int kDecimalRepCapacity = kMaxExponentialDigits + 2; + DCHECK_GT(kDecimalRepCapacity, kBase10MaximalLength); + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; + + if (requested_digits == -1) { + DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity, &sign, + &decimal_rep_length, &decimal_point); + } else { + DoubleToAscii(value, PRECISION, requested_digits + 1, decimal_rep, + kDecimalRepCapacity, &sign, &decimal_rep_length, + &decimal_point); + DCHECK_LE(decimal_rep_length, requested_digits + 1); + + for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { + decimal_rep[i] = '0'; + } + decimal_rep_length = requested_digits + 1; + } + + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + int exponent = decimal_point - 1; + CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, + result_builder); + return true; +} + +bool DoubleToStringConverter::ToPrecision(double value, + int precision, StringBuilder* result_builder) const { - DCHECK_EQ(kMaxFixedDigitsBeforePoint, 60); - const double kFirstNonFixed = 1e60; + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } + if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { + return false; + } - if (requested_digits > kMaxFixedDigitsAfterPoint) return false; - if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false; + // Find a sufficiently precise decimal representation of n. + int decimal_point; + bool sign; + // Add one for the terminating null character. + const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; - // Find a sufficiently precise decimal representation of n. - int decimal_point; - bool sign; - // Add space for the '\0' byte. - const int kDecimalRepCapacity = - kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - DoubleToAscii(value, FIXED, requested_digits, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); + DoubleToAscii(value, PRECISION, precision, decimal_rep, kDecimalRepCapacity, + &sign, &decimal_rep_length, &decimal_point); + DCHECK_LE(decimal_rep_length, precision); - bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } - CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, - requested_digits, result_builder); - return true; + // The exponent if we print the number as x.xxeyyy. That is with the + // decimal point after the first digit. + int exponent = decimal_point - 1; + + int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; + if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || + (decimal_point - precision + extra_zero > + max_trailing_padding_zeroes_in_precision_mode_)) { + // Fill buffer to contain 'precision' digits. + // Usually the buffer is already at the correct length, but 'DoubleToAscii' + // is allowed to return less characters. + for (int i = decimal_rep_length; i < precision; ++i) { + decimal_rep[i] = '0'; } + CreateExponentialRepresentation(decimal_rep, precision, exponent, + result_builder); + } else { + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, + Max(0, precision - decimal_point), + result_builder); + } + return true; +} - bool DoubleToStringConverter::ToExponential( - double value, - int requested_digits, - StringBuilder* result_builder) const { - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } +static BignumDtoaMode DtoaToBignumDtoaMode( + DoubleToStringConverter::DtoaMode dtoa_mode) { + switch (dtoa_mode) { + case DoubleToStringConverter::SHORTEST: + return BIGNUM_DTOA_SHORTEST; + case DoubleToStringConverter::FIXED: + return BIGNUM_DTOA_FIXED; + case DoubleToStringConverter::PRECISION: + return BIGNUM_DTOA_PRECISION; + default: + UNREACHABLE(); + return BIGNUM_DTOA_SHORTEST; // To silence compiler. + } +} - if (requested_digits < -1) return false; - if (requested_digits > kMaxExponentialDigits) return false; +void DoubleToStringConverter::DoubleToAscii(double v, + DtoaMode mode, + int requested_digits, + char* buffer, + int buffer_length, + bool* sign, + int* length, + int* point) { + Vector<char> vector(buffer, buffer_length); + DCHECK(!Double(v).IsSpecial()); + DCHECK(mode == SHORTEST || requested_digits >= 0); - int decimal_point; - bool sign; - // Add space for digit before the decimal point and the '\0' character. - const int kDecimalRepCapacity = kMaxExponentialDigits + 2; - DCHECK_GT(kDecimalRepCapacity, kBase10MaximalLength); - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; + if (Double(v).Sign() < 0) { + *sign = true; + v = -v; + } else { + *sign = false; + } - if (requested_digits == -1) { - DoubleToAscii(value, SHORTEST, 0, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - } else { - DoubleToAscii(value, PRECISION, requested_digits + 1, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - DCHECK_LE(decimal_rep_length, requested_digits + 1); + if (mode == PRECISION && requested_digits == 0) { + vector[0] = '\0'; + *length = 0; + return; + } - for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { - decimal_rep[i] = '0'; - } - decimal_rep_length = requested_digits + 1; - } + if (v == 0) { + vector[0] = '0'; + vector[1] = '\0'; + *length = 1; + *point = 1; + return; + } - bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } + bool fast_worked; + switch (mode) { + case SHORTEST: + fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); + break; + case FIXED: + fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); + break; + case PRECISION: + fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, vector, + length, point); + break; + default: + UNREACHABLE(); + fast_worked = false; + } + if (fast_worked) + return; - int exponent = decimal_point - 1; - CreateExponentialRepresentation(decimal_rep, - decimal_rep_length, - exponent, - result_builder); - return true; + // If the fast dtoa didn't succeed use the slower bignum version. + BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); + BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); + vector[*length] = '\0'; +} + +// Maximum number of significant digits in decimal representation. +// The longest possible double in decimal representation is +// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 +// (768 digits). If we parse a number whose first digits are equal to a +// mean of 2 adjacent doubles (that could have up to 769 digits) the result +// must be rounded to the bigger one unless the tail consists of zeros, so +// we don't need to preserve all the digits. +const int kMaxSignificantDigits = 772; + +static double SignedZero(bool sign) { + return sign ? -0.0 : 0.0; +} + +double StringToDoubleConverter::StringToDouble( + const char* input, + size_t length, + size_t* processed_characters_count) { + const char* current = input; + const char* end = input + length; + + *processed_characters_count = 0; + + // To make sure that iterator dereferencing is valid the following + // convention is used: + // 1. Each '++current' statement is followed by check for equality to 'end'. + // 3. If 'current' becomes equal to 'end' the function returns or goes to + // 'parsing_done'. + // 4. 'current' is not dereferenced after the 'parsing_done' label. + // 5. Code before 'parsing_done' may rely on 'current != end'. + if (current == end) + return 0.0; + + // The longest form of simplified number is: "-<significant digits>.1eXXX\0". + const int kBufferSize = kMaxSignificantDigits + 10; + char buffer[kBufferSize]; // NOLINT: size is known at compile time. + int buffer_pos = 0; + + // Exponent will be adjusted if insignificant digits of the integer part + // or insignificant leading zeros of the fractional part are dropped. + int exponent = 0; + int significant_digits = 0; + int insignificant_digits = 0; + bool nonzero_digit_dropped = false; + bool sign = false; + + if (*current == '+' || *current == '-') { + sign = (*current == '-'); + ++current; + if (current == end) + return 0.0; + } + + bool leading_zero = false; + if (*current == '0') { + ++current; + if (current == end) { + *processed_characters_count = current - input; + return SignedZero(sign); } + leading_zero = true; - bool DoubleToStringConverter::ToPrecision(double value, - int precision, - StringBuilder* result_builder) const { - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } - - if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { - return false; - } - - // Find a sufficiently precise decimal representation of n. - int decimal_point; - bool sign; - // Add one for the terminating null character. - const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - - DoubleToAscii(value, PRECISION, precision, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - DCHECK_LE(decimal_rep_length, precision); - - bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } - - // The exponent if we print the number as x.xxeyyy. That is with the - // decimal point after the first digit. - int exponent = decimal_point - 1; - - int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; - if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || - (decimal_point - precision + extra_zero > - max_trailing_padding_zeroes_in_precision_mode_)) { - // Fill buffer to contain 'precision' digits. - // Usually the buffer is already at the correct length, but 'DoubleToAscii' - // is allowed to return less characters. - for (int i = decimal_rep_length; i < precision; ++i) { - decimal_rep[i] = '0'; - } - - CreateExponentialRepresentation(decimal_rep, - precision, - exponent, - result_builder); - } else { - CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, - Max(0, precision - decimal_point), - result_builder); - } - return true; - } - - - static BignumDtoaMode DtoaToBignumDtoaMode( - DoubleToStringConverter::DtoaMode dtoa_mode) { - switch (dtoa_mode) { - case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST; - case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED; - case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION; - default: - UNREACHABLE(); - return BIGNUM_DTOA_SHORTEST; // To silence compiler. - } - } - - - void DoubleToStringConverter::DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point) { - Vector<char> vector(buffer, buffer_length); - DCHECK(!Double(v).IsSpecial()); - DCHECK(mode == SHORTEST || requested_digits >= 0); - - if (Double(v).Sign() < 0) { - *sign = true; - v = -v; - } else { - *sign = false; - } - - if (mode == PRECISION && requested_digits == 0) { - vector[0] = '\0'; - *length = 0; - return; - } - - if (v == 0) { - vector[0] = '0'; - vector[1] = '\0'; - *length = 1; - *point = 1; - return; - } - - bool fast_worked; - switch (mode) { - case SHORTEST: - fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); - break; - case FIXED: - fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); - break; - case PRECISION: - fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, - vector, length, point); - break; - default: - UNREACHABLE(); - fast_worked = false; - } - if (fast_worked) return; - - // If the fast dtoa didn't succeed use the slower bignum version. - BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); - BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); - vector[*length] = '\0'; - } - - - // Maximum number of significant digits in decimal representation. - // The longest possible double in decimal representation is - // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 - // (768 digits). If we parse a number whose first digits are equal to a - // mean of 2 adjacent doubles (that could have up to 769 digits) the result - // must be rounded to the bigger one unless the tail consists of zeros, so - // we don't need to preserve all the digits. - const int kMaxSignificantDigits = 772; - - - static double SignedZero(bool sign) { - return sign ? -0.0 : 0.0; - } - - - double StringToDoubleConverter::StringToDouble( - const char* input, - size_t length, - size_t* processed_characters_count) { - const char* current = input; - const char* end = input + length; - - *processed_characters_count = 0; - - // To make sure that iterator dereferencing is valid the following - // convention is used: - // 1. Each '++current' statement is followed by check for equality to 'end'. - // 3. If 'current' becomes equal to 'end' the function returns or goes to - // 'parsing_done'. - // 4. 'current' is not dereferenced after the 'parsing_done' label. - // 5. Code before 'parsing_done' may rely on 'current != end'. - if (current == end) return 0.0; - - // The longest form of simplified number is: "-<significant digits>.1eXXX\0". - const int kBufferSize = kMaxSignificantDigits + 10; - char buffer[kBufferSize]; // NOLINT: size is known at compile time. - int buffer_pos = 0; - - // Exponent will be adjusted if insignificant digits of the integer part - // or insignificant leading zeros of the fractional part are dropped. - int exponent = 0; - int significant_digits = 0; - int insignificant_digits = 0; - bool nonzero_digit_dropped = false; - bool sign = false; - - if (*current == '+' || *current == '-') { - sign = (*current == '-'); - ++current; - if (current == end) return 0.0; - } - - bool leading_zero = false; - if (*current == '0') { - ++current; - if (current == end) { - *processed_characters_count = current - input; - return SignedZero(sign); - } - - leading_zero = true; - - // Ignore leading zeros in the integer part. - while (*current == '0') { - ++current; - if (current == end) { - *processed_characters_count = current - input; - return SignedZero(sign); - } - } - } - - // Copy significant digits of the integer part (if any) to the buffer. - while (*current >= '0' && *current <= '9') { - if (significant_digits < kMaxSignificantDigits) { - DCHECK_LT(buffer_pos, kBufferSize); - buffer[buffer_pos++] = static_cast<char>(*current); - significant_digits++; - } else { - insignificant_digits++; // Move the digit into the exponential part. - nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; - } - ++current; - if (current == end) goto parsing_done; - } - - if (*current == '.') { - ++current; - if (current == end) { - if (significant_digits == 0 && !leading_zero) { - return 0.0; - } else { - goto parsing_done; - } - } - - if (significant_digits == 0) { - // Integer part consists of 0 or is absent. Significant digits start after - // leading zeros (if any). - while (*current == '0') { - ++current; - if (current == end) { - *processed_characters_count = current - input; - return SignedZero(sign); - } - exponent--; // Move this 0 into the exponent. - } - } - - // There is a fractional part. - while (*current >= '0' && *current <= '9') { - if (significant_digits < kMaxSignificantDigits) { - DCHECK_LT(buffer_pos, kBufferSize); - buffer[buffer_pos++] = static_cast<char>(*current); - significant_digits++; - exponent--; - } else { - // Ignore insignificant digits in the fractional part. - nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; - } - ++current; - if (current == end) goto parsing_done; - } - } - - if (!leading_zero && exponent == 0 && significant_digits == 0) { - // If leading_zeros is true then the string contains zeros. - // If exponent < 0 then string was [+-]\.0*... - // If significant_digits != 0 the string is not equal to 0. - // Otherwise there are no digits in the string. - return 0.0; - } - - // Parse exponential part. - if (*current == 'e' || *current == 'E') { - ++current; - if (current == end) { - --current; - goto parsing_done; - } - char sign = 0; - if (*current == '+' || *current == '-') { - sign = static_cast<char>(*current); - ++current; - if (current == end) { - current -= 2; - goto parsing_done; - } - } - - if (*current < '0' || *current > '9') { - if (sign) - --current; - --current; - goto parsing_done; - } - - const int max_exponent = INT_MAX / 2; - DCHECK_LE(-max_exponent / 2, exponent); - DCHECK_LE(exponent, max_exponent / 2); - int num = 0; - do { - // Check overflow. - int digit = *current - '0'; - if (num >= max_exponent / 10 - && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { - num = max_exponent; - } else { - num = num * 10 + digit; - } - ++current; - } while (current != end && *current >= '0' && *current <= '9'); - - exponent += (sign == '-' ? -num : num); - } - - parsing_done: - exponent += insignificant_digits; - - if (nonzero_digit_dropped) { - buffer[buffer_pos++] = '1'; - exponent--; - } - - DCHECK_LT(buffer_pos, kBufferSize); - buffer[buffer_pos] = '\0'; - - double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); + // Ignore leading zeros in the integer part. + while (*current == '0') { + ++current; + if (current == end) { *processed_characters_count = current - input; - return sign? -converted: converted; + return SignedZero(sign); + } } + } + + // Copy significant digits of the integer part (if any) to the buffer. + while (*current >= '0' && *current <= '9') { + if (significant_digits < kMaxSignificantDigits) { + DCHECK_LT(buffer_pos, kBufferSize); + buffer[buffer_pos++] = static_cast<char>(*current); + significant_digits++; + } else { + insignificant_digits++; // Move the digit into the exponential part. + nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; + } + ++current; + if (current == end) + goto parsing_done; + } + + if (*current == '.') { + ++current; + if (current == end) { + if (significant_digits == 0 && !leading_zero) { + return 0.0; + } else { + goto parsing_done; + } + } + + if (significant_digits == 0) { + // Integer part consists of 0 or is absent. Significant digits start after + // leading zeros (if any). + while (*current == '0') { + ++current; + if (current == end) { + *processed_characters_count = current - input; + return SignedZero(sign); + } + exponent--; // Move this 0 into the exponent. + } + } + + // There is a fractional part. + while (*current >= '0' && *current <= '9') { + if (significant_digits < kMaxSignificantDigits) { + DCHECK_LT(buffer_pos, kBufferSize); + buffer[buffer_pos++] = static_cast<char>(*current); + significant_digits++; + exponent--; + } else { + // Ignore insignificant digits in the fractional part. + nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; + } + ++current; + if (current == end) + goto parsing_done; + } + } + + if (!leading_zero && exponent == 0 && significant_digits == 0) { + // If leading_zeros is true then the string contains zeros. + // If exponent < 0 then string was [+-]\.0*... + // If significant_digits != 0 the string is not equal to 0. + // Otherwise there are no digits in the string. + return 0.0; + } + + // Parse exponential part. + if (*current == 'e' || *current == 'E') { + ++current; + if (current == end) { + --current; + goto parsing_done; + } + char sign = 0; + if (*current == '+' || *current == '-') { + sign = static_cast<char>(*current); + ++current; + if (current == end) { + current -= 2; + goto parsing_done; + } + } + + if (*current < '0' || *current > '9') { + if (sign) + --current; + --current; + goto parsing_done; + } + + const int max_exponent = INT_MAX / 2; + DCHECK_LE(-max_exponent / 2, exponent); + DCHECK_LE(exponent, max_exponent / 2); + int num = 0; + do { + // Check overflow. + int digit = *current - '0'; + if (num >= max_exponent / 10 && + !(num == max_exponent / 10 && digit <= max_exponent % 10)) { + num = max_exponent; + } else { + num = num * 10 + digit; + } + ++current; + } while (current != end && *current >= '0' && *current <= '9'); + + exponent += (sign == '-' ? -num : num); + } + +parsing_done: + exponent += insignificant_digits; + + if (nonzero_digit_dropped) { + buffer[buffer_pos++] = '1'; + exponent--; + } + + DCHECK_LT(buffer_pos, kBufferSize); + buffer[buffer_pos] = '\0'; + + double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); + *processed_characters_count = current - input; + return sign ? -converted : converted; +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/fast-dtoa.cc b/third_party/WebKit/Source/platform/wtf/dtoa/fast-dtoa.cc index f58d186..169ed06 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/fast-dtoa.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/fast-dtoa.cc
@@ -35,708 +35,699 @@ namespace double_conversion { - // The minimal and maximal target exponent define the range of w's binary - // exponent, where 'w' is the result of multiplying the input by a cached power - // of ten. - // - // A different range might be chosen on a different platform, to optimize digit - // generation, but a smaller range requires more powers of ten to be cached. - static const int kMinimalTargetExponent = -60; - static const int kMaximalTargetExponent = -32; +// The minimal and maximal target exponent define the range of w's binary +// exponent, where 'w' is the result of multiplying the input by a cached power +// of ten. +// +// A different range might be chosen on a different platform, to optimize digit +// generation, but a smaller range requires more powers of ten to be cached. +static const int kMinimalTargetExponent = -60; +static const int kMaximalTargetExponent = -32; +// Adjusts the last digit of the generated number, and screens out generated +// solutions that may be inaccurate. A solution may be inaccurate if it is +// outside the safe interval, or if we cannot prove that it is closer to the +// input than a neighboring representation of the same length. +// +// Input: * buffer containing the digits of too_high / 10^kappa +// * the buffer's length +// * distance_too_high_w == (too_high - w).f() * unit +// * unsafe_interval == (too_high - too_low).f() * unit +// * rest = (too_high - buffer * 10^kappa).f() * unit +// * ten_kappa = 10^kappa * unit +// * unit = the common multiplier +// Output: returns true if the buffer is guaranteed to contain the closest +// representable number to the input. +// Modifies the generated digits in the buffer to approach (round towards) w. +static bool RoundWeed(Vector<char> buffer, + int length, + uint64_t distance_too_high_w, + uint64_t unsafe_interval, + uint64_t rest, + uint64_t ten_kappa, + uint64_t unit) { + uint64_t small_distance = distance_too_high_w - unit; + uint64_t big_distance = distance_too_high_w + unit; + // Let w_low = too_high - big_distance, and + // w_high = too_high - small_distance. + // Note: w_low < w < w_high + // + // The real w (* unit) must lie somewhere inside the interval + // ]w_low; w_high[ (often written as "(w_low; w_high)") - // Adjusts the last digit of the generated number, and screens out generated - // solutions that may be inaccurate. A solution may be inaccurate if it is - // outside the safe interval, or if we cannot prove that it is closer to the - // input than a neighboring representation of the same length. - // - // Input: * buffer containing the digits of too_high / 10^kappa - // * the buffer's length - // * distance_too_high_w == (too_high - w).f() * unit - // * unsafe_interval == (too_high - too_low).f() * unit - // * rest = (too_high - buffer * 10^kappa).f() * unit - // * ten_kappa = 10^kappa * unit - // * unit = the common multiplier - // Output: returns true if the buffer is guaranteed to contain the closest - // representable number to the input. - // Modifies the generated digits in the buffer to approach (round towards) w. - static bool RoundWeed(Vector<char> buffer, - int length, - uint64_t distance_too_high_w, - uint64_t unsafe_interval, - uint64_t rest, - uint64_t ten_kappa, - uint64_t unit) { - uint64_t small_distance = distance_too_high_w - unit; - uint64_t big_distance = distance_too_high_w + unit; - // Let w_low = too_high - big_distance, and - // w_high = too_high - small_distance. - // Note: w_low < w < w_high - // - // The real w (* unit) must lie somewhere inside the interval - // ]w_low; w_high[ (often written as "(w_low; w_high)") + // Basically the buffer currently contains a number in the unsafe interval + // ]too_low; too_high[ with too_low < w < too_high + // + // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // ^v 1 unit ^ ^ ^ ^ + // boundary_high --------------------- . . . . + // ^v 1 unit . . . . + // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . + // . . ^ . . + // . big_distance . . . + // . . . . rest + // small_distance . . . . + // v . . . . + // w_high - - - - - - - - - - - - - - - - - - . . . . + // ^v 1 unit . . . . + // w ---------------------------------------- . . . . + // ^v 1 unit v . . . + // w_low - - - - - - - - - - - - - - - - - - - - - . . . + // . . v + // buffer --------------------------------------------------+-------+-------- + // . . + // safe_interval . + // v . + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + // ^v 1 unit . + // boundary_low ------------------------- unsafe_interval + // ^v 1 unit v + // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // + // Note that the value of buffer could lie anywhere inside the range too_low + // to too_high. + // + // boundary_low, boundary_high and w are approximations of the real boundaries + // and v (the input number). They are guaranteed to be precise up to one unit. + // In fact the error is guaranteed to be strictly less than one unit. + // + // Anything that lies outside the unsafe interval is guaranteed not to round + // to v when read again. + // Anything that lies inside the safe interval is guaranteed to round to v + // when read again. + // If the number inside the buffer lies inside the unsafe interval but not + // inside the safe interval then we simply do not know and bail out (returning + // false). + // + // Similarly we have to take into account the imprecision of 'w' when finding + // the closest representation of 'w'. If we have two potential + // representations, and one is closer to both w_low and w_high, then we know + // it is closer to the actual value v. + // + // By generating the digits of too_high we got the largest (closest to + // too_high) buffer that is still in the unsafe interval. In the case where + // w_high < buffer < too_high we try to decrement the buffer. + // This way the buffer approaches (rounds towards) w. + // There are 3 conditions that stop the decrementation process: + // 1) the buffer is already below w_high + // 2) decrementing the buffer would make it leave the unsafe interval + // 3) decrementing the buffer would yield a number below w_high and farther + // away than the current number. In other words: + // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high + // Instead of using the buffer directly we use its distance to too_high. + // Conceptually rest ~= too_high - buffer + // We need to do the following tests in this order to avoid over- and + // underflows. + DCHECK_LE(rest, unsafe_interval); + while (rest < small_distance && // Negated condition 1 + unsafe_interval - rest >= ten_kappa && // Negated condition 2 + (rest + ten_kappa < small_distance || // buffer{-1} > w_high + small_distance - rest >= rest + ten_kappa - small_distance)) { + buffer[length - 1]--; + rest += ten_kappa; + } - // Basically the buffer currently contains a number in the unsafe interval - // ]too_low; too_high[ with too_low < w < too_high - // - // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ^v 1 unit ^ ^ ^ ^ - // boundary_high --------------------- . . . . - // ^v 1 unit . . . . - // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . . - // . . ^ . . - // . big_distance . . . - // . . . . rest - // small_distance . . . . - // v . . . . - // w_high - - - - - - - - - - - - - - - - - - . . . . - // ^v 1 unit . . . . - // w ---------------------------------------- . . . . - // ^v 1 unit v . . . - // w_low - - - - - - - - - - - - - - - - - - - - - . . . - // . . v - // buffer --------------------------------------------------+-------+-------- - // . . - // safe_interval . - // v . - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . - // ^v 1 unit . - // boundary_low ------------------------- unsafe_interval - // ^v 1 unit v - // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - // - // Note that the value of buffer could lie anywhere inside the range too_low - // to too_high. - // - // boundary_low, boundary_high and w are approximations of the real boundaries - // and v (the input number). They are guaranteed to be precise up to one unit. - // In fact the error is guaranteed to be strictly less than one unit. - // - // Anything that lies outside the unsafe interval is guaranteed not to round - // to v when read again. - // Anything that lies inside the safe interval is guaranteed to round to v - // when read again. - // If the number inside the buffer lies inside the unsafe interval but not - // inside the safe interval then we simply do not know and bail out (returning - // false). - // - // Similarly we have to take into account the imprecision of 'w' when finding - // the closest representation of 'w'. If we have two potential - // representations, and one is closer to both w_low and w_high, then we know - // it is closer to the actual value v. - // - // By generating the digits of too_high we got the largest (closest to - // too_high) buffer that is still in the unsafe interval. In the case where - // w_high < buffer < too_high we try to decrement the buffer. - // This way the buffer approaches (rounds towards) w. - // There are 3 conditions that stop the decrementation process: - // 1) the buffer is already below w_high - // 2) decrementing the buffer would make it leave the unsafe interval - // 3) decrementing the buffer would yield a number below w_high and farther - // away than the current number. In other words: - // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high - // Instead of using the buffer directly we use its distance to too_high. - // Conceptually rest ~= too_high - buffer - // We need to do the following tests in this order to avoid over- and - // underflows. - DCHECK_LE(rest, unsafe_interval); - while (rest < small_distance && // Negated condition 1 - unsafe_interval - rest >= ten_kappa && // Negated condition 2 - (rest + ten_kappa < small_distance || // buffer{-1} > w_high - small_distance - rest >= rest + ten_kappa - small_distance)) { - buffer[length - 1]--; - rest += ten_kappa; - } + // We have approached w+ as much as possible. We now test if approaching w- + // would require changing the buffer. If yes, then we have two possible + // representations close to w, but we cannot decide which one is closer. + if (rest < big_distance && unsafe_interval - rest >= ten_kappa && + (rest + ten_kappa < big_distance || + big_distance - rest > rest + ten_kappa - big_distance)) { + return false; + } - // We have approached w+ as much as possible. We now test if approaching w- - // would require changing the buffer. If yes, then we have two possible - // representations close to w, but we cannot decide which one is closer. - if (rest < big_distance && - unsafe_interval - rest >= ten_kappa && - (rest + ten_kappa < big_distance || - big_distance - rest > rest + ten_kappa - big_distance)) { - return false; - } + // Weeding test. + // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] + // Since too_low = too_high - unsafe_interval this is equivalent to + // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] + // Conceptually we have: rest ~= too_high - buffer + return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); +} - // Weeding test. - // The safe interval is [too_low + 2 ulp; too_high - 2 ulp] - // Since too_low = too_high - unsafe_interval this is equivalent to - // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp] - // Conceptually we have: rest ~= too_high - buffer - return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit); +// Rounds the buffer upwards if the result is closer to v by possibly adding +// 1 to the buffer. If the precision of the calculation is not sufficient to +// round correctly, return false. +// The rounding might shift the whole buffer in which case the kappa is +// adjusted. For example "99", kappa = 3 might become "10", kappa = 4. +// +// If 2*rest > ten_kappa then the buffer needs to be round up. +// rest can have an error of +/- 1 unit. This function accounts for the +// imprecision and returns false, if the rounding direction cannot be +// unambiguously determined. +// +// Precondition: rest < ten_kappa. +static bool RoundWeedCounted(Vector<char> buffer, + int length, + uint64_t rest, + uint64_t ten_kappa, + uint64_t unit, + int* kappa) { + DCHECK_LT(rest, ten_kappa); + // The following tests are done in a specific order to avoid overflows. They + // will work correctly with any uint64 values of rest < ten_kappa and unit. + // + // If the unit is too big, then we don't know which way to round. For example + // a unit of 50 means that the real number lies within rest +/- 50. If + // 10^kappa == 40 then there is no way to tell which way to round. + if (unit >= ten_kappa) + return false; + // Even if unit is just half the size of 10^kappa we are already completely + // lost. (And after the previous test we know that the expression will not + // over/underflow.) + if (ten_kappa - unit <= unit) + return false; + // If 2 * (rest + unit) <= 10^kappa we can safely round down. + if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) { + return true; + } + // If 2 * (rest - unit) >= 10^kappa, then we can safely round up. + if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) { + // Increment the last digit recursively until we find a non '9' digit. + buffer[length - 1]++; + for (int i = length - 1; i > 0; --i) { + if (buffer[i] != '0' + 10) + break; + buffer[i] = '0'; + buffer[i - 1]++; } - - - // Rounds the buffer upwards if the result is closer to v by possibly adding - // 1 to the buffer. If the precision of the calculation is not sufficient to - // round correctly, return false. - // The rounding might shift the whole buffer in which case the kappa is - // adjusted. For example "99", kappa = 3 might become "10", kappa = 4. - // - // If 2*rest > ten_kappa then the buffer needs to be round up. - // rest can have an error of +/- 1 unit. This function accounts for the - // imprecision and returns false, if the rounding direction cannot be - // unambiguously determined. - // - // Precondition: rest < ten_kappa. - static bool RoundWeedCounted(Vector<char> buffer, - int length, - uint64_t rest, - uint64_t ten_kappa, - uint64_t unit, - int* kappa) { - DCHECK_LT(rest, ten_kappa); - // The following tests are done in a specific order to avoid overflows. They - // will work correctly with any uint64 values of rest < ten_kappa and unit. - // - // If the unit is too big, then we don't know which way to round. For example - // a unit of 50 means that the real number lies within rest +/- 50. If - // 10^kappa == 40 then there is no way to tell which way to round. - if (unit >= ten_kappa) return false; - // Even if unit is just half the size of 10^kappa we are already completely - // lost. (And after the previous test we know that the expression will not - // over/underflow.) - if (ten_kappa - unit <= unit) return false; - // If 2 * (rest + unit) <= 10^kappa we can safely round down. - if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) { - return true; - } - // If 2 * (rest - unit) >= 10^kappa, then we can safely round up. - if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) { - // Increment the last digit recursively until we find a non '9' digit. - buffer[length - 1]++; - for (int i = length - 1; i > 0; --i) { - if (buffer[i] != '0' + 10) break; - buffer[i] = '0'; - buffer[i - 1]++; - } - // If the first digit is now '0'+ 10 we had a buffer with all '9's. With the - // exception of the first digit all digits are now '0'. Simply switch the - // first digit to '1' and adjust the kappa. Example: "99" becomes "10" and - // the power (the kappa) is increased. - if (buffer[0] == '0' + 10) { - buffer[0] = '1'; - (*kappa) += 1; - } - return true; - } - return false; + // If the first digit is now '0'+ 10 we had a buffer with all '9's. With the + // exception of the first digit all digits are now '0'. Simply switch the + // first digit to '1' and adjust the kappa. Example: "99" becomes "10" and + // the power (the kappa) is increased. + if (buffer[0] == '0' + 10) { + buffer[0] = '1'; + (*kappa) += 1; } + return true; + } + return false; +} +static const uint32_t kTen4 = 10000; +static const uint32_t kTen5 = 100000; +static const uint32_t kTen6 = 1000000; +static const uint32_t kTen7 = 10000000; +static const uint32_t kTen8 = 100000000; +static const uint32_t kTen9 = 1000000000; - static const uint32_t kTen4 = 10000; - static const uint32_t kTen5 = 100000; - static const uint32_t kTen6 = 1000000; - static const uint32_t kTen7 = 10000000; - static const uint32_t kTen8 = 100000000; - static const uint32_t kTen9 = 1000000000; +// Returns the biggest power of ten that is less than or equal to the given +// number. We furthermore receive the maximum number of bits 'number' has. +// If number_bits == 0 then 0^-1 is returned +// The number of bits must be <= 32. +// Precondition: number < (1 << (number_bits + 1)). +static void BiggestPowerTen(uint32_t number, + int number_bits, + uint32_t* power, + int* exponent) { + DCHECK_LT(number, (uint32_t)(1 << (number_bits + 1))); - // Returns the biggest power of ten that is less than or equal to the given - // number. We furthermore receive the maximum number of bits 'number' has. - // If number_bits == 0 then 0^-1 is returned - // The number of bits must be <= 32. - // Precondition: number < (1 << (number_bits + 1)). - static void BiggestPowerTen(uint32_t number, - int number_bits, - uint32_t* power, - int* exponent) { - DCHECK_LT(number, (uint32_t)(1 << (number_bits + 1))); + switch (number_bits) { + case 32: + case 31: + case 30: + if (kTen9 <= number) { + *power = kTen9; + *exponent = 9; + break; + } // else fallthrough + case 29: + case 28: + case 27: + if (kTen8 <= number) { + *power = kTen8; + *exponent = 8; + break; + } // else fallthrough + case 26: + case 25: + case 24: + if (kTen7 <= number) { + *power = kTen7; + *exponent = 7; + break; + } // else fallthrough + case 23: + case 22: + case 21: + case 20: + if (kTen6 <= number) { + *power = kTen6; + *exponent = 6; + break; + } // else fallthrough + case 19: + case 18: + case 17: + if (kTen5 <= number) { + *power = kTen5; + *exponent = 5; + break; + } // else fallthrough + case 16: + case 15: + case 14: + if (kTen4 <= number) { + *power = kTen4; + *exponent = 4; + break; + } // else fallthrough + case 13: + case 12: + case 11: + case 10: + if (1000 <= number) { + *power = 1000; + *exponent = 3; + break; + } // else fallthrough + case 9: + case 8: + case 7: + if (100 <= number) { + *power = 100; + *exponent = 2; + break; + } // else fallthrough + case 6: + case 5: + case 4: + if (10 <= number) { + *power = 10; + *exponent = 1; + break; + } // else fallthrough + case 3: + case 2: + case 1: + if (1 <= number) { + *power = 1; + *exponent = 0; + break; + } // else fallthrough + case 0: + *power = 0; + *exponent = -1; + break; + default: + // Following assignments are here to silence compiler warnings. + *power = 0; + *exponent = 0; + UNREACHABLE(); + } +} - switch (number_bits) { - case 32: - case 31: - case 30: - if (kTen9 <= number) { - *power = kTen9; - *exponent = 9; - break; - } // else fallthrough - case 29: - case 28: - case 27: - if (kTen8 <= number) { - *power = kTen8; - *exponent = 8; - break; - } // else fallthrough - case 26: - case 25: - case 24: - if (kTen7 <= number) { - *power = kTen7; - *exponent = 7; - break; - } // else fallthrough - case 23: - case 22: - case 21: - case 20: - if (kTen6 <= number) { - *power = kTen6; - *exponent = 6; - break; - } // else fallthrough - case 19: - case 18: - case 17: - if (kTen5 <= number) { - *power = kTen5; - *exponent = 5; - break; - } // else fallthrough - case 16: - case 15: - case 14: - if (kTen4 <= number) { - *power = kTen4; - *exponent = 4; - break; - } // else fallthrough - case 13: - case 12: - case 11: - case 10: - if (1000 <= number) { - *power = 1000; - *exponent = 3; - break; - } // else fallthrough - case 9: - case 8: - case 7: - if (100 <= number) { - *power = 100; - *exponent = 2; - break; - } // else fallthrough - case 6: - case 5: - case 4: - if (10 <= number) { - *power = 10; - *exponent = 1; - break; - } // else fallthrough - case 3: - case 2: - case 1: - if (1 <= number) { - *power = 1; - *exponent = 0; - break; - } // else fallthrough - case 0: - *power = 0; - *exponent = -1; - break; - default: - // Following assignments are here to silence compiler warnings. - *power = 0; - *exponent = 0; - UNREACHABLE(); - } +// Generates the digits of input number w. +// w is a floating-point number (DiyFp), consisting of a significand and an +// exponent. Its exponent is bounded by kMinimalTargetExponent and +// kMaximalTargetExponent. +// Hence -60 <= w.e() <= -32. +// +// Returns false if it fails, in which case the generated digits in the buffer +// should not be used. +// Preconditions: +// * low, w and high are correct up to 1 ulp (unit in the last place). That +// is, their error must be less than a unit of their last digits. +// * low.e() == w.e() == high.e() +// * low < w < high, and taking into account their error: low~ <= high~ +// * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent +// Postconditions: returns false if procedure fails. +// otherwise: +// * buffer is not null-terminated, but len contains the number of digits. +// * buffer contains the shortest possible decimal digit-sequence +// such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the +// correct values of low and high (without their error). +// * if more than one decimal representation gives the minimal number of +// decimal digits then the one closest to W (where W is the correct value +// of w) is chosen. +// Remark: this procedure takes into account the imprecision of its input +// numbers. If the precision is not enough to guarantee all the postconditions +// then false is returned. This usually happens rarely (~0.5%). +// +// Say, for the sake of example, that +// w.e() == -48, and w.f() == 0x1234567890abcdef +// w's value can be computed by w.f() * 2^w.e() +// We can obtain w's integral digits by simply shifting w.f() by -w.e(). +// -> w's integral part is 0x1234 +// w's fractional part is therefore 0x567890abcdef. +// Printing w's integral part is easy (simply print 0x1234 in decimal). +// In order to print its fraction we repeatedly multiply the fraction by 10 and +// get each digit. Example the first digit after the point would be computed by +// (0x567890abcdef * 10) >> 48. -> 3 +// The whole thing becomes slightly more complicated because we want to stop +// once we have enough digits. That is, once the digits inside the buffer +// represent 'w' we can stop. Everything inside the interval low - high +// represents w. However we have to pay attention to low, high and w's +// imprecision. +static bool DigitGen(DiyFp low, + DiyFp w, + DiyFp high, + Vector<char> buffer, + int* length, + int* kappa) { + DCHECK_EQ(low.E(), w.E()); + DCHECK_EQ(w.E(), high.E()); + DCHECK_LE(low.F() + 1, high.F() - 1); + DCHECK_LE(kMinimalTargetExponent, w.E()); + DCHECK_LE(w.E(), kMaximalTargetExponent); + // low, w and high are imprecise, but by less than one ulp (unit in the + // last place). If we remove (resp. add) 1 ulp from low (resp. high) we + // are certain that the new numbers are outside of the interval we want + // the final representation to lie in. Inversely adding (resp. removing) 1 + // ulp from low (resp. high) would yield numbers that are certain to lie + // in the interval. We will use this fact later on. We will now start by + // generating the digits within the uncertain interval. Later we will weed + // out representations that lie outside the safe interval and thus _might_ + // lie outside the correct interval. + uint64_t unit = 1; + DiyFp too_low = DiyFp(low.F() - unit, low.E()); + DiyFp too_high = DiyFp(high.F() + unit, high.E()); + // too_low and too_high are guaranteed to lie outside the interval we want + // the generated number in. + DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low); + // We now cut the input number into two parts: the integral digits and the + // fractionals. We will not write any decimal separator though, but adapt + // kappa instead. + // Reminder: we are currently computing the digits (stored inside the + // buffer) such that: too_low < buffer * 10^kappa < too_high We use + // too_high for the digit_generation and stop as soon as possible. If we + // stop early we effectively round down. + DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.E(), w.E()); + // Division by one is a shift. + uint32_t integrals = static_cast<uint32_t>(too_high.F() >> -one.E()); + // Modulo by one is an and. + uint64_t fractionals = too_high.F() & (one.F() - 1); + uint32_t divisor; + int divisor_exponent; + BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.E()), &divisor, + &divisor_exponent); + *kappa = divisor_exponent + 1; + *length = 0; + // Loop invariant: buffer = too_high / 10^kappa (integer division) + // The invariant holds for the first iteration: kappa has been initialized + // with the divisor exponent + 1. And the divisor is the biggest power of + // ten that is smaller than integrals. + while (*kappa > 0) { + char digit = static_cast<char>(integrals / divisor); + buffer[*length] = '0' + digit; + (*length)++; + integrals %= divisor; + (*kappa)--; + // Note that kappa now equals the exponent of the divisor and that the + // invariant thus holds again. + uint64_t rest = + (static_cast<uint64_t>(integrals) << -one.E()) + fractionals; + // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) + // Reminder: unsafe_interval.e() == one.e() + if (rest < unsafe_interval.F()) { + // Rounding down (by not emitting the remaining digits) yields a + // number that lies within the unsafe interval. + return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).F(), + unsafe_interval.F(), rest, + static_cast<uint64_t>(divisor) << -one.E(), unit); } + divisor /= 10; + } - - // Generates the digits of input number w. - // w is a floating-point number (DiyFp), consisting of a significand and an - // exponent. Its exponent is bounded by kMinimalTargetExponent and - // kMaximalTargetExponent. - // Hence -60 <= w.e() <= -32. - // - // Returns false if it fails, in which case the generated digits in the buffer - // should not be used. - // Preconditions: - // * low, w and high are correct up to 1 ulp (unit in the last place). That - // is, their error must be less than a unit of their last digits. - // * low.e() == w.e() == high.e() - // * low < w < high, and taking into account their error: low~ <= high~ - // * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent - // Postconditions: returns false if procedure fails. - // otherwise: - // * buffer is not null-terminated, but len contains the number of digits. - // * buffer contains the shortest possible decimal digit-sequence - // such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the - // correct values of low and high (without their error). - // * if more than one decimal representation gives the minimal number of - // decimal digits then the one closest to W (where W is the correct value - // of w) is chosen. - // Remark: this procedure takes into account the imprecision of its input - // numbers. If the precision is not enough to guarantee all the postconditions - // then false is returned. This usually happens rarely (~0.5%). - // - // Say, for the sake of example, that - // w.e() == -48, and w.f() == 0x1234567890abcdef - // w's value can be computed by w.f() * 2^w.e() - // We can obtain w's integral digits by simply shifting w.f() by -w.e(). - // -> w's integral part is 0x1234 - // w's fractional part is therefore 0x567890abcdef. - // Printing w's integral part is easy (simply print 0x1234 in decimal). - // In order to print its fraction we repeatedly multiply the fraction by 10 and - // get each digit. Example the first digit after the point would be computed by - // (0x567890abcdef * 10) >> 48. -> 3 - // The whole thing becomes slightly more complicated because we want to stop - // once we have enough digits. That is, once the digits inside the buffer - // represent 'w' we can stop. Everything inside the interval low - high - // represents w. However we have to pay attention to low, high and w's - // imprecision. - static bool DigitGen(DiyFp low, - DiyFp w, - DiyFp high, - Vector<char> buffer, - int* length, - int* kappa) { - DCHECK_EQ(low.E(), w.E()); - DCHECK_EQ(w.E(), high.E()); - DCHECK_LE(low.F() + 1, high.F() - 1); - DCHECK_LE(kMinimalTargetExponent, w.E()); - DCHECK_LE(w.E(), kMaximalTargetExponent); - // low, w and high are imprecise, but by less than one ulp (unit in the - // last place). If we remove (resp. add) 1 ulp from low (resp. high) we - // are certain that the new numbers are outside of the interval we want - // the final representation to lie in. Inversely adding (resp. removing) 1 - // ulp from low (resp. high) would yield numbers that are certain to lie - // in the interval. We will use this fact later on. We will now start by - // generating the digits within the uncertain interval. Later we will weed - // out representations that lie outside the safe interval and thus _might_ - // lie outside the correct interval. - uint64_t unit = 1; - DiyFp too_low = DiyFp(low.F() - unit, low.E()); - DiyFp too_high = DiyFp(high.F() + unit, high.E()); - // too_low and too_high are guaranteed to lie outside the interval we want - // the generated number in. - DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low); - // We now cut the input number into two parts: the integral digits and the - // fractionals. We will not write any decimal separator though, but adapt - // kappa instead. - // Reminder: we are currently computing the digits (stored inside the - // buffer) such that: too_low < buffer * 10^kappa < too_high We use - // too_high for the digit_generation and stop as soon as possible. If we - // stop early we effectively round down. - DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.E(), w.E()); - // Division by one is a shift. - uint32_t integrals = static_cast<uint32_t>(too_high.F() >> -one.E()); - // Modulo by one is an and. - uint64_t fractionals = too_high.F() & (one.F() - 1); - uint32_t divisor; - int divisor_exponent; - BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.E()), &divisor, - &divisor_exponent); - *kappa = divisor_exponent + 1; - *length = 0; - // Loop invariant: buffer = too_high / 10^kappa (integer division) - // The invariant holds for the first iteration: kappa has been initialized - // with the divisor exponent + 1. And the divisor is the biggest power of - // ten that is smaller than integrals. - while (*kappa > 0) { - char digit = static_cast<char>(integrals / divisor); - buffer[*length] = '0' + digit; - (*length)++; - integrals %= divisor; - (*kappa)--; - // Note that kappa now equals the exponent of the divisor and that the - // invariant thus holds again. - uint64_t rest = - (static_cast<uint64_t>(integrals) << -one.E()) + fractionals; - // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e()) - // Reminder: unsafe_interval.e() == one.e() - if (rest < unsafe_interval.F()) { - // Rounding down (by not emitting the remaining digits) yields a - // number that lies within the unsafe interval. - return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).F(), - unsafe_interval.F(), rest, - static_cast<uint64_t>(divisor) << -one.E(), unit); - } - divisor /= 10; - } - - // The integrals have been generated. We are at the point of the decimal - // separator. In the following loop we simply multiply the remaining digits by - // 10 and divide by one. We just need to pay attention to multiply associated - // data (like the interval or 'unit'), too. - // Note that the multiplication by 10 does not overflow, because w.e >= -60 - // and thus one.e >= -60. - DCHECK_GE(one.E(), -60); - DCHECK_LT(fractionals, one.F()); - DCHECK_GE(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10, one.F()); - while (true) { - fractionals *= 10; - unit *= 10; - unsafe_interval.set_f(unsafe_interval.F() * 10); - // Integer division by one. - char digit = static_cast<char>(fractionals >> -one.E()); - buffer[*length] = '0' + digit; - (*length)++; - fractionals &= one.F() - 1; // Modulo by one. - (*kappa)--; - if (fractionals < unsafe_interval.F()) { - return RoundWeed(buffer, *length, - DiyFp::Minus(too_high, w).F() * unit, - unsafe_interval.F(), fractionals, one.F(), unit); - } - } + // The integrals have been generated. We are at the point of the decimal + // separator. In the following loop we simply multiply the remaining digits by + // 10 and divide by one. We just need to pay attention to multiply associated + // data (like the interval or 'unit'), too. + // Note that the multiplication by 10 does not overflow, because w.e >= -60 + // and thus one.e >= -60. + DCHECK_GE(one.E(), -60); + DCHECK_LT(fractionals, one.F()); + DCHECK_GE(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10, one.F()); + while (true) { + fractionals *= 10; + unit *= 10; + unsafe_interval.set_f(unsafe_interval.F() * 10); + // Integer division by one. + char digit = static_cast<char>(fractionals >> -one.E()); + buffer[*length] = '0' + digit; + (*length)++; + fractionals &= one.F() - 1; // Modulo by one. + (*kappa)--; + if (fractionals < unsafe_interval.F()) { + return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).F() * unit, + unsafe_interval.F(), fractionals, one.F(), unit); } + } +} +// Generates (at most) requested_digits digits of input number w. +// w is a floating-point number (DiyFp), consisting of a significand and an +// exponent. Its exponent is bounded by kMinimalTargetExponent and +// kMaximalTargetExponent. +// Hence -60 <= w.e() <= -32. +// +// Returns false if it fails, in which case the generated digits in the buffer +// should not be used. +// Preconditions: +// * w is correct up to 1 ulp (unit in the last place). That +// is, its error must be strictly less than a unit of its last digit. +// * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent +// +// Postconditions: returns false if procedure fails. +// otherwise: +// * buffer is not null-terminated, but length contains the number of +// digits. +// * the representation in buffer is the most precise representation of +// requested_digits digits. +// * buffer contains at most requested_digits digits of w. If there are less +// than requested_digits digits then some trailing '0's have been removed. +// * kappa is such that +// w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2. +// +// Remark: This procedure takes into account the imprecision of its input +// numbers. If the precision is not enough to guarantee all the postconditions +// then false is returned. This usually happens rarely, but the failure-rate +// increases with higher requested_digits. +static bool DigitGenCounted(DiyFp w, + int requested_digits, + Vector<char> buffer, + int* length, + int* kappa) { + DCHECK_LE(kMinimalTargetExponent, w.E()); + DCHECK_LE(w.E(), kMaximalTargetExponent); + DCHECK_GE(kMinimalTargetExponent, -60); + DCHECK_LE(kMaximalTargetExponent, -32); + // w is assumed to have an error less than 1 unit. Whenever w is scaled we + // also scale its error. + uint64_t w_error = 1; + // We cut the input number into two parts: the integral digits and the + // fractional digits. We don't emit any decimal separator, but adapt kappa + // instead. Example: instead of writing "1.2" we put "12" into the buffer + // and increase kappa by 1. + DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.E(), w.E()); + // Division by one is a shift. + uint32_t integrals = static_cast<uint32_t>(w.F() >> -one.E()); + // Modulo by one is an and. + uint64_t fractionals = w.F() & (one.F() - 1); + uint32_t divisor; + int divisor_exponent; + BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.E()), &divisor, + &divisor_exponent); + *kappa = divisor_exponent + 1; + *length = 0; + // Loop invariant: buffer = w / 10^kappa (integer division) + // The invariant holds for the first iteration: kappa has been initialized + // with the divisor exponent + 1. And the divisor is the biggest power of + // ten that is smaller than 'integrals'. + while (*kappa > 0) { + char digit = static_cast<char>(integrals / divisor); + buffer[*length] = '0' + digit; + (*length)++; + requested_digits--; + integrals %= divisor; + (*kappa)--; + // Note that kappa now equals the exponent of the divisor and that the + // invariant thus holds again. + if (requested_digits == 0) + break; + divisor /= 10; + } - // Generates (at most) requested_digits digits of input number w. - // w is a floating-point number (DiyFp), consisting of a significand and an - // exponent. Its exponent is bounded by kMinimalTargetExponent and - // kMaximalTargetExponent. - // Hence -60 <= w.e() <= -32. - // - // Returns false if it fails, in which case the generated digits in the buffer - // should not be used. - // Preconditions: - // * w is correct up to 1 ulp (unit in the last place). That - // is, its error must be strictly less than a unit of its last digit. - // * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent - // - // Postconditions: returns false if procedure fails. - // otherwise: - // * buffer is not null-terminated, but length contains the number of - // digits. - // * the representation in buffer is the most precise representation of - // requested_digits digits. - // * buffer contains at most requested_digits digits of w. If there are less - // than requested_digits digits then some trailing '0's have been removed. - // * kappa is such that - // w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2. - // - // Remark: This procedure takes into account the imprecision of its input - // numbers. If the precision is not enough to guarantee all the postconditions - // then false is returned. This usually happens rarely, but the failure-rate - // increases with higher requested_digits. - static bool DigitGenCounted(DiyFp w, - int requested_digits, - Vector<char> buffer, - int* length, - int* kappa) { - DCHECK_LE(kMinimalTargetExponent, w.E()); - DCHECK_LE(w.E(), kMaximalTargetExponent); - DCHECK_GE(kMinimalTargetExponent, -60); - DCHECK_LE(kMaximalTargetExponent, -32); - // w is assumed to have an error less than 1 unit. Whenever w is scaled we - // also scale its error. - uint64_t w_error = 1; - // We cut the input number into two parts: the integral digits and the - // fractional digits. We don't emit any decimal separator, but adapt kappa - // instead. Example: instead of writing "1.2" we put "12" into the buffer - // and increase kappa by 1. - DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.E(), w.E()); - // Division by one is a shift. - uint32_t integrals = static_cast<uint32_t>(w.F() >> -one.E()); - // Modulo by one is an and. - uint64_t fractionals = w.F() & (one.F() - 1); - uint32_t divisor; - int divisor_exponent; - BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.E()), &divisor, - &divisor_exponent); - *kappa = divisor_exponent + 1; - *length = 0; + if (requested_digits == 0) { + uint64_t rest = + (static_cast<uint64_t>(integrals) << -one.E()) + fractionals; + return RoundWeedCounted(buffer, *length, rest, + static_cast<uint64_t>(divisor) << -one.E(), w_error, + kappa); + } - // Loop invariant: buffer = w / 10^kappa (integer division) - // The invariant holds for the first iteration: kappa has been initialized - // with the divisor exponent + 1. And the divisor is the biggest power of - // ten that is smaller than 'integrals'. - while (*kappa > 0) { - char digit = static_cast<char>(integrals / divisor); - buffer[*length] = '0' + digit; - (*length)++; - requested_digits--; - integrals %= divisor; - (*kappa)--; - // Note that kappa now equals the exponent of the divisor and that the - // invariant thus holds again. - if (requested_digits == 0) - break; - divisor /= 10; - } + // The integrals have been generated. We are at the point of the decimal + // separator. In the following loop we simply multiply the remaining digits by + // 10 and divide by one. We just need to pay attention to multiply associated + // data (the 'unit'), too. + // Note that the multiplication by 10 does not overflow, because w.e >= -60 + // and thus one.e >= -60. + DCHECK_GE(one.E(), -60); + DCHECK_LT(fractionals, one.F()); + DCHECK_GE(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10, one.F()); + while (requested_digits > 0 && fractionals > w_error) { + fractionals *= 10; + w_error *= 10; + // Integer division by one. + char digit = static_cast<char>(fractionals >> -one.E()); + buffer[*length] = '0' + digit; + (*length)++; + requested_digits--; + fractionals &= one.F() - 1; // Modulo by one. + (*kappa)--; + } + if (requested_digits != 0) + return false; + return RoundWeedCounted(buffer, *length, fractionals, one.F(), w_error, + kappa); +} - if (requested_digits == 0) { - uint64_t rest = - (static_cast<uint64_t>(integrals) << -one.E()) + fractionals; - return RoundWeedCounted(buffer, *length, rest, - static_cast<uint64_t>(divisor) << -one.E(), - w_error, kappa); - } +// Provides a decimal representation of v. +// Returns true if it succeeds, otherwise the result cannot be trusted. +// There will be *length digits inside the buffer (not null-terminated). +// If the function returns true then +// v == (double) (buffer * 10^decimal_exponent). +// The digits in the buffer are the shortest representation possible: no +// 0.09999999999999999 instead of 0.1. The shorter representation will even be +// chosen even if the longer one would be closer to v. +// The last digit will be closest to the actual v. That is, even if several +// digits might correctly yield 'v' when read again, the closest will be +// computed. +static bool Grisu3(double v, + Vector<char> buffer, + int* length, + int* decimal_exponent) { + DiyFp w = Double(v).AsNormalizedDiyFp(); + // boundary_minus and boundary_plus are the boundaries between v and its + // closest floating-point neighbors. Any number strictly between + // boundary_minus and boundary_plus will round to v when convert to a double. + // Grisu3 will never output representations that lie exactly on a boundary. + DiyFp boundary_minus, boundary_plus; + Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); + DCHECK_EQ(boundary_plus.E(), w.E()); + DiyFp ten_mk; // Cached power of ten: 10^-k + int mk; // -k + int ten_mk_minimal_binary_exponent = + kMinimalTargetExponent - (w.E() + DiyFp::kSignificandSize); + int ten_mk_maximal_binary_exponent = + kMaximalTargetExponent - (w.E() + DiyFp::kSignificandSize); + PowersOfTenCache::GetCachedPowerForBinaryExponentRange( + ten_mk_minimal_binary_exponent, ten_mk_maximal_binary_exponent, &ten_mk, + &mk); + DCHECK_LE(kMinimalTargetExponent, + w.E() + ten_mk.E() + DiyFp::kSignificandSize); + DCHECK_GE(kMaximalTargetExponent, + w.E() + ten_mk.E() + DiyFp::kSignificandSize); + // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a + // 64 bit significand and ten_mk is thus only precise up to 64 bits. - // The integrals have been generated. We are at the point of the decimal - // separator. In the following loop we simply multiply the remaining digits by - // 10 and divide by one. We just need to pay attention to multiply associated - // data (the 'unit'), too. - // Note that the multiplication by 10 does not overflow, because w.e >= -60 - // and thus one.e >= -60. - DCHECK_GE(one.E(), -60); - DCHECK_LT(fractionals, one.F()); - DCHECK_GE(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10, one.F()); - while (requested_digits > 0 && fractionals > w_error) { - fractionals *= 10; - w_error *= 10; - // Integer division by one. - char digit = static_cast<char>(fractionals >> -one.E()); - buffer[*length] = '0' + digit; - (*length)++; - requested_digits--; - fractionals &= one.F() - 1; // Modulo by one. - (*kappa)--; - } - if (requested_digits != 0) return false; - return RoundWeedCounted(buffer, *length, fractionals, one.F(), w_error, - kappa); - } + // The DiyFp::Times procedure rounds its result, and ten_mk is approximated + // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now + // off by a small amount. + // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. + // In other words: let f = scaled_w.f() and e = scaled_w.e(), then + // (f-1) * 2^e < w*10^k < (f+1) * 2^e + DiyFp scaled_w = DiyFp::Times(w, ten_mk); + DCHECK_EQ(scaled_w.E(), + boundary_plus.E() + ten_mk.E() + DiyFp::kSignificandSize); + // In theory it would be possible to avoid some recomputations by computing + // the difference between w and boundary_minus/plus (a power of 2) and to + // compute scaled_boundary_minus/plus by subtracting/adding from + // scaled_w. However the code becomes much less readable and the speed + // enhancements are not terriffic. + DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk); + DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk); + // DigitGen will generate the digits of scaled_w. Therefore we have + // v == (double) (scaled_w * 10^-mk). + // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an + // integer than it will be updated. For instance if scaled_w == 1.23 then + // the buffer will be filled with "123" und the decimal_exponent will be + // decreased by 2. + int kappa; + bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, + buffer, length, &kappa); + *decimal_exponent = -mk + kappa; + return result; +} - // Provides a decimal representation of v. - // Returns true if it succeeds, otherwise the result cannot be trusted. - // There will be *length digits inside the buffer (not null-terminated). - // If the function returns true then - // v == (double) (buffer * 10^decimal_exponent). - // The digits in the buffer are the shortest representation possible: no - // 0.09999999999999999 instead of 0.1. The shorter representation will even be - // chosen even if the longer one would be closer to v. - // The last digit will be closest to the actual v. That is, even if several - // digits might correctly yield 'v' when read again, the closest will be - // computed. - static bool Grisu3(double v, - Vector<char> buffer, - int* length, - int* decimal_exponent) { - DiyFp w = Double(v).AsNormalizedDiyFp(); - // boundary_minus and boundary_plus are the boundaries between v and its - // closest floating-point neighbors. Any number strictly between - // boundary_minus and boundary_plus will round to v when convert to a double. - // Grisu3 will never output representations that lie exactly on a boundary. - DiyFp boundary_minus, boundary_plus; - Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); - DCHECK_EQ(boundary_plus.E(), w.E()); - DiyFp ten_mk; // Cached power of ten: 10^-k - int mk; // -k - int ten_mk_minimal_binary_exponent = - kMinimalTargetExponent - (w.E() + DiyFp::kSignificandSize); - int ten_mk_maximal_binary_exponent = - kMaximalTargetExponent - (w.E() + DiyFp::kSignificandSize); - PowersOfTenCache::GetCachedPowerForBinaryExponentRange( - ten_mk_minimal_binary_exponent, - ten_mk_maximal_binary_exponent, - &ten_mk, &mk); - DCHECK_LE(kMinimalTargetExponent, - w.E() + ten_mk.E() + DiyFp::kSignificandSize); - DCHECK_GE(kMaximalTargetExponent, - w.E() + ten_mk.E() + DiyFp::kSignificandSize); - // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a - // 64 bit significand and ten_mk is thus only precise up to 64 bits. +// The "counted" version of grisu3 (see above) only generates requested_digits +// number of digits. This version does not generate the shortest representation, +// and with enough requested digits 0.1 will at some point print as 0.9999999... +// Grisu3 is too imprecise for real halfway cases (1.5 will not work) and +// therefore the rounding strategy for halfway cases is irrelevant. +static bool Grisu3Counted(double v, + int requested_digits, + Vector<char> buffer, + int* length, + int* decimal_exponent) { + DiyFp w = Double(v).AsNormalizedDiyFp(); + DiyFp ten_mk; // Cached power of ten: 10^-k + int mk; // -k + int ten_mk_minimal_binary_exponent = + kMinimalTargetExponent - (w.E() + DiyFp::kSignificandSize); + int ten_mk_maximal_binary_exponent = + kMaximalTargetExponent - (w.E() + DiyFp::kSignificandSize); + PowersOfTenCache::GetCachedPowerForBinaryExponentRange( + ten_mk_minimal_binary_exponent, ten_mk_maximal_binary_exponent, &ten_mk, + &mk); + DCHECK_LE(kMinimalTargetExponent, + w.E() + ten_mk.E() + DiyFp::kSignificandSize); + DCHECK_GE(kMaximalTargetExponent, + w.E() + ten_mk.E() + DiyFp::kSignificandSize); + // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a + // 64 bit significand and ten_mk is thus only precise up to 64 bits. - // The DiyFp::Times procedure rounds its result, and ten_mk is approximated - // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now - // off by a small amount. - // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. - // In other words: let f = scaled_w.f() and e = scaled_w.e(), then - // (f-1) * 2^e < w*10^k < (f+1) * 2^e - DiyFp scaled_w = DiyFp::Times(w, ten_mk); - DCHECK_EQ(scaled_w.E(), - boundary_plus.E() + ten_mk.E() + DiyFp::kSignificandSize); - // In theory it would be possible to avoid some recomputations by computing - // the difference between w and boundary_minus/plus (a power of 2) and to - // compute scaled_boundary_minus/plus by subtracting/adding from - // scaled_w. However the code becomes much less readable and the speed - // enhancements are not terriffic. - DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk); - DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk); + // The DiyFp::Times procedure rounds its result, and ten_mk is approximated + // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now + // off by a small amount. + // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. + // In other words: let f = scaled_w.f() and e = scaled_w.e(), then + // (f-1) * 2^e < w*10^k < (f+1) * 2^e + DiyFp scaled_w = DiyFp::Times(w, ten_mk); - // DigitGen will generate the digits of scaled_w. Therefore we have - // v == (double) (scaled_w * 10^-mk). - // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an - // integer than it will be updated. For instance if scaled_w == 1.23 then - // the buffer will be filled with "123" und the decimal_exponent will be - // decreased by 2. - int kappa; - bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, - buffer, length, &kappa); - *decimal_exponent = -mk + kappa; - return result; - } + // We now have (double) (scaled_w * 10^-mk). + // DigitGen will generate the first requested_digits digits of scaled_w and + // return together with a kappa such that scaled_w ~= buffer * 10^kappa. (It + // will not always be exactly the same since DigitGenCounted only produces a + // limited number of digits.) + int kappa; + bool result = + DigitGenCounted(scaled_w, requested_digits, buffer, length, &kappa); + *decimal_exponent = -mk + kappa; + return result; +} +bool FastDtoa(double v, + FastDtoaMode mode, + int requested_digits, + Vector<char> buffer, + int* length, + int* decimal_point) { + DCHECK_GT(v, 0); + DCHECK(!Double(v).IsSpecial()); - // The "counted" version of grisu3 (see above) only generates requested_digits - // number of digits. This version does not generate the shortest representation, - // and with enough requested digits 0.1 will at some point print as 0.9999999... - // Grisu3 is too imprecise for real halfway cases (1.5 will not work) and - // therefore the rounding strategy for halfway cases is irrelevant. - static bool Grisu3Counted(double v, - int requested_digits, - Vector<char> buffer, - int* length, - int* decimal_exponent) { - DiyFp w = Double(v).AsNormalizedDiyFp(); - DiyFp ten_mk; // Cached power of ten: 10^-k - int mk; // -k - int ten_mk_minimal_binary_exponent = - kMinimalTargetExponent - (w.E() + DiyFp::kSignificandSize); - int ten_mk_maximal_binary_exponent = - kMaximalTargetExponent - (w.E() + DiyFp::kSignificandSize); - PowersOfTenCache::GetCachedPowerForBinaryExponentRange( - ten_mk_minimal_binary_exponent, - ten_mk_maximal_binary_exponent, - &ten_mk, &mk); - DCHECK_LE(kMinimalTargetExponent, - w.E() + ten_mk.E() + DiyFp::kSignificandSize); - DCHECK_GE(kMaximalTargetExponent, - w.E() + ten_mk.E() + DiyFp::kSignificandSize); - // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a - // 64 bit significand and ten_mk is thus only precise up to 64 bits. - - // The DiyFp::Times procedure rounds its result, and ten_mk is approximated - // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now - // off by a small amount. - // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w. - // In other words: let f = scaled_w.f() and e = scaled_w.e(), then - // (f-1) * 2^e < w*10^k < (f+1) * 2^e - DiyFp scaled_w = DiyFp::Times(w, ten_mk); - - // We now have (double) (scaled_w * 10^-mk). - // DigitGen will generate the first requested_digits digits of scaled_w and - // return together with a kappa such that scaled_w ~= buffer * 10^kappa. (It - // will not always be exactly the same since DigitGenCounted only produces a - // limited number of digits.) - int kappa; - bool result = DigitGenCounted(scaled_w, requested_digits, - buffer, length, &kappa); - *decimal_exponent = -mk + kappa; - return result; - } - - - bool FastDtoa(double v, - FastDtoaMode mode, - int requested_digits, - Vector<char> buffer, - int* length, - int* decimal_point) { - DCHECK_GT(v, 0); - DCHECK(!Double(v).IsSpecial()); - - bool result = false; - int decimal_exponent = 0; - switch (mode) { - case FAST_DTOA_SHORTEST: - result = Grisu3(v, buffer, length, &decimal_exponent); - break; - case FAST_DTOA_PRECISION: - result = Grisu3Counted(v, requested_digits, - buffer, length, &decimal_exponent); - break; - default: - UNREACHABLE(); - } - if (result) { - *decimal_point = *length + decimal_exponent; - buffer[*length] = '\0'; - } - return result; - } + bool result = false; + int decimal_exponent = 0; + switch (mode) { + case FAST_DTOA_SHORTEST: + result = Grisu3(v, buffer, length, &decimal_exponent); + break; + case FAST_DTOA_PRECISION: + result = + Grisu3Counted(v, requested_digits, buffer, length, &decimal_exponent); + break; + default: + UNREACHABLE(); + } + if (result) { + *decimal_point = *length + decimal_exponent; + buffer[*length] = '\0'; + } + return result; +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/fixed-dtoa.cc b/third_party/WebKit/Source/platform/wtf/dtoa/fixed-dtoa.cc index 3d867e54..af9d88a 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/fixed-dtoa.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/fixed-dtoa.cc
@@ -27,383 +27,383 @@ #include "fixed-dtoa.h" -#include "double.h" #include <math.h> +#include "double.h" namespace WTF { namespace double_conversion { - // Represents a 128bit type. This class should be replaced by a native type on - // platforms that support 128bit integers. - class UInt128 { - public: - UInt128() : high_bits_(0), low_bits_(0) { } - UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { } +// Represents a 128bit type. This class should be replaced by a native type on +// platforms that support 128bit integers. +class UInt128 { + public: + UInt128() : high_bits_(0), low_bits_(0) {} + UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) {} - void Multiply(uint32_t multiplicand) { - uint64_t accumulator; + void Multiply(uint32_t multiplicand) { + uint64_t accumulator; - accumulator = (low_bits_ & kMask32) * multiplicand; - uint32_t part = static_cast<uint32_t>(accumulator & kMask32); - accumulator >>= 32; - accumulator = accumulator + (low_bits_ >> 32) * multiplicand; - low_bits_ = (accumulator << 32) + part; - accumulator >>= 32; - accumulator = accumulator + (high_bits_ & kMask32) * multiplicand; - part = static_cast<uint32_t>(accumulator & kMask32); - accumulator >>= 32; - accumulator = accumulator + (high_bits_ >> 32) * multiplicand; - high_bits_ = (accumulator << 32) + part; - DCHECK_EQ((accumulator >> 32), 0u); - } + accumulator = (low_bits_ & kMask32) * multiplicand; + uint32_t part = static_cast<uint32_t>(accumulator & kMask32); + accumulator >>= 32; + accumulator = accumulator + (low_bits_ >> 32) * multiplicand; + low_bits_ = (accumulator << 32) + part; + accumulator >>= 32; + accumulator = accumulator + (high_bits_ & kMask32) * multiplicand; + part = static_cast<uint32_t>(accumulator & kMask32); + accumulator >>= 32; + accumulator = accumulator + (high_bits_ >> 32) * multiplicand; + high_bits_ = (accumulator << 32) + part; + DCHECK_EQ((accumulator >> 32), 0u); + } - void Shift(int shift_amount) { - DCHECK_LE(-64, shift_amount); - DCHECK_LE(shift_amount, 64); - if (shift_amount == 0) { - return; - } else if (shift_amount == -64) { - high_bits_ = low_bits_; - low_bits_ = 0; - } else if (shift_amount == 64) { - low_bits_ = high_bits_; - high_bits_ = 0; - } else if (shift_amount <= 0) { - high_bits_ <<= -shift_amount; - high_bits_ += low_bits_ >> (64 + shift_amount); - low_bits_ <<= -shift_amount; - } else { - low_bits_ >>= shift_amount; - low_bits_ += high_bits_ << (64 - shift_amount); - high_bits_ >>= shift_amount; - } - } - - // Modifies *this to *this MOD (2^power). - // Returns *this DIV (2^power). - int DivModPowerOf2(int power) { - if (power >= 64) { - int result = static_cast<int>(high_bits_ >> (power - 64)); - high_bits_ -= static_cast<uint64_t>(result) << (power - 64); - return result; - } else { - uint64_t part_low = low_bits_ >> power; - uint64_t part_high = high_bits_ << (64 - power); - int result = static_cast<int>(part_low + part_high); - high_bits_ = 0; - low_bits_ -= part_low << power; - return result; - } - } - - bool IsZero() const { - return high_bits_ == 0 && low_bits_ == 0; - } - - int BitAt(int position) { - if (position >= 64) { - return static_cast<int>(high_bits_ >> (position - 64)) & 1; - } else { - return static_cast<int>(low_bits_ >> position) & 1; - } - } - - private: - static const uint64_t kMask32 = 0xFFFFFFFF; - // Value == (high_bits_ << 64) + low_bits_ - uint64_t high_bits_; - uint64_t low_bits_; - }; - - - static const int kDoubleSignificandSize = 53; // Includes the hidden bit. - - - static void FillDigits32FixedLength(uint32_t number, int requested_length, - Vector<char> buffer, int* length) { - for (int i = requested_length - 1; i >= 0; --i) { - buffer[(*length) + i] = '0' + number % 10; - number /= 10; - } - *length += requested_length; + void Shift(int shift_amount) { + DCHECK_LE(-64, shift_amount); + DCHECK_LE(shift_amount, 64); + if (shift_amount == 0) { + return; + } else if (shift_amount == -64) { + high_bits_ = low_bits_; + low_bits_ = 0; + } else if (shift_amount == 64) { + low_bits_ = high_bits_; + high_bits_ = 0; + } else if (shift_amount <= 0) { + high_bits_ <<= -shift_amount; + high_bits_ += low_bits_ >> (64 + shift_amount); + low_bits_ <<= -shift_amount; + } else { + low_bits_ >>= shift_amount; + low_bits_ += high_bits_ << (64 - shift_amount); + high_bits_ >>= shift_amount; } + } - - static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) { - int number_length = 0; - // We fill the digits in reverse order and exchange them afterwards. - while (number != 0) { - char digit = number % 10; - number /= 10; - buffer[(*length) + number_length] = '0' + digit; - number_length++; - } - // Exchange the digits. - int i = *length; - int j = *length + number_length - 1; - while (i < j) { - char tmp = buffer[i]; - buffer[i] = buffer[j]; - buffer[j] = tmp; - i++; - j--; - } - *length += number_length; + // Modifies *this to *this MOD (2^power). + // Returns *this DIV (2^power). + int DivModPowerOf2(int power) { + if (power >= 64) { + int result = static_cast<int>(high_bits_ >> (power - 64)); + high_bits_ -= static_cast<uint64_t>(result) << (power - 64); + return result; + } else { + uint64_t part_low = low_bits_ >> power; + uint64_t part_high = high_bits_ << (64 - power); + int result = static_cast<int>(part_low + part_high); + high_bits_ = 0; + low_bits_ -= part_low << power; + return result; } + } + bool IsZero() const { return high_bits_ == 0 && low_bits_ == 0; } - static void FillDigits64FixedLength(uint64_t number, int, - Vector<char> buffer, int* length) { - const uint32_t kTen7 = 10000000; - // For efficiency cut the number into 3 uint32_t parts, and print those. - uint32_t part2 = static_cast<uint32_t>(number % kTen7); - number /= kTen7; - uint32_t part1 = static_cast<uint32_t>(number % kTen7); - uint32_t part0 = static_cast<uint32_t>(number / kTen7); - - FillDigits32FixedLength(part0, 3, buffer, length); - FillDigits32FixedLength(part1, 7, buffer, length); - FillDigits32FixedLength(part2, 7, buffer, length); + int BitAt(int position) { + if (position >= 64) { + return static_cast<int>(high_bits_ >> (position - 64)) & 1; + } else { + return static_cast<int>(low_bits_ >> position) & 1; } + } + private: + static const uint64_t kMask32 = 0xFFFFFFFF; + // Value == (high_bits_ << 64) + low_bits_ + uint64_t high_bits_; + uint64_t low_bits_; +}; - static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) { - const uint32_t kTen7 = 10000000; - // For efficiency cut the number into 3 uint32_t parts, and print those. - uint32_t part2 = static_cast<uint32_t>(number % kTen7); - number /= kTen7; - uint32_t part1 = static_cast<uint32_t>(number % kTen7); - uint32_t part0 = static_cast<uint32_t>(number / kTen7); +static const int kDoubleSignificandSize = 53; // Includes the hidden bit. - if (part0 != 0) { - FillDigits32(part0, buffer, length); - FillDigits32FixedLength(part1, 7, buffer, length); - FillDigits32FixedLength(part2, 7, buffer, length); - } else if (part1 != 0) { - FillDigits32(part1, buffer, length); - FillDigits32FixedLength(part2, 7, buffer, length); - } else { - FillDigits32(part2, buffer, length); - } +static void FillDigits32FixedLength(uint32_t number, + int requested_length, + Vector<char> buffer, + int* length) { + for (int i = requested_length - 1; i >= 0; --i) { + buffer[(*length) + i] = '0' + number % 10; + number /= 10; + } + *length += requested_length; +} + +static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) { + int number_length = 0; + // We fill the digits in reverse order and exchange them afterwards. + while (number != 0) { + char digit = number % 10; + number /= 10; + buffer[(*length) + number_length] = '0' + digit; + number_length++; + } + // Exchange the digits. + int i = *length; + int j = *length + number_length - 1; + while (i < j) { + char tmp = buffer[i]; + buffer[i] = buffer[j]; + buffer[j] = tmp; + i++; + j--; + } + *length += number_length; +} + +static void FillDigits64FixedLength(uint64_t number, + int, + Vector<char> buffer, + int* length) { + const uint32_t kTen7 = 10000000; + // For efficiency cut the number into 3 uint32_t parts, and print those. + uint32_t part2 = static_cast<uint32_t>(number % kTen7); + number /= kTen7; + uint32_t part1 = static_cast<uint32_t>(number % kTen7); + uint32_t part0 = static_cast<uint32_t>(number / kTen7); + + FillDigits32FixedLength(part0, 3, buffer, length); + FillDigits32FixedLength(part1, 7, buffer, length); + FillDigits32FixedLength(part2, 7, buffer, length); +} + +static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) { + const uint32_t kTen7 = 10000000; + // For efficiency cut the number into 3 uint32_t parts, and print those. + uint32_t part2 = static_cast<uint32_t>(number % kTen7); + number /= kTen7; + uint32_t part1 = static_cast<uint32_t>(number % kTen7); + uint32_t part0 = static_cast<uint32_t>(number / kTen7); + + if (part0 != 0) { + FillDigits32(part0, buffer, length); + FillDigits32FixedLength(part1, 7, buffer, length); + FillDigits32FixedLength(part2, 7, buffer, length); + } else if (part1 != 0) { + FillDigits32(part1, buffer, length); + FillDigits32FixedLength(part2, 7, buffer, length); + } else { + FillDigits32(part2, buffer, length); + } +} + +static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) { + // An empty buffer represents 0. + if (*length == 0) { + buffer[0] = '1'; + *decimal_point = 1; + *length = 1; + return; + } + // Round the last digit until we either have a digit that was not '9' or until + // we reached the first digit. + buffer[(*length) - 1]++; + for (int i = (*length) - 1; i > 0; --i) { + if (buffer[i] != '0' + 10) { + return; } + buffer[i] = '0'; + buffer[i - 1]++; + } + // If the first digit is now '0' + 10, we would need to set it to '0' and add + // a '1' in front. However we reach the first digit only if all following + // digits had been '9' before rounding up. Now all trailing digits are '0' and + // we simply switch the first digit to '1' and update the decimal-point + // (indicating that the point is now one digit to the right). + if (buffer[0] == '0' + 10) { + buffer[0] = '1'; + (*decimal_point)++; + } +} - - static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) { - // An empty buffer represents 0. - if (*length == 0) { - buffer[0] = '1'; - *decimal_point = 1; - *length = 1; - return; - } - // Round the last digit until we either have a digit that was not '9' or until - // we reached the first digit. - buffer[(*length) - 1]++; - for (int i = (*length) - 1; i > 0; --i) { - if (buffer[i] != '0' + 10) { - return; - } - buffer[i] = '0'; - buffer[i - 1]++; - } - // If the first digit is now '0' + 10, we would need to set it to '0' and add - // a '1' in front. However we reach the first digit only if all following - // digits had been '9' before rounding up. Now all trailing digits are '0' and - // we simply switch the first digit to '1' and update the decimal-point - // (indicating that the point is now one digit to the right). - if (buffer[0] == '0' + 10) { - buffer[0] = '1'; - (*decimal_point)++; - } +// The given fractionals number represents a fixed-point number with binary +// point at bit (-exponent). +// Preconditions: +// -128 <= exponent <= 0. +// 0 <= fractionals * 2^exponent < 1 +// The buffer holds the result. +// The function will round its result. During the rounding-process digits not +// generated by this function might be updated, and the decimal-point variable +// might be updated. If this function generates the digits 99 and the buffer +// already contained "199" (thus yielding a buffer of "19999") then a +// rounding-up will change the contents of the buffer to "20000". +static void FillFractionals(uint64_t fractionals, + int exponent, + int fractional_count, + Vector<char> buffer, + int* length, + int* decimal_point) { + DCHECK_LE(-128, exponent); + DCHECK_LE(exponent, 0); + // 'fractionals' is a fixed-point number, with binary point at bit + // (-exponent). Inside the function the non-converted remainder of fractionals + // is a fixed-point number, with binary point at bit 'point'. + if (-exponent <= 64) { + // One 64 bit number is sufficient. + DCHECK(fractionals >> 56 == 0); + int point = -exponent; + for (int i = 0; i < fractional_count; ++i) { + if (fractionals == 0) + break; + // Instead of multiplying by 10 we multiply by 5 and adjust the point + // location. This way the fractionals variable will not overflow. + // Invariant at the beginning of the loop: fractionals < 2^point. + // Initially we have: point <= 64 and fractionals < 2^56 + // After each iteration the point is decremented by one. + // Note that 5^3 = 125 < 128 = 2^7. + // Therefore three iterations of this loop will not overflow fractionals + // (even without the subtraction at the end of the loop body). At this + // time point will satisfy point <= 61 and therefore fractionals < 2^point + // and any further multiplication of fractionals by 5 will not overflow. + fractionals *= 5; + point--; + char digit = static_cast<char>(fractionals >> point); + buffer[*length] = '0' + digit; + (*length)++; + fractionals -= static_cast<uint64_t>(digit) << point; } - - - // The given fractionals number represents a fixed-point number with binary - // point at bit (-exponent). - // Preconditions: - // -128 <= exponent <= 0. - // 0 <= fractionals * 2^exponent < 1 - // The buffer holds the result. - // The function will round its result. During the rounding-process digits not - // generated by this function might be updated, and the decimal-point variable - // might be updated. If this function generates the digits 99 and the buffer - // already contained "199" (thus yielding a buffer of "19999") then a - // rounding-up will change the contents of the buffer to "20000". - static void FillFractionals(uint64_t fractionals, int exponent, - int fractional_count, Vector<char> buffer, - int* length, int* decimal_point) { - DCHECK_LE(-128, exponent); - DCHECK_LE(exponent, 0); - // 'fractionals' is a fixed-point number, with binary point at bit - // (-exponent). Inside the function the non-converted remainder of fractionals - // is a fixed-point number, with binary point at bit 'point'. - if (-exponent <= 64) { - // One 64 bit number is sufficient. - DCHECK(fractionals >> 56 == 0); - int point = -exponent; - for (int i = 0; i < fractional_count; ++i) { - if (fractionals == 0) break; - // Instead of multiplying by 10 we multiply by 5 and adjust the point - // location. This way the fractionals variable will not overflow. - // Invariant at the beginning of the loop: fractionals < 2^point. - // Initially we have: point <= 64 and fractionals < 2^56 - // After each iteration the point is decremented by one. - // Note that 5^3 = 125 < 128 = 2^7. - // Therefore three iterations of this loop will not overflow fractionals - // (even without the subtraction at the end of the loop body). At this - // time point will satisfy point <= 61 and therefore fractionals < 2^point - // and any further multiplication of fractionals by 5 will not overflow. - fractionals *= 5; - point--; - char digit = static_cast<char>(fractionals >> point); - buffer[*length] = '0' + digit; - (*length)++; - fractionals -= static_cast<uint64_t>(digit) << point; - } - // If the first bit after the point is set we have to round up. - if (((fractionals >> (point - 1)) & 1) == 1) { - RoundUp(buffer, length, decimal_point); - } - } else { // We need 128 bits. - DCHECK_LT(64, -exponent); - DCHECK_LE(-exponent, 128); - UInt128 fractionals128 = UInt128(fractionals, 0); - fractionals128.Shift(-exponent - 64); - int point = 128; - for (int i = 0; i < fractional_count; ++i) { - if (fractionals128.IsZero()) break; - // As before: instead of multiplying by 10 we multiply by 5 and adjust the - // point location. - // This multiplication will not overflow for the same reasons as before. - fractionals128.Multiply(5); - point--; - char digit = static_cast<char>(fractionals128.DivModPowerOf2(point)); - buffer[*length] = '0' + digit; - (*length)++; - } - if (fractionals128.BitAt(point - 1) == 1) { - RoundUp(buffer, length, decimal_point); - } - } + // If the first bit after the point is set we have to round up. + if (((fractionals >> (point - 1)) & 1) == 1) { + RoundUp(buffer, length, decimal_point); } - - - // Removes leading and trailing zeros. - // If leading zeros are removed then the decimal point position is adjusted. - static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) { - while (*length > 0 && buffer[(*length) - 1] == '0') { - (*length)--; - } - int first_non_zero = 0; - while (first_non_zero < *length && buffer[first_non_zero] == '0') { - first_non_zero++; - } - if (first_non_zero != 0) { - for (int i = first_non_zero; i < *length; ++i) { - buffer[i - first_non_zero] = buffer[i]; - } - *length -= first_non_zero; - *decimal_point -= first_non_zero; - } + } else { // We need 128 bits. + DCHECK_LT(64, -exponent); + DCHECK_LE(-exponent, 128); + UInt128 fractionals128 = UInt128(fractionals, 0); + fractionals128.Shift(-exponent - 64); + int point = 128; + for (int i = 0; i < fractional_count; ++i) { + if (fractionals128.IsZero()) + break; + // As before: instead of multiplying by 10 we multiply by 5 and adjust the + // point location. + // This multiplication will not overflow for the same reasons as before. + fractionals128.Multiply(5); + point--; + char digit = static_cast<char>(fractionals128.DivModPowerOf2(point)); + buffer[*length] = '0' + digit; + (*length)++; } - - - bool FastFixedDtoa(double v, - int fractional_count, - Vector<char> buffer, - int* length, - int* decimal_point) { - const uint32_t kMaxUInt32 = 0xFFFFFFFF; - uint64_t significand = Double(v).Significand(); - int exponent = Double(v).Exponent(); - // v = significand * 2^exponent (with significand a 53bit integer). - // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we - // don't know how to compute the representation. 2^73 ~= 9.5*10^21. - // If necessary this limit could probably be increased, but we don't need - // more. - if (exponent > 20) return false; - if (fractional_count > 20) return false; - *length = 0; - // At most kDoubleSignificandSize bits of the significand are non-zero. - // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero - // bits: 0..11*..0xxx..53*..xx - if (exponent + kDoubleSignificandSize > 64) { - // The exponent must be > 11. - // - // We know that v = significand * 2^exponent. - // And the exponent > 11. - // We simplify the task by dividing v by 10^17. - // The quotient delivers the first digits, and the remainder fits into a 64 - // bit number. - // Dividing by 10^17 is equivalent to dividing by 5^17*2^17. - const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17 - uint64_t divisor = kFive17; - int divisor_power = 17; - uint64_t dividend = significand; - uint32_t quotient; - uint64_t remainder; - // Let v = f * 2^e with f == significand and e == exponent. - // Then need q (quotient) and r (remainder) as follows: - // v = q * 10^17 + r - // f * 2^e = q * 10^17 + r - // f * 2^e = q * 5^17 * 2^17 + r - // If e > 17 then - // f * 2^(e-17) = q * 5^17 + r/2^17 - // else - // f = q * 5^17 * 2^(17-e) + r/2^e - if (exponent > divisor_power) { - // We only allow exponents of up to 20 and therefore (17 - e) <= 3 - dividend <<= exponent - divisor_power; - quotient = static_cast<uint32_t>(dividend / divisor); - remainder = (dividend % divisor) << divisor_power; - } else { - divisor <<= divisor_power - exponent; - quotient = static_cast<uint32_t>(dividend / divisor); - remainder = (dividend % divisor) << exponent; - } - FillDigits32(quotient, buffer, length); - FillDigits64FixedLength(remainder, divisor_power, buffer, length); - *decimal_point = *length; - } else if (exponent >= 0) { - // 0 <= exponent <= 11 - significand <<= exponent; - FillDigits64(significand, buffer, length); - *decimal_point = *length; - } else if (exponent > -kDoubleSignificandSize) { - // We have to cut the number. - uint64_t integrals = significand >> -exponent; - uint64_t fractionals = significand - (integrals << -exponent); - if (integrals > kMaxUInt32) { - FillDigits64(integrals, buffer, length); - } else { - FillDigits32(static_cast<uint32_t>(integrals), buffer, length); - } - *decimal_point = *length; - FillFractionals(fractionals, exponent, fractional_count, - buffer, length, decimal_point); - } else if (exponent < -128) { - // This configuration (with at most 20 digits) means that all digits must be - // 0. - DCHECK_LE(fractional_count, 20); - buffer[0] = '\0'; - *length = 0; - *decimal_point = -fractional_count; - } else { - *decimal_point = 0; - FillFractionals(significand, exponent, fractional_count, - buffer, length, decimal_point); - } - TrimZeros(buffer, length, decimal_point); - buffer[*length] = '\0'; - if ((*length) == 0) { - // The string is empty and the decimal_point thus has no importance. Mimick - // Gay's dtoa and and set it to -fractional_count. - *decimal_point = -fractional_count; - } - return true; + if (fractionals128.BitAt(point - 1) == 1) { + RoundUp(buffer, length, decimal_point); } + } +} + +// Removes leading and trailing zeros. +// If leading zeros are removed then the decimal point position is adjusted. +static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) { + while (*length > 0 && buffer[(*length) - 1] == '0') { + (*length)--; + } + int first_non_zero = 0; + while (first_non_zero < *length && buffer[first_non_zero] == '0') { + first_non_zero++; + } + if (first_non_zero != 0) { + for (int i = first_non_zero; i < *length; ++i) { + buffer[i - first_non_zero] = buffer[i]; + } + *length -= first_non_zero; + *decimal_point -= first_non_zero; + } +} + +bool FastFixedDtoa(double v, + int fractional_count, + Vector<char> buffer, + int* length, + int* decimal_point) { + const uint32_t kMaxUInt32 = 0xFFFFFFFF; + uint64_t significand = Double(v).Significand(); + int exponent = Double(v).Exponent(); + // v = significand * 2^exponent (with significand a 53bit integer). + // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we + // don't know how to compute the representation. 2^73 ~= 9.5*10^21. + // If necessary this limit could probably be increased, but we don't need + // more. + if (exponent > 20) + return false; + if (fractional_count > 20) + return false; + *length = 0; + // At most kDoubleSignificandSize bits of the significand are non-zero. + // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero + // bits: 0..11*..0xxx..53*..xx + if (exponent + kDoubleSignificandSize > 64) { + // The exponent must be > 11. + // + // We know that v = significand * 2^exponent. + // And the exponent > 11. + // We simplify the task by dividing v by 10^17. + // The quotient delivers the first digits, and the remainder fits into a 64 + // bit number. + // Dividing by 10^17 is equivalent to dividing by 5^17*2^17. + const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17 + uint64_t divisor = kFive17; + int divisor_power = 17; + uint64_t dividend = significand; + uint32_t quotient; + uint64_t remainder; + // Let v = f * 2^e with f == significand and e == exponent. + // Then need q (quotient) and r (remainder) as follows: + // v = q * 10^17 + r + // f * 2^e = q * 10^17 + r + // f * 2^e = q * 5^17 * 2^17 + r + // If e > 17 then + // f * 2^(e-17) = q * 5^17 + r/2^17 + // else + // f = q * 5^17 * 2^(17-e) + r/2^e + if (exponent > divisor_power) { + // We only allow exponents of up to 20 and therefore (17 - e) <= 3 + dividend <<= exponent - divisor_power; + quotient = static_cast<uint32_t>(dividend / divisor); + remainder = (dividend % divisor) << divisor_power; + } else { + divisor <<= divisor_power - exponent; + quotient = static_cast<uint32_t>(dividend / divisor); + remainder = (dividend % divisor) << exponent; + } + FillDigits32(quotient, buffer, length); + FillDigits64FixedLength(remainder, divisor_power, buffer, length); + *decimal_point = *length; + } else if (exponent >= 0) { + // 0 <= exponent <= 11 + significand <<= exponent; + FillDigits64(significand, buffer, length); + *decimal_point = *length; + } else if (exponent > -kDoubleSignificandSize) { + // We have to cut the number. + uint64_t integrals = significand >> -exponent; + uint64_t fractionals = significand - (integrals << -exponent); + if (integrals > kMaxUInt32) { + FillDigits64(integrals, buffer, length); + } else { + FillDigits32(static_cast<uint32_t>(integrals), buffer, length); + } + *decimal_point = *length; + FillFractionals(fractionals, exponent, fractional_count, buffer, length, + decimal_point); + } else if (exponent < -128) { + // This configuration (with at most 20 digits) means that all digits must be + // 0. + DCHECK_LE(fractional_count, 20); + buffer[0] = '\0'; + *length = 0; + *decimal_point = -fractional_count; + } else { + *decimal_point = 0; + FillFractionals(significand, exponent, fractional_count, buffer, length, + decimal_point); + } + TrimZeros(buffer, length, decimal_point); + buffer[*length] = '\0'; + if ((*length) == 0) { + // The string is empty and the decimal_point thus has no importance. Mimick + // Gay's dtoa and and set it to -fractional_count. + *decimal_point = -fractional_count; + } + return true; +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/dtoa/strtod.cc b/third_party/WebKit/Source/platform/wtf/dtoa/strtod.cc index 3746aa7..8c13eb9c 100644 --- a/third_party/WebKit/Source/platform/wtf/dtoa/strtod.cc +++ b/third_party/WebKit/Source/platform/wtf/dtoa/strtod.cc
@@ -27,420 +27,420 @@ #include "strtod.h" +#include <limits.h> +#include <stdarg.h> #include "bignum.h" #include "cached-powers.h" #include "double.h" -#include <stdarg.h> -#include <limits.h> namespace WTF { namespace double_conversion { - // 2^53 = 9007199254740992. - // Any integer with at most 15 decimal digits will hence fit into a double - // (which has a 53bit significand) without loss of precision. - static const int kMaxExactDoubleIntegerDecimalDigits = 15; - // 2^64 = 18446744073709551616 > 10^19 - static const int kMaxUint64DecimalDigits = 19; +// 2^53 = 9007199254740992. +// Any integer with at most 15 decimal digits will hence fit into a double +// (which has a 53bit significand) without loss of precision. +static const int kMaxExactDoubleIntegerDecimalDigits = 15; +// 2^64 = 18446744073709551616 > 10^19 +static const int kMaxUint64DecimalDigits = 19; - // Max double: 1.7976931348623157 x 10^308 - // Min non-zero double: 4.9406564584124654 x 10^-324 - // Any x >= 10^309 is interpreted as +infinity. - // Any x <= 10^-324 is interpreted as 0. - // Note that 2.5e-324 (despite being smaller than the min double) will be read - // as non-zero (equal to the min non-zero double). - static const int kMaxDecimalPower = 309; - static const int kMinDecimalPower = -324; +// Max double: 1.7976931348623157 x 10^308 +// Min non-zero double: 4.9406564584124654 x 10^-324 +// Any x >= 10^309 is interpreted as +infinity. +// Any x <= 10^-324 is interpreted as 0. +// Note that 2.5e-324 (despite being smaller than the min double) will be read +// as non-zero (equal to the min non-zero double). +static const int kMaxDecimalPower = 309; +static const int kMinDecimalPower = -324; - // 2^64 = 18446744073709551616 - static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF); +// 2^64 = 18446744073709551616 +static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF); +// clang-format off +static const double exact_powers_of_ten[] = { + 1.0, // 10^0 + 10.0, + 100.0, + 1000.0, + 10000.0, + 100000.0, + 1000000.0, + 10000000.0, + 100000000.0, + 1000000000.0, + 10000000000.0, // 10^10 + 100000000000.0, + 1000000000000.0, + 10000000000000.0, + 100000000000000.0, + 1000000000000000.0, + 10000000000000000.0, + 100000000000000000.0, + 1000000000000000000.0, + 10000000000000000000.0, + 100000000000000000000.0, // 10^20 + 1000000000000000000000.0, + // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 + 10000000000000000000000.0}; +// clang-format on - static const double exact_powers_of_ten[] = { - 1.0, // 10^0 - 10.0, - 100.0, - 1000.0, - 10000.0, - 100000.0, - 1000000.0, - 10000000.0, - 100000000.0, - 1000000000.0, - 10000000000.0, // 10^10 - 100000000000.0, - 1000000000000.0, - 10000000000000.0, - 100000000000000.0, - 1000000000000000.0, - 10000000000000000.0, - 100000000000000000.0, - 1000000000000000000.0, - 10000000000000000000.0, - 100000000000000000000.0, // 10^20 - 1000000000000000000000.0, - // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 - 10000000000000000000000.0 - }; - static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten); +static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten); - // Maximum number of significant digits in the decimal representation. - // In fact the value is 772 (see conversions.cc), but to give us some margin - // we round up to 780. - static const int kMaxSignificantDecimalDigits = 780; +// Maximum number of significant digits in the decimal representation. +// In fact the value is 772 (see conversions.cc), but to give us some margin +// we round up to 780. +static const int kMaxSignificantDecimalDigits = 780; - static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) { - for (int i = 0; i < buffer.length(); i++) { - if (buffer[i] != '0') { - return buffer.SubVector(i, buffer.length()); - } - } - return Vector<const char>(buffer.Start(), 0); +static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) { + for (int i = 0; i < buffer.length(); i++) { + if (buffer[i] != '0') { + return buffer.SubVector(i, buffer.length()); } + } + return Vector<const char>(buffer.Start(), 0); +} - - static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) { - for (int i = buffer.length() - 1; i >= 0; --i) { - if (buffer[i] != '0') { - return buffer.SubVector(0, i + 1); - } - } - return Vector<const char>(buffer.Start(), 0); +static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) { + for (int i = buffer.length() - 1; i >= 0; --i) { + if (buffer[i] != '0') { + return buffer.SubVector(0, i + 1); } + } + return Vector<const char>(buffer.Start(), 0); +} +static void TrimToMaxSignificantDigits(Vector<const char> buffer, + int exponent, + char* significant_buffer, + int* significant_exponent) { + for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) { + significant_buffer[i] = buffer[i]; + } + // The input buffer has been trimmed. Therefore the last digit must be + // different from '0'. + DCHECK_NE(buffer[buffer.length() - 1], '0'); + // Set the last digit to be non-zero. This is sufficient to guarantee + // correct rounding. + significant_buffer[kMaxSignificantDecimalDigits - 1] = '1'; + *significant_exponent = + exponent + (buffer.length() - kMaxSignificantDecimalDigits); +} - static void TrimToMaxSignificantDigits(Vector<const char> buffer, - int exponent, - char* significant_buffer, - int* significant_exponent) { - for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) { - significant_buffer[i] = buffer[i]; - } - // The input buffer has been trimmed. Therefore the last digit must be - // different from '0'. - DCHECK_NE(buffer[buffer.length() - 1], '0'); - // Set the last digit to be non-zero. This is sufficient to guarantee - // correct rounding. - significant_buffer[kMaxSignificantDecimalDigits - 1] = '1'; - *significant_exponent = - exponent + (buffer.length() - kMaxSignificantDecimalDigits); +// Reads digits from the buffer and converts them to a uint64. +// Reads in as many digits as fit into a uint64. +// When the string starts with "1844674407370955161" no further digit is read. +// Since 2^64 = 18446744073709551616 it would still be possible read another +// digit if it was less or equal than 6, but this would complicate the code. +static uint64_t ReadUint64(Vector<const char> buffer, + int* number_of_read_digits) { + uint64_t result = 0; + int i = 0; + while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) { + int digit = buffer[i++] - '0'; + DCHECK_LE(0, digit); + DCHECK_LE(digit, 9); + result = 10 * result + digit; + } + *number_of_read_digits = i; + return result; +} + +// Reads a DiyFp from the buffer. +// The returned DiyFp is not necessarily normalized. +// If remaining_decimals is zero then the returned DiyFp is accurate. +// Otherwise it has been rounded and has error of at most 1/2 ulp. +static void ReadDiyFp(Vector<const char> buffer, + DiyFp* result, + int* remaining_decimals) { + int read_digits; + uint64_t significand = ReadUint64(buffer, &read_digits); + if (buffer.length() == read_digits) { + *result = DiyFp(significand, 0); + *remaining_decimals = 0; + } else { + // Round the significand. + if (buffer[read_digits] >= '5') { + significand++; } + // Compute the binary exponent. + int exponent = 0; + *result = DiyFp(significand, exponent); + *remaining_decimals = buffer.length() - read_digits; + } +} - // Reads digits from the buffer and converts them to a uint64. - // Reads in as many digits as fit into a uint64. - // When the string starts with "1844674407370955161" no further digit is read. - // Since 2^64 = 18446744073709551616 it would still be possible read another - // digit if it was less or equal than 6, but this would complicate the code. - static uint64_t ReadUint64(Vector<const char> buffer, - int* number_of_read_digits) { - uint64_t result = 0; - int i = 0; - while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) { - int digit = buffer[i++] - '0'; - DCHECK_LE(0, digit); - DCHECK_LE(digit, 9); - result = 10 * result + digit; - } - *number_of_read_digits = i; - return result; - } - - - // Reads a DiyFp from the buffer. - // The returned DiyFp is not necessarily normalized. - // If remaining_decimals is zero then the returned DiyFp is accurate. - // Otherwise it has been rounded and has error of at most 1/2 ulp. - static void ReadDiyFp(Vector<const char> buffer, - DiyFp* result, - int* remaining_decimals) { - int read_digits; - uint64_t significand = ReadUint64(buffer, &read_digits); - if (buffer.length() == read_digits) { - *result = DiyFp(significand, 0); - *remaining_decimals = 0; - } else { - // Round the significand. - if (buffer[read_digits] >= '5') { - significand++; - } - // Compute the binary exponent. - int exponent = 0; - *result = DiyFp(significand, exponent); - *remaining_decimals = buffer.length() - read_digits; - } - } - - - static bool DoubleStrtod(Vector<const char> trimmed, - int exponent, - double* result) { +static bool DoubleStrtod(Vector<const char> trimmed, + int exponent, + double* result) { #if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS) - // On x86 the floating-point stack can be 64 or 80 bits wide. If it is - // 80 bits wide (as is the case on Linux) then double-rounding occurs and the - // result is not accurate. - // We know that Windows32 uses 64 bits and is therefore accurate. - // Note that the ARM simulator is compiled for 32bits. It therefore exhibits - // the same problem. - return false; + // On x86 the floating-point stack can be 64 or 80 bits wide. If it is + // 80 bits wide (as is the case on Linux) then double-rounding occurs and the + // result is not accurate. + // We know that Windows32 uses 64 bits and is therefore accurate. + // Note that the ARM simulator is compiled for 32bits. It therefore exhibits + // the same problem. + return false; #endif - if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { - int read_digits; - // The trimmed input fits into a double. - // If the 10^exponent (resp. 10^-exponent) fits into a double too then we - // can compute the result-double simply by multiplying (resp. dividing) the - // two numbers. - // This is possible because IEEE guarantees that floating-point operations - // return the best possible approximation. - if (exponent < 0 && -exponent < kExactPowersOfTenSize) { - // 10^-exponent fits into a double. - *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); - DCHECK_EQ(read_digits, trimmed.length()); - *result /= exact_powers_of_ten[-exponent]; - return true; - } - if (0 <= exponent && exponent < kExactPowersOfTenSize) { - // 10^exponent fits into a double. - *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); - DCHECK_EQ(read_digits, trimmed.length()); - *result *= exact_powers_of_ten[exponent]; - return true; - } - int remaining_digits = - kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); - if ((0 <= exponent) && - (exponent - remaining_digits < kExactPowersOfTenSize)) { - // The trimmed string was short and we can multiply it with - // 10^remaining_digits. As a result the remaining exponent now fits - // into a double too. - *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); - DCHECK_EQ(read_digits, trimmed.length()); - *result *= exact_powers_of_ten[remaining_digits]; - *result *= exact_powers_of_ten[exponent - remaining_digits]; - return true; - } - } - return false; + if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { + int read_digits; + // The trimmed input fits into a double. + // If the 10^exponent (resp. 10^-exponent) fits into a double too then we + // can compute the result-double simply by multiplying (resp. dividing) the + // two numbers. + // This is possible because IEEE guarantees that floating-point operations + // return the best possible approximation. + if (exponent < 0 && -exponent < kExactPowersOfTenSize) { + // 10^-exponent fits into a double. + *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); + DCHECK_EQ(read_digits, trimmed.length()); + *result /= exact_powers_of_ten[-exponent]; + return true; } - - - // Returns 10^exponent as an exact DiyFp. - // The given exponent must be in the range [1; kDecimalExponentDistance[. - static DiyFp AdjustmentPowerOfTen(int exponent) { - DCHECK_LT(0, exponent); - DCHECK_LT(exponent, PowersOfTenCache::kDecimalExponentDistance); - // Simply hardcode the remaining powers for the given decimal exponent - // distance. - DCHECK_EQ(PowersOfTenCache::kDecimalExponentDistance, 8); - switch (exponent) { - case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60); - case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57); - case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54); - case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50); - case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47); - case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44); - case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40); - default: - UNREACHABLE(); - return DiyFp(0, 0); - } + if (0 <= exponent && exponent < kExactPowersOfTenSize) { + // 10^exponent fits into a double. + *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); + DCHECK_EQ(read_digits, trimmed.length()); + *result *= exact_powers_of_ten[exponent]; + return true; } - - - // If the function returns true then the result is the correct double. - // Otherwise it is either the correct double or the double that is just below - // the correct double. - static bool DiyFpStrtod(Vector<const char> buffer, - int exponent, - double* result) { - DiyFp input; - int remaining_decimals; - ReadDiyFp(buffer, &input, &remaining_decimals); - // Since we may have dropped some digits the input is not accurate. - // If remaining_decimals is different than 0 than the error is at most - // .5 ulp (unit in the last place). - // We don't want to deal with fractions and therefore keep a common - // denominator. - const int kDenominatorLog = 3; - const int kDenominator = 1 << kDenominatorLog; - // Move the remaining decimals into the exponent. - exponent += remaining_decimals; - int64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2); - - int old_e = input.E(); - input.Normalize(); - error <<= old_e - input.E(); - - DCHECK_LE(exponent, PowersOfTenCache::kMaxDecimalExponent); - if (exponent < PowersOfTenCache::kMinDecimalExponent) { - *result = 0.0; - return true; - } - DiyFp cached_power; - int cached_decimal_exponent; - PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent, - &cached_power, - &cached_decimal_exponent); - - if (cached_decimal_exponent != exponent) { - int adjustment_exponent = exponent - cached_decimal_exponent; - DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent); - input.Multiply(adjustment_power); - if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) { - // The product of input with the adjustment power fits into a 64 bit - // integer. - DCHECK_EQ(DiyFp::kSignificandSize, 64); - } else { - // The adjustment power is exact. There is hence only an error of 0.5. - error += kDenominator / 2; - } - } - - input.Multiply(cached_power); - // The error introduced by a multiplication of a*b equals - // error_a + error_b + error_a*error_b/2^64 + 0.5 - // Substituting a with 'input' and b with 'cached_power' we have - // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp), - // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64 - int error_b = kDenominator / 2; - int error_ab = (error == 0 ? 0 : 1); // We round up to 1. - int fixed_error = kDenominator / 2; - error += error_b + error_ab + fixed_error; - - old_e = input.E(); - input.Normalize(); - error <<= old_e - input.E(); - - // See if the double's significand changes if we add/subtract the error. - int order_of_magnitude = DiyFp::kSignificandSize + input.E(); - int effective_significand_size = - Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude); - int precision_digits_count = - DiyFp::kSignificandSize - effective_significand_size; - if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) { - // This can only happen for very small denormals. In this case the - // half-way multiplied by the denominator exceeds the range of an uint64. - // Simply shift everything to the right. - int shift_amount = (precision_digits_count + kDenominatorLog) - - DiyFp::kSignificandSize + 1; - input.set_f(input.F() >> shift_amount); - input.set_e(input.E() + shift_amount); - // We add 1 for the lost precision of error, and kDenominator for - // the lost precision of input.f(). - error = (error >> shift_amount) + 1 + kDenominator; - precision_digits_count -= shift_amount; - } - // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. - DCHECK_EQ(DiyFp::kSignificandSize, 64); - DCHECK_LT(precision_digits_count, 64); - uint64_t one64 = 1; - uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; - uint64_t precision_bits = input.F() & precision_bits_mask; - uint64_t half_way = one64 << (precision_digits_count - 1); - precision_bits *= kDenominator; - half_way *= kDenominator; - DiyFp rounded_input(input.F() >> precision_digits_count, - input.E() + precision_digits_count); - if (precision_bits >= half_way + error) { - rounded_input.set_f(rounded_input.F() + 1); - } - // If the last_bits are too close to the half-way case than we are too - // inaccurate and round down. In this case we return false so that we can - // fall back to a more precise algorithm. - - *result = Double(rounded_input).Value(); - if (half_way - error < precision_bits && precision_bits < half_way + error) { - // Too imprecise. The caller will have to fall back to a slower version. - // However the returned number is guaranteed to be either the correct - // double, or the next-lower double. - return false; - } else { - return true; - } + int remaining_digits = + kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); + if ((0 <= exponent) && + (exponent - remaining_digits < kExactPowersOfTenSize)) { + // The trimmed string was short and we can multiply it with + // 10^remaining_digits. As a result the remaining exponent now fits + // into a double too. + *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); + DCHECK_EQ(read_digits, trimmed.length()); + *result *= exact_powers_of_ten[remaining_digits]; + *result *= exact_powers_of_ten[exponent - remaining_digits]; + return true; } + } + return false; +} +// Returns 10^exponent as an exact DiyFp. +// The given exponent must be in the range [1; kDecimalExponentDistance[. +static DiyFp AdjustmentPowerOfTen(int exponent) { + DCHECK_LT(0, exponent); + DCHECK_LT(exponent, PowersOfTenCache::kDecimalExponentDistance); + // Simply hardcode the remaining powers for the given decimal exponent + // distance. + DCHECK_EQ(PowersOfTenCache::kDecimalExponentDistance, 8); + switch (exponent) { + case 1: + return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60); + case 2: + return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57); + case 3: + return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54); + case 4: + return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50); + case 5: + return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47); + case 6: + return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44); + case 7: + return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40); + default: + UNREACHABLE(); + return DiyFp(0, 0); + } +} - // Returns the correct double for the buffer*10^exponent. - // The variable guess should be a close guess that is either the correct double - // or its lower neighbor (the nearest double less than the correct one). - // Preconditions: - // buffer.length() + exponent <= kMaxDecimalPower + 1 - // buffer.length() + exponent > kMinDecimalPower - // buffer.length() <= kMaxDecimalSignificantDigits - static double BignumStrtod(Vector<const char> buffer, - int exponent, - double guess) { - if (guess == Double::Infinity()) { - return guess; - } +// If the function returns true then the result is the correct double. +// Otherwise it is either the correct double or the double that is just below +// the correct double. +static bool DiyFpStrtod(Vector<const char> buffer, + int exponent, + double* result) { + DiyFp input; + int remaining_decimals; + ReadDiyFp(buffer, &input, &remaining_decimals); + // Since we may have dropped some digits the input is not accurate. + // If remaining_decimals is different than 0 than the error is at most + // .5 ulp (unit in the last place). + // We don't want to deal with fractions and therefore keep a common + // denominator. + const int kDenominatorLog = 3; + const int kDenominator = 1 << kDenominatorLog; + // Move the remaining decimals into the exponent. + exponent += remaining_decimals; + int64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2); - DiyFp upper_boundary = Double(guess).UpperBoundary(); + int old_e = input.E(); + input.Normalize(); + error <<= old_e - input.E(); - DCHECK_LE(buffer.length() + exponent, kMaxDecimalPower + 1); - DCHECK_GT(buffer.length() + exponent, kMinDecimalPower); - DCHECK_LE(buffer.length(), kMaxSignificantDecimalDigits); - // Make sure that the Bignum will be able to hold all our numbers. - // Our Bignum implementation has a separate field for exponents. Shifts will - // consume at most one bigit (< 64 bits). - // ln(10) == 3.3219... - DCHECK_LT(((kMaxDecimalPower + 1) * 333 / 100), Bignum::kMaxSignificantBits); - Bignum input; - Bignum boundary; - input.AssignDecimalString(buffer); - boundary.AssignUInt64(upper_boundary.F()); - if (exponent >= 0) { - input.MultiplyByPowerOfTen(exponent); - } else { - boundary.MultiplyByPowerOfTen(-exponent); - } - if (upper_boundary.E() > 0) { - boundary.ShiftLeft(upper_boundary.E()); - } else { - input.ShiftLeft(-upper_boundary.E()); - } - int comparison = Bignum::Compare(input, boundary); - if (comparison < 0) { - return guess; - } else if (comparison > 0) { - return Double(guess).NextDouble(); - } else if ((Double(guess).Significand() & 1) == 0) { - // Round towards even. - return guess; - } else { - return Double(guess).NextDouble(); - } + DCHECK_LE(exponent, PowersOfTenCache::kMaxDecimalExponent); + if (exponent < PowersOfTenCache::kMinDecimalExponent) { + *result = 0.0; + return true; + } + DiyFp cached_power; + int cached_decimal_exponent; + PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent, &cached_power, + &cached_decimal_exponent); + + if (cached_decimal_exponent != exponent) { + int adjustment_exponent = exponent - cached_decimal_exponent; + DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent); + input.Multiply(adjustment_power); + if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) { + // The product of input with the adjustment power fits into a 64 bit + // integer. + DCHECK_EQ(DiyFp::kSignificandSize, 64); + } else { + // The adjustment power is exact. There is hence only an error of 0.5. + error += kDenominator / 2; } + } + input.Multiply(cached_power); + // The error introduced by a multiplication of a*b equals + // error_a + error_b + error_a*error_b/2^64 + 0.5 + // Substituting a with 'input' and b with 'cached_power' we have + // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp), + // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64 + int error_b = kDenominator / 2; + int error_ab = (error == 0 ? 0 : 1); // We round up to 1. + int fixed_error = kDenominator / 2; + error += error_b + error_ab + fixed_error; - double Strtod(Vector<const char> buffer, int exponent) { - Vector<const char> left_trimmed = TrimLeadingZeros(buffer); - Vector<const char> trimmed = TrimTrailingZeros(left_trimmed); - exponent += left_trimmed.length() - trimmed.length(); - if (trimmed.length() == 0) return 0.0; - if (trimmed.length() > kMaxSignificantDecimalDigits) { - char significant_buffer[kMaxSignificantDecimalDigits]; - int significant_exponent; - TrimToMaxSignificantDigits(trimmed, exponent, - significant_buffer, &significant_exponent); - return Strtod(Vector<const char>(significant_buffer, - kMaxSignificantDecimalDigits), - significant_exponent); - } - if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) { - return Double::Infinity(); - } - if (exponent + trimmed.length() <= kMinDecimalPower) { - return 0.0; - } + old_e = input.E(); + input.Normalize(); + error <<= old_e - input.E(); - double guess; - if (DoubleStrtod(trimmed, exponent, &guess) || - DiyFpStrtod(trimmed, exponent, &guess)) { - return guess; - } - return BignumStrtod(trimmed, exponent, guess); - } + // See if the double's significand changes if we add/subtract the error. + int order_of_magnitude = DiyFp::kSignificandSize + input.E(); + int effective_significand_size = + Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude); + int precision_digits_count = + DiyFp::kSignificandSize - effective_significand_size; + if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) { + // This can only happen for very small denormals. In this case the + // half-way multiplied by the denominator exceeds the range of an uint64. + // Simply shift everything to the right. + int shift_amount = (precision_digits_count + kDenominatorLog) - + DiyFp::kSignificandSize + 1; + input.set_f(input.F() >> shift_amount); + input.set_e(input.E() + shift_amount); + // We add 1 for the lost precision of error, and kDenominator for + // the lost precision of input.f(). + error = (error >> shift_amount) + 1 + kDenominator; + precision_digits_count -= shift_amount; + } + // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. + DCHECK_EQ(DiyFp::kSignificandSize, 64); + DCHECK_LT(precision_digits_count, 64); + uint64_t one64 = 1; + uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; + uint64_t precision_bits = input.F() & precision_bits_mask; + uint64_t half_way = one64 << (precision_digits_count - 1); + precision_bits *= kDenominator; + half_way *= kDenominator; + DiyFp rounded_input(input.F() >> precision_digits_count, + input.E() + precision_digits_count); + if (precision_bits >= half_way + error) { + rounded_input.set_f(rounded_input.F() + 1); + } + // If the last_bits are too close to the half-way case than we are too + // inaccurate and round down. In this case we return false so that we can + // fall back to a more precise algorithm. + + *result = Double(rounded_input).Value(); + if (half_way - error < precision_bits && precision_bits < half_way + error) { + // Too imprecise. The caller will have to fall back to a slower version. + // However the returned number is guaranteed to be either the correct + // double, or the next-lower double. + return false; + } else { + return true; + } +} + +// Returns the correct double for the buffer*10^exponent. +// The variable guess should be a close guess that is either the correct double +// or its lower neighbor (the nearest double less than the correct one). +// Preconditions: +// buffer.length() + exponent <= kMaxDecimalPower + 1 +// buffer.length() + exponent > kMinDecimalPower +// buffer.length() <= kMaxDecimalSignificantDigits +static double BignumStrtod(Vector<const char> buffer, + int exponent, + double guess) { + if (guess == Double::Infinity()) { + return guess; + } + + DiyFp upper_boundary = Double(guess).UpperBoundary(); + + DCHECK_LE(buffer.length() + exponent, kMaxDecimalPower + 1); + DCHECK_GT(buffer.length() + exponent, kMinDecimalPower); + DCHECK_LE(buffer.length(), kMaxSignificantDecimalDigits); + // Make sure that the Bignum will be able to hold all our numbers. + // Our Bignum implementation has a separate field for exponents. Shifts will + // consume at most one bigit (< 64 bits). + // ln(10) == 3.3219... + DCHECK_LT(((kMaxDecimalPower + 1) * 333 / 100), Bignum::kMaxSignificantBits); + Bignum input; + Bignum boundary; + input.AssignDecimalString(buffer); + boundary.AssignUInt64(upper_boundary.F()); + if (exponent >= 0) { + input.MultiplyByPowerOfTen(exponent); + } else { + boundary.MultiplyByPowerOfTen(-exponent); + } + if (upper_boundary.E() > 0) { + boundary.ShiftLeft(upper_boundary.E()); + } else { + input.ShiftLeft(-upper_boundary.E()); + } + int comparison = Bignum::Compare(input, boundary); + if (comparison < 0) { + return guess; + } else if (comparison > 0) { + return Double(guess).NextDouble(); + } else if ((Double(guess).Significand() & 1) == 0) { + // Round towards even. + return guess; + } else { + return Double(guess).NextDouble(); + } +} + +double Strtod(Vector<const char> buffer, int exponent) { + Vector<const char> left_trimmed = TrimLeadingZeros(buffer); + Vector<const char> trimmed = TrimTrailingZeros(left_trimmed); + exponent += left_trimmed.length() - trimmed.length(); + if (trimmed.length() == 0) + return 0.0; + if (trimmed.length() > kMaxSignificantDecimalDigits) { + char significant_buffer[kMaxSignificantDecimalDigits]; + int significant_exponent; + TrimToMaxSignificantDigits(trimmed, exponent, significant_buffer, + &significant_exponent); + return Strtod( + Vector<const char>(significant_buffer, kMaxSignificantDecimalDigits), + significant_exponent); + } + if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) { + return Double::Infinity(); + } + if (exponent + trimmed.length() <= kMinDecimalPower) { + return 0.0; + } + + double guess; + if (DoubleStrtod(trimmed, exponent, &guess) || + DiyFpStrtod(trimmed, exponent, &guess)) { + return guess; + } + return BignumStrtod(trimmed, exponent, guess); +} } // namespace double_conversion -} // namespace WTF +} // namespace WTF
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp b/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp index 2076edf..cb399fe 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.cpp
@@ -247,14 +247,7 @@ } TextCodecICU::TextCodecICU(const TextEncoding& encoding) - : encoding_(encoding), - converter_icu_(0) -#if defined(USING_SYSTEM_ICU) - , - m_needsGBKFallbacks(false) -#endif -{ -} + : encoding_(encoding) {} TextCodecICU::~TextCodecICU() { ReleaseICUConverter(); @@ -266,7 +259,7 @@ if (cached_converter) ucnv_close(cached_converter); cached_converter = converter_icu_; - converter_icu_ = 0; + converter_icu_ = nullptr; } } @@ -275,7 +268,7 @@ #if defined(USING_SYSTEM_ICU) const char* name = encoding_.GetName(); - m_needsGBKFallbacks = + needs_gbk_fallbacks_ = name[0] == 'G' && name[1] == 'B' && name[2] == 'K' && !name[3]; #endif @@ -416,7 +409,7 @@ #if defined(USING_SYSTEM_ICU) // U+01F9 and U+1E3F have to be mapped to xA8xBF and xA8xBC per the encoding // spec, but ICU converter does not have them. -static UChar fallbackForGBK(UChar32 character) { +static UChar FallbackForGBK(UChar32 character) { switch (character) { case 0x01F9: return 0xE7C8; // mapped to xA8xBF by ICU. @@ -494,86 +487,88 @@ #if defined(USING_SYSTEM_ICU) // Substitutes special GBK characters, escaping all other unassigned entities. -static void gbkCallbackEscape(const void* context, - UConverterFromUnicodeArgs* fromUArgs, - const UChar* codeUnits, +static void GbkCallbackEscape(const void* context, + UConverterFromUnicodeArgs* from_unicode_args, + const UChar* code_units, int32_t length, - UChar32 codePoint, + UChar32 code_point, UConverterCallbackReason reason, UErrorCode* err) { - UChar outChar; - if (reason == UCNV_UNASSIGNED && (outChar = fallbackForGBK(codePoint))) { - const UChar* source = &outChar; + UChar out_char; + if (reason == UCNV_UNASSIGNED && (out_char = FallbackForGBK(code_point))) { + const UChar* source = &out_char; *err = U_ZERO_ERROR; - ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); + ucnv_cbFromUWriteUChars(from_unicode_args, &source, source + 1, 0, err); return; } - NumericEntityCallback(context, fromUArgs, codeUnits, length, codePoint, - reason, err); + NumericEntityCallback(context, from_unicode_args, code_units, length, + code_point, reason, err); } // Combines both gbkCssEscapedEntityCallback and GBK character substitution. -static void gbkCssEscapedEntityCallack(const void* context, - UConverterFromUnicodeArgs* fromUArgs, - const UChar* codeUnits, - int32_t length, - UChar32 codePoint, - UConverterCallbackReason reason, - UErrorCode* err) { +static void GbkCssEscapedEntityCallack( + const void* context, + UConverterFromUnicodeArgs* from_unicode_args, + const UChar* code_units, + int32_t length, + UChar32 code_point, + UConverterCallbackReason reason, + UErrorCode* err) { if (reason == UCNV_UNASSIGNED) { - if (UChar outChar = fallbackForGBK(codePoint)) { - const UChar* source = &outChar; + if (UChar out_char = FallbackForGBK(code_point)) { + const UChar* source = &out_char; *err = U_ZERO_ERROR; - ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); + ucnv_cbFromUWriteUChars(from_unicode_args, &source, source + 1, 0, err); return; } - CssEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, - reason, err); + CssEscapedEntityCallback(context, from_unicode_args, code_units, length, + code_point, reason, err); return; } - UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, - reason, err); + UCNV_FROM_U_CALLBACK_ESCAPE(context, from_unicode_args, code_units, length, + code_point, reason, err); } // Combines both gbkUrlEscapedEntityCallback and GBK character substitution. -static void gbkUrlEscapedEntityCallack(const void* context, - UConverterFromUnicodeArgs* fromUArgs, - const UChar* codeUnits, - int32_t length, - UChar32 codePoint, - UConverterCallbackReason reason, - UErrorCode* err) { +static void GbkUrlEscapedEntityCallack( + const void* context, + UConverterFromUnicodeArgs* from_unicode_args, + const UChar* code_units, + int32_t length, + UChar32 code_point, + UConverterCallbackReason reason, + UErrorCode* err) { if (reason == UCNV_UNASSIGNED) { - if (UChar outChar = fallbackForGBK(codePoint)) { - const UChar* source = &outChar; + if (UChar out_char = FallbackForGBK(code_point)) { + const UChar* source = &out_char; *err = U_ZERO_ERROR; - ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); + ucnv_cbFromUWriteUChars(from_unicode_args, &source, source + 1, 0, err); return; } - UrlEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, - reason, err); + UrlEscapedEntityCallback(context, from_unicode_args, code_units, length, + code_point, reason, err); return; } - UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, - reason, err); + UCNV_FROM_U_CALLBACK_ESCAPE(context, from_unicode_args, code_units, length, + code_point, reason, err); } -static void gbkCallbackSubstitute(const void* context, - UConverterFromUnicodeArgs* fromUArgs, - const UChar* codeUnits, +static void GbkCallbackSubstitute(const void* context, + UConverterFromUnicodeArgs* from_unicode_args, + const UChar* code_units, int32_t length, - UChar32 codePoint, + UChar32 code_point, UConverterCallbackReason reason, UErrorCode* err) { - UChar outChar; - if (reason == UCNV_UNASSIGNED && (outChar = fallbackForGBK(codePoint))) { - const UChar* source = &outChar; + UChar out_char; + if (reason == UCNV_UNASSIGNED && (out_char = FallbackForGBK(code_point))) { + const UChar* source = &out_char; *err = U_ZERO_ERROR; - ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); + ucnv_cbFromUWriteUChars(from_unicode_args, &source, source + 1, 0, err); return; } - UCNV_FROM_U_CALLBACK_SUBSTITUTE(context, fromUArgs, codeUnits, length, - codePoint, reason, err); + UCNV_FROM_U_CALLBACK_SUBSTITUTE(context, from_unicode_args, code_units, + length, code_point, reason, err); } #endif // USING_SYSTEM_ICU @@ -623,10 +618,11 @@ ucnv_setFromUCallBack(converter_icu_, UCNV_FROM_U_CALLBACK_SUBSTITUTE, 0, 0, 0, &err); #else - ucnv_setFromUCallBack( - converter_icu_, m_needsGBKFallbacks ? gbkCallbackSubstitute - : UCNV_FROM_U_CALLBACK_SUBSTITUTE, - 0, 0, 0, &err); + ucnv_setFromUCallBack(converter_icu_, + needs_gbk_fallbacks_ + ? GbkCallbackSubstitute + : UCNV_FROM_U_CALLBACK_SUBSTITUTE, + 0, 0, 0, &err); #endif break; case kEntitiesForUnencodables: @@ -636,8 +632,8 @@ #else ucnv_setFromUCallBack( converter_icu_, - m_needsGBKFallbacks ? gbkCallbackEscape : NumericEntityCallback, 0, 0, - 0, &err); + needs_gbk_fallbacks_ ? GbkCallbackEscape : NumericEntityCallback, 0, + 0, 0, &err); #endif break; case kURLEncodedEntitiesForUnencodables: @@ -646,8 +642,8 @@ &err); #else ucnv_setFromUCallBack(converter_icu_, - m_needsGBKFallbacks ? gbkUrlEscapedEntityCallack - : UrlEscapedEntityCallback, + needs_gbk_fallbacks_ ? GbkUrlEscapedEntityCallack + : UrlEscapedEntityCallback, 0, 0, 0, &err); #endif break; @@ -657,8 +653,8 @@ &err); #else ucnv_setFromUCallBack(converter_icu_, - m_needsGBKFallbacks ? gbkCssEscapedEntityCallack - : CssEscapedEntityCallback, + needs_gbk_fallbacks_ ? GbkCssEscapedEntityCallack + : CssEscapedEntityCallback, 0, 0, 0, &err); #endif break;
diff --git a/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.h b/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.h index 83f4ac0..f983a9a 100644 --- a/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.h +++ b/third_party/WebKit/Source/platform/wtf/text/TextCodecICU.h
@@ -65,12 +65,6 @@ void CreateICUConverter() const; void ReleaseICUConverter() const; -#if defined(USING_SYSTEM_ICU) - bool needsGBKFallbacks() const { return m_needsGBKFallbacks; } - void setNeedsGBKFallbacks(bool needsFallbacks) { - m_needsGBKFallbacks = needsFallbacks; - } -#endif int DecodeToBuffer(UChar* buffer, UChar* buffer_limit, @@ -81,9 +75,9 @@ UErrorCode&); TextEncoding encoding_; - mutable UConverter* converter_icu_; + mutable UConverter* converter_icu_ = nullptr; #if defined(USING_SYSTEM_ICU) - mutable bool m_needsGBKFallbacks; + mutable bool needs_gbk_fallbacks_ = false; #endif FRIEND_TEST_ALL_PREFIXES(TextCodecICUTest, IgnorableCodePoint);
diff --git a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp index 566fa93..2895655b 100644 --- a/third_party/WebKit/Source/web/AssertMatchingEnums.cpp +++ b/third_party/WebKit/Source/web/AssertMatchingEnums.cpp
@@ -134,7 +134,6 @@ #include "public/web/WebSpeechRecognizerClient.h" #include "public/web/WebTextCheckingResult.h" #include "public/web/WebTextDecorationType.h" -#include "public/web/WebTouchAction.h" #include "public/web/WebView.h" namespace blink { @@ -797,19 +796,6 @@ STATIC_ASSERT_ENUM(kWebCustomHandlersDeclined, NavigatorContentUtilsClient::kCustomHandlersDeclined); -STATIC_ASSERT_ENUM(kWebTouchActionNone, kTouchActionNone); -STATIC_ASSERT_ENUM(kWebTouchActionPanLeft, kTouchActionPanLeft); -STATIC_ASSERT_ENUM(kWebTouchActionPanRight, kTouchActionPanRight); -STATIC_ASSERT_ENUM(kWebTouchActionPanX, kTouchActionPanX); -STATIC_ASSERT_ENUM(kWebTouchActionPanUp, kTouchActionPanUp); -STATIC_ASSERT_ENUM(kWebTouchActionPanDown, kTouchActionPanDown); -STATIC_ASSERT_ENUM(kWebTouchActionPanY, kTouchActionPanY); -STATIC_ASSERT_ENUM(kWebTouchActionPan, kTouchActionPan); -STATIC_ASSERT_ENUM(kWebTouchActionPinchZoom, kTouchActionPinchZoom); -STATIC_ASSERT_ENUM(kWebTouchActionManipulation, kTouchActionManipulation); -STATIC_ASSERT_ENUM(kWebTouchActionDoubleTapZoom, kTouchActionDoubleTapZoom); -STATIC_ASSERT_ENUM(kWebTouchActionAuto, kTouchActionAuto); - STATIC_ASSERT_ENUM(WebSelection::kNoSelection, kNoSelection); STATIC_ASSERT_ENUM(WebSelection::kCaretSelection, kCaretSelection); STATIC_ASSERT_ENUM(WebSelection::kRangeSelection, kRangeSelection);
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn index f71b28f3..d600f48 100644 --- a/third_party/WebKit/Source/web/BUILD.gn +++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -123,17 +123,7 @@ "ValidationMessageClientImpl.cpp", "ValidationMessageClientImpl.h", "WebAXObject.cpp", - "WebCSSParser.cpp", - "WebColorSuggestion.cpp", - "WebCryptoNormalize.cpp", - "WebCustomElement.cpp", - "WebDOMActivityLogger.cpp", - "WebDOMEvent.cpp", - "WebDOMFileSystem.cpp", - "WebDOMMediaStreamTrack.cpp", "WebDOMMessageEvent.cpp", - "WebDatabase.cpp", - "WebDateTimeSuggestion.cpp", "WebDevToolsAgentImpl.cpp", "WebDevToolsAgentImpl.h", "WebDevToolsFrontendImpl.cpp", @@ -144,8 +134,6 @@ "WebEmbeddedWorkerImpl.cpp", "WebEmbeddedWorkerImpl.h", "WebExport.h", - "WebFileChooserCompletionImpl.cpp", - "WebFileChooserCompletionImpl.h", "WebFormControlElement.cpp", "WebFormElement.cpp", "WebFrame.cpp", @@ -158,15 +146,12 @@ "WebFrameWidgetBase.h", "WebFrameWidgetImpl.cpp", "WebFrameWidgetImpl.h", - "WebHeap.cpp", "WebHelperPluginImpl.cpp", "WebHelperPluginImpl.h", "WebHistoryItem.cpp", "WebHitTestResult.cpp", "WebIDBKey.cpp", "WebIDBKeyRange.cpp", - "WebImageCache.cpp", - "WebImageDecoder.cpp", "WebInputElement.cpp", "WebInputEvent.cpp", "WebInputEventConversion.cpp",
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp index c557bf4..fde3271 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp +++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -39,6 +39,7 @@ #include "core/dom/Fullscreen.h" #include "core/dom/Node.h" #include "core/events/UIEventWithKeyState.h" +#include "core/exported/WebFileChooserCompletionImpl.h" #include "core/exported/WebViewBase.h" #include "core/frame/FrameView.h" #include "core/frame/Settings.h" @@ -74,6 +75,7 @@ #include "platform/exported/WrappedResourceRequest.h" #include "platform/geometry/IntRect.h" #include "platform/graphics/GraphicsLayer.h" +#include "platform/graphics/TouchAction.h" #include "platform/scheduler/renderer/web_view_scheduler.h" #include "platform/weborigin/SecurityOrigin.h" #include "platform/wtf/Optional.h" @@ -102,7 +104,6 @@ #include "public/web/WebSelection.h" #include "public/web/WebSettings.h" #include "public/web/WebTextDirection.h" -#include "public/web/WebTouchAction.h" #include "public/web/WebUserGestureIndicator.h" #include "public/web/WebUserGestureToken.h" #include "public/web/WebViewClient.h" @@ -118,7 +119,6 @@ #include "web/LocalFileSystemClient.h" #include "web/NavigatorContentUtilsClientImpl.h" #include "web/PopupMenuImpl.h" -#include "web/WebFileChooserCompletionImpl.h" #include "web/WebFrameWidgetImpl.h" #include "web/WebInputEventConversion.h" #include "web/WebLocalFrameImpl.h" @@ -1060,7 +1060,7 @@ return; if (WebWidgetClient* client = widget->Client()) - client->SetTouchAction(static_cast<WebTouchAction>(touch_action)); + client->SetTouchAction(static_cast<TouchAction>(touch_action)); } bool ChromeClientImpl::RequestPointerLock(LocalFrame* frame) {
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.h b/third_party/WebKit/Source/web/ChromeClientImpl.h index 9db76e7..eca5580 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.h +++ b/third_party/WebKit/Source/web/ChromeClientImpl.h
@@ -32,11 +32,12 @@ #ifndef ChromeClientImpl_h #define ChromeClientImpl_h +#include <memory> #include "core/page/ChromeClient.h" #include "core/page/WindowFeatures.h" +#include "platform/graphics/TouchAction.h" #include "public/web/WebNavigationPolicy.h" #include "web/WebExport.h" -#include <memory> namespace blink {
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 32bfe0a..854caa6 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -2760,7 +2760,7 @@ // not to zoom in if the user won't be able to zoom out. e.g if the textbox // is within a touch-action: none container the user can't zoom back out. TouchAction action = TouchActionUtil::ComputeEffectiveTouchAction(*element); - if (!(action & kTouchActionPinchZoom)) + if (!(action & TouchAction::kTouchActionPinchZoom)) zoom_in_to_legible_scale = false; }
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index 5718d39d8..b681fe6 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -40,6 +40,7 @@ #include "platform/geometry/IntPoint.h" #include "platform/geometry/IntRect.h" #include "platform/graphics/GraphicsLayer.h" +#include "platform/graphics/TouchAction.h" #include "platform/heap/Handle.h" #include "platform/scheduler/child/web_scheduler.h" #include "platform/wtf/Compiler.h"
diff --git a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp index 7f83f42..bde7fcf 100644 --- a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp +++ b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
@@ -42,6 +42,7 @@ #include "core/layout/HitTestResult.h" #include "core/layout/LayoutTreeAsText.h" #include "core/layout/api/LayoutViewItem.h" +#include "platform/graphics/TouchAction.h" #include "platform/testing/URLTestHelpers.h" #include "platform/testing/UnitTestHelpers.h" #include "public/platform/Platform.h" @@ -51,7 +52,6 @@ #include "public/web/WebDocument.h" #include "public/web/WebFrame.h" #include "public/web/WebHitTestResult.h" -#include "public/web/WebTouchAction.h" #include "public/web/WebView.h" #include "public/web/WebViewClient.h" #include "public/web/WebWidgetClient.h" @@ -66,10 +66,10 @@ : public FrameTestHelpers::TestWebWidgetClient { public: TouchActionTrackingWebWidgetClient() - : action_set_count_(0), action_(kWebTouchActionAuto) {} + : action_set_count_(0), action_(TouchAction::kTouchActionAuto) {} // WebWidgetClient methods - void SetTouchAction(WebTouchAction touch_action) override { + void SetTouchAction(TouchAction touch_action) override { action_set_count_++; action_ = touch_action; } @@ -77,16 +77,16 @@ // Local methods void Reset() { action_set_count_ = 0; - action_ = kWebTouchActionAuto; + action_ = TouchAction::kTouchActionAuto; } int TouchActionSetCount() { return action_set_count_; } - WebTouchAction LastTouchAction() { return action_; } + TouchAction LastTouchAction() { return action_; } private: int action_set_count_; - WebTouchAction action_; + TouchAction action_; }; const int kKfakeTouchId = 7; @@ -339,26 +339,27 @@ if (expected_action == "auto") { // Auto is the default - no action set. EXPECT_EQ(0, client.TouchActionSetCount()) << failure_context_pos; - EXPECT_EQ(kWebTouchActionAuto, client.LastTouchAction()) + EXPECT_EQ(TouchAction::kTouchActionAuto, client.LastTouchAction()) << failure_context_pos; } else { // Should have received exactly one touch action. EXPECT_EQ(1, client.TouchActionSetCount()) << failure_context_pos; if (client.TouchActionSetCount()) { if (expected_action == "none") { - EXPECT_EQ(kWebTouchActionNone, client.LastTouchAction()) + EXPECT_EQ(TouchAction::kTouchActionNone, client.LastTouchAction()) << failure_context_pos; } else if (expected_action == "pan-x") { - EXPECT_EQ(kWebTouchActionPanX, client.LastTouchAction()) + EXPECT_EQ(TouchAction::kTouchActionPanX, client.LastTouchAction()) << failure_context_pos; } else if (expected_action == "pan-y") { - EXPECT_EQ(kWebTouchActionPanY, client.LastTouchAction()) + EXPECT_EQ(TouchAction::kTouchActionPanY, client.LastTouchAction()) << failure_context_pos; } else if (expected_action == "pan-x-y") { - EXPECT_EQ((kWebTouchActionPan), client.LastTouchAction()) + EXPECT_EQ((TouchAction::kTouchActionPan), client.LastTouchAction()) << failure_context_pos; } else if (expected_action == "manipulation") { - EXPECT_EQ((kWebTouchActionManipulation), client.LastTouchAction()) + EXPECT_EQ((TouchAction::kTouchActionManipulation), + client.LastTouchAction()) << failure_context_pos; } else { FAIL() << "Unrecognized expected-action \""
diff --git a/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp b/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp index a61af48..1176d909 100644 --- a/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp +++ b/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp
@@ -61,7 +61,8 @@ // hard time limit. void RunTasksForPeriod(double delay_ms) { Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostDelayedTask( - BLINK_FROM_HERE, WTF::Bind(&QuitRunLoop), delay_ms); + BLINK_FROM_HERE, WTF::Bind(&QuitRunLoop), + TimeDelta::FromMillisecondsD(delay_ms)); testing::EnterRunLoop(); } } @@ -223,7 +224,7 @@ WebViewScheduler::VirtualTimePolicy::PAUSE); }, WTF::Unretained(WebView().Scheduler())), - 1000); + TimeDelta::FromMilliseconds(1000)); // ALso schedule a second timer for the same point in time. ExecuteJavaScript("setTimeout(() => { run_order.push(2); }, 1000);");
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp index 194bd45..d4c6a21 100644 --- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp +++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -781,8 +781,9 @@ // Ensure the scroll layer matches the frame view's size. EXPECT_SIZE_EQ(FloatSize(320, 240), visual_viewport.ScrollLayer()->Size()); - EXPECT_EQ(static_cast<int>(CompositorSubElementId::kViewport), - visual_viewport.ScrollLayer()->GetElementId().secondaryId); + EXPECT_EQ(CompositorSubElementId::kViewport, + SubElementIdFromCompositorElementId( + visual_viewport.ScrollLayer()->GetElementId())); // Ensure the location and scale were reset. EXPECT_SIZE_EQ(FloatSize(), visual_viewport.GetScrollOffset());
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index 2425e40..face788 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -19,6 +19,7 @@ ] deps = [ "//third_party/WebKit/Source/core", + "//third_party/WebKit/Source/modules", "//third_party/WebKit/Source/platform", "//third_party/WebKit/Source/web", ] @@ -335,6 +336,7 @@ "platform/WebThread.h", "platform/WebThreadSafeData.h", "platform/WebTimeRange.h", + "platform/WebTouchAction.h", "platform/WebTouchEvent.h", "platform/WebTouchPoint.h", "platform/WebTraceLocation.h", @@ -592,7 +594,6 @@ "web/WebTextDecorationType.h", "web/WebTextDirection.h", "web/WebTextInputType.h", - "web/WebTouchAction.h", "web/WebTreeScopeType.h", "web/WebUserGestureIndicator.h", "web/WebUserGestureToken.h",
diff --git a/third_party/WebKit/public/platform/WebTouchAction.h b/third_party/WebKit/public/platform/WebTouchAction.h new file mode 100644 index 0000000..88bd63c --- /dev/null +++ b/third_party/WebKit/public/platform/WebTouchAction.h
@@ -0,0 +1,19 @@ +// Copyright 2017 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 WebTouchAction_h +#define WebTouchAction_h + +#include "cc/input/touch_action.h" + +namespace blink { + +// The only reason of creating a WebTouchAction is that there is a virtual +// function under WebWidgetClient that is overridden by classes under content/ +// and WebKit/. +using WebTouchAction = cc::TouchAction; + +} // namespace blink + +#endif // WebTouchAction_h
diff --git a/third_party/WebKit/public/web/WebColorSuggestion.h b/third_party/WebKit/public/web/WebColorSuggestion.h index ff3fa69..018bad1f 100644 --- a/third_party/WebKit/public/web/WebColorSuggestion.h +++ b/third_party/WebKit/public/web/WebColorSuggestion.h
@@ -43,8 +43,8 @@ WebString label; #if BLINK_IMPLEMENTATION - WebColorSuggestion(const ColorSuggestion&); - WebColorSuggestion& operator=(const ColorSuggestion&); + BLINK_EXPORT WebColorSuggestion(const ColorSuggestion&); + BLINK_EXPORT WebColorSuggestion& operator=(const ColorSuggestion&); #endif };
diff --git a/third_party/WebKit/public/web/WebDOMEvent.h b/third_party/WebKit/public/web/WebDOMEvent.h index 71ce822e..1813e45 100644 --- a/third_party/WebKit/public/web/WebDOMEvent.h +++ b/third_party/WebKit/public/web/WebDOMEvent.h
@@ -55,8 +55,8 @@ bool IsNull() const { return private_.IsNull(); } #if BLINK_IMPLEMENTATION - WebDOMEvent(Event*); - operator Event*() const; + BLINK_EXPORT WebDOMEvent(Event*); + BLINK_EXPORT operator Event*() const; #endif template <typename T>
diff --git a/third_party/WebKit/public/web/WebDateTimeSuggestion.h b/third_party/WebKit/public/web/WebDateTimeSuggestion.h index 314cd10..60997ff 100644 --- a/third_party/WebKit/public/web/WebDateTimeSuggestion.h +++ b/third_party/WebKit/public/web/WebDateTimeSuggestion.h
@@ -26,6 +26,7 @@ #ifndef WebDateTimeSuggestion_h #define WebDateTimeSuggestion_h +#include "public/platform/WebCommon.h" #include "public/platform/WebString.h" namespace blink { @@ -40,8 +41,8 @@ WebDateTimeSuggestion() {} #if BLINK_IMPLEMENTATION - WebDateTimeSuggestion(const DateTimeSuggestion&); - WebDateTimeSuggestion& operator=(const DateTimeSuggestion&); + BLINK_EXPORT WebDateTimeSuggestion(const DateTimeSuggestion&); + BLINK_EXPORT WebDateTimeSuggestion& operator=(const DateTimeSuggestion&); #endif };
diff --git a/third_party/WebKit/public/web/WebTouchAction.h b/third_party/WebKit/public/web/WebTouchAction.h deleted file mode 100644 index 8a6552233..0000000 --- a/third_party/WebKit/public/web/WebTouchAction.h +++ /dev/null
@@ -1,68 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebTouchAction_h -#define WebTouchAction_h - -namespace blink { - -// Flags for permitted touch actions, specified in -// http://w3c.github.io/pointerevents/#the-touch-action-css-property. -enum WebTouchAction { - kWebTouchActionNone = 0x0, - kWebTouchActionPanLeft = 0x1, - kWebTouchActionPanRight = 0x2, - kWebTouchActionPanX = kWebTouchActionPanLeft | kWebTouchActionPanRight, - kWebTouchActionPanUp = 0x4, - kWebTouchActionPanDown = 0x8, - kWebTouchActionPanY = kWebTouchActionPanUp | kWebTouchActionPanDown, - kWebTouchActionPan = kWebTouchActionPanX | kWebTouchActionPanY, - kWebTouchActionPinchZoom = 0x10, - kWebTouchActionManipulation = kWebTouchActionPan | kWebTouchActionPinchZoom, - kWebTouchActionDoubleTapZoom = 0x20, - kWebTouchActionAuto = - kWebTouchActionManipulation | kWebTouchActionDoubleTapZoom -}; -inline WebTouchAction operator|(WebTouchAction a, WebTouchAction b) { - return static_cast<WebTouchAction>(int(a) | int(b)); -} -inline WebTouchAction& operator|=(WebTouchAction& a, WebTouchAction b) { - return a = a | b; -} -inline WebTouchAction operator&(WebTouchAction a, WebTouchAction b) { - return static_cast<WebTouchAction>(int(a) & int(b)); -} -inline WebTouchAction& operator&=(WebTouchAction& a, WebTouchAction b) { - return a = a & b; -} - -} // namespace blink - -#endif
diff --git a/third_party/WebKit/public/web/WebWidgetClient.h b/third_party/WebKit/public/web/WebWidgetClient.h index 28e941f7..cd62e3384 100644 --- a/third_party/WebKit/public/web/WebWidgetClient.h +++ b/third_party/WebKit/public/web/WebWidgetClient.h
@@ -39,9 +39,9 @@ #include "public/platform/WebRect.h" #include "public/platform/WebReferrerPolicy.h" #include "public/platform/WebScreenInfo.h" +#include "public/platform/WebTouchAction.h" #include "public/web/WebMeaningfulLayout.h" #include "public/web/WebTextDirection.h" -#include "public/web/WebTouchAction.h" namespace blink {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a05ea63..b5c057f7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -14926,6 +14926,7 @@ <int value="1970" label="GATTServerDisconnectedEvent"/> <int value="1971" label="AnchorClickDispatchForNonConnectedNode"/> <int value="1972" label="HTMLParseErrorNestedForm"/> + <int value="1973" label="FontShapingNotDefGlyphObserved"/> </enum> <enum name="FeedbackSource" type="int">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 425d72e..4771494 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -71585,6 +71585,26 @@ </summary> </histogram> +<histogram name="SubresourceFilter.DocumentLoad.ActivationComputingDelay" + units="microseconds"> + <owner>csharrison@chromium.org</owner> + <summary> + Records the total time the activation state navigation throttle within a + document is delayed while calculating activation. Recorded at resume time. + </summary> +</histogram> + +<histogram + name="SubresourceFilter.DocumentLoad.ActivationComputingDelay.MainFrame" + units="microseconds"> + <owner>csharrison@chromium.org</owner> + <summary> + Records the total time the activation state navigation throttle within a + main frame document is delayed while calculating activation. Recorded at + resume time. + </summary> +</histogram> + <histogram name="SubresourceFilter.DocumentLoad.ActivationState" enum="SubresourceFilterActivationState"> <owner>engedy@chromium.org</owner> @@ -71648,6 +71668,27 @@ </summary> </histogram> +<histogram name="SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Allowed" + units="microseconds"> + <owner>csharrison@chromium.org</owner> + <summary> + Records the total time a subframe navigation was delayed while calculating + whether it should be disallowed or not. Logged for all navigations that were + allowed. + </summary> +</histogram> + +<histogram + name="SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed" + units="microseconds"> + <owner>csharrison@chromium.org</owner> + <summary> + Records the total time a subframe navigation was delayed while calculating + whether it should be disallowed or not. Logged for all navigations that were + disallowed. + </summary> +</histogram> + <histogram name="SubresourceFilter.DocumentLoad.SubresourceEvaluation.TotalCPUDuration" units="microseconds">
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index f128fe4..f7d0341 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -64,7 +64,7 @@ page_cycler_v2.top_10_mobile,"kouhei@chromium.org, ksakamoto@chromium.org", page_cycler_v2.typical_25,"kouhei@chromium.org, ksakamoto@chromium.org", page_cycler_v2_site_isolation.basic_oopif,nasko@chromium.org, -performance_browser_tests,"hubbe@chromium.org, justinlin@chromium.org, miu@chromium.org", +performance_browser_tests,miu@chromium.org, power.android_acceptance,perezju@chromium.org, power.idle_platform,, power.steady_state,,
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index f208cc7..f5ec294 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -444,7 +444,10 @@ 'pool': 'Chrome-perf', 'device_ids': [ 'build4-b1', 'build5-b1', 'build6-b1', 'build7-b1', 'build8-b1' - ] + ], + 'perf_tests': [ + ('performance_browser_tests', 'build8-b1') + ] } ]) waterfall = add_tester( @@ -458,7 +461,10 @@ 'device_ids': [ 'build128-b1', 'build129-b1', 'build130-b1', 'build131-b1', 'build132-b1' - ] + ], + 'perf_tests': [ + ('performance_browser_tests', 'build132-b1') + ] } ]) waterfall = add_tester( @@ -472,7 +478,10 @@ 'device_ids': [ 'build123-b1', 'build124-b1', 'build125-b1', 'build126-b1', 'build127-b1' - ] + ], + 'perf_tests': [ + ('performance_browser_tests', 'build126-b1') + ] } ]) waterfall = add_tester( @@ -830,8 +839,7 @@ 'load_library_perf_tests': BenchmarkMetadata(None, None, False), 'media_perftests': BenchmarkMetadata('crouleau@chromium.org', None, False), 'performance_browser_tests': BenchmarkMetadata( - 'hubbe@chromium.org, justinlin@chromium.org, miu@chromium.org', None, - False) + 'miu@chromium.org', None, False) }
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc index 6d2d7c25e..15e51a0 100644 --- a/ui/android/view_android.cc +++ b/ui/android/view_android.cc
@@ -104,10 +104,8 @@ ScopedJavaLocalRef<jobject> ViewAndroid::GetEventForwarder() { if (!event_forwarder_) { - DCHECK(!RootPathHasEventForwarder(parent_)) - << "The view tree path already has an event forwarder."; - DCHECK(!SubtreeHasEventForwarder(this)) - << "The view tree path already has an event forwarder."; + DCHECK(!ViewTreeHasEventForwarder(this)) + << "Root of the ViewAndroid can have at most one handler."; event_forwarder_.reset(new EventForwarder(this)); } return event_forwarder_->GetJavaObject(); @@ -117,9 +115,8 @@ DCHECK(child); DCHECK(std::find(children_.begin(), children_.end(), child) == children_.end()); - DCHECK(!RootPathHasEventForwarder(this) || !SubtreeHasEventForwarder(child)) - << "Some view tree path will have more than one event forwarder " - "if the child is added."; + DCHECK(!SubtreeHasEventForwarder(child) || !ViewTreeHasEventForwarder(this)) + << "Only one event handler is allowed."; // The new child goes to the top, which is the end of the list. children_.push_back(child); @@ -129,21 +126,20 @@ } // static -bool ViewAndroid::RootPathHasEventForwarder(ViewAndroid* view) { - while (view) { - if (view->has_event_forwarder()) +bool ViewAndroid::ViewTreeHasEventForwarder(ViewAndroid* view) { + ViewAndroid* v = view; + do { + if (v->has_event_forwarder()) return true; - view = view->parent_; - } - - return false; + v = v->parent_; + } while (v); + return SubtreeHasEventForwarder(view); } // static bool ViewAndroid::SubtreeHasEventForwarder(ViewAndroid* view) { if (view->has_event_forwarder()) return true; - for (auto* child : view->children_) { if (SubtreeHasEventForwarder(child)) return true;
diff --git a/ui/android/view_android.h b/ui/android/view_android.h index 0fdc598..fbd3c45 100644 --- a/ui/android/view_android.h +++ b/ui/android/view_android.h
@@ -178,11 +178,11 @@ bool has_event_forwarder() const { return !!event_forwarder_; } - // Checks if there is any event forwarder in any node up to root. - static bool RootPathHasEventForwarder(ViewAndroid* view); + // Returns true if any node of the tree along the hierarchy (view's children + // and parents) already has |EventForwarder| attached to it. + static bool ViewTreeHasEventForwarder(ViewAndroid* view); - // Checks if there is any event forwarder in the node paths down to - // each leaf of subtree. + // Returns true if any children node (or self) has |EventForwarder|. static bool SubtreeHasEventForwarder(ViewAndroid* view); // Returns the Java delegate for this view. This is used to delegate work
diff --git a/ui/android/view_android_unittests.cc b/ui/android/view_android_unittests.cc index f3c95de0..77c9bca 100644 --- a/ui/android/view_android_unittests.cc +++ b/ui/android/view_android_unittests.cc
@@ -166,37 +166,4 @@ ExpectHit(client3_); } -TEST(ViewAndroidTest, ChecksMultipleEventForwarders) { - ViewAndroid parent; - ViewAndroid child; - parent.GetEventForwarder(); - child.GetEventForwarder(); - EXPECT_DEATH(parent.AddChild(&child), "Check failed:"); - - ViewAndroid parent2; - ViewAndroid child2; - parent2.GetEventForwarder(); - parent2.AddChild(&child2); - EXPECT_DEATH(child2.GetEventForwarder(), "Check failed:"); - - ViewAndroid window; - ViewAndroid wcv1, wcv2; - ViewAndroid rwhv1a, rwhv1b, rwhv2; - wcv1.GetEventForwarder(); - wcv2.GetEventForwarder(); - - window.AddChild(&wcv1); - wcv1.AddChild(&rwhv1a); - wcv1.AddChild(&rwhv1b); - - wcv2.AddChild(&rwhv2); - - // window should be able to add wcv2 since there's only one event forwarder - // in the path window - wcv2* - rwvh2 - window.AddChild(&wcv2); - - // Additional event forwarder will cause failure. - EXPECT_DEATH(rwhv2.GetEventForwarder(), "Check failed:"); -} - } // namespace ui
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 64faa6a..8e61385 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -617,7 +617,7 @@ cc_layer_->SetContentsOpaque(fills_bounds_opaquely_); cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); cc_layer_->SetHideLayerAndSubtree(!visible_); - cc_layer_->SetElementId(cc::ElementId(cc_layer_->id(), 0)); + cc_layer_->SetElementId(cc::ElementId(cc_layer_->id())); SetLayerFilters(); SetLayerBackgroundFilters(); @@ -1167,7 +1167,7 @@ cc_layer_->SetContentsOpaque(true); cc_layer_->SetIsDrawable(type_ != LAYER_NOT_DRAWN); cc_layer_->SetLayerClient(this); - cc_layer_->SetElementId(cc::ElementId(cc_layer_->id(), 0)); + cc_layer_->SetElementId(cc::ElementId(cc_layer_->id())); RecomputePosition(); }
diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc index c58be9c..851d0204 100644 --- a/ui/compositor/layer_animator.cc +++ b/ui/compositor/layer_animator.cc
@@ -166,7 +166,7 @@ void LayerAnimator::AttachLayerToAnimationPlayer(int layer_id) { // For ui, layer and element ids are equivalent. - cc::ElementId element_id(layer_id, 0); + cc::ElementId element_id(layer_id); if (!animation_player_->element_id()) animation_player_->AttachElement(element_id); else
diff --git a/ui/vector_icons/BUILD.gn b/ui/vector_icons/BUILD.gn index 9530a13..5c2ebcd 100644 --- a/ui/vector_icons/BUILD.gn +++ b/ui/vector_icons/BUILD.gn
@@ -20,6 +20,7 @@ "forward_arrow.icon", "info_outline.icon", "location_on.icon", + "lock.icon", "media_router_active.icon", "media_router_error.icon", "media_router_idle.icon",
diff --git a/chrome/app/vector_icons/lock.icon b/ui/vector_icons/lock.icon similarity index 100% rename from chrome/app/vector_icons/lock.icon rename to ui/vector_icons/lock.icon