Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(751)

Side by Side Diff: Source/core/rendering/RenderQuote.cpp

Issue 15093007: Shrink RenderQuote.o by 134K (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderQuote.h ('k') | Source/core/rendering/style/QuotesData.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /** 1 /**
2 * Copyright (C) 2011 Nokia Inc. All rights reserved. 2 * Copyright (C) 2011 Nokia Inc. All rights reserved.
3 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public License 15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to 16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA. 18 * Boston, MA 02110-1301, USA.
19 * 19 *
20 */ 20 */
21 21
22 #include "config.h" 22 #include "config.h"
23 #include "core/rendering/RenderQuote.h" 23 #include "core/rendering/RenderQuote.h"
24 24
25 #include "core/rendering/RenderView.h" 25 #include "core/rendering/style/QuotesData.h"
26 #include <wtf/text/AtomicString.h>
27 26
28 #define U(x) ((const UChar*)L##x) 27 using namespace WTF::Unicode;
29 28
30 namespace WebCore { 29 namespace WebCore {
31 30
32 RenderQuote::RenderQuote(Document* node, QuoteType quote) 31 RenderQuote::RenderQuote(Document* node, QuoteType quote)
33 : RenderText(node, StringImpl::empty()) 32 : RenderText(node, StringImpl::empty())
34 , m_type(quote) 33 , m_type(quote)
35 , m_depth(0) 34 , m_depth(0)
36 , m_next(0) 35 , m_next(0)
37 , m_previous(0) 36 , m_previous(0)
38 , m_attached(false) 37 , m_isAttached(false)
39 { 38 {
40 } 39 }
41 40
42 RenderQuote::~RenderQuote() 41 RenderQuote::~RenderQuote()
43 { 42 {
44 ASSERT(!m_attached); 43 ASSERT(!m_isAttached);
45 ASSERT(!m_next && !m_previous); 44 ASSERT(!m_next);
45 ASSERT(!m_previous);
46 } 46 }
47 47
48 void RenderQuote::willBeDestroyed() 48 void RenderQuote::willBeDestroyed()
49 { 49 {
50 detachQuote(); 50 detachQuote();
51 RenderText::willBeDestroyed(); 51 RenderText::willBeDestroyed();
52 } 52 }
53 53
54 void RenderQuote::willBeRemovedFromTree() 54 void RenderQuote::willBeRemovedFromTree()
55 { 55 {
56 RenderText::willBeRemovedFromTree(); 56 RenderText::willBeRemovedFromTree();
57 detachQuote(); 57 detachQuote();
58 } 58 }
59 59
60 void RenderQuote::styleDidChange(StyleDifference diff, const RenderStyle* oldSty le) 60 void RenderQuote::styleDidChange(StyleDifference diff, const RenderStyle* oldSty le)
61 { 61 {
62 RenderText::styleDidChange(diff, oldStyle); 62 RenderText::styleDidChange(diff, oldStyle);
63 setText(originalText()); 63 setText(originalText());
64 } 64 }
65 65
66 typedef HashMap<AtomicString, const QuotesData*, CaseFoldingHash> QuotesMap; 66 const unsigned maxDistinctQuoteCharacters = 16;
67 67
68 static const QuotesMap& quotesDataLanguageMap() 68 #if !ASSERT_DISABLED
69 { 69
70 DEFINE_STATIC_LOCAL(QuotesMap, staticQuotesMap, ()); 70 static void checkNumberOfDistinctQuoteCharacters(UChar character)
71 if (staticQuotesMap.size()) 71 {
72 return staticQuotesMap; 72 ASSERT(character);
73 73 static UChar distinctQuoteCharacters[maxDistinctQuoteCharacters];
74 for (unsigned i = 0; i < maxDistinctQuoteCharacters; ++i) {
75 if (distinctQuoteCharacters[i] == character)
76 return;
77 if (!distinctQuoteCharacters[i]) {
78 distinctQuoteCharacters[i] = character;
79 return;
80 }
81 }
82 ASSERT_NOT_REACHED();
83 }
84
85 #endif
86
87 struct QuotesForLanguage {
88 const char* language;
89 UChar open1;
90 UChar close1;
91 UChar open2;
92 UChar close2;
93 };
94
95 static int quoteTableLanguageComparisonFunction(const void* a, const void* b)
96 {
97 return strcmp(static_cast<const QuotesForLanguage*>(a)->language,
98 static_cast<const QuotesForLanguage*>(b)->language);
99 }
100
101 static const QuotesForLanguage* quotesForLanguage(const String& language)
102 {
74 // Table of quotes from http://www.whatwg.org/specs/web-apps/current-work/mu ltipage/rendering.html#quotes 103 // Table of quotes from http://www.whatwg.org/specs/web-apps/current-work/mu ltipage/rendering.html#quotes
75 #define QUOTES_LANG(lang, o1, c1, o2, c2) staticQuotesMap.set(lang, QuotesDa ta::create(U(o1), U(c1), U(o2), U(c2)).leakRef()) 104 static const QuotesForLanguage quoteTable[] = {
76 QUOTES_LANG("af", "\x201c", "\x201d", "\x2018", "\x2019"); 105 { "af", 0x201c, 0x201d, 0x2018, 0x2019 },
77 QUOTES_LANG("agq", "\x201e", "\x201d", "\x201a", "\x2019"); 106 { "agq", 0x201e, 0x201d, 0x201a, 0x2019 },
78 QUOTES_LANG("ak", "\x201c", "\x201d", "\x2018", "\x2019"); 107 { "ak", 0x201c, 0x201d, 0x2018, 0x2019 },
79 QUOTES_LANG("am", "\x00ab", "\x00bb", "\x2039", "\x203a"); 108 { "am", 0x00ab, 0x00bb, 0x2039, 0x203a },
80 QUOTES_LANG("ar", "\x201d", "\x201c", "\x2019", "\x2018"); 109 { "ar", 0x201d, 0x201c, 0x2019, 0x2018 },
81 QUOTES_LANG("asa", "\x201c", "\x201d", "\x2018", "\x2019"); 110 { "asa", 0x201c, 0x201d, 0x2018, 0x2019 },
82 QUOTES_LANG("az-Cyrl", "\x00ab", "\x00bb", "\x2039", "\x203a"); 111 { "az-cyrl", 0x00ab, 0x00bb, 0x2039, 0x203a },
83 QUOTES_LANG("bas", "\x00ab", "\x00bb", "\x201e", "\x201c"); 112 { "bas", 0x00ab, 0x00bb, 0x201e, 0x201c },
84 QUOTES_LANG("bem", "\x201c", "\x201d", "\x2018", "\x2019"); 113 { "bem", 0x201c, 0x201d, 0x2018, 0x2019 },
85 QUOTES_LANG("bez", "\x201c", "\x201d", "\x2018", "\x2019"); 114 { "bez", 0x201c, 0x201d, 0x2018, 0x2019 },
86 QUOTES_LANG("bg", "\x201e", "\x201c", "\x201a", "\x2018"); 115 { "bg", 0x201e, 0x201c, 0x201a, 0x2018 },
87 QUOTES_LANG("bm", "\x00ab", "\x00bb", "\x201c", "\x201d"); 116 { "bm", 0x00ab, 0x00bb, 0x201c, 0x201d },
88 QUOTES_LANG("bn", "\x201c", "\x201d", "\x2018", "\x2019"); 117 { "bn", 0x201c, 0x201d, 0x2018, 0x2019 },
89 QUOTES_LANG("br", "\x00ab", "\x00bb", "\x2039", "\x203a"); 118 { "br", 0x00ab, 0x00bb, 0x2039, 0x203a },
90 QUOTES_LANG("brx", "\x201c", "\x201d", "\x2018", "\x2019"); 119 { "brx", 0x201c, 0x201d, 0x2018, 0x2019 },
91 QUOTES_LANG("bs-Cyrl", "\x201e", "\x201c", "\x201a", "\x2018"); 120 { "bs-cyrl", 0x201e, 0x201c, 0x201a, 0x2018 },
92 QUOTES_LANG("ca", "\x201c", "\x201d", "\x00ab", "\x00bb"); 121 { "ca", 0x201c, 0x201d, 0x00ab, 0x00bb },
93 QUOTES_LANG("cgg", "\x201c", "\x201d", "\x2018", "\x2019"); 122 { "cgg", 0x201c, 0x201d, 0x2018, 0x2019 },
94 QUOTES_LANG("chr", "\x201c", "\x201d", "\x2018", "\x2019"); 123 { "chr", 0x201c, 0x201d, 0x2018, 0x2019 },
95 QUOTES_LANG("cs", "\x201e", "\x201c", "\x201a", "\x2018"); 124 { "cs", 0x201e, 0x201c, 0x201a, 0x2018 },
96 QUOTES_LANG("da", "\x201c", "\x201d", "\x2018", "\x2019"); 125 { "da", 0x201c, 0x201d, 0x2018, 0x2019 },
97 QUOTES_LANG("dav", "\x201c", "\x201d", "\x2018", "\x2019"); 126 { "dav", 0x201c, 0x201d, 0x2018, 0x2019 },
98 QUOTES_LANG("de", "\x201e", "\x201c", "\x201a", "\x2018"); 127 { "de", 0x201e, 0x201c, 0x201a, 0x2018 },
99 QUOTES_LANG("de-CH", "\x00ab", "\x00bb", "\x2039", "\x203a"); 128 { "de-ch", 0x00ab, 0x00bb, 0x2039, 0x203a },
100 QUOTES_LANG("dje", "\x201c", "\x201d", "\x2018", "\x2019"); 129 { "dje", 0x201c, 0x201d, 0x2018, 0x2019 },
101 QUOTES_LANG("dua", "\x00ab", "\x00bb", "\x2018", "\x2019"); 130 { "dua", 0x00ab, 0x00bb, 0x2018, 0x2019 },
102 QUOTES_LANG("dyo", "\x00ab", "\x00bb", "\x201c", "\x201d"); 131 { "dyo", 0x00ab, 0x00bb, 0x201c, 0x201d },
103 QUOTES_LANG("dz", "\x201c", "\x201d", "\x2018", "\x2019"); 132 { "dz", 0x201c, 0x201d, 0x2018, 0x2019 },
104 QUOTES_LANG("ebu", "\x201c", "\x201d", "\x2018", "\x2019"); 133 { "ebu", 0x201c, 0x201d, 0x2018, 0x2019 },
105 QUOTES_LANG("ee", "\x201c", "\x201d", "\x2018", "\x2019"); 134 { "ee", 0x201c, 0x201d, 0x2018, 0x2019 },
106 QUOTES_LANG("el", "\x00ab", "\x00bb", "\x201c", "\x201d"); 135 { "el", 0x00ab, 0x00bb, 0x201c, 0x201d },
107 QUOTES_LANG("en", "\x201c", "\x201d", "\x2018", "\x2019"); 136 { "en", 0x201c, 0x201d, 0x2018, 0x2019 },
108 QUOTES_LANG("en-GB", "\x201c", "\x201d", "\x2018", "\x2019"); 137 { "en-gb", 0x201c, 0x201d, 0x2018, 0x2019 },
109 QUOTES_LANG("es", "\x201c", "\x201d", "\x00ab", "\x00bb"); 138 { "es", 0x201c, 0x201d, 0x00ab, 0x00bb },
110 QUOTES_LANG("et", "\x201e", "\x201c", "\x201a", "\x2018"); 139 { "et", 0x201e, 0x201c, 0x201a, 0x2018 },
111 QUOTES_LANG("eu", "\x201c", "\x201d", "\x00ab", "\x00bb"); 140 { "eu", 0x201c, 0x201d, 0x00ab, 0x00bb },
112 QUOTES_LANG("ewo", "\x00ab", "\x00bb", "\x201c", "\x201d"); 141 { "ewo", 0x00ab, 0x00bb, 0x201c, 0x201d },
113 QUOTES_LANG("fa", "\x00ab", "\x00bb", "\x2039", "\x203a"); 142 { "fa", 0x00ab, 0x00bb, 0x2039, 0x203a },
114 QUOTES_LANG("ff", "\x201e", "\x201d", "\x201a", "\x2019"); 143 { "ff", 0x201e, 0x201d, 0x201a, 0x2019 },
115 QUOTES_LANG("fi", "\x201d", "\x201d", "\x2019", "\x2019"); 144 { "fi", 0x201d, 0x201d, 0x2019, 0x2019 },
116 QUOTES_LANG("fr", "\x00ab", "\x00bb", "\x00ab", "\x00bb"); 145 { "fr", 0x00ab, 0x00bb, 0x00ab, 0x00bb },
117 QUOTES_LANG("fr-CA", "\x00ab", "\x00bb", "\x2039", "\x203a"); 146 { "fr-ca", 0x00ab, 0x00bb, 0x2039, 0x203a },
118 QUOTES_LANG("fr-CH", "\x00ab", "\x00bb", "\x2039", "\x203a"); 147 { "fr-ch", 0x00ab, 0x00bb, 0x2039, 0x203a },
119 QUOTES_LANG("gsw", "\x00ab", "\x00bb", "\x2039", "\x203a"); 148 { "gsw", 0x00ab, 0x00bb, 0x2039, 0x203a },
120 QUOTES_LANG("gu", "\x201c", "\x201d", "\x2018", "\x2019"); 149 { "gu", 0x201c, 0x201d, 0x2018, 0x2019 },
121 QUOTES_LANG("guz", "\x201c", "\x201d", "\x2018", "\x2019"); 150 { "guz", 0x201c, 0x201d, 0x2018, 0x2019 },
122 QUOTES_LANG("ha", "\x201c", "\x201d", "\x2018", "\x2019"); 151 { "ha", 0x201c, 0x201d, 0x2018, 0x2019 },
123 QUOTES_LANG("he", "\x0022", "\x0022", "\x0027", "\x0027"); 152 { "he", 0x0022, 0x0022, 0x0027, 0x0027 },
124 QUOTES_LANG("hi", "\x201c", "\x201d", "\x2018", "\x2019"); 153 { "hi", 0x201c, 0x201d, 0x2018, 0x2019 },
125 QUOTES_LANG("hr", "\x201e", "\x201c", "\x201a", "\x2018"); 154 { "hr", 0x201e, 0x201c, 0x201a, 0x2018 },
126 QUOTES_LANG("hu", "\x201e", "\x201d", "\x00bb", "\x00ab"); 155 { "hu", 0x201e, 0x201d, 0x00bb, 0x00ab },
127 QUOTES_LANG("id", "\x201c", "\x201d", "\x2018", "\x2019"); 156 { "id", 0x201c, 0x201d, 0x2018, 0x2019 },
128 QUOTES_LANG("ig", "\x201c", "\x201d", "\x2018", "\x2019"); 157 { "ig", 0x201c, 0x201d, 0x2018, 0x2019 },
129 QUOTES_LANG("it", "\x00ab", "\x00bb", "\x201c", "\x201d"); 158 { "it", 0x00ab, 0x00bb, 0x201c, 0x201d },
130 QUOTES_LANG("ja", "\x300c", "\x300d", "\x300e", "\x300f"); 159 { "ja", 0x300c, 0x300d, 0x300e, 0x300f },
131 QUOTES_LANG("jgo", "\x00ab", "\x00bb", "\x2039", "\x203a"); 160 { "jgo", 0x00ab, 0x00bb, 0x2039, 0x203a },
132 QUOTES_LANG("jmc", "\x201c", "\x201d", "\x2018", "\x2019"); 161 { "jmc", 0x201c, 0x201d, 0x2018, 0x2019 },
133 QUOTES_LANG("kab", "\x00ab", "\x00bb", "\x201c", "\x201d"); 162 { "kab", 0x00ab, 0x00bb, 0x201c, 0x201d },
134 QUOTES_LANG("kam", "\x201c", "\x201d", "\x2018", "\x2019"); 163 { "kam", 0x201c, 0x201d, 0x2018, 0x2019 },
135 QUOTES_LANG("kde", "\x201c", "\x201d", "\x2018", "\x2019"); 164 { "kde", 0x201c, 0x201d, 0x2018, 0x2019 },
136 QUOTES_LANG("kea", "\x201c", "\x201d", "\x2018", "\x2019"); 165 { "kea", 0x201c, 0x201d, 0x2018, 0x2019 },
137 QUOTES_LANG("khq", "\x201c", "\x201d", "\x2018", "\x2019"); 166 { "khq", 0x201c, 0x201d, 0x2018, 0x2019 },
138 QUOTES_LANG("ki", "\x201c", "\x201d", "\x2018", "\x2019"); 167 { "ki", 0x201c, 0x201d, 0x2018, 0x2019 },
139 QUOTES_LANG("kkj", "\x00ab", "\x00bb", "\x2039", "\x203a"); 168 { "kkj", 0x00ab, 0x00bb, 0x2039, 0x203a },
140 QUOTES_LANG("kln", "\x201c", "\x201d", "\x2018", "\x2019"); 169 { "kln", 0x201c, 0x201d, 0x2018, 0x2019 },
141 QUOTES_LANG("km", "\x201c", "\x201d", "\x2018", "\x2019"); 170 { "km", 0x201c, 0x201d, 0x2018, 0x2019 },
142 QUOTES_LANG("kn", "\x201c", "\x201d", "\x2018", "\x2019"); 171 { "kn", 0x201c, 0x201d, 0x2018, 0x2019 },
143 QUOTES_LANG("ko", "\x201c", "\x201d", "\x2018", "\x2019"); 172 { "ko", 0x201c, 0x201d, 0x2018, 0x2019 },
144 QUOTES_LANG("ksb", "\x201c", "\x201d", "\x2018", "\x2019"); 173 { "ksb", 0x201c, 0x201d, 0x2018, 0x2019 },
145 QUOTES_LANG("ksf", "\x00ab", "\x00bb", "\x2018", "\x2019"); 174 { "ksf", 0x00ab, 0x00bb, 0x2018, 0x2019 },
146 QUOTES_LANG("lag", "\x201d", "\x201d", "\x2019", "\x2019"); 175 { "lag", 0x201d, 0x201d, 0x2019, 0x2019 },
147 QUOTES_LANG("lg", "\x201c", "\x201d", "\x2018", "\x2019"); 176 { "lg", 0x201c, 0x201d, 0x2018, 0x2019 },
148 QUOTES_LANG("ln", "\x201c", "\x201d", "\x2018", "\x2019"); 177 { "ln", 0x201c, 0x201d, 0x2018, 0x2019 },
149 QUOTES_LANG("lo", "\x201c", "\x201d", "\x2018", "\x2019"); 178 { "lo", 0x201c, 0x201d, 0x2018, 0x2019 },
150 QUOTES_LANG("lt", "\x201e", "\x201c", "\x201e", "\x201c"); 179 { "lt", 0x201e, 0x201c, 0x201e, 0x201c },
151 QUOTES_LANG("lu", "\x201c", "\x201d", "\x2018", "\x2019"); 180 { "lu", 0x201c, 0x201d, 0x2018, 0x2019 },
152 QUOTES_LANG("luo", "\x201c", "\x201d", "\x2018", "\x2019"); 181 { "luo", 0x201c, 0x201d, 0x2018, 0x2019 },
153 QUOTES_LANG("luy", "\x201e", "\x201c", "\x201a", "\x2018"); 182 { "luy", 0x201e, 0x201c, 0x201a, 0x2018 },
154 QUOTES_LANG("lv", "\x201c", "\x201d", "\x2018", "\x2019"); 183 { "lv", 0x201c, 0x201d, 0x2018, 0x2019 },
155 QUOTES_LANG("mas", "\x201c", "\x201d", "\x2018", "\x2019"); 184 { "mas", 0x201c, 0x201d, 0x2018, 0x2019 },
156 QUOTES_LANG("mer", "\x201c", "\x201d", "\x2018", "\x2019"); 185 { "mer", 0x201c, 0x201d, 0x2018, 0x2019 },
157 QUOTES_LANG("mfe", "\x201c", "\x201d", "\x2018", "\x2019"); 186 { "mfe", 0x201c, 0x201d, 0x2018, 0x2019 },
158 QUOTES_LANG("mg", "\x00ab", "\x00bb", "\x201c", "\x201d"); 187 { "mg", 0x00ab, 0x00bb, 0x201c, 0x201d },
159 QUOTES_LANG("mgo", "\x201c", "\x201d", "\x2018", "\x2019"); 188 { "mgo", 0x201c, 0x201d, 0x2018, 0x2019 },
160 QUOTES_LANG("mk", "\x201e", "\x201c", "\x201a", "\x2018"); 189 { "mk", 0x201e, 0x201c, 0x201a, 0x2018 },
161 QUOTES_LANG("ml", "\x201c", "\x201d", "\x2018", "\x2019"); 190 { "ml", 0x201c, 0x201d, 0x2018, 0x2019 },
162 QUOTES_LANG("mr", "\x201c", "\x201d", "\x2018", "\x2019"); 191 { "mr", 0x201c, 0x201d, 0x2018, 0x2019 },
163 QUOTES_LANG("ms", "\x201c", "\x201d", "\x2018", "\x2019"); 192 { "ms", 0x201c, 0x201d, 0x2018, 0x2019 },
164 QUOTES_LANG("mua", "\x00ab", "\x00bb", "\x201c", "\x201d"); 193 { "mua", 0x00ab, 0x00bb, 0x201c, 0x201d },
165 QUOTES_LANG("my", "\x201c", "\x201d", "\x2018", "\x2019"); 194 { "my", 0x201c, 0x201d, 0x2018, 0x2019 },
166 QUOTES_LANG("naq", "\x201c", "\x201d", "\x2018", "\x2019"); 195 { "naq", 0x201c, 0x201d, 0x2018, 0x2019 },
167 QUOTES_LANG("nb", "\x00ab", "\x00bb", "\x2018", "\x2019"); 196 { "nb", 0x00ab, 0x00bb, 0x2018, 0x2019 },
168 QUOTES_LANG("nd", "\x201c", "\x201d", "\x2018", "\x2019"); 197 { "nd", 0x201c, 0x201d, 0x2018, 0x2019 },
169 QUOTES_LANG("nl", "\x201c", "\x201d", "\x2018", "\x2019"); 198 { "nl", 0x201c, 0x201d, 0x2018, 0x2019 },
170 QUOTES_LANG("nmg", "\x201e", "\x201d", "\x00ab", "\x00bb"); 199 { "nmg", 0x201e, 0x201d, 0x00ab, 0x00bb },
171 QUOTES_LANG("nn", "\x00ab", "\x00bb", "\x2018", "\x2019"); 200 { "nn", 0x00ab, 0x00bb, 0x2018, 0x2019 },
172 QUOTES_LANG("nnh", "\x00ab", "\x00bb", "\x201c", "\x201d"); 201 { "nnh", 0x00ab, 0x00bb, 0x201c, 0x201d },
173 QUOTES_LANG("nus", "\x201c", "\x201d", "\x2018", "\x2019"); 202 { "nus", 0x201c, 0x201d, 0x2018, 0x2019 },
174 QUOTES_LANG("nyn", "\x201c", "\x201d", "\x2018", "\x2019"); 203 { "nyn", 0x201c, 0x201d, 0x2018, 0x2019 },
175 QUOTES_LANG("pl", "\x201e", "\x201d", "\x00ab", "\x00bb"); 204 { "pl", 0x201e, 0x201d, 0x00ab, 0x00bb },
176 QUOTES_LANG("pt", "\x201c", "\x201d", "\x2018", "\x2019"); 205 { "pt", 0x201c, 0x201d, 0x2018, 0x2019 },
177 QUOTES_LANG("pt-PT", "\x00ab", "\x00bb", "\x201c", "\x201d"); 206 { "pt-pt", 0x00ab, 0x00bb, 0x201c, 0x201d },
178 QUOTES_LANG("rn", "\x201d", "\x201d", "\x2019", "\x2019"); 207 { "rn", 0x201d, 0x201d, 0x2019, 0x2019 },
179 QUOTES_LANG("ro", "\x201e", "\x201d", "\x00ab", "\x00bb"); 208 { "ro", 0x201e, 0x201d, 0x00ab, 0x00bb },
180 QUOTES_LANG("rof", "\x201c", "\x201d", "\x2018", "\x2019"); 209 { "rof", 0x201c, 0x201d, 0x2018, 0x2019 },
181 QUOTES_LANG("ru", "\x00ab", "\x00bb", "\x201e", "\x201c"); 210 { "ru", 0x00ab, 0x00bb, 0x201e, 0x201c },
182 QUOTES_LANG("rw", "\x00ab", "\x00bb", "\x2018", "\x2019"); 211 { "rw", 0x00ab, 0x00bb, 0x2018, 0x2019 },
183 QUOTES_LANG("rwk", "\x201c", "\x201d", "\x2018", "\x2019"); 212 { "rwk", 0x201c, 0x201d, 0x2018, 0x2019 },
184 QUOTES_LANG("saq", "\x201c", "\x201d", "\x2018", "\x2019"); 213 { "saq", 0x201c, 0x201d, 0x2018, 0x2019 },
185 QUOTES_LANG("sbp", "\x201c", "\x201d", "\x2018", "\x2019"); 214 { "sbp", 0x201c, 0x201d, 0x2018, 0x2019 },
186 QUOTES_LANG("seh", "\x201c", "\x201d", "\x2018", "\x2019"); 215 { "seh", 0x201c, 0x201d, 0x2018, 0x2019 },
187 QUOTES_LANG("ses", "\x201c", "\x201d", "\x2018", "\x2019"); 216 { "ses", 0x201c, 0x201d, 0x2018, 0x2019 },
188 QUOTES_LANG("sg", "\x00ab", "\x00bb", "\x201c", "\x201d"); 217 { "sg", 0x00ab, 0x00bb, 0x201c, 0x201d },
189 QUOTES_LANG("shi", "\x00ab", "\x00bb", "\x201e", "\x201d"); 218 { "shi", 0x00ab, 0x00bb, 0x201e, 0x201d },
190 QUOTES_LANG("shi-Tfng", "\x00ab", "\x00bb", "\x201e", "\x201d"); 219 { "shi-tfng", 0x00ab, 0x00bb, 0x201e, 0x201d },
191 QUOTES_LANG("si", "\x201c", "\x201d", "\x2018", "\x2019"); 220 { "si", 0x201c, 0x201d, 0x2018, 0x2019 },
192 QUOTES_LANG("sk", "\x201e", "\x201c", "\x201a", "\x2018"); 221 { "sk", 0x201e, 0x201c, 0x201a, 0x2018 },
193 QUOTES_LANG("sl", "\x201e", "\x201c", "\x201a", "\x2018"); 222 { "sl", 0x201e, 0x201c, 0x201a, 0x2018 },
194 QUOTES_LANG("sn", "\x201d", "\x201d", "\x2019", "\x2019"); 223 { "sn", 0x201d, 0x201d, 0x2019, 0x2019 },
195 QUOTES_LANG("so", "\x201c", "\x201d", "\x2018", "\x2019"); 224 { "so", 0x201c, 0x201d, 0x2018, 0x2019 },
196 QUOTES_LANG("sq", "\x201e", "\x201c", "\x201a", "\x2018"); 225 { "sq", 0x201e, 0x201c, 0x201a, 0x2018 },
197 QUOTES_LANG("sr", "\x201e", "\x201c", "\x201a", "\x2018"); 226 { "sr", 0x201e, 0x201c, 0x201a, 0x2018 },
198 QUOTES_LANG("sr-Latn", "\x201e", "\x201c", "\x201a", "\x2018"); 227 { "sr-latn", 0x201e, 0x201c, 0x201a, 0x2018 },
199 QUOTES_LANG("sv", "\x201d", "\x201d", "\x2019", "\x2019"); 228 { "sv", 0x201d, 0x201d, 0x2019, 0x2019 },
200 QUOTES_LANG("sw", "\x201c", "\x201d", "\x2018", "\x2019"); 229 { "sw", 0x201c, 0x201d, 0x2018, 0x2019 },
201 QUOTES_LANG("swc", "\x201c", "\x201d", "\x2018", "\x2019"); 230 { "swc", 0x201c, 0x201d, 0x2018, 0x2019 },
202 QUOTES_LANG("ta", "\x201c", "\x201d", "\x2018", "\x2019"); 231 { "ta", 0x201c, 0x201d, 0x2018, 0x2019 },
203 QUOTES_LANG("te", "\x201c", "\x201d", "\x2018", "\x2019"); 232 { "te", 0x201c, 0x201d, 0x2018, 0x2019 },
204 QUOTES_LANG("teo", "\x201c", "\x201d", "\x2018", "\x2019"); 233 { "teo", 0x201c, 0x201d, 0x2018, 0x2019 },
205 QUOTES_LANG("th", "\x201c", "\x201d", "\x2018", "\x2019"); 234 { "th", 0x201c, 0x201d, 0x2018, 0x2019 },
206 QUOTES_LANG("ti-ER", "\x2018", "\x2019", "\x201c", "\x201d"); 235 { "ti-er", 0x2018, 0x2019, 0x201c, 0x201d },
207 QUOTES_LANG("to", "\x201c", "\x201d", "\x2018", "\x2019"); 236 { "to", 0x201c, 0x201d, 0x2018, 0x2019 },
208 QUOTES_LANG("tr", "\x201c", "\x201d", "\x2018", "\x2019"); 237 { "tr", 0x201c, 0x201d, 0x2018, 0x2019 },
209 QUOTES_LANG("twq", "\x201c", "\x201d", "\x2018", "\x2019"); 238 { "twq", 0x201c, 0x201d, 0x2018, 0x2019 },
210 QUOTES_LANG("tzm", "\x201c", "\x201d", "\x2018", "\x2019"); 239 { "tzm", 0x201c, 0x201d, 0x2018, 0x2019 },
211 QUOTES_LANG("uk", "\x00ab", "\x00bb", "\x201e", "\x201c"); 240 { "uk", 0x00ab, 0x00bb, 0x201e, 0x201c },
212 QUOTES_LANG("ur", "\x201d", "\x201c", "\x2019", "\x2018"); 241 { "ur", 0x201d, 0x201c, 0x2019, 0x2018 },
213 QUOTES_LANG("vai", "\x201c", "\x201d", "\x2018", "\x2019"); 242 { "vai", 0x201c, 0x201d, 0x2018, 0x2019 },
214 QUOTES_LANG("vai-Latn", "\x201c", "\x201d", "\x2018", "\x2019"); 243 { "vai-latn", 0x201c, 0x201d, 0x2018, 0x2019 },
215 QUOTES_LANG("vi", "\x201c", "\x201d", "\x2018", "\x2019"); 244 { "vi", 0x201c, 0x201d, 0x2018, 0x2019 },
216 QUOTES_LANG("vun", "\x201c", "\x201d", "\x2018", "\x2019"); 245 { "vun", 0x201c, 0x201d, 0x2018, 0x2019 },
217 QUOTES_LANG("xh", "\x2018", "\x2019", "\x201c", "\x201d"); 246 { "xh", 0x2018, 0x2019, 0x201c, 0x201d },
218 QUOTES_LANG("xog", "\x201c", "\x201d", "\x2018", "\x2019"); 247 { "xog", 0x201c, 0x201d, 0x2018, 0x2019 },
219 QUOTES_LANG("yav", "\x00ab", "\x00bb", "\x00ab", "\x00bb"); 248 { "yav", 0x00ab, 0x00bb, 0x00ab, 0x00bb },
220 QUOTES_LANG("yo", "\x201c", "\x201d", "\x2018", "\x2019"); 249 { "yo", 0x201c, 0x201d, 0x2018, 0x2019 },
221 QUOTES_LANG("zh", "\x201c", "\x201d", "\x2018", "\x2019"); 250 { "zh", 0x201c, 0x201d, 0x2018, 0x2019 },
222 QUOTES_LANG("zh-Hant", "\x300c", "\x300d", "\x300e", "\x300f"); 251 { "zh-hant", 0x300c, 0x300d, 0x300e, 0x300f },
223 QUOTES_LANG("zu", "\x201c", "\x201d", "\x2018", "\x2019"); 252 { "zu", 0x201c, 0x201d, 0x2018, 0x2019 },
224 #undef QUOTES_LANG 253 };
225 254
226 return staticQuotesMap; 255 const unsigned maxLanguageLength = 8;
227 } 256
228 257 #if !ASSERT_DISABLED
229 static const QuotesData* basicQuotesData() 258 // One time check that the table meets the constraints that the code below r elies on.
230 { 259
231 // FIXME: The default quotes should be the fancy quotes for "en". 260 static bool didOneTimeCheck = false;
232 static const QuotesData* staticBasicQuotes = QuotesData::create(U("\""), U(" \""), U("'"), U("'")).leakRef(); 261 if (!didOneTimeCheck) {
233 return staticBasicQuotes; 262 didOneTimeCheck = true;
263
264 checkNumberOfDistinctQuoteCharacters(quotationMark);
265 checkNumberOfDistinctQuoteCharacters(apostrophe);
266
267 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(quoteTable); ++i) {
268 ASSERT(strlen(quoteTable[i].language) <= maxLanguageLength);
269
270 if (i)
271 ASSERT(strcmp(quoteTable[i - 1].language, quoteTable[i].language ) < 0);
272
273 for (unsigned j = 0; UChar character = quoteTable[i].language[j]; ++ j)
274 ASSERT(isASCIILower(character) || character == '-');
275
276 checkNumberOfDistinctQuoteCharacters(quoteTable[i].open1);
277 checkNumberOfDistinctQuoteCharacters(quoteTable[i].close1);
278 checkNumberOfDistinctQuoteCharacters(quoteTable[i].open2);
279 checkNumberOfDistinctQuoteCharacters(quoteTable[i].close2);
280 }
281 }
282 #endif
283
284 unsigned length = language.length();
285 if (!length || length > maxLanguageLength)
286 return 0;
287
288 char languageKeyBuffer[maxLanguageLength + 1];
289 for (unsigned i = 0; i < length; ++i) {
290 UChar character = toASCIILower(language[i]);
291 if (!(isASCIILower(character) || character == '-'))
292 return 0;
293 languageKeyBuffer[i] = static_cast<char>(character);
294 }
295 languageKeyBuffer[length] = 0;
296
297 QuotesForLanguage languageKey = { languageKeyBuffer, 0, 0, 0, 0 };
298
299 return static_cast<const QuotesForLanguage*>(bsearch(&languageKey,
300 quoteTable, WTF_ARRAY_LENGTH(quoteTable), sizeof(quoteTable[0]), quoteTa bleLanguageComparisonFunction));
301 }
302
303 static StringImpl* stringForQuoteCharacter(UChar character)
304 {
305 // Use linear search because there is a small number of distinct characters, thus binary search is unneeded.
306 ASSERT(character);
307 struct StringForCharacter {
308 UChar character;
309 StringImpl* string;
310 };
311 static StringForCharacter strings[maxDistinctQuoteCharacters];
312 for (unsigned i = 0; i < maxDistinctQuoteCharacters; ++i) {
313 if (strings[i].character == character)
314 return strings[i].string;
315 if (!strings[i].character) {
316 strings[i].character = character;
317 strings[i].string = StringImpl::create8BitIfPossible(&character, 1). leakRef();
318 return strings[i].string;
319 }
320 }
321 ASSERT_NOT_REACHED();
322 return StringImpl::empty();
323 }
324
325 static inline StringImpl* quotationMarkString()
326 {
327 static StringImpl* quotationMarkString = stringForQuoteCharacter(quotationMa rk);
328 return quotationMarkString;
329 }
330
331 static inline StringImpl* apostropheString()
332 {
333 static StringImpl* apostropheString = stringForQuoteCharacter(apostrophe);
334 return apostropheString;
234 } 335 }
235 336
236 PassRefPtr<StringImpl> RenderQuote::originalText() const 337 PassRefPtr<StringImpl> RenderQuote::originalText() const
237 { 338 {
339 if (m_depth < 0)
340 return StringImpl::empty();
341 bool isOpenQuote = false;
238 switch (m_type) { 342 switch (m_type) {
239 case NO_OPEN_QUOTE: 343 case NO_OPEN_QUOTE:
240 case NO_CLOSE_QUOTE: 344 case NO_CLOSE_QUOTE:
241 return StringImpl::empty(); 345 return StringImpl::empty();
346 case OPEN_QUOTE:
347 isOpenQuote = true;
348 // fall through
242 case CLOSE_QUOTE: 349 case CLOSE_QUOTE:
243 return quotesData()->getCloseQuote(m_depth - 1).impl(); 350 if (const QuotesData* quotes = style()->quotes())
244 case OPEN_QUOTE: 351 return isOpenQuote ? quotes->openQuote(m_depth).impl() : quotes->clo seQuote(m_depth).impl();
245 return quotesData()->getOpenQuote(m_depth).impl(); 352 if (const QuotesForLanguage* quotes = quotesForLanguage(style()->locale( )))
353 return stringForQuoteCharacter(isOpenQuote ? (m_depth ? quotes->open 2 : quotes->open1) : (m_depth ? quotes->close2 : quotes->close1));
354 // FIXME: Should the default be the quotes for "en" rather than straight quotes?
355 return m_depth ? apostropheString() : quotationMarkString();
246 } 356 }
247 ASSERT_NOT_REACHED(); 357 ASSERT_NOT_REACHED();
248 return StringImpl::empty(); 358 return StringImpl::empty();
249 } 359 }
250 360
251 const QuotesData* RenderQuote::quotesData() const
252 {
253 if (QuotesData* customQuotes = style()->quotes())
254 return customQuotes;
255
256 AtomicString language = style()->locale();
257 if (language.isNull())
258 return basicQuotesData();
259 const QuotesData* quotes = quotesDataLanguageMap().get(language);
260 if (!quotes)
261 return basicQuotesData();
262 return quotes;
263 }
264
265 void RenderQuote::attachQuote() 361 void RenderQuote::attachQuote()
266 { 362 {
267 ASSERT(view()); 363 ASSERT(view());
268 ASSERT(!m_attached); 364 ASSERT(!m_isAttached);
269 ASSERT(!m_next && !m_previous); 365 ASSERT(!m_next);
366 ASSERT(!m_previous);
270 ASSERT(isRooted()); 367 ASSERT(isRooted());
271 368
272 if (!view()->renderQuoteHead()) { 369 // Optimize case where this is the first quote in a RenderView by not search ing for predecessors in that case.
273 view()->setRenderQuoteHead(this); 370 if (view()->renderQuoteHead()) {
274 m_attached = true; 371 for (RenderObject* predecessor = previousInPreOrder(); predecessor; pred ecessor = predecessor->previousInPreOrder()) {
275 return; 372 // Skip unattached predecessors to avoid having stale m_previous poi nters
276 } 373 // if the previous node is never attached and is then destroyed.
277 374 if (!predecessor->isQuote() || !toRenderQuote(predecessor)->m_isAtta ched)
278 for (RenderObject* predecessor = previousInPreOrder(); predecessor; predeces sor = predecessor->previousInPreOrder()) { 375 continue;
279 // Skip unattached predecessors to avoid having stale m_previous pointer s 376 m_previous = toRenderQuote(predecessor);
280 // if the previous node is never attached and is then destroyed. 377 m_next = m_previous->m_next;
281 if (!predecessor->isQuote() || !toRenderQuote(predecessor)->isAttached() ) 378 m_previous->m_next = this;
282 continue; 379 if (m_next)
283 m_previous = toRenderQuote(predecessor); 380 m_next->m_previous = this;
284 m_next = m_previous->m_next; 381 break;
285 m_previous->m_next = this; 382 }
286 if (m_next)
287 m_next->m_previous = this;
288 break;
289 } 383 }
290 384
291 if (!m_previous) { 385 if (!m_previous) {
292 m_next = view()->renderQuoteHead(); 386 m_next = view()->renderQuoteHead();
293 view()->setRenderQuoteHead(this); 387 view()->setRenderQuoteHead(this);
294 if (m_next) 388 if (m_next)
295 m_next->m_previous = this; 389 m_next->m_previous = this;
296 } 390 }
297 m_attached = true; 391 m_isAttached = true;
298 392
299 for (RenderQuote* quote = this; quote; quote = quote->m_next) 393 for (RenderQuote* quote = this; quote; quote = quote->m_next)
300 quote->updateDepth(); 394 quote->updateDepth();
301 395
302 ASSERT(!m_next || m_next->m_attached); 396 ASSERT(!m_next || m_next->m_isAttached);
303 ASSERT(!m_next || m_next->m_previous == this); 397 ASSERT(!m_next || m_next->m_previous == this);
304 ASSERT(!m_previous || m_previous->m_attached); 398 ASSERT(!m_previous || m_previous->m_isAttached);
305 ASSERT(!m_previous || m_previous->m_next == this); 399 ASSERT(!m_previous || m_previous->m_next == this);
306 } 400 }
307 401
308 void RenderQuote::detachQuote() 402 void RenderQuote::detachQuote()
309 { 403 {
310 ASSERT(!m_next || m_next->m_attached); 404 ASSERT(!m_next || m_next->m_isAttached);
311 ASSERT(!m_previous || m_previous->m_attached); 405 ASSERT(!m_previous || m_previous->m_isAttached);
312 if (!m_attached) 406 if (!m_isAttached)
313 return; 407 return;
314 if (m_previous) 408 if (m_previous)
315 m_previous->m_next = m_next; 409 m_previous->m_next = m_next;
316 else if (view()) 410 else if (view())
317 view()->setRenderQuoteHead(m_next); 411 view()->setRenderQuoteHead(m_next);
318 if (m_next) 412 if (m_next)
319 m_next->m_previous = m_previous; 413 m_next->m_previous = m_previous;
320 if (!documentBeingDestroyed()) { 414 if (!documentBeingDestroyed()) {
321 for (RenderQuote* quote = m_next; quote; quote = quote->m_next) 415 for (RenderQuote* quote = m_next; quote; quote = quote->m_next)
322 quote->updateDepth(); 416 quote->updateDepth();
323 } 417 }
324 m_attached = false; 418 m_isAttached = false;
325 m_next = 0; 419 m_next = 0;
326 m_previous = 0; 420 m_previous = 0;
327 m_depth = 0; 421 m_depth = 0;
328 } 422 }
329 423
330 void RenderQuote::updateDepth() 424 void RenderQuote::updateDepth()
331 { 425 {
332 ASSERT(m_attached); 426 ASSERT(m_isAttached);
333 int oldDepth = m_depth; 427 int oldDepth = m_depth;
334 m_depth = 0; 428 m_depth = 0;
335 if (m_previous) { 429 if (m_previous) {
336 m_depth = m_previous->m_depth; 430 m_depth = m_previous->m_depth;
337 switch (m_previous->m_type) { 431 switch (m_previous->m_type) {
338 case OPEN_QUOTE: 432 case OPEN_QUOTE:
339 case NO_OPEN_QUOTE: 433 case NO_OPEN_QUOTE:
340 m_depth++; 434 m_depth++;
341 break; 435 break;
342 case CLOSE_QUOTE: 436 case CLOSE_QUOTE:
343 case NO_CLOSE_QUOTE: 437 case NO_CLOSE_QUOTE:
344 if (m_depth) 438 if (m_depth)
345 m_depth--; 439 m_depth--;
346 break; 440 break;
347 } 441 }
348 } 442 }
349 if (oldDepth != m_depth) 443 if (oldDepth != m_depth)
350 setText(originalText()); 444 setText(originalText());
351 } 445 }
352 446
353 } // namespace WebCore 447 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderQuote.h ('k') | Source/core/rendering/style/QuotesData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698