| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "core/layout/line/AbstractInlineTextBox.h" | 32 #include "core/layout/line/AbstractInlineTextBox.h" |
| 33 | 33 |
| 34 #include "core/dom/AXObjectCache.h" | 34 #include "core/dom/AXObjectCache.h" |
| 35 #include "core/editing/iterators/TextIterator.h" | 35 #include "core/editing/iterators/TextIterator.h" |
| 36 #include "platform/text/TextBreakIterator.h" | 36 #include "platform/text/TextBreakIterator.h" |
| 37 | 37 |
| 38 namespace blink { | 38 namespace blink { |
| 39 | 39 |
| 40 AbstractInlineTextBox::InlineToAbstractInlineTextBoxHashMap* AbstractInlineTextB
ox::gAbstractInlineTextBoxMap = nullptr; | 40 AbstractInlineTextBox::InlineToAbstractInlineTextBoxHashMap* AbstractInlineTextB
ox::gAbstractInlineTextBoxMap = nullptr; |
| 41 | 41 |
| 42 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::getOrCreate(LayoutText*
layoutText, InlineTextBox* inlineTextBox) | 42 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::getOrCreate(LineLayoutT
ext lineLayoutText, InlineTextBox* inlineTextBox) |
| 43 { | 43 { |
| 44 if (!inlineTextBox) | 44 if (!inlineTextBox) |
| 45 return nullptr; | 45 return nullptr; |
| 46 | 46 |
| 47 if (!gAbstractInlineTextBoxMap) | 47 if (!gAbstractInlineTextBoxMap) |
| 48 gAbstractInlineTextBoxMap = new InlineToAbstractInlineTextBoxHashMap(); | 48 gAbstractInlineTextBoxMap = new InlineToAbstractInlineTextBoxHashMap(); |
| 49 | 49 |
| 50 InlineToAbstractInlineTextBoxHashMap::const_iterator it = gAbstractInlineTex
tBoxMap->find(inlineTextBox); | 50 InlineToAbstractInlineTextBoxHashMap::const_iterator it = gAbstractInlineTex
tBoxMap->find(inlineTextBox); |
| 51 if (it != gAbstractInlineTextBoxMap->end()) | 51 if (it != gAbstractInlineTextBoxMap->end()) |
| 52 return it->value; | 52 return it->value; |
| 53 | 53 |
| 54 RefPtr<AbstractInlineTextBox> obj = adoptRef(new AbstractInlineTextBox(layou
tText, inlineTextBox)); | 54 RefPtr<AbstractInlineTextBox> obj = adoptRef(new AbstractInlineTextBox(lineL
ayoutText, inlineTextBox)); |
| 55 gAbstractInlineTextBoxMap->set(inlineTextBox, obj); | 55 gAbstractInlineTextBoxMap->set(inlineTextBox, obj); |
| 56 return obj; | 56 return obj; |
| 57 } | 57 } |
| 58 | 58 |
| 59 void AbstractInlineTextBox::willDestroy(InlineTextBox* inlineTextBox) | 59 void AbstractInlineTextBox::willDestroy(InlineTextBox* inlineTextBox) |
| 60 { | 60 { |
| 61 if (!gAbstractInlineTextBoxMap) | 61 if (!gAbstractInlineTextBoxMap) |
| 62 return; | 62 return; |
| 63 | 63 |
| 64 InlineToAbstractInlineTextBoxHashMap::const_iterator it = gAbstractInlineTex
tBoxMap->find(inlineTextBox); | 64 InlineToAbstractInlineTextBoxHashMap::const_iterator it = gAbstractInlineTex
tBoxMap->find(inlineTextBox); |
| 65 if (it != gAbstractInlineTextBoxMap->end()) { | 65 if (it != gAbstractInlineTextBoxMap->end()) { |
| 66 it->value->detach(); | 66 it->value->detach(); |
| 67 gAbstractInlineTextBoxMap->remove(inlineTextBox); | 67 gAbstractInlineTextBoxMap->remove(inlineTextBox); |
| 68 } | 68 } |
| 69 } | 69 } |
| 70 | 70 |
| 71 AbstractInlineTextBox::~AbstractInlineTextBox() | 71 AbstractInlineTextBox::~AbstractInlineTextBox() |
| 72 { | 72 { |
| 73 ASSERT(!m_layoutText); | 73 ASSERT(!m_lineLayoutItem); |
| 74 ASSERT(!m_inlineTextBox); | 74 ASSERT(!m_inlineTextBox); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void AbstractInlineTextBox::detach() | 77 void AbstractInlineTextBox::detach() |
| 78 { | 78 { |
| 79 if (Node* node = m_layoutText->node()) { | 79 if (Node* node = m_lineLayoutItem.node()) { |
| 80 if (AXObjectCache* cache = node->document().existingAXObjectCache()) | 80 if (AXObjectCache* cache = node->document().existingAXObjectCache()) |
| 81 cache->remove(this); | 81 cache->remove(this); |
| 82 } | 82 } |
| 83 | 83 |
| 84 m_layoutText = 0; | 84 m_lineLayoutItem = LineLayoutText(nullptr); |
| 85 m_inlineTextBox = 0; | 85 m_inlineTextBox = nullptr; |
| 86 } | 86 } |
| 87 | 87 |
| 88 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::nextInlineTextBox() con
st | 88 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::nextInlineTextBox() con
st |
| 89 { | 89 { |
| 90 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; | 90 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; |
| 91 if (!m_inlineTextBox) | 91 if (!m_inlineTextBox) |
| 92 return nullptr; | 92 return nullptr; |
| 93 | 93 |
| 94 return getOrCreate(m_layoutText, m_inlineTextBox->nextTextBox()); | 94 return getOrCreate(m_lineLayoutItem, m_inlineTextBox->nextTextBox()); |
| 95 } | 95 } |
| 96 | 96 |
| 97 LayoutRect AbstractInlineTextBox::bounds() const | 97 LayoutRect AbstractInlineTextBox::bounds() const |
| 98 { | 98 { |
| 99 if (!m_inlineTextBox || !m_layoutText) | 99 if (!m_inlineTextBox || !m_lineLayoutItem) |
| 100 return LayoutRect(); | 100 return LayoutRect(); |
| 101 | 101 |
| 102 FloatRect boundaries(m_inlineTextBox->calculateBoundaries()); | 102 FloatRect boundaries(m_inlineTextBox->calculateBoundaries()); |
| 103 return LayoutRect(m_layoutText->localToAbsoluteQuad(boundaries).enclosingBou
ndingBox()); | 103 return LayoutRect(m_lineLayoutItem.localToAbsoluteQuad(boundaries).enclosing
BoundingBox()); |
| 104 } | 104 } |
| 105 | 105 |
| 106 unsigned AbstractInlineTextBox::len() const | 106 unsigned AbstractInlineTextBox::len() const |
| 107 { | 107 { |
| 108 if (!m_inlineTextBox) | 108 if (!m_inlineTextBox) |
| 109 return 0; | 109 return 0; |
| 110 | 110 |
| 111 return m_inlineTextBox->len(); | 111 return m_inlineTextBox->len(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 AbstractInlineTextBox::Direction AbstractInlineTextBox::direction() const | 114 AbstractInlineTextBox::Direction AbstractInlineTextBox::direction() const |
| 115 { | 115 { |
| 116 if (!m_inlineTextBox || !m_layoutText) | 116 if (!m_inlineTextBox || !m_lineLayoutItem) |
| 117 return LeftToRight; | 117 return LeftToRight; |
| 118 | 118 |
| 119 if (m_layoutText->style()->isHorizontalWritingMode()) | 119 if (m_lineLayoutItem.style()->isHorizontalWritingMode()) |
| 120 return (m_inlineTextBox->direction() == RTL ? RightToLeft : LeftToRight)
; | 120 return (m_inlineTextBox->direction() == RTL ? RightToLeft : LeftToRight)
; |
| 121 return (m_inlineTextBox->direction() == RTL ? BottomToTop : TopToBottom); | 121 return (m_inlineTextBox->direction() == RTL ? BottomToTop : TopToBottom); |
| 122 } | 122 } |
| 123 | 123 |
| 124 void AbstractInlineTextBox::characterWidths(Vector<float>& widths) const | 124 void AbstractInlineTextBox::characterWidths(Vector<float>& widths) const |
| 125 { | 125 { |
| 126 if (!m_inlineTextBox) | 126 if (!m_inlineTextBox) |
| 127 return; | 127 return; |
| 128 | 128 |
| 129 m_inlineTextBox->characterWidths(widths); | 129 m_inlineTextBox->characterWidths(widths); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 146 while (pos >= 0 && pos < len) { | 146 while (pos >= 0 && pos < len) { |
| 147 int next = iterator->next(); | 147 int next = iterator->next(); |
| 148 if (isWordTextBreak(iterator)) | 148 if (isWordTextBreak(iterator)) |
| 149 words.append(WordBoundaries(pos, next)); | 149 words.append(WordBoundaries(pos, next)); |
| 150 pos = next; | 150 pos = next; |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 | 153 |
| 154 String AbstractInlineTextBox::text() const | 154 String AbstractInlineTextBox::text() const |
| 155 { | 155 { |
| 156 if (!m_inlineTextBox || !m_layoutText) | 156 if (!m_inlineTextBox || !m_lineLayoutItem) |
| 157 return String(); | 157 return String(); |
| 158 | 158 |
| 159 unsigned start = m_inlineTextBox->start(); | 159 unsigned start = m_inlineTextBox->start(); |
| 160 unsigned len = m_inlineTextBox->len(); | 160 unsigned len = m_inlineTextBox->len(); |
| 161 if (Node* node = m_layoutText->node()) { | 161 if (Node* node = m_lineLayoutItem.node()) { |
| 162 if (node->isTextNode()) | 162 if (node->isTextNode()) |
| 163 return plainText(EphemeralRange(Position(node, start), Position(node
, start + len)), TextIteratorIgnoresStyleVisibility); | 163 return plainText(EphemeralRange(Position(node, start), Position(node
, start + len)), TextIteratorIgnoresStyleVisibility); |
| 164 return plainText(EphemeralRange(Position(node, PositionAnchorType::Befor
eAnchor), Position(node, PositionAnchorType::AfterAnchor)), TextIteratorIgnoresS
tyleVisibility); | 164 return plainText(EphemeralRange(Position(node, PositionAnchorType::Befor
eAnchor), Position(node, PositionAnchorType::AfterAnchor)), TextIteratorIgnoresS
tyleVisibility); |
| 165 } | 165 } |
| 166 | 166 |
| 167 String result = m_layoutText->text().substring(start, len).simplifyWhiteSpac
e(WTF::DoNotStripWhiteSpace); | 167 String result = m_lineLayoutItem.text().substring(start, len).simplifyWhiteS
pace(WTF::DoNotStripWhiteSpace); |
| 168 if (m_inlineTextBox->nextTextBox() && m_inlineTextBox->nextTextBox()->start(
) > m_inlineTextBox->end() && result.length() && !result.right(1).containsOnlyWh
itespace()) | 168 if (m_inlineTextBox->nextTextBox() && m_inlineTextBox->nextTextBox()->start(
) > m_inlineTextBox->end() && result.length() && !result.right(1).containsOnlyWh
itespace()) |
| 169 return result + " "; | 169 return result + " "; |
| 170 return result; | 170 return result; |
| 171 } | 171 } |
| 172 | 172 |
| 173 bool AbstractInlineTextBox::isFirst() const | 173 bool AbstractInlineTextBox::isFirst() const |
| 174 { | 174 { |
| 175 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; | 175 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; |
| 176 return !m_inlineTextBox || !m_inlineTextBox->prevTextBox(); | 176 return !m_inlineTextBox || !m_inlineTextBox->prevTextBox(); |
| 177 } | 177 } |
| 178 | 178 |
| 179 bool AbstractInlineTextBox::isLast() const | 179 bool AbstractInlineTextBox::isLast() const |
| 180 { | 180 { |
| 181 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; | 181 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; |
| 182 return !m_inlineTextBox || !m_inlineTextBox->nextTextBox(); | 182 return !m_inlineTextBox || !m_inlineTextBox->nextTextBox(); |
| 183 } | 183 } |
| 184 | 184 |
| 185 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::nextOnLine() const | 185 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::nextOnLine() const |
| 186 { | 186 { |
| 187 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; | 187 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; |
| 188 if (!m_inlineTextBox) | 188 if (!m_inlineTextBox) |
| 189 return nullptr; | 189 return nullptr; |
| 190 | 190 |
| 191 InlineBox* next = m_inlineTextBox->nextOnLine(); | 191 InlineBox* next = m_inlineTextBox->nextOnLine(); |
| 192 if (next && next->isInlineTextBox()) | 192 if (next && next->isInlineTextBox()) |
| 193 return getOrCreate(&toInlineTextBox(next)->layoutObject(), toInlineTextB
ox(next)); | 193 return getOrCreate(toInlineTextBox(next)->lineLayoutItem(), toInlineText
Box(next)); |
| 194 | 194 |
| 195 return nullptr; | 195 return nullptr; |
| 196 } | 196 } |
| 197 | 197 |
| 198 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::previousOnLine() const | 198 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::previousOnLine() const |
| 199 { | 199 { |
| 200 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; | 200 ASSERT(!m_inlineTextBox || !m_inlineTextBox->lineLayoutItem().needsLayout())
; |
| 201 if (!m_inlineTextBox) | 201 if (!m_inlineTextBox) |
| 202 return nullptr; | 202 return nullptr; |
| 203 | 203 |
| 204 InlineBox* previous = m_inlineTextBox->prevOnLine(); | 204 InlineBox* previous = m_inlineTextBox->prevOnLine(); |
| 205 if (previous && previous->isInlineTextBox()) | 205 if (previous && previous->isInlineTextBox()) |
| 206 return getOrCreate(&toInlineTextBox(previous)->layoutObject(), toInlineT
extBox(previous)); | 206 return getOrCreate(toInlineTextBox(previous)->lineLayoutItem(), toInline
TextBox(previous)); |
| 207 | 207 |
| 208 return nullptr; | 208 return nullptr; |
| 209 } | 209 } |
| 210 | 210 |
| 211 } // namespace blink | 211 } // namespace blink |
| OLD | NEW |