Title: [226168] trunk/Source/WebCore
Revision
226168
Author
[email protected]
Date
2017-12-19 17:44:37 -0800 (Tue, 19 Dec 2017)

Log Message

Move first-letter building code to RenderTreeBuilder
https://bugs.webkit.org/show_bug.cgi?id=180992

Reviewed by Zalan Bujtas.

All special case tree building logic should go to RenderTreeBuilder.

- RenderTreeUpdater::FirstLetter -> RenderTreeBuilder::FirstLetter
- Make the builder non-static and stop using RenderTreeBuilder::current() there.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* rendering/TextAutoSizing.cpp:
(WebCore::TextAutoSizingValue::adjustTextNodeSizes):
* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::RenderTreeBuilder):
(WebCore::RenderTreeBuilder::insertChild):
(WebCore::RenderTreeBuilder::updateAfterDescendants):
* rendering/updating/RenderTreeBuilder.h:
(WebCore::RenderTreeBuilder::firstLetterBuilder):
(WebCore::RenderTreeBuilder::tableBuilder):
* rendering/updating/RenderTreeBuilderFirstLetter.cpp: Copied from rendering/updating/RenderTreeUpdaterFirstLetter.cpp.
(WebCore::supportsFirstLetter):
(WebCore::RenderTreeBuilder::FirstLetter::FirstLetter):
(WebCore::RenderTreeBuilder::FirstLetter::updateAfterDescendants):
(WebCore::RenderTreeBuilder::FirstLetter::updateStyle):
(WebCore::RenderTreeBuilder::FirstLetter::createRenderers):
(WebCore::updateFirstLetterStyle): Deleted.
(WebCore::createFirstLetterRenderer): Deleted.
(WebCore::RenderTreeUpdater::FirstLetter::update): Deleted.
* rendering/updating/RenderTreeBuilderFirstLetter.h: Copied from rendering/updating/RenderTreeUpdaterFirstLetter.h.
* rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::updateAfterDescendants):
* rendering/updating/RenderTreeUpdater.h:
* rendering/updating/RenderTreeUpdaterFirstLetter.cpp: Removed.
* rendering/updating/RenderTreeUpdaterFirstLetter.h: Removed.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (226167 => 226168)


--- trunk/Source/WebCore/ChangeLog	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/ChangeLog	2017-12-20 01:44:37 UTC (rev 226168)
@@ -1,3 +1,42 @@
+2017-12-19  Antti Koivisto  <[email protected]>
+
+        Move first-letter building code to RenderTreeBuilder
+        https://bugs.webkit.org/show_bug.cgi?id=180992
+
+        Reviewed by Zalan Bujtas.
+
+        All special case tree building logic should go to RenderTreeBuilder.
+
+        - RenderTreeUpdater::FirstLetter -> RenderTreeBuilder::FirstLetter
+        - Make the builder non-static and stop using RenderTreeBuilder::current() there.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/TextAutoSizing.cpp:
+        (WebCore::TextAutoSizingValue::adjustTextNodeSizes):
+        * rendering/updating/RenderTreeBuilder.cpp:
+        (WebCore::RenderTreeBuilder::RenderTreeBuilder):
+        (WebCore::RenderTreeBuilder::insertChild):
+        (WebCore::RenderTreeBuilder::updateAfterDescendants):
+        * rendering/updating/RenderTreeBuilder.h:
+        (WebCore::RenderTreeBuilder::firstLetterBuilder):
+        (WebCore::RenderTreeBuilder::tableBuilder):
+        * rendering/updating/RenderTreeBuilderFirstLetter.cpp: Copied from rendering/updating/RenderTreeUpdaterFirstLetter.cpp.
+        (WebCore::supportsFirstLetter):
+        (WebCore::RenderTreeBuilder::FirstLetter::FirstLetter):
+        (WebCore::RenderTreeBuilder::FirstLetter::updateAfterDescendants):
+        (WebCore::RenderTreeBuilder::FirstLetter::updateStyle):
+        (WebCore::RenderTreeBuilder::FirstLetter::createRenderers):
+        (WebCore::updateFirstLetterStyle): Deleted.
+        (WebCore::createFirstLetterRenderer): Deleted.
+        (WebCore::RenderTreeUpdater::FirstLetter::update): Deleted.
+        * rendering/updating/RenderTreeBuilderFirstLetter.h: Copied from rendering/updating/RenderTreeUpdaterFirstLetter.h.
+        * rendering/updating/RenderTreeUpdater.cpp:
+        (WebCore::RenderTreeUpdater::updateAfterDescendants):
+        * rendering/updating/RenderTreeUpdater.h:
+        * rendering/updating/RenderTreeUpdaterFirstLetter.cpp: Removed.
+        * rendering/updating/RenderTreeUpdaterFirstLetter.h: Removed.
+
 2017-12-19  Chris Dumez  <[email protected]>
 
         [Fetch] Extracting a body of type Blob should not set Content-Type to the empty string

Modified: trunk/Source/WebCore/Sources.txt (226167 => 226168)


--- trunk/Source/WebCore/Sources.txt	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/Sources.txt	2017-12-20 01:44:37 UTC (rev 226168)
@@ -1980,10 +1980,10 @@
 rendering/svg/SVGTextQuery.cpp
 
 rendering/updating/RenderTreeBuilder.cpp
+rendering/updating/RenderTreeBuilderFirstLetter.cpp
 rendering/updating/RenderTreeBuilderTable.cpp
 rendering/updating/RenderTreePosition.cpp
 rendering/updating/RenderTreeUpdater.cpp
-rendering/updating/RenderTreeUpdaterFirstLetter.cpp
 rendering/updating/RenderTreeUpdaterGeneratedContent.cpp
 rendering/updating/RenderTreeUpdaterListItem.cpp
 rendering/updating/RenderTreeUpdaterMultiColumn.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (226167 => 226168)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-12-20 01:44:37 UTC (rev 226168)
@@ -4579,7 +4579,7 @@
 		E47C392D1FE6E0F300BBBC6B /* RenderTreeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C392A1FE6E0DE00BBBC6B /* RenderTreeBuilder.h */; };
 		E47C392E1FE6E0F700BBBC6B /* RenderTreePosition.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39241FE6E0DB00BBBC6B /* RenderTreePosition.h */; };
 		E47C392F1FE6E0F900BBBC6B /* RenderTreeUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C392C1FE6E0DF00BBBC6B /* RenderTreeUpdater.h */; };
-		E47C39301FE6E0FD00BBBC6B /* RenderTreeUpdaterFirstLetter.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39261FE6E0DC00BBBC6B /* RenderTreeUpdaterFirstLetter.h */; };
+		E47C39301FE6E0FD00BBBC6B /* RenderTreeBuilderFirstLetter.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39261FE6E0DC00BBBC6B /* RenderTreeBuilderFirstLetter.h */; };
 		E47C39311FE6E10200BBBC6B /* RenderTreeUpdaterGeneratedContent.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39251FE6E0DB00BBBC6B /* RenderTreeUpdaterGeneratedContent.h */; };
 		E47C39321FE6E10500BBBC6B /* RenderTreeUpdaterListItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39281FE6E0DD00BBBC6B /* RenderTreeUpdaterListItem.h */; };
 		E47C39331FE6E10800BBBC6B /* RenderTreeUpdaterMultiColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39271FE6E0DC00BBBC6B /* RenderTreeUpdaterMultiColumn.h */; };
@@ -13908,12 +13908,12 @@
 		E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedResourceHandle.cpp; sourceTree = "<group>"; };
 		E47C391F1FE6E0D800BBBC6B /* RenderTreeUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdater.cpp; sourceTree = "<group>"; };
 		E47C39201FE6E0D900BBBC6B /* RenderTreeBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilder.cpp; sourceTree = "<group>"; };
-		E47C39211FE6E0DA00BBBC6B /* RenderTreeUpdaterFirstLetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdaterFirstLetter.cpp; sourceTree = "<group>"; };
+		E47C39211FE6E0DA00BBBC6B /* RenderTreeBuilderFirstLetter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderFirstLetter.cpp; sourceTree = "<group>"; };
 		E47C39221FE6E0DA00BBBC6B /* RenderTreeUpdaterGeneratedContent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdaterGeneratedContent.cpp; sourceTree = "<group>"; };
 		E47C39231FE6E0DA00BBBC6B /* RenderTreeUpdaterMultiColumn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeUpdaterMultiColumn.cpp; sourceTree = "<group>"; };
 		E47C39241FE6E0DB00BBBC6B /* RenderTreePosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreePosition.h; sourceTree = "<group>"; };
 		E47C39251FE6E0DB00BBBC6B /* RenderTreeUpdaterGeneratedContent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterGeneratedContent.h; sourceTree = "<group>"; };
-		E47C39261FE6E0DC00BBBC6B /* RenderTreeUpdaterFirstLetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterFirstLetter.h; sourceTree = "<group>"; };
+		E47C39261FE6E0DC00BBBC6B /* RenderTreeBuilderFirstLetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderFirstLetter.h; sourceTree = "<group>"; };
 		E47C39271FE6E0DC00BBBC6B /* RenderTreeUpdaterMultiColumn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterMultiColumn.h; sourceTree = "<group>"; };
 		E47C39281FE6E0DD00BBBC6B /* RenderTreeUpdaterListItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdaterListItem.h; sourceTree = "<group>"; };
 		E47C39291FE6E0DE00BBBC6B /* RenderTreePosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreePosition.cpp; sourceTree = "<group>"; };
@@ -24516,6 +24516,8 @@
 			children = (
 				E47C39201FE6E0D900BBBC6B /* RenderTreeBuilder.cpp */,
 				E47C392A1FE6E0DE00BBBC6B /* RenderTreeBuilder.h */,
+				E47C39211FE6E0DA00BBBC6B /* RenderTreeBuilderFirstLetter.cpp */,
+				E47C39261FE6E0DC00BBBC6B /* RenderTreeBuilderFirstLetter.h */,
 				119340761FE8B92300935F1E /* RenderTreeBuilderTable.cpp */,
 				119340771FE8B92300935F1E /* RenderTreeBuilderTable.h */,
 				E47C39291FE6E0DE00BBBC6B /* RenderTreePosition.cpp */,
@@ -24522,8 +24524,6 @@
 				E47C39241FE6E0DB00BBBC6B /* RenderTreePosition.h */,
 				E47C391F1FE6E0D800BBBC6B /* RenderTreeUpdater.cpp */,
 				E47C392C1FE6E0DF00BBBC6B /* RenderTreeUpdater.h */,
-				E47C39211FE6E0DA00BBBC6B /* RenderTreeUpdaterFirstLetter.cpp */,
-				E47C39261FE6E0DC00BBBC6B /* RenderTreeUpdaterFirstLetter.h */,
 				E47C39221FE6E0DA00BBBC6B /* RenderTreeUpdaterGeneratedContent.cpp */,
 				E47C39251FE6E0DB00BBBC6B /* RenderTreeUpdaterGeneratedContent.h */,
 				E47C392B1FE6E0DF00BBBC6B /* RenderTreeUpdaterListItem.cpp */,
@@ -27242,6 +27242,7 @@
 				977B3878122883E900B81FF8 /* HTMLTokenizer.h in Headers */,
 				0707568C142262D600414161 /* HTMLTrackElement.h in Headers */,
 				977B37261228721700B81FF8 /* HTMLTreeBuilder.h in Headers */,
+				E47C39301FE6E0FD00BBBC6B /* RenderTreeBuilderFirstLetter.h in Headers */,
 				A8EA79F20A1916DF00A8EF5F /* HTMLUListElement.h in Headers */,
 				AD49914318F0815100BF0092 /* HTMLUnknownElement.h in Headers */,
 				E44613AB0CD6331000FADA75 /* HTMLVideoElement.h in Headers */,
@@ -28932,7 +28933,6 @@
 				119340791FE8B92300935F1E /* RenderTreeBuilderTable.h in Headers */,
 				E47C392E1FE6E0F700BBBC6B /* RenderTreePosition.h in Headers */,
 				E47C392F1FE6E0F900BBBC6B /* RenderTreeUpdater.h in Headers */,
-				E47C39301FE6E0FD00BBBC6B /* RenderTreeUpdaterFirstLetter.h in Headers */,
 				E47C39311FE6E10200BBBC6B /* RenderTreeUpdaterGeneratedContent.h in Headers */,
 				E47C39321FE6E10500BBBC6B /* RenderTreeUpdaterListItem.h in Headers */,
 				E47C39331FE6E10800BBBC6B /* RenderTreeUpdaterMultiColumn.h in Headers */,

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj.orig (226167 => 226168)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj.orig	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj.orig	2017-12-20 01:44:37 UTC (rev 226168)
@@ -169,6 +169,7 @@
 		078E094417D16E1C00420AA1 /* RTCSessionDescriptionRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BAD17CF0AD400848E51 /* RTCSessionDescriptionRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		078E094717D16E1C00420AA1 /* RTCVoidRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BB017CF0AD400848E51 /* RTCVoidRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		078E094C17D1709600420AA1 /* MediaStreamAudioDestinationNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E094917D1709600420AA1 /* MediaStreamAudioDestinationNode.h */; };
+		078E3CC01FE1C73C00483C1D /* MediaStreamRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E3CBE1FE19F3000483C1D /* MediaStreamRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		078E43DA1ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		078E43DD1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		078E43DE1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */; };
@@ -5174,6 +5175,7 @@
 		078E094817D1709600420AA1 /* MediaStreamAudioDestinationNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamAudioDestinationNode.cpp; sourceTree = "<group>"; };
 		078E094917D1709600420AA1 /* MediaStreamAudioDestinationNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamAudioDestinationNode.h; sourceTree = "<group>"; };
 		078E094A17D1709600420AA1 /* MediaStreamAudioDestinationNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaStreamAudioDestinationNode.idl; sourceTree = "<group>"; };
+		078E3CBE1FE19F3000483C1D /* MediaStreamRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamRequest.h; sourceTree = "<group>"; };
 		078E43D71ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaPlaybackTargetPicker.cpp; sourceTree = "<group>"; };
 		078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPicker.h; sourceTree = "<group>"; };
 		078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPickerMac.h; sourceTree = "<group>"; };
@@ -14717,6 +14719,7 @@
 				070F549717F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h */,
 				0711588F17DF633700EDFE2B /* MediaStreamPrivate.cpp */,
 				07221B9D17CF0AD400848E51 /* MediaStreamPrivate.h */,
+				078E3CBE1FE19F3000483C1D /* MediaStreamRequest.h */,
 				07FFDE66181AED420072D409 /* MediaStreamTrackPrivate.cpp */,
 				07FFDE67181AED420072D409 /* MediaStreamTrackPrivate.h */,
 				5EBB89381C77BDA400C65D41 /* PeerMediaDescription.h */,
@@ -26928,6 +26931,7 @@
 				517A535B1F588A4C00DCDC0A /* FetchBodyConsumer.h in Headers */,
 				4129C9971F59B963009D7403 /* FetchBodySource.h in Headers */,
 				41D129DB1F3D143800D15E47 /* FetchHeaders.h in Headers */,
+				4161E2D51FE48DC500EC2E96 /* FetchLoader.h in Headers */,
 				517A53581F5889E800DCDC0A /* FetchLoaderClient.h in Headers */,
 				41AD753A1CEF6BD100A31486 /* FetchOptions.h in Headers */,
 				7CE1914D1F2A9AFB00272F78 /* FetchReferrerPolicy.h in Headers */,
@@ -27389,7 +27393,6 @@
 				7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */,
 				A5B81CAE1FAA44620037D1E6 /* InspectorIndexedDBAgent.h in Headers */,
 				20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */,
-				4161E2D51FE48DC500EC2E96 /* FetchLoader.h in Headers */,
 				A5840E1D187B74D500843B10 /* InspectorInstrumentationCookie.h in Headers */,
 				A5B81CAF1FAA44620037D1E6 /* InspectorLayerTreeAgent.h in Headers */,
 				A5B81CB01FAA44620037D1E6 /* InspectorMemoryAgent.h in Headers */,
@@ -28420,6 +28423,7 @@
 				078E091617D14D1C00420AA1 /* MediaStreamEvent.h in Headers */,
 				078E093717D16B2C00420AA1 /* MediaStreamPrivate.h in Headers */,
 				078E091717D14D1C00420AA1 /* MediaStreamRegistry.h in Headers */,
+				078E3CC01FE1C73C00483C1D /* MediaStreamRequest.h in Headers */,
 				078E091817D14D1C00420AA1 /* MediaStreamTrack.h in Headers */,
 				078E091917D14D1C00420AA1 /* MediaStreamTrackEvent.h in Headers */,
 				07FFDE69181AED420072D409 /* MediaStreamTrackPrivate.h in Headers */,

Modified: trunk/Source/WebCore/rendering/TextAutoSizing.cpp (226167 => 226168)


--- trunk/Source/WebCore/rendering/TextAutoSizing.cpp	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/TextAutoSizing.cpp	2017-12-20 01:44:37 UTC (rev 226168)
@@ -37,7 +37,7 @@
 #include "RenderText.h"
 #include "RenderTextFragment.h"
 #include "RenderTreeBuilder.h"
-#include "RenderTreeUpdaterFirstLetter.h"
+#include "RenderTreeBuilderFirstLetter.h"
 #include "RenderTreeUpdaterListItem.h"
 #include "StyleResolver.h"
 
@@ -173,8 +173,7 @@
         auto* block = downcast<RenderTextFragment>(textRenderer).blockForAccompanyingFirstLetter();
         if (!block)
             continue;
-        // FIXME: All render tree mutations should be done by RenderTreeUpdater commit.
-        RenderTreeUpdater::FirstLetter::update(*block);
+        builder.updateAfterDescendants(*block);
     }
 
     return stillHasNodes;

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp (226167 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2017-12-20 01:44:37 UTC (rev 226168)
@@ -32,8 +32,8 @@
 #include "RenderRubyRun.h"
 #include "RenderTableRow.h"
 #include "RenderText.h"
+#include "RenderTreeBuilderFirstLetter.h"
 #include "RenderTreeBuilderTable.h"
-#include "RenderTreeUpdater.h"
 
 namespace WebCore {
 
@@ -41,6 +41,7 @@
 
 RenderTreeBuilder::RenderTreeBuilder(RenderView& view)
     : m_view(view)
+    , m_firstLetterBuilder(std::make_unique<FirstLetter>(*this))
     , m_tableBuilder(std::make_unique<Table>(*this))
 {
     RELEASE_ASSERT(!s_current || &m_view != &s_current->m_view);
@@ -63,12 +64,12 @@
     }
 
     if (is<RenderTableRow>(parent)) {
-        m_tableBuilder->findOrCreateParentForChild(downcast<RenderTableRow>(parent), *child, beforeChild).addChild(*this, WTFMove(child), beforeChild);
+        tableBuilder().findOrCreateParentForChild(downcast<RenderTableRow>(parent), *child, beforeChild).addChild(*this, WTFMove(child), beforeChild);
         return;
     }
 
     if (is<RenderTableSection>(parent)) {
-        auto& parentCandidate = m_tableBuilder->findOrCreateParentForChild(downcast<RenderTableSection>(parent), *child, beforeChild);
+        auto& parentCandidate = tableBuilder().findOrCreateParentForChild(downcast<RenderTableSection>(parent), *child, beforeChild);
         if (&parent != &parentCandidate) {
             insertChild(parentCandidate, WTFMove(child), beforeChild);
             return;
@@ -90,6 +91,12 @@
     insertChild(position.parent(), WTFMove(child), position.nextSibling());
 }
 
+void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer)
+{
+    if (is<RenderBlock>(renderer))
+        firstLetterBuilder().updateAfterDescendants(downcast<RenderBlock>(renderer));
+}
+
 void RenderTreeBuilder::rubyRunInsertChild(RenderRubyRun& parent, RenderPtr<RenderObject> child, RenderObject* beforeChild)
 {
     if (child->isRubyText()) {

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h (226167 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.h	2017-12-20 01:44:37 UTC (rev 226168)
@@ -40,20 +40,28 @@
     void insertChild(RenderElement& parent, RenderPtr<RenderObject>, RenderObject* beforeChild = nullptr);
     void insertChild(RenderTreePosition&, RenderPtr<RenderObject>);
 
+    void updateAfterDescendants(RenderElement&);
+
     // This avoids having to convert all sites that need RenderTreeBuilder in one go.
     // FIXME: Remove.
     static RenderTreeBuilder* current() { return s_current; }
 
 private:
+    class FirstLetter;
     class Table;
 
     void rubyRunInsertChild(RenderRubyRun&, RenderPtr<RenderObject> child, RenderObject* beforeChild);
 
+    FirstLetter& firstLetterBuilder() { return *m_firstLetterBuilder; }
+    Table& tableBuilder() { return *m_tableBuilder; }
+
     RenderView& m_view;
 
     RenderTreeBuilder* m_previous { nullptr };
+    static RenderTreeBuilder* s_current;
+
+    std::unique_ptr<FirstLetter> m_firstLetterBuilder;
     std::unique_ptr<Table> m_tableBuilder;
-    static RenderTreeBuilder* s_current;
 };
 
 }

Copied: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp (from rev 226165, trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.cpp) (0 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp	2017-12-20 01:44:37 UTC (rev 226168)
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 1999 Lars Knoll ([email protected])
+ *           (C) 1999 Antti Koivisto ([email protected])
+ *           (C) 2007 David Smith ([email protected])
+ * Copyright (C) 2003-2011, 2017 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "RenderTreeBuilderFirstLetter.h"
+
+#include "FontCascade.h"
+#include "RenderBlock.h"
+#include "RenderButton.h"
+#include "RenderInline.h"
+#include "RenderRubyRun.h"
+#include "RenderSVGText.h"
+#include "RenderStyle.h"
+#include "RenderTable.h"
+#include "RenderTextFragment.h"
+#include "RenderTreeBuilder.h"
+
+namespace WebCore {
+
+static RenderStyle styleForFirstLetter(const RenderBlock& firstLetterBlock, const RenderObject& firstLetterContainer)
+{
+    auto* containerFirstLetterStyle = firstLetterBlock.getCachedPseudoStyle(FIRST_LETTER, &firstLetterContainer.firstLineStyle());
+    // FIXME: There appears to be some path where we have a first letter renderer without first letter style.
+    ASSERT(containerFirstLetterStyle);
+    auto firstLetterStyle = RenderStyle::clone(containerFirstLetterStyle ? *containerFirstLetterStyle : firstLetterContainer.firstLineStyle());
+
+    // If we have an initial letter drop that is >= 1, then we need to force floating to be on.
+    if (firstLetterStyle.initialLetterDrop() >= 1 && !firstLetterStyle.isFloating())
+        firstLetterStyle.setFloating(firstLetterStyle.isLeftToRightDirection() ? LeftFloat : RightFloat);
+
+    // We have to compute the correct font-size for the first-letter if it has an initial letter height set.
+    auto* paragraph = firstLetterContainer.isRenderBlockFlow() ? &firstLetterContainer : firstLetterContainer.containingBlock();
+    if (firstLetterStyle.initialLetterHeight() >= 1 && firstLetterStyle.fontMetrics().hasCapHeight() && paragraph->style().fontMetrics().hasCapHeight()) {
+        // FIXME: For ideographic baselines, we want to go from line edge to line edge. This is equivalent to (N-1)*line-height + the font height.
+        // We don't yet support ideographic baselines.
+        // For an N-line first-letter and for alphabetic baselines, the cap-height of the first letter needs to equal (N-1)*line-height of paragraph lines + cap-height of the paragraph
+        // Mathematically we can't rely on font-size, since font().height() doesn't necessarily match. For reliability, the best approach is simply to
+        // compare the final measured cap-heights of the two fonts in order to get to the closest possible value.
+        firstLetterStyle.setLineBoxContain(LineBoxContainInitialLetter);
+        int lineHeight = paragraph->style().computedLineHeight();
+
+        // Set the font to be one line too big and then ratchet back to get to a precise fit. We can't just set the desired font size based off font height metrics
+        // because many fonts bake ascent into the font metrics. Therefore we have to look at actual measured cap height values in order to know when we have a good fit.
+        auto newFontDescription = firstLetterStyle.fontDescription();
+        float capRatio = firstLetterStyle.fontMetrics().floatCapHeight() / firstLetterStyle.computedFontPixelSize();
+        float startingFontSize = ((firstLetterStyle.initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight()) / capRatio;
+        newFontDescription.setSpecifiedSize(startingFontSize);
+        newFontDescription.setComputedSize(startingFontSize);
+        firstLetterStyle.setFontDescription(newFontDescription);
+        firstLetterStyle.fontCascade().update(firstLetterStyle.fontCascade().fontSelector());
+
+        int desiredCapHeight = (firstLetterStyle.initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight();
+        int actualCapHeight = firstLetterStyle.fontMetrics().capHeight();
+        while (actualCapHeight > desiredCapHeight) {
+            auto newFontDescription = firstLetterStyle.fontDescription();
+            newFontDescription.setSpecifiedSize(newFontDescription.specifiedSize() - 1);
+            newFontDescription.setComputedSize(newFontDescription.computedSize() -1);
+            firstLetterStyle.setFontDescription(newFontDescription);
+            firstLetterStyle.fontCascade().update(firstLetterStyle.fontCascade().fontSelector());
+            actualCapHeight = firstLetterStyle.fontMetrics().capHeight();
+        }
+    }
+
+    // Force inline display (except for floating first-letters).
+    firstLetterStyle.setDisplay(firstLetterStyle.isFloating() ? BLOCK : INLINE);
+    // CSS2 says first-letter can't be positioned.
+    firstLetterStyle.setPosition(StaticPosition);
+    return firstLetterStyle;
+}
+
+// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
+// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
+// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
+static inline bool isPunctuationForFirstLetter(UChar c)
+{
+    return U_GET_GC_MASK(c) & (U_GC_PS_MASK | U_GC_PE_MASK | U_GC_PI_MASK | U_GC_PF_MASK | U_GC_PO_MASK);
+}
+
+static inline bool shouldSkipForFirstLetter(UChar c)
+{
+    return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
+}
+
+static bool supportsFirstLetter(RenderBlock& block)
+{
+    if (is<RenderButton>(block))
+        return true;
+    if (!is<RenderBlockFlow>(block))
+        return false;
+    if (is<RenderSVGText>(block))
+        return false;
+    if (is<RenderRubyRun>(block))
+        return false;
+    return block.canHaveGeneratedChildren();
+}
+
+RenderTreeBuilder::FirstLetter::FirstLetter(RenderTreeBuilder& builder)
+    : m_builder(builder)
+{
+}
+
+void RenderTreeBuilder::FirstLetter::updateAfterDescendants(RenderBlock& block)
+{
+    if (!block.style().hasPseudoStyle(FIRST_LETTER))
+        return;
+    if (!supportsFirstLetter(block))
+        return;
+
+    // FIXME: This should be refactored, firstLetterContainer is not needed.
+    RenderObject* firstLetterRenderer;
+    RenderElement* firstLetterContainer;
+    block.getFirstLetter(firstLetterRenderer, firstLetterContainer);
+
+    if (!firstLetterRenderer)
+        return;
+
+    // Other containers are handled when updating their renderers.
+    if (&block != firstLetterContainer)
+        return;
+
+    // If the child already has style, then it has already been created, so we just want
+    // to update it.
+    if (firstLetterRenderer->parent()->style().styleType() == FIRST_LETTER) {
+        updateStyle(block, *firstLetterRenderer);
+        return;
+    }
+
+    if (!is<RenderText>(firstLetterRenderer))
+        return;
+
+    createRenderers(block, downcast<RenderText>(*firstLetterRenderer));
+}
+
+void RenderTreeBuilder::FirstLetter::updateStyle(RenderBlock& firstLetterBlock, RenderObject& currentChild)
+{
+    RenderElement* firstLetter = currentChild.parent();
+    ASSERT(firstLetter->isFirstLetter());
+
+    RenderElement* firstLetterContainer = firstLetter->parent();
+    auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
+    ASSERT(firstLetter->isFloating() || firstLetter->isInline());
+
+    if (Style::determineChange(firstLetter->style(), pseudoStyle) == Style::Detach) {
+        // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
+        RenderPtr<RenderBoxModelObject> newFirstLetter;
+        if (pseudoStyle.display() == INLINE)
+            newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+        else
+            newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+        newFirstLetter->initializeStyle();
+        newFirstLetter->setIsFirstLetter();
+
+        // Move the first letter into the new renderer.
+        while (RenderObject* child = firstLetter->firstChild()) {
+            if (is<RenderText>(*child))
+                downcast<RenderText>(*child).removeAndDestroyTextBoxes();
+            auto toMove = firstLetter->takeChild(*child);
+            m_builder.insertChild(*newFirstLetter, WTFMove(toMove));
+        }
+
+        RenderObject* nextSibling = firstLetter->nextSibling();
+        if (RenderTextFragment* remainingText = downcast<RenderBoxModelObject>(*firstLetter).firstLetterRemainingText()) {
+            ASSERT(remainingText->isAnonymous() || remainingText->textNode()->renderer() == remainingText);
+            // Replace the old renderer with the new one.
+            remainingText->setFirstLetter(*newFirstLetter);
+            newFirstLetter->setFirstLetterRemainingText(*remainingText);
+        }
+        firstLetterContainer->removeAndDestroyChild(*firstLetter);
+        m_builder.insertChild(*firstLetterContainer, WTFMove(newFirstLetter), nextSibling);
+        return;
+    }
+
+    firstLetter->setStyle(WTFMove(pseudoStyle));
+}
+
+void RenderTreeBuilder::FirstLetter::createRenderers(RenderBlock& firstLetterBlock, RenderText& currentTextChild)
+{
+    RenderElement* firstLetterContainer = currentTextChild.parent();
+    auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
+    RenderPtr<RenderBoxModelObject> newFirstLetter;
+    if (pseudoStyle.display() == INLINE)
+        newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+    else
+        newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+    newFirstLetter->initializeStyle();
+    newFirstLetter->setIsFirstLetter();
+
+    auto& firstLetter = *newFirstLetter;
+    m_builder.insertChild(*firstLetterContainer, WTFMove(newFirstLetter), &currentTextChild);
+
+    // The original string is going to be either a generated content string or a DOM node's
+    // string. We want the original string before it got transformed in case first-letter has
+    // no text-transform or a different text-transform applied to it.
+    String oldText = currentTextChild.originalText();
+    ASSERT(!oldText.isNull());
+
+    if (!oldText.isEmpty()) {
+        unsigned length = 0;
+
+        // Account for leading spaces and punctuation.
+        while (length < oldText.length() && shouldSkipForFirstLetter(oldText[length]))
+            length++;
+
+        // Account for first grapheme cluster.
+        length += numCharactersInGraphemeClusters(StringView(oldText).substring(length), 1);
+
+        // Keep looking for whitespace and allowed punctuation, but avoid
+        // accumulating just whitespace into the :first-letter.
+        for (unsigned scanLength = length; scanLength < oldText.length(); ++scanLength) {
+            UChar c = oldText[scanLength];
+
+            if (!shouldSkipForFirstLetter(c))
+                break;
+
+            if (isPunctuationForFirstLetter(c))
+                length = scanLength + 1;
+        }
+
+        auto* textNode = currentTextChild.textNode();
+        auto* beforeChild = currentTextChild.nextSibling();
+        firstLetterContainer->removeAndDestroyChild(currentTextChild);
+
+        // Construct a text fragment for the text after the first letter.
+        // This text fragment might be empty.
+        RenderPtr<RenderTextFragment> newRemainingText;
+        if (textNode) {
+            newRemainingText = createRenderer<RenderTextFragment>(*textNode, oldText, length, oldText.length() - length);
+            textNode->setRenderer(newRemainingText.get());
+        } else
+            newRemainingText = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, length, oldText.length() - length);
+
+        RenderTextFragment& remainingText = *newRemainingText;
+        m_builder.insertChild(*firstLetterContainer, WTFMove(newRemainingText), beforeChild);
+        remainingText.setFirstLetter(firstLetter);
+        firstLetter.setFirstLetterRemainingText(remainingText);
+
+        // construct text fragment for the first letter
+        auto letter = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, 0, length);
+
+        m_builder.insertChild(firstLetter, WTFMove(letter));
+    }
+}
+
+};

Copied: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.h (from rev 226165, trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.h) (0 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.h	2017-12-20 01:44:37 UTC (rev 226168)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 Apple 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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+#pragma once
+
+#include "RenderTreeBuilder.h"
+
+namespace WebCore {
+
+class RenderElement;
+
+class RenderTreeBuilder::FirstLetter {
+public:
+    FirstLetter(RenderTreeBuilder&);
+
+    void updateAfterDescendants(RenderBlock&);
+
+private:
+    void updateStyle(RenderBlock& firstLetterBlock, RenderObject& currentChild);
+    void createRenderers(RenderBlock& firstLetterBlock, RenderText& currentTextChild);
+
+    RenderTreeBuilder& m_builder;
+};
+
+}

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp (226167 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp	2017-12-20 01:44:37 UTC (rev 226168)
@@ -41,7 +41,7 @@
 #include "RenderFullScreen.h"
 #include "RenderInline.h"
 #include "RenderListItem.h"
-#include "RenderTreeUpdaterFirstLetter.h"
+#include "RenderTreeBuilderFirstLetter.h"
 #include "RenderTreeUpdaterGeneratedContent.h"
 #include "RenderTreeUpdaterListItem.h"
 #include "RenderTreeUpdaterMultiColumn.h"
@@ -271,9 +271,9 @@
     if (!renderer)
         return;
 
+    m_builder.updateAfterDescendants(*renderer);
+
     // These functions do render tree mutations that require descendant renderers.
-    if (is<RenderBlock>(*renderer))
-        FirstLetter::update(downcast<RenderBlock>(*renderer));
     if (is<RenderListItem>(*renderer))
         ListItem::updateMarker(m_builder, downcast<RenderListItem>(*renderer));
     if (is<RenderBlockFlow>(*renderer))

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.h (226167 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.h	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.h	2017-12-20 01:44:37 UTC (rev 226168)
@@ -51,7 +51,6 @@
     static void tearDownRenderers(Element&);
     static void tearDownRenderer(Text&);
 
-    class FirstLetter;
     class ListItem;
 
 private:

Deleted: trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.cpp (226167 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.cpp	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.cpp	2017-12-20 01:44:37 UTC (rev 226168)
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll ([email protected])
- *           (C) 1999 Antti Koivisto ([email protected])
- *           (C) 2007 David Smith ([email protected])
- * Copyright (C) 2003-2011, 2017 Apple Inc. All rights reserved.
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * 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.
- */
-
-#include "config.h"
-#include "RenderTreeUpdaterFirstLetter.h"
-
-#include "FontCascade.h"
-#include "RenderBlock.h"
-#include "RenderButton.h"
-#include "RenderInline.h"
-#include "RenderRubyRun.h"
-#include "RenderSVGText.h"
-#include "RenderStyle.h"
-#include "RenderTable.h"
-#include "RenderTextFragment.h"
-#include "RenderTreeBuilder.h"
-
-namespace WebCore {
-
-static RenderStyle styleForFirstLetter(const RenderBlock& firstLetterBlock, const RenderObject& firstLetterContainer)
-{
-    auto* containerFirstLetterStyle = firstLetterBlock.getCachedPseudoStyle(FIRST_LETTER, &firstLetterContainer.firstLineStyle());
-    // FIXME: There appears to be some path where we have a first letter renderer without first letter style.
-    ASSERT(containerFirstLetterStyle);
-    auto firstLetterStyle = RenderStyle::clone(containerFirstLetterStyle ? *containerFirstLetterStyle : firstLetterContainer.firstLineStyle());
-
-    // If we have an initial letter drop that is >= 1, then we need to force floating to be on.
-    if (firstLetterStyle.initialLetterDrop() >= 1 && !firstLetterStyle.isFloating())
-        firstLetterStyle.setFloating(firstLetterStyle.isLeftToRightDirection() ? LeftFloat : RightFloat);
-
-    // We have to compute the correct font-size for the first-letter if it has an initial letter height set.
-    auto* paragraph = firstLetterContainer.isRenderBlockFlow() ? &firstLetterContainer : firstLetterContainer.containingBlock();
-    if (firstLetterStyle.initialLetterHeight() >= 1 && firstLetterStyle.fontMetrics().hasCapHeight() && paragraph->style().fontMetrics().hasCapHeight()) {
-        // FIXME: For ideographic baselines, we want to go from line edge to line edge. This is equivalent to (N-1)*line-height + the font height.
-        // We don't yet support ideographic baselines.
-        // For an N-line first-letter and for alphabetic baselines, the cap-height of the first letter needs to equal (N-1)*line-height of paragraph lines + cap-height of the paragraph
-        // Mathematically we can't rely on font-size, since font().height() doesn't necessarily match. For reliability, the best approach is simply to
-        // compare the final measured cap-heights of the two fonts in order to get to the closest possible value.
-        firstLetterStyle.setLineBoxContain(LineBoxContainInitialLetter);
-        int lineHeight = paragraph->style().computedLineHeight();
-
-        // Set the font to be one line too big and then ratchet back to get to a precise fit. We can't just set the desired font size based off font height metrics
-        // because many fonts bake ascent into the font metrics. Therefore we have to look at actual measured cap height values in order to know when we have a good fit.
-        auto newFontDescription = firstLetterStyle.fontDescription();
-        float capRatio = firstLetterStyle.fontMetrics().floatCapHeight() / firstLetterStyle.computedFontPixelSize();
-        float startingFontSize = ((firstLetterStyle.initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight()) / capRatio;
-        newFontDescription.setSpecifiedSize(startingFontSize);
-        newFontDescription.setComputedSize(startingFontSize);
-        firstLetterStyle.setFontDescription(newFontDescription);
-        firstLetterStyle.fontCascade().update(firstLetterStyle.fontCascade().fontSelector());
-
-        int desiredCapHeight = (firstLetterStyle.initialLetterHeight() - 1) * lineHeight + paragraph->style().fontMetrics().capHeight();
-        int actualCapHeight = firstLetterStyle.fontMetrics().capHeight();
-        while (actualCapHeight > desiredCapHeight) {
-            auto newFontDescription = firstLetterStyle.fontDescription();
-            newFontDescription.setSpecifiedSize(newFontDescription.specifiedSize() - 1);
-            newFontDescription.setComputedSize(newFontDescription.computedSize() -1);
-            firstLetterStyle.setFontDescription(newFontDescription);
-            firstLetterStyle.fontCascade().update(firstLetterStyle.fontCascade().fontSelector());
-            actualCapHeight = firstLetterStyle.fontMetrics().capHeight();
-        }
-    }
-
-    // Force inline display (except for floating first-letters).
-    firstLetterStyle.setDisplay(firstLetterStyle.isFloating() ? BLOCK : INLINE);
-    // CSS2 says first-letter can't be positioned.
-    firstLetterStyle.setPosition(StaticPosition);
-    return firstLetterStyle;
-}
-
-// CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
-// "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
-// "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
-static inline bool isPunctuationForFirstLetter(UChar c)
-{
-    return U_GET_GC_MASK(c) & (U_GC_PS_MASK | U_GC_PE_MASK | U_GC_PI_MASK | U_GC_PF_MASK | U_GC_PO_MASK);
-}
-
-static inline bool shouldSkipForFirstLetter(UChar c)
-{
-    return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
-}
-
-static void updateFirstLetterStyle(RenderBlock& firstLetterBlock, RenderObject& currentChild)
-{
-    RenderElement* firstLetter = currentChild.parent();
-    ASSERT(firstLetter->isFirstLetter());
-
-    RenderElement* firstLetterContainer = firstLetter->parent();
-    auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
-    ASSERT(firstLetter->isFloating() || firstLetter->isInline());
-
-    if (Style::determineChange(firstLetter->style(), pseudoStyle) == Style::Detach) {
-        // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
-        RenderPtr<RenderBoxModelObject> newFirstLetter;
-        if (pseudoStyle.display() == INLINE)
-            newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
-        else
-            newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
-        newFirstLetter->initializeStyle();
-        newFirstLetter->setIsFirstLetter();
-
-        // Move the first letter into the new renderer.
-        while (RenderObject* child = firstLetter->firstChild()) {
-            if (is<RenderText>(*child))
-                downcast<RenderText>(*child).removeAndDestroyTextBoxes();
-            auto toMove = firstLetter->takeChild(*child);
-            RenderTreeBuilder::current()->insertChild(*newFirstLetter, WTFMove(toMove));
-        }
-
-        RenderObject* nextSibling = firstLetter->nextSibling();
-        if (RenderTextFragment* remainingText = downcast<RenderBoxModelObject>(*firstLetter).firstLetterRemainingText()) {
-            ASSERT(remainingText->isAnonymous() || remainingText->textNode()->renderer() == remainingText);
-            // Replace the old renderer with the new one.
-            remainingText->setFirstLetter(*newFirstLetter);
-            newFirstLetter->setFirstLetterRemainingText(*remainingText);
-        }
-        firstLetterContainer->removeAndDestroyChild(*firstLetter);
-        RenderTreeBuilder::current()->insertChild(*firstLetterContainer, WTFMove(newFirstLetter), nextSibling);
-    } else
-        firstLetter->setStyle(WTFMove(pseudoStyle));
-}
-
-static void createFirstLetterRenderer(RenderBlock& firstLetterBlock, RenderText& currentTextChild)
-{
-    RenderElement* firstLetterContainer = currentTextChild.parent();
-    auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
-    RenderPtr<RenderBoxModelObject> newFirstLetter;
-    if (pseudoStyle.display() == INLINE)
-        newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
-    else
-        newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
-    newFirstLetter->initializeStyle();
-    newFirstLetter->setIsFirstLetter();
-
-    auto& firstLetter = *newFirstLetter;
-    RenderTreeBuilder::current()->insertChild(*firstLetterContainer, WTFMove(newFirstLetter), &currentTextChild);
-
-    // The original string is going to be either a generated content string or a DOM node's
-    // string. We want the original string before it got transformed in case first-letter has
-    // no text-transform or a different text-transform applied to it.
-    String oldText = currentTextChild.originalText();
-    ASSERT(!oldText.isNull());
-
-    if (!oldText.isEmpty()) {
-        unsigned length = 0;
-
-        // Account for leading spaces and punctuation.
-        while (length < oldText.length() && shouldSkipForFirstLetter(oldText[length]))
-            length++;
-
-        // Account for first grapheme cluster.
-        length += numCharactersInGraphemeClusters(StringView(oldText).substring(length), 1);
-
-        // Keep looking for whitespace and allowed punctuation, but avoid
-        // accumulating just whitespace into the :first-letter.
-        for (unsigned scanLength = length; scanLength < oldText.length(); ++scanLength) {
-            UChar c = oldText[scanLength];
-
-            if (!shouldSkipForFirstLetter(c))
-                break;
-
-            if (isPunctuationForFirstLetter(c))
-                length = scanLength + 1;
-        }
-
-        auto* textNode = currentTextChild.textNode();
-        auto* beforeChild = currentTextChild.nextSibling();
-        firstLetterContainer->removeAndDestroyChild(currentTextChild);
-
-        // Construct a text fragment for the text after the first letter.
-        // This text fragment might be empty.
-        RenderPtr<RenderTextFragment> newRemainingText;
-        if (textNode) {
-            newRemainingText = createRenderer<RenderTextFragment>(*textNode, oldText, length, oldText.length() - length);
-            textNode->setRenderer(newRemainingText.get());
-        } else
-            newRemainingText = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, length, oldText.length() - length);
-
-        RenderTextFragment& remainingText = *newRemainingText;
-        RenderTreeBuilder::current()->insertChild(*firstLetterContainer, WTFMove(newRemainingText), beforeChild);
-        remainingText.setFirstLetter(firstLetter);
-        firstLetter.setFirstLetterRemainingText(remainingText);
-
-        // construct text fragment for the first letter
-        auto letter = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, 0, length);
-
-        RenderTreeBuilder::current()->insertChild(firstLetter, WTFMove(letter));
-    }
-}
-
-static bool supportsFirstLetter(RenderBlock& block)
-{
-    if (is<RenderButton>(block))
-        return true;
-    if (!is<RenderBlockFlow>(block))
-        return false;
-    if (is<RenderSVGText>(block))
-        return false;
-    if (is<RenderRubyRun>(block))
-        return false;
-    return block.canHaveGeneratedChildren();
-}
-
-void RenderTreeUpdater::FirstLetter::update(RenderBlock& block)
-{
-    if (!block.style().hasPseudoStyle(FIRST_LETTER))
-        return;
-    if (!supportsFirstLetter(block))
-        return;
-
-    // FIXME: This should be refactored, firstLetterContainer is not needed.
-    RenderObject* firstLetterRenderer;
-    RenderElement* firstLetterContainer;
-    block.getFirstLetter(firstLetterRenderer, firstLetterContainer);
-
-    if (!firstLetterRenderer)
-        return;
-
-    // Other containers are handled when updating their renderers.
-    if (&block != firstLetterContainer)
-        return;
-
-    // If the child already has style, then it has already been created, so we just want
-    // to update it.
-    if (firstLetterRenderer->parent()->style().styleType() == FIRST_LETTER) {
-        updateFirstLetterStyle(block, *firstLetterRenderer);
-        return;
-    }
-
-    if (!is<RenderText>(firstLetterRenderer))
-        return;
-
-    createFirstLetterRenderer(block, downcast<RenderText>(*firstLetterRenderer));
-}
-
-};

Deleted: trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.h (226167 => 226168)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.h	2017-12-20 01:44:07 UTC (rev 226167)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterFirstLetter.h	2017-12-20 01:44:37 UTC (rev 226168)
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 Apple 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:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-
-#pragma once
-
-#include "RenderTreeUpdater.h"
-
-namespace WebCore {
-
-class RenderBlock;
-
-class RenderTreeUpdater::FirstLetter {
-public:
-    static void update(RenderBlock&);
-};
-
-}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to