Changeset 279165 in webkit
- Timestamp:
- Jun 22, 2021 6:33:57 PM (13 months ago)
- Location:
- trunk
- Files:
-
- 27 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/TestExpectations (modified) (2 diffs)
-
LayoutTests/fast/lists/li-values-expected.txt (modified) (1 diff)
-
LayoutTests/fast/lists/li-values.html (modified) (1 diff)
-
LayoutTests/fast/lists/w3-css3-list-styles-fallback-style-expected.txt (modified) (5 diffs)
-
LayoutTests/fast/lists/w3-css3-list-styles-fallback-style.html (modified) (8 diffs)
-
LayoutTests/fast/lists/w3-css3-list-styles-numeric-expected.txt (modified) (1 diff)
-
LayoutTests/fast/lists/w3-css3-list-styles-numeric.html (modified) (4 diffs)
-
LayoutTests/fast/lists/w3-list-styles-expected.txt (modified) (1 diff)
-
LayoutTests/platform/mac/TestExpectations (modified) (1 diff)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/unicode/CharacterNames.h (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/accessibility/AccessibilityObject.cpp (modified) (1 diff)
-
Source/WebCore/accessibility/AccessibilityRenderObject.cpp (modified) (1 diff)
-
Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp (modified) (1 diff)
-
Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp (modified) (2 diffs)
-
Source/WebCore/css/CSSPrimitiveValueMappings.h (modified) (1 diff)
-
Source/WebCore/css/CSSValueKeywords.in (modified) (1 diff)
-
Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (modified) (1 diff)
-
Source/WebCore/rendering/RenderListItem.cpp (modified) (1 diff)
-
Source/WebCore/rendering/RenderListItem.h (modified) (2 diffs)
-
Source/WebCore/rendering/RenderListMarker.cpp (modified) (42 diffs)
-
Source/WebCore/rendering/RenderListMarker.h (modified) (2 diffs)
-
Source/WebCore/rendering/RenderTreeAsText.cpp (modified) (2 diffs)
-
Source/WebCore/rendering/style/RenderStyleConstants.cpp (modified) (2 diffs)
-
Source/WebCore/rendering/style/RenderStyleConstants.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r279158 r279165 1 2021-06-21 Darin Adler <darin@apple.com> 2 3 Improve more of the CSS list style implementations 4 https://bugs.webkit.org/show_bug.cgi?id=227206 5 6 Reviewed by Antti Koivisto. 7 8 * TestExpectations: Expect about 50 more css-counter-styles tests to pass. 9 10 * fast/lists/li-values-expected.txt: Updated to expect newly specified behavior. When 11 this test was written, the specification was different. 12 * fast/lists/li-values.html: Ditto. 13 * fast/lists/w3-css3-list-styles-fallback-style-expected.txt: Ditto. Also many of these 14 were expecting failures. 15 * fast/lists/w3-css3-list-styles-fallback-style.html: Ditto. 16 * fast/lists/w3-css3-list-styles-numeric-expected.txt: Ditto. Also added tests for 17 ethiopic-numeric. 18 * fast/lists/w3-css3-list-styles-numeric.html: Ditto. 19 20 * fast/lists/w3-list-styles-expected.txt: Updated expected result for 0 in Hebrew. 21 22 * platform/mac/TestExpectations: Moved some image failure expectations from here to the 23 main TestExpectations because they do not seem to be platform-specific. 24 1 25 2021-06-22 Amir Mark Jr <amir_mark@apple.com> 2 26 -
trunk/LayoutTests/TestExpectations
r279108 r279165 4744 4744 webkit.org/b/224357 imported/w3c/web-platform-tests/css/cssom-view/cssom-getBoundingClientRect-vertical-rl.html [ ImageOnlyFailure ] 4745 4745 4746 # @counter-style ref tests that currently fail 4746 # Counter style tests that fail on some platforms because of subtle character positioning differences, presumably from subpixel rounding. 4747 # These failures are slightly different per-platform, but it seems unwise to move the expectations into platform-specific expectations files. 4748 imported/w3c/web-platform-tests/css/css-counter-styles/bengali/css3-counter-styles-117.html [ Pass ImageOnlyFailure ] 4749 imported/w3c/web-platform-tests/css/css-counter-styles/gujarati/css3-counter-styles-123.html [ Pass ImageOnlyFailure ] 4750 imported/w3c/web-platform-tests/css/css-counter-styles/gurmukhi/css3-counter-styles-126.html [ Pass ImageOnlyFailure ] 4751 imported/w3c/web-platform-tests/css/css-counter-styles/hebrew/css3-counter-styles-016a.html [ Pass ImageOnlyFailure ] 4752 imported/w3c/web-platform-tests/css/css-counter-styles/lao/css3-counter-styles-132.html [ Pass ImageOnlyFailure ] 4753 imported/w3c/web-platform-tests/css/css-counter-styles/lower-armenian/css3-counter-styles-114.html [ Pass ImageOnlyFailure ] 4754 imported/w3c/web-platform-tests/css/css-counter-styles/lower-roman/css3-counter-styles-020.html [ Pass ImageOnlyFailure ] 4755 imported/w3c/web-platform-tests/css/css-counter-styles/upper-roman/css3-counter-styles-024.html [ Pass ImageOnlyFailure ] 4756 4757 # Tests that fail because @counter-style is not implemented yet. Could skip the entire directory instead. 4747 4758 imported/w3c/web-platform-tests/css/css-counter-styles/cssom/cssom-additive-symbols-setter-invalid.html [ ImageOnlyFailure ] 4748 4759 imported/w3c/web-platform-tests/css/css-counter-styles/cssom/cssom-additive-symbols-setter.html [ ImageOnlyFailure ] … … 4764 4775 imported/w3c/web-platform-tests/css/css-counter-styles/cssom/cssom-system-setter-2.html [ ImageOnlyFailure ] 4765 4776 imported/w3c/web-platform-tests/css/css-counter-styles/cssom/cssom-system-setter-invalid.html [ ImageOnlyFailure ] 4766 imported/w3c/web-platform-tests/css/css-counter-styles/hebrew/css3-counter-styles-016a.html [ ImageOnlyFailure ]4767 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-formal/css3-counter-styles-047.html [ ImageOnlyFailure ]4768 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-formal/css3-counter-styles-048.html [ ImageOnlyFailure ]4769 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-formal/css3-counter-styles-049.html [ ImageOnlyFailure ]4770 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-formal/css3-counter-styles-050.html [ ImageOnlyFailure ]4771 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-formal/css3-counter-styles-051.html [ ImageOnlyFailure ]4772 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-informal/css3-counter-styles-042.html [ ImageOnlyFailure ]4773 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-informal/css3-counter-styles-043.html [ ImageOnlyFailure ]4774 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-informal/css3-counter-styles-044.html [ ImageOnlyFailure ]4775 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-informal/css3-counter-styles-045.html [ ImageOnlyFailure ]4776 imported/w3c/web-platform-tests/css/css-counter-styles/japanese-informal/css3-counter-styles-046.html [ ImageOnlyFailure ]4777 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hangul-formal/css3-counter-styles-052.html [ ImageOnlyFailure ]4778 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hangul-formal/css3-counter-styles-053.html [ ImageOnlyFailure ]4779 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hangul-formal/css3-counter-styles-054.html [ ImageOnlyFailure ]4780 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hangul-formal/css3-counter-styles-055.html [ ImageOnlyFailure ]4781 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hangul-formal/css3-counter-styles-056.html [ ImageOnlyFailure ]4782 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-formal/css3-counter-styles-062.html [ ImageOnlyFailure ]4783 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-formal/css3-counter-styles-063.html [ ImageOnlyFailure ]4784 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-formal/css3-counter-styles-064.html [ ImageOnlyFailure ]4785 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-formal/css3-counter-styles-065.html [ ImageOnlyFailure ]4786 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-formal/css3-counter-styles-066.html [ ImageOnlyFailure ]4787 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-informal/css3-counter-styles-057.html [ ImageOnlyFailure ]4788 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-informal/css3-counter-styles-058.html [ ImageOnlyFailure ]4789 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-informal/css3-counter-styles-059.html [ ImageOnlyFailure ]4790 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-informal/css3-counter-styles-060.html [ ImageOnlyFailure ]4791 imported/w3c/web-platform-tests/css/css-counter-styles/korean-hanja-informal/css3-counter-styles-061.html [ ImageOnlyFailure ]4792 imported/w3c/web-platform-tests/css/css-counter-styles/lower-armenian/css3-counter-styles-114.html [ ImageOnlyFailure ]4793 imported/w3c/web-platform-tests/css/css-counter-styles/lower-roman/css3-counter-styles-019.html [ ImageOnlyFailure ]4794 imported/w3c/web-platform-tests/css/css-counter-styles/lower-roman/css3-counter-styles-020.html [ ImageOnlyFailure ]4795 imported/w3c/web-platform-tests/css/css-counter-styles/lower-roman/css3-counter-styles-020a.html [ ImageOnlyFailure ]4796 imported/w3c/web-platform-tests/css/css-counter-styles/lower-roman/css3-counter-styles-020b.html [ ImageOnlyFailure ]4797 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-formal/css3-counter-styles-076.html [ ImageOnlyFailure ]4798 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-formal/css3-counter-styles-077.html [ ImageOnlyFailure ]4799 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-formal/css3-counter-styles-078.html [ ImageOnlyFailure ]4800 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-formal/css3-counter-styles-079.html [ ImageOnlyFailure ]4801 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-formal/css3-counter-styles-080.html [ ImageOnlyFailure ]4802 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-informal/css3-counter-styles-071.html [ ImageOnlyFailure ]4803 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-informal/css3-counter-styles-072.html [ ImageOnlyFailure ]4804 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-informal/css3-counter-styles-073.html [ ImageOnlyFailure ]4805 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-informal/css3-counter-styles-074.html [ ImageOnlyFailure ]4806 imported/w3c/web-platform-tests/css/css-counter-styles/simp-chinese-informal/css3-counter-styles-075.html [ ImageOnlyFailure ]4807 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-formal/css3-counter-styles-086.html [ ImageOnlyFailure ]4808 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-formal/css3-counter-styles-087.html [ ImageOnlyFailure ]4809 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-formal/css3-counter-styles-088.html [ ImageOnlyFailure ]4810 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-formal/css3-counter-styles-089.html [ ImageOnlyFailure ]4811 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-formal/css3-counter-styles-090.html [ ImageOnlyFailure ]4812 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-informal/css3-counter-styles-081.html [ ImageOnlyFailure ]4813 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-informal/css3-counter-styles-082.html [ ImageOnlyFailure ]4814 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-informal/css3-counter-styles-083.html [ ImageOnlyFailure ]4815 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-informal/css3-counter-styles-084.html [ ImageOnlyFailure ]4816 imported/w3c/web-platform-tests/css/css-counter-styles/trad-chinese-informal/css3-counter-styles-085.html [ ImageOnlyFailure ]4817 imported/w3c/web-platform-tests/css/css-counter-styles/upper-roman/css3-counter-styles-023.html [ ImageOnlyFailure ]4818 imported/w3c/web-platform-tests/css/css-counter-styles/upper-roman/css3-counter-styles-024.html [ ImageOnlyFailure ]4819 imported/w3c/web-platform-tests/css/css-counter-styles/upper-roman/css3-counter-styles-024a.html [ ImageOnlyFailure ]4820 4777 4821 4778 # CSS will-change failures -
trunk/LayoutTests/fast/lists/li-values-expected.txt
r102290 r279165 14 14 0 The list marker should fall back to decimal 0 (georgian: 1-19999). 15 15 0 The list marker should fall back to decimal 0 (ancient-tamil: 1-9999). 16 -1 The list marker should fall back to cjk-decimal -1 (japanese-informal: 0-9999). 17 -1 The list marker should fall back to cjk-decimal -1 (japanese-formal: 0-9999). 18 -1 The list marker should fall back to decimal -1 (korean-hangul-formal: 0-9999). 19 -1 The list marker should fall back to decimal -1 (korean-hanja-informal: 0-9999). 20 -1 The list marker should fall back to decimal -1 (korean-hanja-formal: 0-9999). 16 一〇〇〇〇 The list marker should fall back to cjk-decimal 10000 (japanese-informal: -9999-9999). 17 -10000 The list marker should fall back to decimal -10000 (japanese-informal: -9999-9999). 18 一〇〇〇〇 The list marker should fall back to cjk-decimal 10000 (japanese-formal: -9999-9999). 19 -10000 The list marker should fall back to decimal -10000 (japanese-formal: -9999-9999). 20 -10000 The list marker should fall back to decimal -10000 (korean-hangul-formal: -9999-9999). 21 -10000 The list marker should fall back to decimal -10000 (korean-hanja-informal: -9999-9999). 22 -10000 The list marker should fall back to decimal -10000 (korean-hanja-formal: -9999-9999). 21 23 0 The list marker should fall back to decimal 0 (greek: 1-999). 22 24 -
trunk/LayoutTests/fast/lists/li-values.html
r122687 r279165 41 41 <li value="0" style="list-style-type: georgian;">The list marker should fall back to decimal 0 (georgian: 1-19999).</li> 42 42 <li value="0" style="list-style-type: ancient-tamil;">The list marker should fall back to decimal 0 (ancient-tamil: 1-9999).</li> 43 < !-- FIXME: We don't currently support this list-style-type -> fall back to decimal -->44 <li value="-1 " style="list-style-type: japanese-informal;">The list marker should fall back to cjk-decimal -1 (japanese-informal: 0-9999).</li>45 < !-- FIXME: We don't currently support this list-style-type -> fall back to decimal -->46 <li value="-1 " style="list-style-type: japanese-formal;">The list marker should fall back to cjk-decimal -1 (japanese-formal: 0-9999).</li>47 <li value="-1 " style="list-style-type: korean-hangul-formal;">The list marker should fall back to decimal -1 (korean-hangul-formal: 0-9999).</li>48 <li value="-1 " style="list-style-type: korean-hanja-informal;">The list marker should fall back to decimal -1 (korean-hanja-informal: 0-9999).</li>49 <li value="-1 " style="list-style-type: korean-hanja-formal;">The list marker should fall back to decimal -1 (korean-hanja-formal: 0-9999).</li>43 <li value="10000" style="list-style-type: japanese-informal;">The list marker should fall back to cjk-decimal 10000 (japanese-informal: -9999-9999).</li> 44 <li value="-10000" style="list-style-type: japanese-informal;">The list marker should fall back to decimal -10000 (japanese-informal: -9999-9999).</li> 45 <li value="10000" style="list-style-type: japanese-formal;">The list marker should fall back to cjk-decimal 10000 (japanese-formal: -9999-9999).</li> 46 <li value="-10000" style="list-style-type: japanese-formal;">The list marker should fall back to decimal -10000 (japanese-formal: -9999-9999).</li> 47 <li value="-10000" style="list-style-type: korean-hangul-formal;">The list marker should fall back to decimal -10000 (korean-hangul-formal: -9999-9999).</li> 48 <li value="-10000" style="list-style-type: korean-hanja-informal;">The list marker should fall back to decimal -10000 (korean-hanja-informal: -9999-9999).</li> 49 <li value="-10000" style="list-style-type: korean-hanja-formal;">The list marker should fall back to decimal -10000 (korean-hanja-formal: -9999-9999).</li> 50 50 <li value="0" style="list-style-type: greek;">The list marker should fall back to decimal 0 (greek: 1-999).</li> 51 51 </ol> -
trunk/LayoutTests/fast/lists/w3-css3-list-styles-fallback-style-expected.txt
r279055 r279165 12 12 cjk-ideographic 13 13 14 PASS list marker is -1.14 PASS list marker is 負一. 15 15 PASS list marker is 零. 16 16 PASS list marker is 一. … … 19 19 PASS list marker is -1. 20 20 PASS list marker is 0. 21 PASS list marker is 1.21 PASS list marker is ፩. 22 22 georgian 23 23 … … 31 31 32 32 PASS list marker is -1. 33 PASS list marker is אפס.33 PASS list marker is 0. 34 34 PASS list marker is א. 35 PASS list marker is תתקצט'תתקצט.35 PASS list marker is 999999. 36 36 PASS list marker is 1000000. 37 37 PASS list marker is 1000001. 38 38 japanese-formal 39 39 40 PASS list marker is -1.41 PASS list marker is 0.42 PASS list marker is 1.40 PASS list marker is マイナス壱. 41 PASS list marker is 零. 42 PASS list marker is 壱. 43 43 japanese-informal 44 44 45 PASS list marker is -1.46 PASS list marker is 0.47 PASS list marker is 1.45 PASS list marker is マイナス一. 46 PASS list marker is 〇. 47 PASS list marker is 一. 48 48 lower-armenian 49 49 … … 58 58 simp-chinese-formal 59 59 60 PASS list marker is -1.61 PASS list marker is 0.62 PASS list marker is 1.60 PASS list marker is 负壹. 61 PASS list marker is 零. 62 PASS list marker is 壹. 63 63 simp-chinese-informal 64 64 65 PASS list marker is -1.66 PASS list marker is 0.67 PASS list marker is 1.65 PASS list marker is 负一. 66 PASS list marker is 零. 67 PASS list marker is 一. 68 68 syriac 69 69 … … 78 78 trad-chinese-formal 79 79 80 PASS list marker is -1.81 PASS list marker is 0.82 PASS list marker is 1.80 PASS list marker is 負壹. 81 PASS list marker is 零. 82 PASS list marker is 壹. 83 83 trad-chinese-informal 84 84 85 PASS list marker is -1.86 PASS list marker is 0.87 PASS list marker is 1.85 PASS list marker is 負一. 86 PASS list marker is 零. 87 PASS list marker is 一. 88 88 upper-armenian 89 89 -
trunk/LayoutTests/fast/lists/w3-css3-list-styles-fallback-style.html
r279055 r279165 16 16 17 17 ol.armenian { list-style-type: armenian; } 18 19 18 ol.cjk-ideographic { list-style-type: cjk-ideographic; } 20 21 19 ol.ethiopic-numeric { list-style-type: ethiopic-numeric; } 22 23 20 ol.georgian { list-style-type: georgian; } 24 25 21 ol.hebrew { list-style-type: hebrew; } 26 27 22 ol.japanese-formal { list-style-type: japanese-formal; } 28 29 23 ol.japanese-informal { list-style-type: japanese-informal; } 30 31 24 ol.lower-armenian { list-style-type: lower-armenian; } 32 33 25 ol.lower-roman { list-style-type: lower-roman; } 34 35 26 ol.simp-chinese-formal { list-style-type: simp-chinese-formal; } 36 37 27 ol.simp-chinese-informal { list-style-type: simp-chinese-informal; } 38 39 28 ol.syriac { list-style-type: syriac; } 40 41 29 ol.tamil { list-style-type: tamil; } 42 43 30 ol.trad-chinese-formal { list-style-type: trad-chinese-formal; } 44 45 31 ol.trad-chinese-informal { list-style-type: trad-chinese-informal; } 46 47 32 ol.upper-armenian { list-style-type: upper-armenian; } 48 49 33 ol.upper-roman { list-style-type: upper-roman; } 50 34 </style> … … 67 51 <div id="description"> 68 52 <p>This tests that we fallback to the decimal list style type when the ordinal is outside the representable range for the list style type as per the <a href="http://www.w3.org/TR/css3-lists/">CSS3 Lists module</a> (Draft 7 November 2002). This test PASSED if the list item matches its marker for every list item (below).</p> 69 <p>Note, as of 12/04/2010, ethiopic-numeric; japanese-formal; japanese-informal; simp-chinese-formal; simp-chinese-informal; syriac; tamil; trad-chinese-formal; and trad-chinese-informal are unsupported and hence haveexpected failure results.</p>53 <p>Note, as of 2021-06-20, syriac is unsupported and hence has expected failure results.</p> 70 54 </div> 71 55 <hr/> … … 87 71 <h2>cjk-ideographic</h2> 88 72 <ol class="cjk-ideographic" start="-1"> 89 <li> -1</li>73 <li>負一</li> 90 74 <li>零</li> 91 75 <li>一</li> … … 94 78 95 79 <div class="test"> 96 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. -->97 80 <h2>ethiopic-numeric</h2> 98 81 <ol class="ethiopic-numeric" start="-1"> 99 82 <li>-1</li> 100 83 <li>0</li> 101 <li> 1</li>84 <li>፩</li> 102 85 </ol> 103 86 </div> … … 120 103 <ol class="hebrew" start="-1"> 121 104 <li>-1</li> 122 <li> אפס</li>105 <li>0</li> 123 106 <li>א</li> 124 107 </ol> 125 108 <ol class="hebrew" start="999999"> 126 <li> תתקצט'תתקצט</li>109 <li>999999</li> 127 110 <li>1000000</li> 128 111 <li>1000001</li> … … 130 113 </div> 131 114 <div class="test"> 132 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. -->133 115 <h2>japanese-formal</h2> 134 116 <ol class="japanese-formal" start="-1"> 135 <li>-1</li> 136 <li>0</li> 137 <li>1</li> 138 </ol> 139 </div> 140 <div class="test"> 141 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. --> 117 <li>マイナス壱</li> 118 <li>零</li> 119 <li>壱</li> 120 </ol> 121 </div> 122 <div class="test"> 142 123 <h2>japanese-informal</h2> 143 124 <ol class="japanese-informal" start="-1"> 144 <li> -1</li>145 <li> 0</li>146 <li> 1</li>125 <li>マイナス一</li> 126 <li>〇</li> 127 <li>一</li> 147 128 </ol> 148 129 </div> … … 164 145 </div> 165 146 <div class="test"> 166 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. -->167 147 <h2>simp-chinese-formal</h2> 168 148 <ol class="simp-chinese-formal" start="-1"> 169 <li>-1</li> 170 <li>0</li> 171 <li>1</li> 172 </ol> 173 </div> 174 <div class="test"> 175 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. --> 149 <li>负壹</li> 150 <li>零</li> 151 <li>壹</li> 152 </ol> 153 </div> 154 <div class="test"> 176 155 <h2>simp-chinese-informal</h2> 177 156 <ol class="simp-chinese-informal" start="-1"> 178 <li> -1</li>179 <li> 0</li>180 <li> 1</li>157 <li>负一</li> 158 <li>零</li> 159 <li>一</li> 181 160 </ol> 182 161 </div> … … 199 178 </div> 200 179 <div class="test"> 201 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. -->202 180 <h2>trad-chinese-formal</h2> 203 181 <ol class="trad-chinese-formal" start="-1"> 204 <li>-1</li> 205 <li>0</li> 206 <li>1</li> 207 </ol> 208 </div> 209 <div class="test"> 210 <!-- FIXME: We don't currently support this list-style-type. These are expected failure results. --> 182 <li>負壹</li> 183 <li>零</li> 184 <li>壹</li> 185 </ol> 186 </div> 187 <div class="test"> 211 188 <h2>trad-chinese-informal</h2> 212 189 <ol class="trad-chinese-informal" start="-1"> 213 <li> -1</li>214 <li> 0</li>215 <li> 1</li>190 <li>負一</li> 191 <li>零</li> 192 <li>一</li> 216 193 </ol> 217 194 </div> -
trunk/LayoutTests/fast/lists/w3-css3-list-styles-numeric-expected.txt
r82713 r279165 387 387 PASS list marker is -80000000. 388 388 PASS list marker is -7FFFFFFF. 389 389 ethiopic-numeric 390 391 PASS list marker is ፩. 392 PASS list marker is ፪. 393 PASS list marker is ፫. 394 PASS list marker is ፬. 395 PASS list marker is ፭. 396 PASS list marker is ፮. 397 PASS list marker is ፯. 398 PASS list marker is ፰. 399 PASS list marker is ፱. 400 PASS list marker is ፲. 401 PASS list marker is ፲፩. 402 PASS list marker is 0. 403 PASS list marker is ፻. 404 PASS list marker is ፩. 405 PASS list marker is ፸፰፻፩፼፺፪. 406 PASS list marker is -2147483648. 407 PASS list marker is -2147483647. 408 -
trunk/LayoutTests/fast/lists/w3-css3-list-styles-numeric.html
r144524 r279165 5 5 .test ol { float: left; padding-right: 20px; } 6 6 .test h2 { clear: left; } 7 .right { padding-left: 120px; } 7 8 .negative-number { padding-left: 300px; } 8 9 .negative-number li:before { content: "\002D"; } … … 14 15 15 16 ol.arabic-indic { list-style-type: arabic-indic; } 16 17 17 ol.binary { list-style-type: binary; } 18 19 18 ol.bengali { list-style-type: bengali; } 20 21 19 ol.cambodian { list-style-type: cambodian; } 22 20 ol.khmer { list-style-type: khmer; } 23 24 21 ol.decimal { list-style-type: decimal; } 25 26 22 ol.decimal-leading-zero { list-style-type: decimal-leading-zero; } 27 28 23 ol.devanagari { list-style-type: devanagari; } 29 30 24 ol.gujarati { list-style-type: gujarati; } 31 32 25 ol.gurmukhi { list-style-type: gurmukhi; } 33 34 26 ol.kannada { list-style-type: kannada; } 35 36 27 ol.lower-hexadecimal { list-style-type: lower-hexadecimal; } 37 38 28 ol.lao { list-style-type: lao; } 39 40 29 ol.malayalam { list-style-type: malayalam; } 41 42 30 ol.mongolian { list-style-type: mongolian; } 43 44 31 ol.myanmar { list-style-type: myanmar; } 45 46 32 ol.octal { list-style-type: octal; } 47 48 33 ol.oriya { list-style-type: oriya; } 49 50 34 ol.persian { list-style-type: persian; } 51 35 ol.urdu { list-style-type: urdu; } 52 53 36 ol.telugu { list-style-type: telugu; } 54 55 37 ol.tibetan { list-style-type: tibetan; } 56 57 38 ol.thai { list-style-type: thai; } 58 59 39 ol.upper-hexadecimal { list-style-type: upper-hexadecimal; } 60 40 </style> … … 72 52 if (!window.testRunner) 73 53 return; 74 54 75 55 testRunner.dumpAsText(); 76 56 filterListsWithReplacement(document.querySelectorAll(".test ol"), testListItemMarkerEqualsListItemText); … … 706 686 </ol> 707 687 </div> 688 689 <div class="test"> 690 <h2>ethiopic-numeric</h2> 691 <ol style="list-style-type: ethiopic-numeric"> 692 <li>፩</li> 693 <li>፪</li> 694 <li>፫</li> 695 <li>፬</li> 696 <li>፭</li> 697 <li>፮</li> 698 <li>፯</li> 699 <li>፰</li> 700 <li>፱</li> 701 <li>፲</li> 702 <li>፲፩</li> 703 </ol> 704 <ol style="list-style-type: ethiopic-numeric" start="0"> 705 <li>0</li> 706 </ol> 707 <ol style="list-style-type: ethiopic-numeric" start="100"> 708 <li>፻</li> 709 </ol> 710 <ol style="list-style-type: ethiopic-numeric" start="-2147483649"> 711 <li>፩</li> 712 </ol> 713 <ol style="list-style-type: ethiopic-numeric" class="right" start="78010092"> 714 <li>፸፰፻፩፼፺፪</li> 715 </ol> 716 <ol style="list-style-type: ethiopic-numeric" class="negative-number" start="-2147483648"> 717 <li>2147483648</li> 718 <li>2147483647</li> 719 </ol> 720 </div> 708 721 </body> 709 722 </html> -
trunk/LayoutTests/fast/lists/w3-list-styles-expected.txt
r64186 r279165 230 230 ק hundred, undefined, may show ק 231 231 קא a hundred and one, undefined, may show קא 232 אפסzero, undefined, may show אפס232 0 zero, undefined, may show אפס 233 233 א one, should show א 234 234 georgian -
trunk/LayoutTests/platform/mac/TestExpectations
r279145 r279165 2164 2164 # @counter-style WPT failures specific to Mac platforms 2165 2165 [ Mojave Catalina ] imported/w3c/web-platform-tests/css/css-counter-styles/lower-armenian/css3-counter-styles-112.html [ ImageOnlyFailure ] 2166 imported/w3c/web-platform-tests/css/css-counter-styles/bengali/css3-counter-styles-117.html [ ImageOnlyFailure ]2167 imported/w3c/web-platform-tests/css/css-counter-styles/gujarati/css3-counter-styles-123.html [ ImageOnlyFailure ]2168 imported/w3c/web-platform-tests/css/css-counter-styles/gurmukhi/css3-counter-styles-126.html [ ImageOnlyFailure ]2169 imported/w3c/web-platform-tests/css/css-counter-styles/lao/css3-counter-styles-132.html [ ImageOnlyFailure ]2170 2166 2171 2167 webkit.org/b/222185 media/media-extension-with-fragment.html [ Crash ] -
trunk/Source/WTF/ChangeLog
r279164 r279165 1 2021-06-21 Darin Adler <darin@apple.com> 2 3 Improve more of the CSS list style implementations 4 https://bugs.webkit.org/show_bug.cgi?id=227206 5 6 Reviewed by Antti Koivisto. 7 8 * wtf/unicode/CharacterNames.h: Added blackDown/Left/RightPointingSmallTriangle. 9 1 10 2021-06-22 Wenson Hsieh <wenson_hsieh@apple.com> 2 11 -
trunk/Source/WTF/wtf/unicode/CharacterNames.h
r266681 r279165 42 42 constexpr UChar apostrophe = 0x0027; 43 43 constexpr UChar blackCircle = 0x25CF; 44 constexpr UChar blackDownPointingSmallTriangle = 0x25BE; 45 constexpr UChar blackLeftPointingSmallTriangle = 0x25C2; 46 constexpr UChar blackRightPointingSmallTriangle = 0x25B8; 44 47 constexpr UChar blackSquare = 0x25A0; 45 48 constexpr UChar blackUpPointingTriangle = 0x25B2; … … 114 117 using WTF::Unicode::aegeanWordSeparatorLine; 115 118 using WTF::Unicode::blackCircle; 119 using WTF::Unicode::blackDownPointingSmallTriangle; 120 using WTF::Unicode::blackLeftPointingSmallTriangle; 121 using WTF::Unicode::blackRightPointingSmallTriangle; 116 122 using WTF::Unicode::blackSquare; 117 123 using WTF::Unicode::blackUpPointingTriangle; -
trunk/Source/WebCore/ChangeLog
r279164 r279165 1 2021-06-21 Darin Adler <darin@apple.com> 2 3 Improve more of the CSS list style implementations 4 https://bugs.webkit.org/show_bug.cgi?id=227206 5 6 Reviewed by Antti Koivisto. 7 8 Added support for 12 new values for list-style-type: disclosure-closed, 9 disclosure-open, ethiopic-numeric, japanese-formal, japanese-informal, 10 korean-hangul-formal, korean-hanja-formal, korean-hanja-informal, 11 simp-chinese-formal, simp-chinese-informal, trad-chinese-informal, 12 and trad-chinese-formal. 13 14 Improved implementation to match specification more closely for a few 15 existing values for list-style-type: armenian, cjk-ideographic, hebrew, 16 lower-armenian, lower-roman, upper-armenian, and upper-roman. 17 18 Fixed a rendering issue where we would position list items incorrectly 19 in list-style-position:inside cases because of measuring the list marker 20 widths and the list marker suffix widths separately and adding them 21 instead of measuring them together. This was causing some of the 22 Web Platform Tests, done using ref tests, to fail. 23 24 * accessibility/AccessibilityObject.cpp: 25 (WebCore::listMarkerTextForNode): Updated since 26 RenderListItem::markerTextWithSuffix now returns a StringView. 27 * accessibility/AccessibilityRenderObject.cpp: 28 (WebCore::AccessibilityRenderObject::stringValue const): Updated 29 to call RenderListMarker::textWithoutSuffix. 30 * accessibility/atk/WebKitAccessibleHyperlink.cpp: 31 (rangeLengthForObject): Ditto. 32 * accessibility/atk/WebKitAccessibleInterfaceText.cpp: 33 (accessibilityObjectLength): Ditto. 34 (webkitAccessibleTextGetText): Updated since 35 RenderListItem::markerTextWithSuffix now returns a StringView. 36 37 * css/CSSPrimitiveValueMappings.h: 38 (WebCore::toCSSValueID): Factored this out into a separate helper. 39 Also made it take advantage of the relationship between the enumeration 40 and the CSS value keywords that the code in the other direction already 41 was relying on so we don't have to list all the keywords. 42 (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Refactored to call the 43 toCSSValueID function. 44 45 * css/CSSValueKeywords.in: Added 12 new list-type-style constants: 46 disclosure-open, disclosure-closed, japanese-informal, japanese-formal, 47 korean-hangul-formal, korean-hanja-informal, korean-hanja-formal, 48 simp-chinese-informal, simp-chinese-formal, trad-chinese-informal, 49 trad-chinese-formal, and ethiopic-numeric. 50 51 * css/parser/CSSPropertyParserHelpers.cpp: 52 (WebCore::CSSPropertyParserHelpers::isPredefinedCounterStyle): Updated 53 since the last predefined counter style is EthiopicNumeric. 54 55 * rendering/RenderListItem.cpp: 56 (WebCore::RenderListItem::markerTextWithoutSuffix const): Renamed from 57 markerText, and changed to return a StringView. 58 (WebCore::RenderListItem::markerTextWithSuffix const): Return a StringView. 59 * rendering/RenderListItem.h: Updated for the above. 60 61 * rendering/RenderListMarker.cpp: 62 (WebCore::toRoman): Deleted. 63 (WebCore::toAlphabeticOrNumeric): Tweaked to use compile time instead of 64 runtime checks for alphabetic vs. numeric. 65 (WebCore::toSymbolic): Updated for above. 66 (WebCore::toAlphabetic): Ditto. 67 (WebCore::toNumeric): Ditto. 68 (WebCore::toHebrewUnder1000): Deleted. 69 (WebCore::toHebrew): Deleted. 70 (WebCore::toArmenianUnder10000): Deleted. 71 (WebCore::toArmenian): Deleted. 72 (WebCore::toGeorgian): Deleted. 73 (WebCore::toCJKIdeographic): Added handling for negative numbers and also 74 tweaked coding style a bit. 75 (WebCore::toPredefinedAdditiveSystem): Added. Implements the additive 76 system concept, which we use below to re-implement Hebrew, Armenian, 77 Georgian, Japanese, and Korean styles. 78 (WebCore::toEthiopicNumeric): Added. 79 (WebCore::effectiveListMarkerType): Added the new styles. Also updated the 80 allowable values for CJKIdeographic to allow negative numbers, and for Hebrew 81 to no longer allow 0 or numbers over 10999. Also sorted the sections by the 82 name of the first list style type in each section. 83 (WebCore::listMarkerSuffix): Changed to return a StringView instead of a 84 UChar, and include the trailing space. Choose the suffix based on the 85 specified type and not the effective type, so fallback does not cause the 86 suffix to fall back. Added the new types. 87 (WebCore::suffixRequiresSpace): Deleted. 88 (WebCore::listMarkerText): Added implementations for all the new types. 89 Also updated the implementation of CJKIdeographic, LowerRoman, UpperRoman, 90 Armenian, UpperArmenian, LowerArmenian, Georgian, and Hebrew to match a 91 newer CSS specification draft, and in most cases was able to use 92 toPredefinedAdditiveSystem instead of language-specific functions. 93 (WebCore::RenderListMarker::createInlineBox): Stop using the isText function, 94 which was only used here. 95 (WebCore::RenderListMarker::paint): Updated for the name change of 96 relativeMarkerRect. Removed unneeded special case for ListStyleType::None. 97 Use the new RenderListMarker::textRun function, moving all the code that 98 deals with direction and suffix in there. 99 (WebCore::reversed): Added. Helper used by textRun. 100 (WebCore::RenderListMarker::textRun const): Added. Composes a TextRun for 101 drawing or measuring text. By using the same function in all those places, 102 we guarantee we measure the text together instead of in pieces, which fixes 103 some layout errors leading to test failures that measuring separately and 104 adding the results together was causing. 105 (WebCore::RenderListMarker::addOverflowFromListMarker): Use the data 106 member m_lineOffsetForListItem instead of the lineOffsetForListItem 107 function, which was only used here. 108 (WebCore::RenderListMarker::updateMarginsAndContent): Moved the check of 109 preferredLogicalWidthsDirty and the comment about it here. 110 (WebCore::RenderListMarker::updateContent): Moved check of 111 preferredLogicalWidthsDirty out of this function since one caller asserts 112 it, and so the other caller can do the check itself. Added code to set 113 m_textWithSuffix, m_textWithoutSuffixLength, and m_textIsLeftToRightDirection. 114 Removed unneeded special cases for ListStyleType::None, Circle, Disc, and 115 Square, which are all handled correctly by the main algorithm. Added a FIXME 116 about the inadequacy of our bidi algorithm implementation for the general case. 117 (WebCore::RenderListMarker::computePreferredLogicalWidths): Use the new 118 textRun function, allowing us to remove some special case code, including 119 the special cases for ListStyleType::None, Asterisks, Footnotes, and String. 120 (WebCore::RenderListMarker::updateMargins): Removed unneeded special case for 121 ListStyleType::None, and updated string empty checks for the new name of the 122 m_textWithSuffix data member. 123 (WebCore::RenderListMarker::suffix const): Deleted. 124 (WebCore::RenderListMarker::relativeMarkerRect): Renamed from 125 getRelativeMarkerRect. Use the new textRun function, allowing us to remove 126 some special case code, including the special cases for ListTyleType::None, 127 Asterisks, Footnotes, and String. 128 (WebCore::RenderListMarker::textWithoutSuffix const): Added. 129 130 * rendering/RenderListMarker.h: Marked functions as final instead of just 131 override. Got rid of unneeded suffix and lineOffsetForListItem functions. 132 Renamed text ot textWithoutSuffix and added textWithSuffix. Added textRun 133 private member function. Replaced m_text with m_textWithSuffix, 134 m_textWithoutSuffixLength, and m_textIsLeftToRightDirection. 135 136 * rendering/RenderTreeAsText.cpp: 137 (WebCore::RenderTreeAsText::writeRenderObject): Use textWithoutSuffix. 138 (WebCore::markerTextForListItem): Use markerTextWithoutSuffix. 139 140 * rendering/style/RenderStyleConstants.cpp: 141 (WebCore::operator<<): Use getValueName from CSSValueKeywords.h and 142 toCSSValueID to avoid repeating the names of all the list style types here. 143 144 * rendering/style/RenderStyleConstants.h: Added the 12 new list style types. 145 1 146 2021-06-22 Wenson Hsieh <wenson_hsieh@apple.com> 2 147 -
trunk/Source/WebCore/accessibility/AccessibilityObject.cpp
r278542 r279165 1161 1161 // because a RenderListMarker does not have a Node equivalent and thus does not appear 1162 1162 // when iterating text. 1163 return listItem->markerTextWithSuffix() ;1163 return listItem->markerTextWithSuffix().toString(); 1164 1164 } 1165 1165 -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
r278907 r279165 771 771 772 772 if (is<RenderListMarker>(*m_renderer)) 773 return downcast<RenderListMarker>(*m_renderer).text ();773 return downcast<RenderListMarker>(*m_renderer).textWithoutSuffix().toString(); 774 774 775 775 if (isWebArea()) -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp
r278542 r279165 178 178 return baseLength; 179 179 180 auto& marker = downcast<RenderListMarker>(*renderer); 181 return baseLength + marker.text().length() + marker.suffix().length(); 180 return baseLength + downcast<RenderListMarker>(*renderer).textWithSuffix().length(); 182 181 } 183 182 -
trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp
r278542 r279165 244 244 // for those cases when it's needed to take it into account 245 245 // separately (as in getAccessibilityObjectForOffset) 246 RenderObject* renderer = object->renderer(); 247 if (is<RenderListMarker>(renderer)) { 248 auto& marker = downcast<RenderListMarker>(*renderer); 249 return marker.text().length() + marker.suffix().length(); 250 } 246 if (auto renderer = object->renderer(); is<RenderListMarker>(renderer)) 247 return downcast<RenderListMarker>(*renderer).textWithSuffix().length(); 251 248 252 249 return 0; … … 462 459 RenderObject* objRenderer = coreObject->renderer(); 463 460 if (is<RenderListItem>(objRenderer)) { 464 String markerText = downcast<RenderListItem>(*objRenderer).markerTextWithSuffix() ;461 String markerText = downcast<RenderListItem>(*objRenderer).markerTextWithSuffix().toString(); 465 462 ret = objRenderer->style().direction() == TextDirection::LTR ? markerText + ret : ret + markerText; 466 463 if (endOffset == -1) -
trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h
r279055 r279165 1732 1732 } 1733 1733 1734 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ListStyleType e) 1735 : CSSValue(PrimitiveClass) 1736 { 1737 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID); 1738 switch (e) { 1739 case ListStyleType::Afar: 1740 m_value.valueID = CSSValueAfar; 1741 break; 1742 case ListStyleType::Amharic: 1743 m_value.valueID = CSSValueAmharic; 1744 break; 1745 case ListStyleType::AmharicAbegede: 1746 m_value.valueID = CSSValueAmharicAbegede; 1747 break; 1748 case ListStyleType::ArabicIndic: 1749 m_value.valueID = CSSValueArabicIndic; 1750 break; 1751 case ListStyleType::Armenian: 1752 m_value.valueID = CSSValueArmenian; 1753 break; 1754 case ListStyleType::Asterisks: 1755 m_value.valueID = CSSValueAsterisks; 1756 break; 1757 case ListStyleType::Binary: 1758 m_value.valueID = CSSValueBinary; 1759 break; 1760 case ListStyleType::Bengali: 1761 m_value.valueID = CSSValueBengali; 1762 break; 1763 case ListStyleType::CJKDecimal: 1764 m_value.valueID = CSSValueCjkDecimal; 1765 break; 1766 case ListStyleType::CJKEarthlyBranch: 1767 m_value.valueID = CSSValueCjkEarthlyBranch; 1768 break; 1769 case ListStyleType::CJKHeavenlyStem: 1770 m_value.valueID = CSSValueCjkHeavenlyStem; 1771 break; 1772 case ListStyleType::CJKIdeographic: 1773 m_value.valueID = CSSValueCjkIdeographic; 1774 break; 1775 case ListStyleType::Cambodian: 1776 m_value.valueID = CSSValueCambodian; 1777 break; 1778 case ListStyleType::Circle: 1779 m_value.valueID = CSSValueCircle; 1780 break; 1781 case ListStyleType::DecimalLeadingZero: 1782 m_value.valueID = CSSValueDecimalLeadingZero; 1783 break; 1784 case ListStyleType::Decimal: 1785 m_value.valueID = CSSValueDecimal; 1786 break; 1787 case ListStyleType::Devanagari: 1788 m_value.valueID = CSSValueDevanagari; 1789 break; 1790 case ListStyleType::Disc: 1791 m_value.valueID = CSSValueDisc; 1792 break; 1793 case ListStyleType::Ethiopic: 1794 m_value.valueID = CSSValueEthiopic; 1795 break; 1796 case ListStyleType::EthiopicAbegede: 1797 m_value.valueID = CSSValueEthiopicAbegede; 1798 break; 1799 case ListStyleType::EthiopicAbegedeAmEt: 1800 m_value.valueID = CSSValueEthiopicAbegedeAmEt; 1801 break; 1802 case ListStyleType::EthiopicAbegedeGez: 1803 m_value.valueID = CSSValueEthiopicAbegedeGez; 1804 break; 1805 case ListStyleType::EthiopicAbegedeTiEr: 1806 m_value.valueID = CSSValueEthiopicAbegedeTiEr; 1807 break; 1808 case ListStyleType::EthiopicAbegedeTiEt: 1809 m_value.valueID = CSSValueEthiopicAbegedeTiEt; 1810 break; 1811 case ListStyleType::EthiopicHalehameAaEr: 1812 m_value.valueID = CSSValueEthiopicHalehameAaEr; 1813 break; 1814 case ListStyleType::EthiopicHalehameAaEt: 1815 m_value.valueID = CSSValueEthiopicHalehameAaEt; 1816 break; 1817 case ListStyleType::EthiopicHalehameAmEt: 1818 m_value.valueID = CSSValueEthiopicHalehameAmEt; 1819 break; 1820 case ListStyleType::EthiopicHalehameGez: 1821 m_value.valueID = CSSValueEthiopicHalehameGez; 1822 break; 1823 case ListStyleType::EthiopicHalehameOmEt: 1824 m_value.valueID = CSSValueEthiopicHalehameOmEt; 1825 break; 1826 case ListStyleType::EthiopicHalehameSidEt: 1827 m_value.valueID = CSSValueEthiopicHalehameSidEt; 1828 break; 1829 case ListStyleType::EthiopicHalehameSoEt: 1830 m_value.valueID = CSSValueEthiopicHalehameSoEt; 1831 break; 1832 case ListStyleType::EthiopicHalehameTiEr: 1833 m_value.valueID = CSSValueEthiopicHalehameTiEr; 1834 break; 1835 case ListStyleType::EthiopicHalehameTiEt: 1836 m_value.valueID = CSSValueEthiopicHalehameTiEt; 1837 break; 1838 case ListStyleType::EthiopicHalehameTig: 1839 m_value.valueID = CSSValueEthiopicHalehameTig; 1840 break; 1841 case ListStyleType::Footnotes: 1842 m_value.valueID = CSSValueFootnotes; 1843 break; 1844 case ListStyleType::Georgian: 1845 m_value.valueID = CSSValueGeorgian; 1846 break; 1847 case ListStyleType::Gujarati: 1848 m_value.valueID = CSSValueGujarati; 1849 break; 1850 case ListStyleType::Gurmukhi: 1851 m_value.valueID = CSSValueGurmukhi; 1852 break; 1853 case ListStyleType::Hangul: 1854 m_value.valueID = CSSValueHangul; 1855 break; 1856 case ListStyleType::HangulConsonant: 1857 m_value.valueID = CSSValueHangulConsonant; 1858 break; 1859 case ListStyleType::Hebrew: 1860 m_value.valueID = CSSValueHebrew; 1861 break; 1862 case ListStyleType::Hiragana: 1863 m_value.valueID = CSSValueHiragana; 1864 break; 1865 case ListStyleType::HiraganaIroha: 1866 m_value.valueID = CSSValueHiraganaIroha; 1867 break; 1868 case ListStyleType::Kannada: 1869 m_value.valueID = CSSValueKannada; 1870 break; 1871 case ListStyleType::Katakana: 1872 m_value.valueID = CSSValueKatakana; 1873 break; 1874 case ListStyleType::KatakanaIroha: 1875 m_value.valueID = CSSValueKatakanaIroha; 1876 break; 1877 case ListStyleType::Khmer: 1878 m_value.valueID = CSSValueKhmer; 1879 break; 1880 case ListStyleType::Lao: 1881 m_value.valueID = CSSValueLao; 1882 break; 1883 case ListStyleType::LowerAlpha: 1884 m_value.valueID = CSSValueLowerAlpha; 1885 break; 1886 case ListStyleType::LowerArmenian: 1887 m_value.valueID = CSSValueLowerArmenian; 1888 break; 1889 case ListStyleType::LowerGreek: 1890 m_value.valueID = CSSValueLowerGreek; 1891 break; 1892 case ListStyleType::LowerHexadecimal: 1893 m_value.valueID = CSSValueLowerHexadecimal; 1894 break; 1895 case ListStyleType::LowerLatin: 1896 m_value.valueID = CSSValueLowerLatin; 1897 break; 1898 case ListStyleType::LowerNorwegian: 1899 m_value.valueID = CSSValueLowerNorwegian; 1900 break; 1901 case ListStyleType::LowerRoman: 1902 m_value.valueID = CSSValueLowerRoman; 1903 break; 1904 case ListStyleType::Malayalam: 1905 m_value.valueID = CSSValueMalayalam; 1906 break; 1907 case ListStyleType::Mongolian: 1908 m_value.valueID = CSSValueMongolian; 1909 break; 1910 case ListStyleType::Myanmar: 1911 m_value.valueID = CSSValueMyanmar; 1912 break; 1734 inline CSSValueID toCSSValueID(ListStyleType style) 1735 { 1736 switch (style) { 1913 1737 case ListStyleType::None: 1914 m_value.valueID = CSSValueNone; 1915 break; 1916 case ListStyleType::Octal: 1917 m_value.valueID = CSSValueOctal; 1918 break; 1919 case ListStyleType::Oriya: 1920 m_value.valueID = CSSValueOriya; 1921 break; 1922 case ListStyleType::Oromo: 1923 m_value.valueID = CSSValueOromo; 1924 break; 1925 case ListStyleType::Persian: 1926 m_value.valueID = CSSValuePersian; 1927 break; 1928 case ListStyleType::Sidama: 1929 m_value.valueID = CSSValueSidama; 1930 break; 1931 case ListStyleType::Somali: 1932 m_value.valueID = CSSValueSomali; 1933 break; 1934 case ListStyleType::Square: 1935 m_value.valueID = CSSValueSquare; 1936 break; 1738 return CSSValueNone; 1937 1739 case ListStyleType::String: 1938 1740 ASSERT_NOT_REACHED(); 1939 m_value.valueID = CSSValueInvalid; 1940 break; 1941 case ListStyleType::Tamil: 1942 m_value.valueID = CSSValueTamil; 1943 break; 1944 case ListStyleType::Telugu: 1945 m_value.valueID = CSSValueTelugu; 1946 break; 1947 case ListStyleType::Thai: 1948 m_value.valueID = CSSValueThai; 1949 break; 1950 case ListStyleType::Tibetan: 1951 m_value.valueID = CSSValueTibetan; 1952 break; 1953 case ListStyleType::Tigre: 1954 m_value.valueID = CSSValueTigre; 1955 break; 1956 case ListStyleType::TigrinyaEr: 1957 m_value.valueID = CSSValueTigrinyaEr; 1958 break; 1959 case ListStyleType::TigrinyaErAbegede: 1960 m_value.valueID = CSSValueTigrinyaErAbegede; 1961 break; 1962 case ListStyleType::TigrinyaEt: 1963 m_value.valueID = CSSValueTigrinyaEt; 1964 break; 1965 case ListStyleType::TigrinyaEtAbegede: 1966 m_value.valueID = CSSValueTigrinyaEtAbegede; 1967 break; 1968 case ListStyleType::UpperAlpha: 1969 m_value.valueID = CSSValueUpperAlpha; 1970 break; 1971 case ListStyleType::UpperArmenian: 1972 m_value.valueID = CSSValueUpperArmenian; 1973 break; 1974 case ListStyleType::UpperGreek: 1975 m_value.valueID = CSSValueUpperGreek; 1976 break; 1977 case ListStyleType::UpperHexadecimal: 1978 m_value.valueID = CSSValueUpperHexadecimal; 1979 break; 1980 case ListStyleType::UpperLatin: 1981 m_value.valueID = CSSValueUpperLatin; 1982 break; 1983 case ListStyleType::UpperNorwegian: 1984 m_value.valueID = CSSValueUpperNorwegian; 1985 break; 1986 case ListStyleType::UpperRoman: 1987 m_value.valueID = CSSValueUpperRoman; 1988 break; 1989 case ListStyleType::Urdu: 1990 m_value.valueID = CSSValueUrdu; 1991 break; 1992 } 1741 return CSSValueInvalid; 1742 default: 1743 return static_cast<CSSValueID>(static_cast<int>(CSSValueDisc) + static_cast<uint8_t>(style)); 1744 } 1745 } 1746 1747 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ListStyleType style) 1748 : CSSValue(PrimitiveClass) 1749 { 1750 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID); 1751 m_value.valueID = toCSSValueID(style); 1993 1752 } 1994 1753 -
trunk/Source/WebCore/css/CSSValueKeywords.in
r279055 r279165 447 447 cjk-decimal 448 448 tamil 449 disclosure-open 450 disclosure-closed 451 japanese-informal 452 japanese-formal 453 korean-hangul-formal 454 korean-hanja-informal 455 korean-hanja-formal 456 simp-chinese-informal 457 simp-chinese-formal 458 trad-chinese-informal 459 trad-chinese-formal 460 ethiopic-numeric 449 461 //none 450 462 // -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
r279055 r279165 3534 3534 bool isPredefinedCounterStyle(CSSValueID valueID) 3535 3535 { 3536 return valueID >= CSSValueDisc && valueID <= CSSValue Tamil;3536 return valueID >= CSSValueDisc && valueID <= CSSValueEthiopicNumeric; 3537 3537 } 3538 3538 -
trunk/Source/WebCore/rendering/RenderListItem.cpp
r278534 r279165 277 277 } 278 278 279 const String& RenderListItem::markerText() const 280 { 281 if (m_marker) 282 return m_marker->text(); 283 return nullAtom().string(); 284 } 285 286 String RenderListItem::markerTextWithSuffix() const 279 StringView RenderListItem::markerTextWithoutSuffix() const 287 280 { 288 281 if (!m_marker) 289 return String(); 290 291 // Append the suffix for the marker in the right place depending 292 // on the direction of the text (right-to-left or left-to-right). 293 if (m_marker->style().isLeftToRightDirection()) 294 return m_marker->text() + m_marker->suffix(); 295 return m_marker->suffix() + m_marker->text(); 282 return { }; 283 return m_marker->textWithoutSuffix(); 284 } 285 286 StringView RenderListItem::markerTextWithSuffix() const 287 { 288 if (!m_marker) 289 return { }; 290 return m_marker->textWithSuffix(); 296 291 } 297 292 -
trunk/Source/WebCore/rendering/RenderListItem.h
r278253 r279165 47 47 bool notInList() const { return m_notInList; } 48 48 49 WEBCORE_EXPORT const String& markerText() const;50 String markerTextWithSuffix() const;49 WEBCORE_EXPORT StringView markerTextWithoutSuffix() const; 50 StringView markerTextWithSuffix() const; 51 51 52 52 void updateListMarkerNumbers(); … … 63 63 64 64 private: 65 66 65 const char* renderName() const final { return "RenderListItem"; } 67 66 -
trunk/Source/WebCore/rendering/RenderListMarker.cpp
r279055 r279165 42 42 namespace WebCore { 43 43 44 using namespace WTF::Unicode; 44 // As of June 2021, the Microsoft C++ compiler seems unable to include std::initializer_list in a constexpr. 45 #if COMPILER(MSVC) 46 #define CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND const 47 #else 48 #define CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND constexpr 49 #endif 45 50 46 51 WTF_MAKE_ISO_ALLOCATED_IMPL(RenderListMarker); … … 48 53 constexpr int cMarkerPadding = 7; 49 54 50 enum class LetterCase { Lower, Upper }; 51 enum class SequenceType { Numeric, Alphabetic }; 52 53 static NEVER_INLINE String toRoman(int number, LetterCase letterCase) 54 { 55 // FIXME: CSS3 describes how to make this work for much larger numbers, 56 // using overbars and special characters. It also specifies the characters 57 // in the range U+2160 to U+217F instead of standard ASCII ones. 58 ASSERT(number >= 1 && number <= 3999); 59 60 // Big enough to store largest roman number less than 3999 which 61 // is 3888 (MMMDCCCLXXXVIII) 62 constexpr unsigned lettersSize = 15; 63 LChar letters[lettersSize]; 64 65 unsigned length = 0; 66 constexpr LChar ldigits[] = { 'i', 'v', 'x', 'l', 'c', 'd', 'm' }; 67 constexpr LChar udigits[] = { 'I', 'V', 'X', 'L', 'C', 'D', 'M' }; 68 const LChar* digits = letterCase == LetterCase::Upper ? udigits : ldigits; 69 int d = 0; 70 do { 71 int num = number % 10; 72 if (num % 5 < 4) 73 for (int i = num % 5; i > 0; i--) 74 letters[lettersSize - ++length] = digits[d]; 75 if (num >= 4 && num <= 8) 76 letters[lettersSize - ++length] = digits[d + 1]; 77 if (num == 9) 78 letters[lettersSize - ++length] = digits[d + 2]; 79 if (num % 5 == 4) 80 letters[lettersSize - ++length] = digits[d]; 81 number /= 10; 82 d += 2; 83 } while (number); 84 85 ASSERT(length <= lettersSize); 86 return { &letters[lettersSize - length], length }; 87 } 88 89 template<typename CharacterType> 90 static inline String toAlphabeticOrNumeric(int number, const CharacterType* sequence, unsigned sequenceSize, SequenceType type) 55 enum class SequenceType : bool { Numeric, Alphabetic }; 56 enum class Formality : bool { Informal, Formal }; 57 58 template<SequenceType type, typename CharacterType> static String toAlphabeticOrNumeric(int number, const CharacterType* sequence, unsigned sequenceSize) 91 59 { 92 60 ASSERT(sequenceSize >= 2); … … 99 67 bool isNegativeNumber = false; 100 68 unsigned numberShadow = number; 101 if (type == SequenceType::Alphabetic) {69 if constexpr (type == SequenceType::Alphabetic) { 102 70 ASSERT(number > 0); 103 71 --numberShadow; … … 109 77 unsigned length = 1; 110 78 111 if (type == SequenceType::Alphabetic) {79 if constexpr (type == SequenceType::Alphabetic) { 112 80 while ((numberShadow /= sequenceSize) > 0) { 113 81 --numberShadow; … … 125 93 } 126 94 127 template<typename CharacterType> 128 static NEVER_INLINE String toSymbolic(int number, const CharacterType* symbols, unsigned symbolsSize) 95 template<typename CharacterType> static String toSymbolic(int number, const CharacterType* symbols, unsigned symbolsSize) 129 96 { 130 97 ASSERT(number > 0); … … 132 99 133 100 // The asterisks list-style-type is the worst case; we show |number| asterisks. 134 CharacterTypesymbol = symbols[(number - 1) % symbolsSize];101 auto symbol = symbols[(number - 1) % symbolsSize]; 135 102 unsigned count = (number - 1) / symbolsSize + 1; 136 103 … … 142 109 } 143 110 144 template<typename CharacterType> 145 static NEVER_INLINE String toAlphabetic(int number, const CharacterType* alphabet, unsigned alphabetSize) 146 { 147 return toAlphabeticOrNumeric(number, alphabet, alphabetSize, SequenceType::Alphabetic); 148 } 149 150 template<typename CharacterType> 151 static NEVER_INLINE String toNumeric(int number, const CharacterType* numerals, unsigned numeralsSize) 152 { 153 return toAlphabeticOrNumeric(number, numerals, numeralsSize, SequenceType::Numeric); 154 } 155 156 template<typename CharacterType, size_t size> 157 static inline String toAlphabetic(int number, const CharacterType(&alphabet)[size]) 111 template<typename CharacterType> static String toAlphabetic(int number, const CharacterType* alphabet, unsigned alphabetSize) 112 { 113 return toAlphabeticOrNumeric<SequenceType::Alphabetic>(number, alphabet, alphabetSize); 114 } 115 116 template<typename CharacterType> static String toNumeric(int number, const CharacterType* numerals, unsigned numeralsSize) 117 { 118 return toAlphabeticOrNumeric<SequenceType::Numeric>(number, numerals, numeralsSize); 119 } 120 121 template<typename CharacterType, size_t size> static String toAlphabetic(int number, const CharacterType(&alphabet)[size]) 158 122 { 159 123 return toAlphabetic(number, alphabet, size); 160 124 } 161 125 162 template<typename CharacterType, size_t size> 163 static inline String toNumeric(int number, const CharacterType(&alphabet)[size]) 126 template<typename CharacterType, size_t size> static String toNumeric(int number, const CharacterType(&alphabet)[size]) 164 127 { 165 128 return toNumeric(number, alphabet, size); 166 129 } 167 130 168 template<typename CharacterType, size_t size> 169 static inline String toSymbolic(int number, const CharacterType(&alphabet)[size]) 131 template<typename CharacterType, size_t size> static String toSymbolic(int number, const CharacterType(&alphabet)[size]) 170 132 { 171 133 return toSymbolic(number, alphabet, size); 172 134 } 173 135 174 static NEVER_INLINE int toHebrewUnder1000(int number, UChar letters[5]) 175 { 176 // FIXME: CSS3 mentions various refinements not implemented here. 177 // FIXME: Should take a look at Mozilla's HebrewToText function (in nsBulletFrame). 178 ASSERT(number >= 0 && number < 1000); 179 int length = 0; 180 int fourHundreds = number / 400; 181 for (int i = 0; i < fourHundreds; i++) 182 letters[length++] = 1511 + 3; 183 number %= 400; 184 if (number / 100) 185 letters[length++] = 1511 + (number / 100) - 1; 186 number %= 100; 187 if (number == 15 || number == 16) { 188 letters[length++] = 1487 + 9; 189 letters[length++] = 1487 + number - 9; 190 } else { 191 if (int tens = number / 10) { 192 static constexpr UChar hebrewTens[9] = { 1497, 1499, 1500, 1502, 1504, 1505, 1506, 1508, 1510 }; 193 letters[length++] = hebrewTens[tens - 1]; 194 } 195 if (int ones = number % 10) 196 letters[length++] = 1487 + ones; 197 } 198 ASSERT(length <= 5); 199 return length; 200 } 201 202 static NEVER_INLINE String toHebrew(int number) 203 { 204 // FIXME: CSS3 mentions ways to make this work for much larger numbers. 205 ASSERT(number >= 0 && number <= 999999); 206 207 if (number == 0) { 208 static constexpr UChar hebrewZero[3] = { 0x05D0, 0x05E4, 0x05E1 }; 209 return { hebrewZero, 3 }; 210 } 211 212 constexpr unsigned lettersSize = 11; // big enough for two 5-digit sequences plus a quote mark between 213 UChar letters[lettersSize]; 214 215 unsigned length; 216 if (number < 1000) 217 length = 0; 218 else { 219 length = toHebrewUnder1000(number / 1000, letters); 220 letters[length++] = '\''; 221 number = number % 1000; 222 } 223 length += toHebrewUnder1000(number, letters + length); 224 225 ASSERT(length <= lettersSize); 226 return { letters, length }; 227 } 228 229 static NEVER_INLINE unsigned toArmenianUnder10000(int number, LetterCase letterCase, bool addCircumflex, UChar letters[9]) 230 { 231 ASSERT(number >= 0 && number < 10000); 232 unsigned length = 0; 233 234 int lowerOffset = letterCase == LetterCase::Upper ? 0 : 0x0030; 235 236 if (int thousands = number / 1000) { 237 if (thousands == 7) { 238 letters[length++] = 0x0552 + lowerOffset; 239 if (addCircumflex) 240 letters[length++] = 0x0302; 241 } else { 242 letters[length++] = (0x054C - 1 + lowerOffset) + thousands; 243 if (addCircumflex) 244 letters[length++] = 0x0302; 245 } 246 } 247 248 if (int hundreds = (number / 100) % 10) { 249 letters[length++] = (0x0543 - 1 + lowerOffset) + hundreds; 250 if (addCircumflex) 251 letters[length++] = 0x0302; 252 } 253 254 if (int tens = (number / 10) % 10) { 255 letters[length++] = (0x053A - 1 + lowerOffset) + tens; 256 if (addCircumflex) 257 letters[length++] = 0x0302; 258 } 259 260 if (int ones = number % 10) { 261 letters[length++] = (0x531 - 1 + lowerOffset) + ones; 262 if (addCircumflex) 263 letters[length++] = 0x0302; 264 } 265 266 return length; 267 } 268 269 static NEVER_INLINE String toArmenian(int number, LetterCase letterCase) 270 { 271 ASSERT(number >= 1 && number <= 99999999); 272 273 constexpr unsigned lettersSize = 18; // twice what toArmenianUnder10000 needs 274 UChar letters[lettersSize]; 275 276 unsigned length = toArmenianUnder10000(number / 10000, letterCase, true, letters); 277 length += toArmenianUnder10000(number % 10000, letterCase, false, letters + length); 278 279 ASSERT(length <= lettersSize); 280 return { letters, length }; 281 } 282 283 static NEVER_INLINE String toGeorgian(int number) 284 { 285 ASSERT(number >= 1 && number <= 19999); 286 287 constexpr unsigned lettersSize = 5; 288 UChar letters[lettersSize]; 289 290 unsigned length = 0; 291 292 if (number > 9999) 293 letters[length++] = 0x10F5; 294 295 if (int thousands = (number / 1000) % 10) { 296 static constexpr UChar georgianThousands[9] = { 297 0x10E9, 0x10EA, 0x10EB, 0x10EC, 0x10ED, 0x10EE, 0x10F4, 0x10EF, 0x10F0 298 }; 299 letters[length++] = georgianThousands[thousands - 1]; 300 } 301 302 if (int hundreds = (number / 100) % 10) { 303 static constexpr UChar georgianHundreds[9] = { 304 0x10E0, 0x10E1, 0x10E2, 0x10F3, 0x10E4, 0x10E5, 0x10E6, 0x10E7, 0x10E8 305 }; 306 letters[length++] = georgianHundreds[hundreds - 1]; 307 } 308 309 if (int tens = (number / 10) % 10) { 310 static constexpr UChar georgianTens[9] = { 311 0x10D8, 0x10D9, 0x10DA, 0x10DB, 0x10DC, 0x10F2, 0x10DD, 0x10DE, 0x10DF 312 }; 313 letters[length++] = georgianTens[tens - 1]; 314 } 315 316 if (int ones = number % 10) { 317 static constexpr UChar georgianOnes[9] = { 318 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10F1, 0x10D7 319 }; 320 letters[length++] = georgianOnes[ones - 1]; 321 } 322 323 ASSERT(length <= lettersSize); 324 return { letters, length }; 325 } 326 327 // The table uses the order from the CSS3 specification: 328 // first 3 group markers, then 3 digit markers, then ten digits. 329 static NEVER_INLINE String toCJKIdeographic(int number, const UChar table[16]) 330 { 331 ASSERT(number >= 0); 332 333 enum AbstractCJKChar { 334 noChar, 335 secondGroupMarker, thirdGroupMarker, fourthGroupMarker, 336 secondDigitMarker, thirdDigitMarker, fourthDigitMarker, 337 digit0, digit1, digit2, digit3, digit4, 338 digit5, digit6, digit7, digit8, digit9 136 // This table format was derived from an old draft of the CSS specification: 3 group markers, 3 digit markers, 10 digits, negative sign. 137 static String toCJKIdeographic(int number, const UChar table[17], Formality formality) 138 { 139 enum AbstractCJKCharacter { 140 NoChar, 141 SecondGroupMarker, ThirdGroupMarker, FourthGroupMarker, 142 SecondDigitMarker, ThirdDigitMarker, FourthDigitMarker, 143 Digit0, Digit1, Digit2, Digit3, Digit4, 144 Digit5, Digit6, Digit7, Digit8, Digit9, 145 NegativeSign 339 146 }; 340 147 341 148 if (!number) 342 return { &table[digit0 - 1] , 1 }; 149 return { &table[Digit0 - 1] , 1 }; 150 151 ASSERT(number != std::numeric_limits<int>::min()); 152 bool needsNegativeSign = number < 0; 153 if (needsNegativeSign) 154 number = -number; 343 155 344 156 constexpr unsigned groupLength = 8; // 4 digits, 3 digit markers, and a group marker 345 157 constexpr unsigned bufferLength = 4 * groupLength; 346 AbstractCJKChar buffer[bufferLength] = { noChar };158 AbstractCJKCharacter buffer[bufferLength] = { NoChar }; 347 159 348 160 for (int i = 0; i < 4; ++i) { … … 351 163 352 164 // Process least-significant group first, but put it in the buffer last. 353 AbstractCJKChar*group = &buffer[(3 - i) * groupLength];165 auto group = &buffer[(3 - i) * groupLength]; 354 166 355 167 if (groupValue && i) 356 group[7] = static_cast<AbstractCJKChar >(secondGroupMarker - 1 + i);168 group[7] = static_cast<AbstractCJKCharacter>(SecondGroupMarker - 1 + i); 357 169 358 170 // Put in the four digits and digit markers for any non-zero digits. 359 group[6] = static_cast<AbstractCJKChar >(digit0 + (groupValue % 10));171 group[6] = static_cast<AbstractCJKCharacter>(Digit0 + (groupValue % 10)); 360 172 if (number != 0 || groupValue > 9) { 361 173 int digitValue = ((groupValue / 10) % 10); 362 group[4] = static_cast<AbstractCJKChar >(digit0 + digitValue);174 group[4] = static_cast<AbstractCJKCharacter>(Digit0 + digitValue); 363 175 if (digitValue) 364 group[5] = secondDigitMarker;176 group[5] = SecondDigitMarker; 365 177 } 366 178 if (number != 0 || groupValue > 99) { 367 179 int digitValue = ((groupValue / 100) % 10); 368 group[2] = static_cast<AbstractCJKChar >(digit0 + digitValue);180 group[2] = static_cast<AbstractCJKCharacter>(Digit0 + digitValue); 369 181 if (digitValue) 370 group[3] = thirdDigitMarker;182 group[3] = ThirdDigitMarker; 371 183 } 372 184 if (number != 0 || groupValue > 999) { 373 185 int digitValue = groupValue / 1000; 374 group[0] = static_cast<AbstractCJKChar >(digit0 + digitValue);186 group[0] = static_cast<AbstractCJKCharacter>(Digit0 + digitValue); 375 187 if (digitValue) 376 group[1] = fourthDigitMarker;188 group[1] = FourthDigitMarker; 377 189 } 378 190 379 // Remove the tens digit, but leave the marker, for any group that has 380 // a value of less than 20. 381 if (groupValue < 20) { 382 ASSERT(group[4] == noChar || group[4] == digit0 || group[4] == digit1); 383 group[4] = noChar; 191 if (formality == Formality::Informal && groupValue < 20) { 192 // Remove the tens digit, but leave the marker. 193 ASSERT(group[4] == NoChar || group[4] == Digit0 || group[4] == Digit1); 194 group[4] = NoChar; 384 195 } 385 196 … … 390 201 // Convert into characters, omitting consecutive runs of digit0 and trailing digit0. 391 202 unsigned length = 0; 392 UChar characters[bufferLength]; 393 AbstractCJKChar last = noChar; 203 UChar characters[1 + bufferLength]; 204 auto last = NoChar; 205 if (needsNegativeSign) 206 characters[length++] = table[NegativeSign - 1]; 394 207 for (unsigned i = 0; i < bufferLength; ++i) { 395 AbstractCJKChar a= buffer[i];396 if ( a != noChar) {397 if ( a != digit0 || last != digit0)398 characters[length++] = table[ a- 1];399 last = a;208 auto character = buffer[i]; 209 if (character != NoChar) { 210 if (character != Digit0 || last != Digit0) 211 characters[length++] = table[character - 1]; 212 last = character; 400 213 } 401 214 } 402 if (last == digit0)215 if (last == Digit0) 403 216 --length; 404 217 … … 406 219 } 407 220 221 struct AdditiveSymbol { 222 int value; 223 std::initializer_list<UChar> characters; 224 }; 225 struct AdditiveSystem { 226 std::initializer_list<AdditiveSymbol> symbols; 227 std::initializer_list<UChar> negative; 228 }; 229 230 static String toPredefinedAdditiveSystem(int value, const AdditiveSystem& system) 231 { 232 if (!value) { 233 ASSERT(!system.symbols.end()[-1].value); 234 auto& zeroCharacters = system.symbols.end()[-1].characters; 235 return { zeroCharacters.begin(), static_cast<unsigned>(zeroCharacters.size()) }; 236 } 237 238 StringBuilder result; 239 auto append = [&] (std::initializer_list<UChar> characters) { 240 result.append(StringView { characters.begin(), static_cast<unsigned>(characters.size()) }); 241 }; 242 if (value < 0) { 243 ASSERT(value != std::numeric_limits<int>::min()); 244 append(system.negative); 245 value = -value; 246 } 247 for (auto& symbol : system.symbols) { 248 while (value >= symbol.value) { 249 append(symbol.characters); 250 value -= symbol.value; 251 } 252 if (!value) 253 break; 254 } 255 ASSERT(!value); 256 return result.toString(); 257 } 258 259 static String toEthiopicNumeric(int value) 260 { 261 ASSERT(value >= 1); 262 263 if (value == 1) { 264 UChar ethiopicDigitOne = 0x1369; 265 return { ðiopicDigitOne, 1 }; 266 } 267 268 // Split the number into groups of two digits, starting with the least significant decimal digit. 269 uint8_t groups[5]; 270 for (auto& group : groups) { 271 group = value % 100; 272 value /= 100; 273 } 274 275 UChar buffer[std::size(groups) * 3]; 276 unsigned length = 0; 277 bool isMostSignificantGroup = true; 278 for (int i = std::size(groups) - 1; i >= 0; --i) { 279 auto value = groups[i]; 280 bool isOddIndex = i & 1; 281 // If the group has the value zero, or if the group is the most significant one and has the value 1, 282 // or if the group has an odd index (as given in the previous step) and has the value 1, 283 // then remove the digits (but leave the group, so it still has a separator appended below). 284 if (!(value == 1 && (isMostSignificantGroup || isOddIndex))) { 285 if (auto tens = value / 10) 286 buffer[length++] = 0x1371 + tens; 287 if (auto ones = value % 10) 288 buffer[length++] = 0x1368 + ones; 289 } 290 if (value && isOddIndex) 291 buffer[length++] = 0x137B; 292 if ((value || !isMostSignificantGroup) && !isOddIndex && i) 293 buffer[length++] = 0x137C; 294 if (value) 295 isMostSignificantGroup = false; 296 } 297 298 return { buffer, length }; 299 } 300 408 301 static ListStyleType effectiveListMarkerType(ListStyleType type, int value) 409 302 { 410 // FIXME: Types we need to add: japanese-formal, japanese-informal, korean-hangul-formal, korean-hanja-formal, korean-hanja-informal, simp-chinese-formal, simp-chinese-informal, tammil, trad-chinese-formal, trad-chinese-informal411 412 303 // Note, the following switch statement has been explicitly grouped by list-style-type ordinal range. 413 304 switch (type) { … … 421 312 case ListStyleType::Devanagari: 422 313 case ListStyleType::Disc: 314 case ListStyleType::DisclosureClosed: 315 case ListStyleType::DisclosureOpen: 423 316 case ListStyleType::Gujarati: 424 317 case ListStyleType::Gurmukhi: … … 442 335 case ListStyleType::Urdu: 443 336 return type; // Can represent all ordinals. 444 case ListStyleType::Armenian:445 case ListStyleType::LowerArmenian:446 case ListStyleType::UpperArmenian:447 return (value < 1 || value > 9999) ? ListStyleType::Decimal : type;448 case ListStyleType::CJKDecimal:449 case ListStyleType::CJKIdeographic:450 return (value < 0) ? ListStyleType::Decimal : type;451 case ListStyleType::Georgian:452 return (value < 1 || value > 19999) ? ListStyleType::Decimal : type;453 case ListStyleType::Hebrew:454 return (value < 0 || value > 999999) ? ListStyleType::Decimal : type;455 case ListStyleType::LowerRoman:456 case ListStyleType::UpperRoman:457 return (value < 1 || value > 3999) ? ListStyleType::Decimal : type;458 337 case ListStyleType::Afar: 459 338 case ListStyleType::Amharic: … … 478 357 case ListStyleType::EthiopicHalehameTiEt: 479 358 case ListStyleType::EthiopicHalehameTig: 359 case ListStyleType::EthiopicNumeric: 480 360 case ListStyleType::Footnotes: 481 361 case ListStyleType::Hangul: … … 502 382 case ListStyleType::UpperNorwegian: 503 383 return (value < 1) ? ListStyleType::Decimal : type; 384 case ListStyleType::Armenian: 385 case ListStyleType::LowerArmenian: 386 case ListStyleType::UpperArmenian: 387 return (value < 1 || value > 9999) ? ListStyleType::Decimal : type; 388 case ListStyleType::CJKDecimal: 389 return (value < 0) ? ListStyleType::Decimal : type; 390 case ListStyleType::CJKIdeographic: 391 case ListStyleType::JapaneseFormal: 392 case ListStyleType::JapaneseInformal: 393 case ListStyleType::SimplifiedChineseFormal: 394 case ListStyleType::SimplifiedChineseInformal: 395 case ListStyleType::TraditionalChineseFormal: 396 case ListStyleType::TraditionalChineseInformal: 397 return value < -9999 ? ListStyleType::Decimal : value > 9999 ? ListStyleType::CJKDecimal : type; 398 case ListStyleType::Georgian: 399 return (value < 1 || value > 19999) ? ListStyleType::Decimal : type; 400 case ListStyleType::Hebrew: 401 return (value < 1 || value > 10999) ? ListStyleType::Decimal : type; 402 case ListStyleType::KoreanHangulFormal: 403 case ListStyleType::KoreanHanjaInformal: 404 case ListStyleType::KoreanHanjaFormal: 405 return (value < -9999 || value > 9999) ? ListStyleType::Decimal : type; 406 case ListStyleType::LowerRoman: 407 case ListStyleType::UpperRoman: 408 return (value < 1 || value > 3999) ? ListStyleType::Decimal : type; 504 409 case ListStyleType::String: 505 410 ASSERT_NOT_REACHED(); … … 511 416 } 512 417 513 static UChar listMarkerSuffix(ListStyleType type, int value) 514 { 515 // Note, the following switch statement has been explicitly grouped by list-style-type suffix. 516 switch (effectiveListMarkerType(type, value)) { 418 static StringView listMarkerSuffix(ListStyleType type) 419 { 420 switch (type) { 517 421 case ListStyleType::Asterisks: 518 422 case ListStyleType::Circle: 519 423 case ListStyleType::Disc: 424 case ListStyleType::DisclosureClosed: 425 case ListStyleType::DisclosureOpen: 520 426 case ListStyleType::Footnotes: 521 427 case ListStyleType::None: 522 428 case ListStyleType::Square: 523 return ' ';429 return { &space, 1 }; 524 430 case ListStyleType::Afar: 525 431 case ListStyleType::Amharic: … … 548 454 case ListStyleType::TigrinyaErAbegede: 549 455 case ListStyleType::TigrinyaEt: 550 case ListStyleType::TigrinyaEtAbegede: 551 return ethiopicPrefaceColon; 456 case ListStyleType::TigrinyaEtAbegede: { 457 static constexpr UChar ethiopicPrefaceColonAndSpace[2] = { ethiopicPrefaceColon, ' ' }; 458 return { ethiopicPrefaceColonAndSpace, 2 }; 459 } 552 460 case ListStyleType::Armenian: 553 461 case ListStyleType::ArabicIndic: … … 555 463 case ListStyleType::Binary: 556 464 case ListStyleType::Cambodian: 557 case ListStyleType::CJKIdeographic:558 465 case ListStyleType::DecimalLeadingZero: 559 466 case ListStyleType::Decimal: … … 593 500 case ListStyleType::UpperRoman: 594 501 case ListStyleType::Urdu: 595 return '.';502 return ". "; 596 503 case ListStyleType::CJKDecimal: 597 504 case ListStyleType::CJKEarthlyBranch: 598 505 case ListStyleType::CJKHeavenlyStem: 506 case ListStyleType::CJKIdeographic: 599 507 case ListStyleType::Hiragana: 600 508 case ListStyleType::HiraganaIroha: 509 case ListStyleType::JapaneseFormal: 510 case ListStyleType::JapaneseInformal: 601 511 case ListStyleType::Katakana: 602 512 case ListStyleType::KatakanaIroha: 603 return ideographicComma; 513 case ListStyleType::SimplifiedChineseFormal: 514 case ListStyleType::SimplifiedChineseInformal: 515 case ListStyleType::TraditionalChineseFormal: 516 case ListStyleType::TraditionalChineseInformal: 517 return { &ideographicComma, 1 }; 518 case ListStyleType::EthiopicNumeric: 519 return "/ "; 520 case ListStyleType::KoreanHangulFormal: 521 case ListStyleType::KoreanHanjaInformal: 522 case ListStyleType::KoreanHanjaFormal: 523 return ", "; 604 524 case ListStyleType::String: 605 525 ASSERT_NOT_REACHED(); … … 608 528 609 529 ASSERT_NOT_REACHED(); 610 return '.'; 611 } 612 613 static bool suffixRequiresSpace(UChar suffix) 614 { 615 return suffix == '.' || suffix == ethiopicPrefaceColon; 530 return ". "; 616 531 } 617 532 … … 626 541 return toSymbolic(value, asterisksSymbols); 627 542 } 628 // We use the same characters for text security. 629 // See RenderText::setInternalString.543 544 // We use the same characters for text security. See RenderText::setRenderedText. 630 545 case ListStyleType::Circle: 631 546 return { &whiteBullet, 1 }; … … 636 551 return toSymbolic(value, footnotesSymbols); 637 552 } 553 554 // CSS specification calls for U+25FE BLACK MEDIUM SMALL SQUARE; we have been using U+25A0 BLACK SQUARE instead for a long time. 638 555 case ListStyleType::Square: 639 // The CSS 2.1 test suite uses U+25EE BLACK MEDIUM SMALL SQUARE instead,640 // but we used this because we thought it looked better.641 556 return { &blackSquare, 1 }; 557 558 case ListStyleType::DisclosureClosed: 559 return { &blackRightPointingSmallTriangle, 1 }; 560 case ListStyleType::DisclosureOpen: 561 return { &blackDownPointingSmallTriangle, 1 }; 642 562 643 563 case ListStyleType::Decimal: … … 1026 946 return toAlphabetic(value, upperNorwegianAlphabet); 1027 947 } 1028 case ListStyleType::CJKIdeographic: { 1029 static constexpr UChar traditionalChineseInformalTable[16] = { 948 949 case ListStyleType::SimplifiedChineseInformal: { 950 static constexpr UChar simplifiedChineseInformalTable[17] = { 951 0x842C, 0x5104, 0x5146, // These three group markers are probably wrong; OK because we don't use this on big enough numbers. 952 0x5341, 0x767E, 0x5343, 953 0x96F6, 0x4E00, 0x4E8C, 0x4E09, 0x56DB, 954 0x4E94, 0x516D, 0x4E03, 0x516B, 0x4E5D, 955 0x8D1F 956 }; 957 return toCJKIdeographic(value, simplifiedChineseInformalTable, Formality::Informal); 958 } 959 case ListStyleType::SimplifiedChineseFormal: { 960 static constexpr UChar simplifiedChineseFormalTable[17] = { 961 0x842C, 0x5104, 0x5146, // These three group markers are probably wrong; OK because we don't use this on big enough numbers. 962 0x62FE, 0x4F70, 0x4EDF, 963 0x96F6, 0x58F9, 0x8D30, 0x53C1, 0x8086, 964 0x4F0D, 0x9646, 0x67D2, 0x634C, 0x7396, 965 0x8D1F 966 }; 967 return toCJKIdeographic(value, simplifiedChineseFormalTable, Formality::Formal); 968 } 969 case ListStyleType::CJKIdeographic: 970 case ListStyleType::TraditionalChineseInformal: { 971 static constexpr UChar traditionalChineseInformalTable[17] = { 1030 972 0x842C, 0x5104, 0x5146, 1031 973 0x5341, 0x767E, 0x5343, 1032 974 0x96F6, 0x4E00, 0x4E8C, 0x4E09, 0x56DB, 1033 0x4E94, 0x516D, 0x4E03, 0x516B, 0x4E5D 1034 }; 1035 return toCJKIdeographic(value, traditionalChineseInformalTable); 1036 } 1037 1038 case ListStyleType::LowerRoman: 1039 return toRoman(value, LetterCase::Lower); 1040 case ListStyleType::UpperRoman: 1041 return toRoman(value, LetterCase::Upper); 975 0x4E94, 0x516D, 0x4E03, 0x516B, 0x4E5D, 976 0x8CA0 977 }; 978 return toCJKIdeographic(value, traditionalChineseInformalTable, Formality::Informal); 979 } 980 case ListStyleType::TraditionalChineseFormal: { 981 static constexpr UChar traditionalChineseFormalTable[17] = { 982 0x842C, 0x5104, 0x5146, // These three group markers are probably wrong; OK because we don't use this on big enough numbers. 983 0x62FE, 0x4F70, 0x4EDF, 984 0x96F6, 0x58F9, 0x8CB3, 0x53C3, 0x8086, 985 0x4F0D, 0x9678, 0x67D2, 0x634C, 0x7396, 986 0x8CA0 987 }; 988 return toCJKIdeographic(value, traditionalChineseFormalTable, Formality::Formal); 989 } 990 991 case ListStyleType::LowerRoman: { 992 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem lowerRomanSystem { 993 { 994 { 1000, { 'm' } }, 995 { 900, { 'c', 'm' } }, 996 { 500, { 'd' } }, 997 { 400, { 'c', 'd' } }, 998 { 100, { 'c' } }, 999 { 90, { 'x', 'c' } }, 1000 { 50, { 'l' } }, 1001 { 40, { 'x', 'l' } }, 1002 { 10, { 'x' } }, 1003 { 9, { 'i', 'x' } }, 1004 { 5, { 'v' } }, 1005 { 4, { 'i', 'v' } }, 1006 { 1, { 'i' } } 1007 }, 1008 { } 1009 }; 1010 return toPredefinedAdditiveSystem(value, lowerRomanSystem); 1011 } 1012 case ListStyleType::UpperRoman: { 1013 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem upperRomanSystem { 1014 { 1015 { 1000, { 'M' } }, 1016 { 900, { 'C', 'M' } }, 1017 { 500, { 'D' } }, 1018 { 400, { 'C', 'D' } }, 1019 { 100, { 'C' } }, 1020 { 90, { 'X', 'C' } }, 1021 { 50, { 'L' } }, 1022 { 40, { 'X', 'L' } }, 1023 { 10, { 'X' } }, 1024 { 9, { 'I', 'X' } }, 1025 { 5, { 'V' } }, 1026 { 4, { 'I', 'V' } }, 1027 { 1, { 'I' } } 1028 }, 1029 { } 1030 }; 1031 return toPredefinedAdditiveSystem(value, upperRomanSystem); 1032 } 1042 1033 1043 1034 case ListStyleType::Armenian: 1044 case ListStyleType::UpperArmenian: 1045 return toArmenian(value, LetterCase::Upper); 1046 case ListStyleType::LowerArmenian: 1047 return toArmenian(value, LetterCase::Lower); 1048 1049 case ListStyleType::Georgian: 1050 return toGeorgian(value); 1051 case ListStyleType::Hebrew: 1052 return toHebrew(value); 1035 case ListStyleType::UpperArmenian: { 1036 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem upperArmenianSystem { 1037 { 1038 { 9000, { 0x554 } }, 1039 { 8000, { 0x553 } }, 1040 { 7000, { 0x552 } }, 1041 { 6000, { 0x551 } }, 1042 { 5000, { 0x550 } }, 1043 { 4000, { 0x54F } }, 1044 { 3000, { 0x54E } }, 1045 { 2000, { 0x54D } }, 1046 { 1000, { 0x54C } }, 1047 { 900, { 0x54B } }, 1048 { 800, { 0x54A } }, 1049 { 700, { 0x549 } }, 1050 { 600, { 0x548 } }, 1051 { 500, { 0x547 } }, 1052 { 400, { 0x546 } }, 1053 { 300, { 0x545 } }, 1054 { 200, { 0x544 } }, 1055 { 100, { 0x543 } }, 1056 { 90, { 0x542 } }, 1057 { 80, { 0x541 } }, 1058 { 70, { 0x540 } }, 1059 { 60, { 0x53F } }, 1060 { 50, { 0x53E } }, 1061 { 40, { 0x53D } }, 1062 { 30, { 0x53C } }, 1063 { 20, { 0x53B } }, 1064 { 10, { 0x53A } }, 1065 { 9, { 0x539 } }, 1066 { 8, { 0x538 } }, 1067 { 7, { 0x537 } }, 1068 { 6, { 0x536 } }, 1069 { 5, { 0x535 } }, 1070 { 4, { 0x534 } }, 1071 { 3, { 0x533 } }, 1072 { 2, { 0x532 } }, 1073 { 1, { 0x531 } } 1074 }, 1075 { } 1076 }; 1077 return toPredefinedAdditiveSystem(value, upperArmenianSystem); 1078 } 1079 case ListStyleType::LowerArmenian: { 1080 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem lowerArmenianSystem { 1081 { 1082 { 9000, { 0x584 } }, 1083 { 8000, { 0x583 } }, 1084 { 7000, { 0x582 } }, 1085 { 6000, { 0x581 } }, 1086 { 5000, { 0x580 } }, 1087 { 4000, { 0x57F } }, 1088 { 3000, { 0x57E } }, 1089 { 2000, { 0x57D } }, 1090 { 1000, { 0x57C } }, 1091 { 900, { 0x57B } }, 1092 { 800, { 0x57A } }, 1093 { 700, { 0x579 } }, 1094 { 600, { 0x578 } }, 1095 { 500, { 0x577 } }, 1096 { 400, { 0x576 } }, 1097 { 300, { 0x575 } }, 1098 { 200, { 0x574 } }, 1099 { 100, { 0x573 } }, 1100 { 90, { 0x572 } }, 1101 { 80, { 0x571 } }, 1102 { 70, { 0x570 } }, 1103 { 60, { 0x56F } }, 1104 { 50, { 0x56E } }, 1105 { 40, { 0x56D } }, 1106 { 30, { 0x56C } }, 1107 { 20, { 0x56B } }, 1108 { 10, { 0x56A } }, 1109 { 9, { 0x569 } }, 1110 { 8, { 0x568 } }, 1111 { 7, { 0x567 } }, 1112 { 6, { 0x566 } }, 1113 { 5, { 0x565 } }, 1114 { 4, { 0x564 } }, 1115 { 3, { 0x563 } }, 1116 { 2, { 0x562 } }, 1117 { 1, { 0x561 } } 1118 }, 1119 { } 1120 }; 1121 return toPredefinedAdditiveSystem(value, lowerArmenianSystem); 1122 } 1123 1124 case ListStyleType::Georgian: { 1125 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem georgianSystem { 1126 { 1127 { 10000, { 0x10F5 } }, 1128 { 9000, { 0x10F0 } }, 1129 { 8000, { 0x10EF } }, 1130 { 7000, { 0x10F4 } }, 1131 { 6000, { 0x10EE } }, 1132 { 5000, { 0x10ED } }, 1133 { 4000, { 0x10EC } }, 1134 { 3000, { 0x10EB } }, 1135 { 2000, { 0x10EA } }, 1136 { 1000, { 0x10E9 } }, 1137 { 900, { 0x10E8 } }, 1138 { 800, { 0x10E7 } }, 1139 { 700, { 0x10E6 } }, 1140 { 600, { 0x10E5 } }, 1141 { 500, { 0x10E4 } }, 1142 { 400, { 0x10F3 } }, 1143 { 300, { 0x10E2 } }, 1144 { 200, { 0x10E1 } }, 1145 { 100, { 0x10E0 } }, 1146 { 90, { 0x10DF } }, 1147 { 80, { 0x10DE } }, 1148 { 70, { 0x10DD } }, 1149 { 60, { 0x10F2 } }, 1150 { 50, { 0x10DC } }, 1151 { 40, { 0x10DB } }, 1152 { 30, { 0x10DA } }, 1153 { 20, { 0x10D9 } }, 1154 { 10, { 0x10D8 } }, 1155 { 9, { 0x10D7 } }, 1156 { 8, { 0x10F1 } }, 1157 { 7, { 0x10D6 } }, 1158 { 6, { 0x10D5 } }, 1159 { 5, { 0x10D4 } }, 1160 { 4, { 0x10D3 } }, 1161 { 3, { 0x10D2 } }, 1162 { 2, { 0x10D1 } }, 1163 { 1, { 0x10D0 } } 1164 }, 1165 { } 1166 }; 1167 return toPredefinedAdditiveSystem(value, georgianSystem); 1168 } 1169 case ListStyleType::Hebrew: { 1170 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem hebrewSystem { 1171 { 1172 { 10000, { 0x5D9, 0x5F3 } }, 1173 { 9000, { 0x5D8, 0x5F3 } }, 1174 { 8000, { 0x5D7, 0x5F3 } }, 1175 { 7000, { 0x5D6, 0x5F3 } }, 1176 { 6000, { 0x5D5, 0x5F3 } }, 1177 { 5000, { 0x5D4, 0x5F3 } }, 1178 { 4000, { 0x5D3, 0x5F3 } }, 1179 { 3000, { 0x5D2, 0x5F3 } }, 1180 { 2000, { 0x5D1, 0x5F3 } }, 1181 { 1000, { 0x5D0, 0x5F3 } }, 1182 { 400, { 0x5EA } }, 1183 { 300, { 0x5E9 } }, 1184 { 200, { 0x5E8 } }, 1185 { 100, { 0x5E7 } }, 1186 { 90, { 0x5E6 } }, 1187 { 80, { 0x5E4 } }, 1188 { 70, { 0x5E2 } }, 1189 { 60, { 0x5E1 } }, 1190 { 50, { 0x5E0 } }, 1191 { 40, { 0x5DE } }, 1192 { 30, { 0x5DC } }, 1193 { 20, { 0x5DB } }, 1194 { 19, { 0x5D9, 0x5D8 } }, 1195 { 18, { 0x5D9, 0x5D7 } }, 1196 { 17, { 0x5D9, 0x5D6 } }, 1197 { 16, { 0x5D8, 0x5D6 } }, 1198 { 15, { 0x5D8, 0x5D5 } }, 1199 { 10, { 0x5D9 } }, 1200 { 9, { 0x5D8 } }, 1201 { 8, { 0x5D7 } }, 1202 { 7, { 0x5D6 } }, 1203 { 6, { 0x5D5 } }, 1204 { 5, { 0x5D4 } }, 1205 { 4, { 0x5D3 } }, 1206 { 3, { 0x5D2 } }, 1207 { 2, { 0x5D1 } }, 1208 { 1, { 0x5D0 } } 1209 }, 1210 { } 1211 }; 1212 return toPredefinedAdditiveSystem(value, hebrewSystem); 1213 } 1053 1214 1054 1215 case ListStyleType::CJKDecimal: { … … 1064 1225 return toNumeric(value, tamilNumerals); 1065 1226 } 1227 1228 case ListStyleType::JapaneseInformal: { 1229 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem japaneseInformalSystem { 1230 { 1231 { 9000, { 0x4E5D, 0x5343 } }, 1232 { 8000, { 0x516B, 0x5343 } }, 1233 { 7000, { 0x4E03, 0x5343 } }, 1234 { 6000, { 0x516D, 0x5343 } }, 1235 { 5000, { 0x4E94, 0x5343 } }, 1236 { 4000, { 0x56DB, 0x5343 } }, 1237 { 3000, { 0x4E09, 0x5343 } }, 1238 { 2000, { 0x4E8C, 0x5343 } }, 1239 { 1000, { 0x5343 } }, 1240 { 900, { 0x4E5D, 0x767E } }, 1241 { 800, { 0x516B, 0x767E } }, 1242 { 700, { 0x4E03, 0x767E } }, 1243 { 600, { 0x516D, 0x767E } }, 1244 { 500, { 0x4E94, 0x767E } }, 1245 { 400, { 0x56DB, 0x767E } }, 1246 { 300, { 0x4E09, 0x767E } }, 1247 { 200, { 0x4E8C, 0x767E } }, 1248 { 100, { 0x767E } }, 1249 { 90, { 0x4E5D, 0x5341 } }, 1250 { 80, { 0x516B, 0x5341 } }, 1251 { 70, { 0x4E03, 0x5341 } }, 1252 { 60, { 0x516D, 0x5341 } }, 1253 { 50, { 0x4E94, 0x5341 } }, 1254 { 40, { 0x56DB, 0x5341 } }, 1255 { 30, { 0x4E09, 0x5341 } }, 1256 { 20, { 0x4E8C, 0x5341 } }, 1257 { 10, { 0x5341 } }, 1258 { 9, { 0x4E5D } }, 1259 { 8, { 0x516B } }, 1260 { 7, { 0x4E03 } }, 1261 { 6, { 0x516D } }, 1262 { 5, { 0x4E94 } }, 1263 { 4, { 0x56DB } }, 1264 { 3, { 0x4E09 } }, 1265 { 2, { 0x4E8C } }, 1266 { 1, { 0x4E00 } }, 1267 { 0, { 0x3007 } } 1268 }, 1269 { 0x30DE, 0x30A4, 0x30CA, 0x30B9 } 1270 }; 1271 return toPredefinedAdditiveSystem(value, japaneseInformalSystem); 1272 } 1273 case ListStyleType::JapaneseFormal: { 1274 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem japaneseFormalSystem { 1275 { 1276 { 9000, { 0x4E5D, 0x9621 } }, 1277 { 8000, { 0x516B, 0x9621 } }, 1278 { 7000, { 0x4E03, 0x9621 } }, 1279 { 6000, { 0x516D, 0x9621 } }, 1280 { 5000, { 0x4F0D, 0x9621 } }, 1281 { 4000, { 0x56DB, 0x9621 } }, 1282 { 3000, { 0x53C2, 0x9621 } }, 1283 { 2000, { 0x5F10, 0x9621 } }, 1284 { 1000, { 0x58F1, 0x9621 } }, 1285 { 900, { 0x4E5D, 0x767E } }, 1286 { 800, { 0x516B, 0x767E } }, 1287 { 700, { 0x4E03, 0x767E } }, 1288 { 600, { 0x516D, 0x767E } }, 1289 { 500, { 0x4F0D, 0x767E } }, 1290 { 400, { 0x56DB, 0x767E } }, 1291 { 300, { 0x53C2, 0x767E } }, 1292 { 200, { 0x5F10, 0x767E } }, 1293 { 100, { 0x58F1, 0x767E } }, 1294 { 90, { 0x4E5D, 0x62FE } }, 1295 { 80, { 0x516B, 0x62FE } }, 1296 { 70, { 0x4E03, 0x62FE } }, 1297 { 60, { 0x516D, 0x62FE } }, 1298 { 50, { 0x4F0D, 0x62FE } }, 1299 { 40, { 0x56DB, 0x62FE } }, 1300 { 30, { 0x53C2, 0x62FE } }, 1301 { 20, { 0x5F10, 0x62FE } }, 1302 { 10, { 0x58F1, 0x62FE } }, 1303 { 9, { 0x4E5D } }, 1304 { 8, { 0x516B } }, 1305 { 7, { 0x4E03 } }, 1306 { 6, { 0x516D } }, 1307 { 5, { 0x4F0D } }, 1308 { 4, { 0x56DB } }, 1309 { 3, { 0x53C2 } }, 1310 { 2, { 0x5F10 } }, 1311 { 1, { 0x58F1 } }, 1312 { 0, { 0x96F6 } } 1313 }, 1314 { 0x30DE, 0x30A4, 0x30CA, 0x30B9 } 1315 }; 1316 return toPredefinedAdditiveSystem(value, japaneseFormalSystem); 1317 } 1318 case ListStyleType::KoreanHangulFormal: { 1319 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem koreanHangulFormalSystem { 1320 { 1321 { 9000, { 0xAD6C, 0xCC9C } }, 1322 { 8000, { 0xD314, 0xCC9C } }, 1323 { 7000, { 0xCE60, 0xCC9C } }, 1324 { 6000, { 0xC721, 0xCC9C } }, 1325 { 5000, { 0xC624, 0xCC9C } }, 1326 { 4000, { 0xC0AC, 0xCC9C } }, 1327 { 3000, { 0xC0BC, 0xCC9C } }, 1328 { 2000, { 0xC774, 0xCC9C } }, 1329 { 1000, { 0xC77C, 0xCC9C } }, 1330 { 900, { 0xAD6C, 0xBC31 } }, 1331 { 800, { 0xD314, 0xBC31 } }, 1332 { 700, { 0xCE60, 0xBC31 } }, 1333 { 600, { 0xC721, 0xBC31 } }, 1334 { 500, { 0xC624, 0xBC31 } }, 1335 { 400, { 0xC0AC, 0xBC31 } }, 1336 { 300, { 0xC0BC, 0xBC31 } }, 1337 { 200, { 0xC774, 0xBC31 } }, 1338 { 100, { 0xC77C, 0xBC31 } }, 1339 { 90, { 0xAD6C, 0xC2ED } }, 1340 { 80, { 0xD314, 0xC2ED } }, 1341 { 70, { 0xCE60, 0xC2ED } }, 1342 { 60, { 0xC721, 0xC2ED } }, 1343 { 50, { 0xC624, 0xC2ED } }, 1344 { 40, { 0xC0AC, 0xC2ED } }, 1345 { 30, { 0xC0BC, 0xC2ED } }, 1346 { 20, { 0xC774, 0xC2ED } }, 1347 { 10, { 0xC77C, 0xC2ED } }, 1348 { 9, { 0xAD6C } }, 1349 { 8, { 0xD314 } }, 1350 { 7, { 0xCE60 } }, 1351 { 6, { 0xC721 } }, 1352 { 5, { 0xC624 } }, 1353 { 4, { 0xC0AC } }, 1354 { 3, { 0xC0BC } }, 1355 { 2, { 0xC774 } }, 1356 { 1, { 0xC77C } }, 1357 { 0, { 0xC601 } } 1358 }, 1359 { 0xB9C8, 0xC774, 0xB108, 0xC2A4, ' ' } 1360 }; 1361 return toPredefinedAdditiveSystem(value, koreanHangulFormalSystem); 1362 } 1363 case ListStyleType::KoreanHanjaInformal: { 1364 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem koreanHanjaInformalSystem { 1365 { 1366 { 9000, { 0x4E5D, 0x5343 } }, 1367 { 8000, { 0x516B, 0x5343 } }, 1368 { 7000, { 0x4E03, 0x5343 } }, 1369 { 6000, { 0x516D, 0x5343 } }, 1370 { 5000, { 0x4E94, 0x5343 } }, 1371 { 4000, { 0x56DB, 0x5343 } }, 1372 { 3000, { 0x4E09, 0x5343 } }, 1373 { 2000, { 0x4E8C, 0x5343 } }, 1374 { 1000, { 0x5343 } }, 1375 { 900, { 0x4E5D, 0x767E } }, 1376 { 800, { 0x516B, 0x767E } }, 1377 { 700, { 0x4E03, 0x767E } }, 1378 { 600, { 0x516D, 0x767E } }, 1379 { 500, { 0x4E94, 0x767E } }, 1380 { 400, { 0x56DB, 0x767E } }, 1381 { 300, { 0x4E09, 0x767E } }, 1382 { 200, { 0x4E8C, 0x767E } }, 1383 { 100, { 0x767E } }, 1384 { 90, { 0x4E5D, 0x5341 } }, 1385 { 80, { 0x516B, 0x5341 } }, 1386 { 70, { 0x4E03, 0x5341 } }, 1387 { 60, { 0x516D, 0x5341 } }, 1388 { 50, { 0x4E94, 0x5341 } }, 1389 { 40, { 0x56DB, 0x5341 } }, 1390 { 30, { 0x4E09, 0x5341 } }, 1391 { 20, { 0x4E8C, 0x5341 } }, 1392 { 10, { 0x5341 } }, 1393 { 9, { 0x4E5D } }, 1394 { 8, { 0x516B } }, 1395 { 7, { 0x4E03 } }, 1396 { 6, { 0x516D } }, 1397 { 5, { 0x4E94 } }, 1398 { 4, { 0x56DB } }, 1399 { 3, { 0x4E09 } }, 1400 { 2, { 0x4E8C } }, 1401 { 1, { 0x4E00 } }, 1402 { 0, { 0x96F6 } } 1403 }, 1404 { 0xB9C8, 0xC774, 0xB108, 0xC2A4, ' ' } 1405 }; 1406 return toPredefinedAdditiveSystem(value, koreanHanjaInformalSystem); 1407 } 1408 case ListStyleType::KoreanHanjaFormal: { 1409 static CONSTEXPR_WITH_MSVC_INITIALIZER_LIST_WORKAROUND AdditiveSystem koreanHanjaFormalSystem { 1410 { 1411 { 9000, { 0x4E5D, 0x4EDF } }, 1412 { 8000, { 0x516B, 0x4EDF } }, 1413 { 7000, { 0x4E03, 0x4EDF } }, 1414 { 6000, { 0x516D, 0x4EDF } }, 1415 { 5000, { 0x4E94, 0x4EDF } }, 1416 { 4000, { 0x56DB, 0x4EDF } }, 1417 { 3000, { 0x53C3, 0x4EDF } }, 1418 { 2000, { 0x8CB3, 0x4EDF } }, 1419 { 1000, { 0x58F9, 0x4EDF } }, 1420 { 900, { 0x4E5D, 0x767E } }, 1421 { 800, { 0x516B, 0x767E } }, 1422 { 700, { 0x4E03, 0x767E } }, 1423 { 600, { 0x516D, 0x767E } }, 1424 { 500, { 0x4E94, 0x767E } }, 1425 { 400, { 0x56DB, 0x767E } }, 1426 { 300, { 0x53C3, 0x767E } }, 1427 { 200, { 0x8CB3, 0x767E } }, 1428 { 100, { 0x58F9, 0x767E } }, 1429 { 90, { 0x4E5D, 0x62FE } }, 1430 { 80, { 0x516B, 0x62FE } }, 1431 { 70, { 0x4E03, 0x62FE } }, 1432 { 60, { 0x516D, 0x62FE } }, 1433 { 50, { 0x4E94, 0x62FE } }, 1434 { 40, { 0x56DB, 0x62FE } }, 1435 { 30, { 0x53C3, 0x62FE } }, 1436 { 20, { 0x8CB3, 0x62FE } }, 1437 { 10, { 0x58F9, 0x62FE } }, 1438 { 9, { 0x4E5D } }, 1439 { 8, { 0x516B } }, 1440 { 7, { 0x4E03 } }, 1441 { 6, { 0x516D } }, 1442 { 5, { 0x4E94 } }, 1443 { 4, { 0x56DB } }, 1444 { 3, { 0x53C3 } }, 1445 { 2, { 0x8CB3 } }, 1446 { 1, { 0x58F9 } }, 1447 { 0, { 0x96F6 } } 1448 }, 1449 { 0xB9C8, 0xC774, 0xB108, 0xC2A4, ' ' } 1450 }; 1451 return toPredefinedAdditiveSystem(value, koreanHanjaFormalSystem); 1452 } 1453 1454 case ListStyleType::EthiopicNumeric: 1455 return toEthiopicNumeric(value); 1066 1456 1067 1457 case ListStyleType::String: … … 1121 1511 { 1122 1512 auto box = RenderBox::createInlineBox(); 1123 box->setBehavesLikeText( isText());1513 box->setBehavesLikeText(!isImage()); 1124 1514 return box; 1125 1515 } … … 1142 1532 } 1143 1533 1534 static String reversed(StringView string) 1535 { 1536 auto length = string.length(); 1537 if (length <= 1) 1538 return string.toString(); 1539 UChar* characters; 1540 auto result = String::createUninitialized(length, characters); 1541 for (unsigned i = 0; i < length; ++i) 1542 *characters++ = string[length - i - 1]; 1543 return result; 1544 } 1545 1546 struct RenderListMarker::TextRunWithUnderlyingString { 1547 TextRun textRun; 1548 String underlyingString; 1549 operator const TextRun&() const { return textRun; } 1550 }; 1551 1552 auto RenderListMarker::textRun() const -> TextRunWithUnderlyingString 1553 { 1554 ASSERT(!m_textWithSuffix.isEmpty()); 1555 1556 // Since the bidi algorithm doesn't run on this text, we instead reorder the characters here. 1557 // We use u_charDirection to figure out if the marker text is RTL and assume the suffix matches the surrounding direction. 1558 String textForRun; 1559 if (m_textIsLeftToRightDirection) { 1560 if (style().isLeftToRightDirection()) 1561 textForRun = m_textWithSuffix; 1562 else { 1563 if (style().listStyleType() == ListStyleType::DisclosureClosed) 1564 textForRun = { &blackLeftPointingSmallTriangle, 1 }; 1565 else 1566 textForRun = makeString(reversed(m_textWithSuffix.substring(m_textWithoutSuffixLength)), m_textWithSuffix.left(m_textWithoutSuffixLength)); 1567 } 1568 } else { 1569 if (!style().isLeftToRightDirection()) 1570 textForRun = reversed(m_textWithSuffix); 1571 else 1572 textForRun = makeString(reversed(m_textWithSuffix.left(m_textWithoutSuffixLength)), m_textWithSuffix.substring(m_textWithoutSuffixLength)); 1573 } 1574 auto textRun = RenderBlock::constructTextRun(textForRun, style()); 1575 return { WTFMove(textRun), WTFMove(textForRun) }; 1576 } 1577 1144 1578 void RenderListMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 1145 1579 { … … 1158 1592 LayoutRect box(boxOrigin, size()); 1159 1593 1160 auto markerRect = getRelativeMarkerRect();1594 auto markerRect = relativeMarkerRect(); 1161 1595 markerRect.moveBy(boxOrigin); 1162 1596 if (markerRect.isEmpty()) … … 1188 1622 context.setFillColor(color); 1189 1623 1190 auto type = style().listStyleType(); 1191 switch (type) { 1624 switch (style().listStyleType()) { 1192 1625 case ListStyleType::Disc: 1193 1626 context.drawEllipse(markerRect); … … 1200 1633 context.drawRect(markerRect); 1201 1634 return; 1202 case ListStyleType::None:1203 return;1204 1635 default: 1205 1636 break; 1206 1637 } 1207 if (m_text .isEmpty())1638 if (m_textWithSuffix.isEmpty()) 1208 1639 return; 1209 1210 const FontCascade& font = style().fontCascade();1211 TextRun textRun = RenderBlock::constructTextRun(m_text, style());1212 1640 1213 1641 GraphicsContextStateSaver stateSaver(context, false); … … 1224 1652 FloatPoint textOrigin = FloatPoint(markerRect.x(), markerRect.y() + style().fontMetrics().ascent()); 1225 1653 textOrigin = roundPointToDevicePixels(LayoutPoint(textOrigin), document().deviceScaleFactor(), style().isLeftToRightDirection()); 1226 1227 if (type == ListStyleType::Asterisks || type == ListStyleType::Footnotes || type == ListStyleType::String) 1228 context.drawText(font, textRun, textOrigin); 1229 else { 1230 auto suffix = listMarkerSuffix(type, m_listItem->value()); 1231 1232 // FIXME: Could use a Vector with inline capacity instead of String to avoid 1233 // memory allocation here. 1234 String textToDraw; 1235 1236 // Since marker text is not arbitrary, we can judge its direction just by 1237 // checking the first character, and only need to handle U_RIGHT_TO_LEFT. 1238 // FIXME: Could check more efficiently than u_charDirection, since we know 1239 // only certain characters are used and only need to check for U_RIGHT_TO_LEFT. 1240 bool shouldAddSpace = suffixRequiresSpace(suffix); 1241 if (u_charDirection(m_text[0]) == U_RIGHT_TO_LEFT) { 1242 unsigned length = m_text.length(); 1243 UChar* characters; 1244 textToDraw = String::createUninitialized(length + 1 + shouldAddSpace, characters); 1245 if (!style().isLeftToRightDirection()) { 1246 if (shouldAddSpace) 1247 *characters++ = space; 1248 *characters++ = suffix; 1249 } 1250 for (unsigned i = 0; i < length; ++i) 1251 *characters++ = m_text[length - i - 1]; 1252 if (style().isLeftToRightDirection()) { 1253 *characters++ = suffix; 1254 if (shouldAddSpace) 1255 *characters++ = space; 1256 } 1257 } else { 1258 if (style().isLeftToRightDirection()) 1259 textToDraw = makeString(m_text, suffix, shouldAddSpace ? " " : ""); 1260 else 1261 textToDraw = makeString(shouldAddSpace ? " " : "", suffix, m_text); 1262 } 1263 textRun.setText(textToDraw); 1264 1265 context.drawText(font, textRun, textOrigin); 1266 } 1654 context.drawText(style().fontCascade(), textRun(), textOrigin); 1267 1655 } 1268 1656 … … 1306 1694 // FIXME: Need to account for relative positioning in the layout overflow. 1307 1695 if (m_listItem->style().isLeftToRightDirection()) { 1308 markerLogicalLeft = lineOffsetForListItem()- lineOffset - m_listItem->paddingStart() - m_listItem->borderStart() + marginStart();1696 markerLogicalLeft = m_lineOffsetForListItem - lineOffset - m_listItem->paddingStart() - m_listItem->borderStart() + marginStart(); 1309 1697 inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft); 1310 1698 for (auto* box = inlineBoxWrapper()->parent(); box; box = box->parent()) { … … 1328 1716 } 1329 1717 } else { 1330 markerLogicalLeft = lineOffsetForListItem()- lineOffset + m_listItem->paddingStart() + m_listItem->borderStart() + marginEnd();1718 markerLogicalLeft = m_lineOffsetForListItem - lineOffset + m_listItem->paddingStart() + m_listItem->borderStart() + marginEnd(); 1331 1719 inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft); 1332 1720 for (auto* box = inlineBoxWrapper()->parent(); box; box = box->parent()) { … … 1424 1812 void RenderListMarker::updateMarginsAndContent() 1425 1813 { 1426 updateContent(); 1814 // FIXME: It's messy to use the preferredLogicalWidths dirty bit for this optimization, also unclear if this is premature optimization. 1815 if (preferredLogicalWidthsDirty()) 1816 updateContent(); 1427 1817 updateMargins(); 1428 1818 } … … 1430 1820 void RenderListMarker::updateContent() 1431 1821 { 1432 // FIXME: This if-statement is just a performance optimization, but it's messy to use the preferredLogicalWidths dirty bit for this.1433 // It's unclear if this is a premature optimization.1434 if (!preferredLogicalWidthsDirty())1435 return;1436 1437 m_text = emptyString();1438 1439 1822 if (isImage()) { 1440 1823 // FIXME: This is a somewhat arbitrary width. Generated images for markers really won't become particularly useful … … 1444 1827 LayoutSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom); 1445 1828 m_image->setContainerContextForRenderer(*this, imageSize, style().effectiveZoom()); 1829 m_textWithSuffix = emptyString(); 1830 m_textWithoutSuffixLength = 0; 1831 m_textIsLeftToRightDirection = true; 1446 1832 return; 1447 1833 } … … 1449 1835 auto type = style().listStyleType(); 1450 1836 switch (type) { 1451 case ListStyleType::None:1452 break;1453 1837 case ListStyleType::String: 1454 m_text = style().listStyleStringValue(); 1455 break; 1456 case ListStyleType::Circle: 1457 case ListStyleType::Disc: 1458 case ListStyleType::Square: 1459 m_text = listMarkerText(type, 0); // value is ignored for these types 1838 m_textWithSuffix = style().listStyleStringValue(); 1839 m_textWithoutSuffixLength = m_textWithSuffix.length(); 1840 // FIXME: Depending on the string value, we may need the real bidi algorithm. 1841 m_textIsLeftToRightDirection = u_charDirection(m_textWithSuffix[0]) != U_RIGHT_TO_LEFT; 1460 1842 break; 1461 1843 default: 1462 m_text = listMarkerText(type, m_listItem->value()); 1844 auto text = listMarkerText(type, m_listItem->value()); 1845 m_textWithSuffix = makeString(text, listMarkerSuffix(type)); 1846 m_textWithoutSuffixLength = text.length(); 1847 m_textIsLeftToRightDirection = u_charDirection(text[0]) != U_RIGHT_TO_LEFT; 1463 1848 break; 1464 1849 } … … 1481 1866 1482 1867 LayoutUnit logicalWidth; 1483 auto type = style().listStyleType(); 1484 switch (type) { 1485 case ListStyleType::None: 1486 break; 1487 case ListStyleType::Asterisks: 1488 case ListStyleType::Footnotes: 1489 case ListStyleType::String: 1490 if (!m_text.isEmpty()) { 1491 TextRun run = RenderBlock::constructTextRun(m_text, style()); 1492 logicalWidth = font.width(run); // no suffix for these types 1493 } 1494 break; 1868 switch (style().listStyleType()) { 1495 1869 case ListStyleType::Circle: 1496 1870 case ListStyleType::Disc: … … 1499 1873 break; 1500 1874 default: 1501 if (m_text.isEmpty()) 1502 logicalWidth = 0; 1503 else { 1504 TextRun run = RenderBlock::constructTextRun(m_text, style()); 1505 LayoutUnit itemWidth { font.width(run) }; 1506 UChar suffix[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' }; 1507 LayoutUnit suffixWidth { font.width(RenderBlock::constructTextRun(suffix, suffixRequiresSpace(suffix[0]) ? 2 : 1, style())) }; 1508 logicalWidth = itemWidth + suffixWidth; 1509 } 1875 if (!m_textWithSuffix.isEmpty()) 1876 logicalWidth = font.width(textRun()); 1510 1877 break; 1511 1878 } … … 1551 1918 marginEnd = offset + cMarkerPadding + 1 - minPreferredLogicalWidth(); 1552 1919 break; 1553 case ListStyleType::None:1554 break;1555 1920 case ListStyleType::String: 1556 if (!m_text .isEmpty())1921 if (!m_textWithSuffix.isEmpty()) 1557 1922 marginStart = -minPreferredLogicalWidth(); 1558 1923 break; 1559 1924 default: 1560 if (!m_text .isEmpty()) {1925 if (!m_textWithSuffix.isEmpty()) { 1561 1926 marginStart = -minPreferredLogicalWidth() - offset / 2; 1562 1927 marginEnd = offset / 2; … … 1583 1948 } 1584 1949 1585 String RenderListMarker::suffix() const1586 {1587 auto type = style().listStyleType();1588 if (type == ListStyleType::String)1589 return emptyString();1590 1591 auto suffix = listMarkerSuffix(type, m_listItem->value());1592 1593 if (suffix == ' ')1594 return " "_str;1595 if (!suffixRequiresSpace(suffix))1596 return { &suffix, 1 };1597 1598 UChar data[2];1599 if (style().isLeftToRightDirection()) {1600 data[0] = suffix;1601 data[1] = ' ';1602 } else {1603 data[0] = ' ';1604 data[1] = suffix;1605 }1606 return { data, 2 };1607 }1608 1609 1950 bool RenderListMarker::isInside() const 1610 1951 { … … 1612 1953 } 1613 1954 1614 FloatRect RenderListMarker:: getRelativeMarkerRect()1955 FloatRect RenderListMarker::relativeMarkerRect() 1615 1956 { 1616 1957 if (isImage()) 1617 1958 return FloatRect(0, 0, m_image->imageSize(this, style().effectiveZoom()).width(), m_image->imageSize(this, style().effectiveZoom()).height()); 1618 1959 1619 1960 FloatRect relativeRect; 1620 auto type = style().listStyleType(); 1621 switch (type) { 1622 case ListStyleType::Asterisks: 1623 case ListStyleType::Footnotes: 1624 case ListStyleType::String: { 1625 if (m_text.isEmpty()) 1626 return FloatRect(); 1627 const FontCascade& font = style().fontCascade(); 1628 TextRun run = RenderBlock::constructTextRun(m_text, style()); 1629 relativeRect = FloatRect(0, 0, font.width(run), font.fontMetrics().height()); 1630 break; 1631 } 1961 switch (style().listStyleType()) { 1632 1962 case ListStyleType::Disc: 1633 1963 case ListStyleType::Circle: … … 1640 1970 break; 1641 1971 } 1642 case ListStyleType::None:1643 return FloatRect();1644 1972 default: 1645 if (m_text .isEmpty())1973 if (m_textWithSuffix.isEmpty()) 1646 1974 return FloatRect(); 1647 const FontCascade& font = style().fontCascade(); 1648 TextRun run = RenderBlock::constructTextRun(m_text, style()); 1649 float itemWidth = font.width(run); 1650 UChar suffix[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' }; 1651 float suffixWidth = font.width(RenderBlock::constructTextRun(suffix, suffixRequiresSpace(suffix[0]) ? 2 : 1, style())); 1652 relativeRect = FloatRect(0, 0, itemWidth + suffixWidth, font.fontMetrics().height()); 1975 auto& font = style().fontCascade(); 1976 relativeRect = FloatRect(0, 0, font.width(textRun()), font.fontMetrics().height()); 1977 break; 1653 1978 } 1654 1979 … … 1676 2001 } 1677 2002 2003 StringView RenderListMarker::textWithoutSuffix() const 2004 { 2005 return StringView { m_textWithSuffix }.left(m_textWithoutSuffixLength); 2006 } 2007 1678 2008 } // namespace WebCore -
trunk/Source/WebCore/rendering/RenderListMarker.h
r278534 r279165 2 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * Copyright (C) 2003 , 2004, 2005, 2006, 2007, 2009Apple Inc. All rights reserved.4 * Copyright (C) 2003-2021 Apple Inc. All rights reserved. 5 5 * 6 6 * This library is free software; you can redistribute it and/or … … 39 39 virtual ~RenderListMarker(); 40 40 41 const String& text() const { return m_text; }42 String suffix() const;41 StringView textWithoutSuffix() const; 42 StringView textWithSuffix() const { return m_textWithSuffix; } 43 43 44 44 bool isInside() const; 45 45 46 LayoutUnit lineOffsetForListItem() const { return m_lineOffsetForListItem; }47 48 46 void updateMarginsAndContent(); 49 50 47 void addOverflowFromListMarker(); 51 48 52 49 private: 53 void willBeDestroyed() override; 50 void willBeDestroyed() final; 51 const char* renderName() const final { return "RenderListMarker"; } 52 void computePreferredLogicalWidths() final; 53 bool isListMarker() const final { return true; } 54 bool canHaveChildren() const final { return false; } 55 void paint(PaintInfo&, const LayoutPoint&) final; 56 void layout() final; 57 void imageChanged(WrappedImagePtr, const IntRect*) final; 58 std::unique_ptr<LegacyInlineElementBox> createInlineBox() final; 59 LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode) const final; 60 LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode) const final; 61 bool isImage() const final; 62 LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent) final; 63 bool canBeSelectionLeaf() const final { return true; } 64 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final; 54 65 55 66 void element() const = delete; 56 67 57 const char* renderName() const override { return "RenderListMarker"; }58 void computePreferredLogicalWidths() override;59 60 bool isListMarker() const override { return true; }61 bool canHaveChildren() const override { return false; }62 63 void paint(PaintInfo&, const LayoutPoint&) override;64 65 void layout() override;66 67 void imageChanged(WrappedImagePtr, const IntRect* = 0) override;68 69 std::unique_ptr<LegacyInlineElementBox> createInlineBox() override;70 71 LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;72 LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;73 74 bool isImage() const override;75 bool isText() const { return !isImage(); }76 77 LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) override;78 bool canBeSelectionLeaf() const override { return true; }79 80 68 void updateMargins(); 81 69 void updateContent(); 82 83 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;84 85 70 RenderBox* parentBox(RenderBox&); 86 87 FloatRect getRelativeMarkerRect(); 71 FloatRect relativeMarkerRect(); 88 72 LayoutRect localSelectionRect(); 89 73 90 String m_text; 74 struct TextRunWithUnderlyingString; 75 TextRunWithUnderlyingString textRun() const; 76 77 String m_textWithSuffix; 78 uint8_t m_textWithoutSuffixLength { 0 }; 79 bool m_textIsLeftToRightDirection { true }; 91 80 RefPtr<StyleImage> m_image; 92 81 WeakPtr<RenderListItem> m_listItem; -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r278669 r279165 441 441 442 442 if (is<RenderListMarker>(o)) { 443 String text = downcast<RenderListMarker>(o).text ();443 String text = downcast<RenderListMarker>(o).textWithoutSuffix().toString(); 444 444 if (!text.isEmpty()) { 445 445 if (text.length() != 1) … … 958 958 return String(); 959 959 960 return downcast<RenderListItem>(*renderer).markerText ();960 return downcast<RenderListItem>(*renderer).markerTextWithoutSuffix().toString(); 961 961 } 962 962 -
trunk/Source/WebCore/rendering/style/RenderStyleConstants.cpp
r279055 r279165 1 1 /* 2 * Copyright (C) 2015-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2015-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 715 715 TextStream& operator<<(TextStream& ts, ListStyleType styleType) 716 716 { 717 switch (styleType) { 718 case ListStyleType::Afar: ts << "afar"; break; 719 case ListStyleType::Amharic: ts << "amharic"; break; 720 case ListStyleType::AmharicAbegede: ts << "amharic-abegede"; break; 721 case ListStyleType::ArabicIndic: ts << "arabic-indic"; break; 722 case ListStyleType::Armenian: ts << "armenian"; break; 723 case ListStyleType::Asterisks: ts << "asterisks"; break; 724 case ListStyleType::Bengali: ts << "bengali"; break; 725 case ListStyleType::Binary: ts << "binary"; break; 726 case ListStyleType::CJKDecimal: ts << "cjk-decimal"; break; 727 case ListStyleType::CJKIdeographic: ts << "cjk-ideographic"; break; 728 case ListStyleType::Cambodian: ts << "cambodian"; break; 729 case ListStyleType::Circle: ts << "circle"; break; 730 case ListStyleType::CJKEarthlyBranch: ts << "cjk-earthly-branch"; break; 731 case ListStyleType::CJKHeavenlyStem: ts << "cjk-heavenly-stem"; break; 732 case ListStyleType::Decimal: ts << "decimal"; break; 733 case ListStyleType::DecimalLeadingZero: ts << "decimal-leading-zero"; break; 734 case ListStyleType::Devanagari: ts << "devanagari"; break; 735 case ListStyleType::Disc: ts << "disc"; break; 736 case ListStyleType::Ethiopic: ts << "ethiopic"; break; 737 case ListStyleType::EthiopicAbegede: ts << "ethiopic-abegede"; break; 738 case ListStyleType::EthiopicAbegedeAmEt: ts << "ethiopic-abegede-am-et"; break; 739 case ListStyleType::EthiopicAbegedeGez: ts << "ethiopic-abegede-gez"; break; 740 case ListStyleType::EthiopicAbegedeTiEr: ts << "ethiopic-abegede-ti-er"; break; 741 case ListStyleType::EthiopicAbegedeTiEt: ts << "ethiopic-abegede-ti-et"; break; 742 case ListStyleType::EthiopicHalehameAaEr: ts << "ethiopic-halehame-aa-er"; break; 743 case ListStyleType::EthiopicHalehameAaEt: ts << "ethiopic-halehame-aa-et"; break; 744 case ListStyleType::EthiopicHalehameAmEt: ts << "ethiopic-halehame-am-et"; break; 745 case ListStyleType::EthiopicHalehameGez: ts << "ethiopic-halehame-gez"; break; 746 case ListStyleType::EthiopicHalehameOmEt: ts << "ethiopic-halehame-om-et"; break; 747 case ListStyleType::EthiopicHalehameSidEt: ts << "ethiopic-halehame-sid-et"; break; 748 case ListStyleType::EthiopicHalehameSoEt: ts << "ethiopic-halehame-so-et"; break; 749 case ListStyleType::EthiopicHalehameTiEr: ts << "ethiopic-halehame-ti-er"; break; 750 case ListStyleType::EthiopicHalehameTiEt: ts << "ethiopic-halehame-ti-et"; break; 751 case ListStyleType::EthiopicHalehameTig: ts << "ethiopic-halehame-tig"; break; 752 case ListStyleType::Footnotes: ts << "footnotes"; break; 753 case ListStyleType::Georgian: ts << "georgian"; break; 754 case ListStyleType::Gujarati: ts << "gujarati"; break; 755 case ListStyleType::Gurmukhi: ts << "gurmukhi"; break; 756 case ListStyleType::Hangul: ts << "hangul"; break; 757 case ListStyleType::HangulConsonant: ts << "hangul-consonant"; break; 758 case ListStyleType::Hebrew: ts << "hebrew"; break; 759 case ListStyleType::Hiragana: ts << "hiragana"; break; 760 case ListStyleType::HiraganaIroha: ts << "hiragana-iroha"; break; 761 case ListStyleType::Kannada: ts << "kannada"; break; 762 case ListStyleType::Katakana: ts << "katakana"; break; 763 case ListStyleType::KatakanaIroha: ts << "katakana-iroha"; break; 764 case ListStyleType::Khmer: ts << "khmer"; break; 765 case ListStyleType::Lao: ts << "lao"; break; 766 case ListStyleType::LowerAlpha: ts << "lower-alpha"; break; 767 case ListStyleType::LowerArmenian: ts << "lower-armenian"; break; 768 case ListStyleType::LowerGreek: ts << "lower-greek"; break; 769 case ListStyleType::LowerHexadecimal: ts << "lower-hexadecimal"; break; 770 case ListStyleType::LowerLatin: ts << "lower-latin"; break; 771 case ListStyleType::LowerNorwegian: ts << "lower-norwegian"; break; 772 case ListStyleType::LowerRoman: ts << "lower-roman"; break; 773 case ListStyleType::Malayalam: ts << "malayalam"; break; 774 case ListStyleType::Mongolian: ts << "mongolian"; break; 775 case ListStyleType::Myanmar: ts << "myanmar"; break; 776 case ListStyleType::None: ts << "none"; break; 777 case ListStyleType::Octal: ts << "octal"; break; 778 case ListStyleType::Oriya: ts << "oriya"; break; 779 case ListStyleType::Oromo: ts << "oromo"; break; 780 case ListStyleType::Persian: ts << "persian"; break; 781 case ListStyleType::Sidama: ts << "sidama"; break; 782 case ListStyleType::Somali: ts << "somali"; break; 783 case ListStyleType::Square: ts << "square"; break; 784 case ListStyleType::String: ts << "string"; break; 785 case ListStyleType::Tamil: ts << "tamil"; break; 786 case ListStyleType::Telugu: ts << "telugu"; break; 787 case ListStyleType::Thai: ts << "thai"; break; 788 case ListStyleType::Tibetan: ts << "tibetan"; break; 789 case ListStyleType::Tigre: ts << "tigre"; break; 790 case ListStyleType::TigrinyaEr: ts << "tigrinya-er"; break; 791 case ListStyleType::TigrinyaErAbegede: ts << "tigrinya-er-abegede"; break; 792 case ListStyleType::TigrinyaEt: ts << "tigrinya-et"; break; 793 case ListStyleType::TigrinyaEtAbegede: ts << "tigrinya-et-abegede"; break; 794 case ListStyleType::UpperAlpha: ts << "upper-alpha"; break; 795 case ListStyleType::UpperArmenian: ts << "upper-armenian"; break; 796 case ListStyleType::UpperGreek: ts << "upper-greek"; break; 797 case ListStyleType::UpperHexadecimal: ts << "upper-hexadecimal"; break; 798 case ListStyleType::UpperLatin: ts << "upper-latin"; break; 799 case ListStyleType::UpperNorwegian: ts << "upper-norwegian"; break; 800 case ListStyleType::UpperRoman: ts << "upper-roman"; break; 801 case ListStyleType::Urdu: ts << "urdu"; break; 802 } 803 return ts; 717 return ts << getValueName(toCSSValueID(styleType)); 804 718 } 805 719 -
trunk/Source/WebCore/rendering/style/RenderStyleConstants.h
r279055 r279165 659 659 CJKDecimal, 660 660 Tamil, 661 DisclosureOpen, 662 DisclosureClosed, 663 JapaneseInformal, 664 JapaneseFormal, 665 KoreanHangulFormal, 666 KoreanHanjaInformal, 667 KoreanHanjaFormal, 668 SimplifiedChineseInformal, 669 SimplifiedChineseFormal, 670 TraditionalChineseInformal, 671 TraditionalChineseFormal, 672 EthiopicNumeric, 661 673 String, 662 674 None
Note: See TracChangeset
for help on using the changeset viewer.