Changeset 270025 in webkit
- Timestamp:
- Nov 19, 2020 6:17:12 AM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r270024 r270025 1 2020-11-19 Antti Koivisto <antti@apple.com> 2 3 [LFC][Integration] nextLinePosition should use iterator 4 https://bugs.webkit.org/show_bug.cgi?id=219152 5 6 Reviewed by Zalan Bujtas. 7 8 The last major piece of direct InlineBox access in editing code. 9 10 * dom/Position.cpp: 11 (WebCore::InlineBoxAndOffset::InlineBoxAndOffset): Deleted. 12 (WebCore::Position::inlineBoxAndOffset const): Deleted. 13 14 No longer needed. 15 16 * dom/Position.h: 17 * editing/VisibleUnits.cpp: 18 (WebCore::previousLineCandidatePosition): 19 (WebCore::nextLineCandidatePosition): 20 (WebCore::isTextOrLineBreakRun): 21 (WebCore::previousTextOrLineBreakRun): 22 (WebCore::nextTextOrLineBreakRun): 23 (WebCore::startTextOrLineBreakRun): 24 (WebCore::endTextOrLineBreakRun): 25 (WebCore::logicallyPreviousRun): 26 (WebCore::logicallyNextRun): 27 (WebCore::wordBreakIteratorForMinOffsetBoundary): 28 (WebCore::wordBreakIteratorForMaxOffsetBoundary): 29 (WebCore::visualWordPosition): 30 (WebCore::previousLinePosition): 31 (WebCore::nextLinePosition): 32 (WebCore::previousRootInlineBoxCandidatePosition): Deleted. 33 (WebCore::nextRootInlineBoxCandidatePosition): Deleted. 34 (WebCore::CachedLogicallyOrderedLeafBoxes::size const): Deleted. 35 (WebCore::CachedLogicallyOrderedLeafBoxes::firstBox const): Deleted. 36 (WebCore::CachedLogicallyOrderedLeafBoxes::CachedLogicallyOrderedLeafBoxes): Deleted. 37 (WebCore::CachedLogicallyOrderedLeafBoxes::previousTextOrLineBreakBox): Deleted. 38 (WebCore::CachedLogicallyOrderedLeafBoxes::nextTextOrLineBreakBox): Deleted. 39 (WebCore::CachedLogicallyOrderedLeafBoxes::boxIndexInLeaves const): Deleted. 40 41 The iterarator handles logical order caching for InlineBoxes, no need for a separate cache. 42 43 (WebCore::logicallyPreviousBox): Deleted. 44 (WebCore::logicallyNextBox): Deleted. 45 1 46 2020-11-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 47 -
trunk/Source/WebCore/dom/Position.cpp
r269852 r270025 104 104 } 105 105 106 InlineBoxAndOffset::InlineBoxAndOffset(InlineRunAndOffset runAndOffset)107 : box(runAndOffset.run ? runAndOffset.run->legacyInlineBox() : nullptr)108 , offset(runAndOffset.offset)109 {110 }111 112 106 Position::Position(Node* anchorNode, unsigned offset, LegacyEditingPositionFlag) 113 107 : m_anchorNode(anchorNode) … … 1370 1364 } 1371 1365 1372 InlineBoxAndOffset Position::inlineBoxAndOffset(Affinity affinity) const1373 {1374 return inlineBoxAndOffset(affinity, primaryDirection());1375 }1376 1377 InlineBoxAndOffset Position::inlineBoxAndOffset(Affinity affinity, TextDirection primaryDirection) const1378 {1379 ensureLineBoxes();1380 1381 return { inlineRunAndOffset(affinity, primaryDirection) };1382 }1383 1384 1366 void Position::ensureLineBoxes() const 1385 1367 { -
trunk/Source/WebCore/dom/Position.h
r269442 r270025 52 52 struct InlineRunAndOffset; 53 53 54 struct InlineBoxAndOffset {55 InlineBoxAndOffset(InlineRunAndOffset);56 57 InlineBox* box { nullptr };58 int offset { 0 };59 };60 61 54 class Position { 62 55 public: … … 180 173 InlineRunAndOffset inlineRunAndOffset(Affinity, TextDirection primaryDirection) const; 181 174 182 InlineBoxAndOffset inlineBoxAndOffset(Affinity) const;183 InlineBoxAndOffset inlineBoxAndOffset(Affinity, TextDirection primaryDirection) const;184 185 175 TextDirection primaryDirection() const; 186 176 -
trunk/Source/WebCore/editing/VisibleUnits.cpp
r269732 r270025 1 1 /* 2 * Copyright (C) 2004 , 2005, 2006, 2007, 2008, 2009Apple Inc. All rights reserved.2 * Copyright (C) 2004-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 33 33 #include "HTMLNames.h" 34 34 #include "InlineRunAndOffset.h" 35 #include "InlineTextBox.h" 35 #include "LayoutIntegrationLineIterator.h" 36 #include "LayoutIntegrationRunIterator.h" 36 37 #include "NodeTraversal.h" 37 38 #include "Range.h" … … 79 80 80 81 // FIXME: consolidate with code in previousLinePosition. 81 static Position previous RootInlineBoxCandidatePosition(Node* node, const VisiblePosition& visiblePosition, EditableType editableType)82 static Position previousLineCandidatePosition(Node* node, const VisiblePosition& visiblePosition, EditableType editableType) 82 83 { 83 84 auto* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), editableType); … … 102 103 } 103 104 104 static Position next RootInlineBoxCandidatePosition(Node* node, const VisiblePosition& visiblePosition, EditableType editableType)105 static Position nextLineCandidatePosition(Node* node, const VisiblePosition& visiblePosition, EditableType editableType) 105 106 { 106 107 auto* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), editableType); … … 124 125 } 125 126 126 class CachedLogicallyOrderedLeafBoxes { 127 public: 128 CachedLogicallyOrderedLeafBoxes(); 129 130 const InlineBox* previousTextOrLineBreakBox(const RootInlineBox*, const InlineBox*); 131 const InlineBox* nextTextOrLineBreakBox(const RootInlineBox*, const InlineBox*); 132 133 size_t size() const { return m_leafBoxes.size(); } 134 const InlineBox* firstBox() const { return m_leafBoxes[0]; } 135 136 private: 137 const Vector<InlineBox*>& collectBoxes(const RootInlineBox*); 138 int boxIndexInLeaves(const InlineBox*) const; 139 140 const RootInlineBox* m_rootInlineBox { nullptr }; 141 Vector<InlineBox*> m_leafBoxes; 142 }; 143 144 CachedLogicallyOrderedLeafBoxes::CachedLogicallyOrderedLeafBoxes() 145 { 146 } 147 148 const InlineBox* CachedLogicallyOrderedLeafBoxes::previousTextOrLineBreakBox(const RootInlineBox* root, const InlineBox* box) 149 { 150 if (!root) 151 return nullptr; 152 153 collectBoxes(root); 154 155 // If box is null, root is box's previous RootInlineBox, and previousBox is the last logical box in root. 156 int boxIndex = m_leafBoxes.size() - 1; 157 if (box) 158 boxIndex = boxIndexInLeaves(box) - 1; 159 160 for (int i = boxIndex; i >= 0; --i) { 161 InlineBox* box = m_leafBoxes[i]; 162 if (box->isInlineTextBox() || box->renderer().isBR()) 163 return box; 164 } 165 166 return nullptr; 167 } 168 169 const InlineBox* CachedLogicallyOrderedLeafBoxes::nextTextOrLineBreakBox(const RootInlineBox* root, const InlineBox* box) 170 { 171 if (!root) 172 return nullptr; 173 174 collectBoxes(root); 175 176 // If box is null, root is box's next RootInlineBox, and nextBox is the first logical box in root. 177 // Otherwise, root is box's RootInlineBox, and nextBox is the next logical box in the same line. 178 size_t nextBoxIndex = 0; 179 if (box) 180 nextBoxIndex = boxIndexInLeaves(box) + 1; 181 182 for (size_t i = nextBoxIndex; i < m_leafBoxes.size(); ++i) { 183 InlineBox* box = m_leafBoxes[i]; 184 if (box->isInlineTextBox() || box->renderer().isBR()) 185 return box; 186 } 187 188 return nullptr; 189 } 190 191 const Vector<InlineBox*>& CachedLogicallyOrderedLeafBoxes::collectBoxes(const RootInlineBox* root) 192 { 193 if (m_rootInlineBox != root) { 194 m_rootInlineBox = root; 195 m_leafBoxes.clear(); 196 root->collectLeafBoxesInLogicalOrder(m_leafBoxes); 197 } 198 return m_leafBoxes; 199 } 200 201 int CachedLogicallyOrderedLeafBoxes::boxIndexInLeaves(const InlineBox* box) const 202 { 203 for (size_t i = 0; i < m_leafBoxes.size(); ++i) { 204 if (box == m_leafBoxes[i]) 205 return i; 206 } 207 return 0; 208 } 209 210 static const InlineBox* logicallyPreviousBox(const VisiblePosition& visiblePosition, const InlineBox* textBox, 211 bool& previousBoxInDifferentLine, CachedLogicallyOrderedLeafBoxes& leafBoxes) 212 { 213 const InlineBox* startBox = textBox; 214 215 const InlineBox* previousBox = leafBoxes.previousTextOrLineBreakBox(&startBox->root(), textBox); 216 if (previousBox) 217 return previousBox; 218 219 previousBox = leafBoxes.previousTextOrLineBreakBox(startBox->root().prevRootBox(), 0); 220 if (previousBox) 221 return previousBox; 127 static bool isTextOrLineBreakRun(LayoutIntegration::RunIterator run) 128 { 129 return run && (run->isText() || run->renderer().isBR()); 130 } 131 132 static LayoutIntegration::RunIterator previousTextOrLineBreakRun(LayoutIntegration::RunIterator run) 133 { 134 while (run) { 135 run.traversePreviousOnLineInLogicalOrder(); 136 if (isTextOrLineBreakRun(run)) 137 return run; 138 } 139 return { }; 140 } 141 142 static LayoutIntegration::RunIterator nextTextOrLineBreakRun(LayoutIntegration::RunIterator run) 143 { 144 while (run) { 145 run.traverseNextOnLineInLogicalOrder(); 146 if (isTextOrLineBreakRun(run)) 147 return run; 148 } 149 return { }; 150 } 151 152 static LayoutIntegration::RunIterator startTextOrLineBreakRun(LayoutIntegration::LineIterator line) 153 { 154 auto run = line.logicalStartRun(); 155 if (isTextOrLineBreakRun(run)) 156 return run; 157 return nextTextOrLineBreakRun(run); 158 } 159 160 static LayoutIntegration::RunIterator endTextOrLineBreakRun(LayoutIntegration::LineIterator line) 161 { 162 auto run = line.logicalEndRun(); 163 if (isTextOrLineBreakRun(run)) 164 return run; 165 return previousTextOrLineBreakRun(run); 166 } 167 168 static const LayoutIntegration::RunIterator logicallyPreviousRun(const VisiblePosition& visiblePosition, LayoutIntegration::RunIterator startRun, bool& previousBoxInDifferentLine) 169 { 170 if (auto previousRun = previousTextOrLineBreakRun(startRun)) 171 return previousRun; 172 173 if (auto previousLine = startRun.line().previous()) { 174 // FIXME: Why isn't previousBoxInDifferentLine set here? 175 if (auto previousRun = endTextOrLineBreakRun(previousLine)) 176 return previousRun; 177 } 222 178 223 179 while (1) { 224 Node* startNode = startBox->renderer().nonPseudoNode();180 auto* startNode = startRun->renderer().nonPseudoNode(); 225 181 if (!startNode) 226 182 break; 227 183 228 Position position = previous RootInlineBoxCandidatePosition(startNode, visiblePosition, ContentIsEditable);184 Position position = previousLineCandidatePosition(startNode, visiblePosition, ContentIsEditable); 229 185 if (position.isNull()) 230 186 break; 231 187 232 188 RenderedPosition renderedPosition(position, Affinity::Downstream); 233 RootInlineBox* previousRoot = renderedPosition.rootBox(); 234 if (!previousRoot) 235 break; 236 237 previousBox = leafBoxes.previousTextOrLineBreakBox(previousRoot, &startBox->root() == previousRoot ? startBox : nullptr); 238 if (previousBox) { 239 previousBoxInDifferentLine = true; 240 return previousBox; 241 } 242 243 if (!leafBoxes.size()) 244 break; 245 startBox = leafBoxes.firstBox(); 246 } 247 return 0; 248 } 249 250 251 static const InlineBox* logicallyNextBox(const VisiblePosition& visiblePosition, const InlineBox* textBox, 252 bool& nextBoxInDifferentLine, CachedLogicallyOrderedLeafBoxes& leafBoxes) 253 { 254 const InlineBox* startBox = textBox; 255 256 const InlineBox* nextBox = leafBoxes.nextTextOrLineBreakBox(&startBox->root(), textBox); 257 if (nextBox) 258 return nextBox; 259 260 nextBox = leafBoxes.nextTextOrLineBreakBox(startBox->root().nextRootBox(), 0); 261 if (nextBox) 262 return nextBox; 189 auto previousLine = renderedPosition.line(); 190 if (!previousLine) 191 break; 192 193 if (previousLine != startRun.line()) { 194 if (auto previousRun = endTextOrLineBreakRun(previousLine)) { 195 previousBoxInDifferentLine = true; 196 return previousRun; 197 } 198 } 199 200 startRun = previousLine.logicalStartRun(); 201 } 202 return { }; 203 } 204 205 206 static const LayoutIntegration::RunIterator logicallyNextRun(const VisiblePosition& visiblePosition, LayoutIntegration::RunIterator startRun, bool& nextBoxInDifferentLine) 207 { 208 if (auto nextRun = nextTextOrLineBreakRun(startRun)) 209 return nextRun; 210 211 if (auto nextLine = startRun.line().next()) { 212 // FIXME: Why isn't previousBoxInDifferentLine set here? 213 if (auto nextRun = startTextOrLineBreakRun(nextLine)) 214 return nextRun; 215 } 263 216 264 217 while (1) { 265 Node* startNode = startBox->renderer().nonPseudoNode();218 auto* startNode = startRun->renderer().nonPseudoNode(); 266 219 if (!startNode) 267 220 break; 268 221 269 Position position = next RootInlineBoxCandidatePosition(startNode, visiblePosition, ContentIsEditable);222 Position position = nextLineCandidatePosition(startNode, visiblePosition, ContentIsEditable); 270 223 if (position.isNull()) 271 224 break; 272 225 273 226 RenderedPosition renderedPosition(position, Affinity::Downstream); 274 RootInlineBox* nextRoot = renderedPosition.rootBox(); 275 if (!nextRoot) 276 break; 277 278 nextBox = leafBoxes.nextTextOrLineBreakBox(nextRoot, &startBox->root() == nextRoot ? startBox : nullptr); 279 if (nextBox) { 280 nextBoxInDifferentLine = true; 281 return nextBox; 282 } 283 284 if (!leafBoxes.size()) 285 break; 286 startBox = leafBoxes.firstBox(); 287 } 288 return 0; 289 } 290 291 static UBreakIterator* wordBreakIteratorForMinOffsetBoundary(const VisiblePosition& visiblePosition, const InlineTextBox* textBox, 292 int& previousBoxLength, bool& previousBoxInDifferentLine, Vector<UChar, 1024>& string, CachedLogicallyOrderedLeafBoxes& leafBoxes) 293 { 294 previousBoxInDifferentLine = false; 295 296 const InlineBox* previousBox = logicallyPreviousBox(visiblePosition, textBox, previousBoxInDifferentLine, leafBoxes); 297 while (previousBox && !is<InlineTextBox>(previousBox)) { 298 ASSERT(previousBox->renderer().isBR()); 299 previousBoxInDifferentLine = true; 300 previousBox = logicallyPreviousBox(visiblePosition, previousBox, previousBoxInDifferentLine, leafBoxes); 227 auto nextLine = renderedPosition.line(); 228 if (!nextLine) 229 break; 230 231 if (nextLine != startRun.line()) { 232 if (auto nextRun = startTextOrLineBreakRun(nextLine)) { 233 nextBoxInDifferentLine = true; 234 return nextRun; 235 } 236 } 237 238 startRun = nextLine.logicalEndRun(); 239 } 240 return { }; 241 } 242 243 static UBreakIterator* wordBreakIteratorForMinOffsetBoundary(const VisiblePosition& visiblePosition, LayoutIntegration::TextRunIterator textRun, 244 unsigned& previousRunLength, bool& previousRunInDifferentLine, Vector<UChar, 1024>& string) 245 { 246 previousRunInDifferentLine = false; 247 248 auto previousRun = logicallyPreviousRun(visiblePosition, textRun, previousRunInDifferentLine); 249 while (previousRun && !previousRun->isText()) { 250 ASSERT(previousRun->renderer().isBR()); 251 previousRunInDifferentLine = true; 252 previousRun = logicallyPreviousRun(visiblePosition, previousRun, previousRunInDifferentLine); 301 253 } 302 254 303 255 string.clear(); 304 256 305 if ( is<InlineTextBox>(previousBox)) {306 const auto& previousTextBox = downcast<InlineTextBox>(*previousBox);307 previous BoxLength = previousTextBox.len();308 append(string, StringView(previousTextBox.renderer().text()).substring(previousTextBox.start(), previousBoxLength));309 } 310 append(string, StringView(textBox->renderer().text()).substring(textBox->start(), textBox->len()));257 if (previousRun) { 258 auto& previousTextRun = downcast<LayoutIntegration::TextRunIterator>(previousRun); 259 previousRunLength = previousTextRun->length(); 260 append(string, previousTextRun->text()); 261 } 262 append(string, textRun->text()); 311 263 312 264 return wordBreakIterator(StringView(string.data(), string.size())); 313 265 } 314 266 315 static UBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePosition& visiblePosition, const InlineTextBox* textBox,316 bool& next BoxInDifferentLine, Vector<UChar, 1024>& string, CachedLogicallyOrderedLeafBoxes& leafBoxes)317 { 318 next BoxInDifferentLine = false;319 320 const InlineBox* nextBox = logicallyNextBox(visiblePosition, textBox, nextBoxInDifferentLine, leafBoxes);321 while (next Box && !is<InlineTextBox>(nextBox)) {322 ASSERT(next Box->renderer().isBR());323 next BoxInDifferentLine = true;324 next Box = logicallyNextBox(visiblePosition, nextBox, nextBoxInDifferentLine, leafBoxes);267 static UBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePosition& visiblePosition, LayoutIntegration::TextRunIterator textRun, 268 bool& nextRunInDifferentLine, Vector<UChar, 1024>& string) 269 { 270 nextRunInDifferentLine = false; 271 272 auto nextRun = logicallyNextRun(visiblePosition, textRun, nextRunInDifferentLine); 273 while (nextRun && !nextRun->isText()) { 274 ASSERT(nextRun->renderer().isBR()); 275 nextRunInDifferentLine = true; 276 nextRun = logicallyNextRun(visiblePosition, nextRun, nextRunInDifferentLine); 325 277 } 326 278 327 279 string.clear(); 328 append(string, StringView(textBox->renderer().text()).substring(textBox->start(), textBox->len())); 329 if (is<InlineTextBox>(nextBox)) { 330 const auto& nextTextBox = downcast<InlineTextBox>(*nextBox); 331 append(string, StringView(nextTextBox.renderer().text()).substring(nextTextBox.start(), nextTextBox.len())); 280 append(string, textRun->text()); 281 282 if (nextRun) { 283 auto& nextTextRun = downcast<LayoutIntegration::TextRunIterator>(nextRun); 284 append(string, nextTextRun->text()); 332 285 } 333 286 … … 361 314 362 315 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition.deepEquivalent()); 363 InlineBox* previouslyVisitedBox = nullptr;316 LayoutIntegration::RunIterator previouslyVisitedRun; 364 317 VisiblePosition current = visiblePosition; 365 318 Optional<VisiblePosition> previousPosition; 366 319 UBreakIterator* iter = nullptr; 367 320 368 CachedLogicallyOrderedLeafBoxes leafBoxes;369 321 Vector<UChar, 1024> string; 370 322 … … 377 329 return VisiblePosition(); 378 330 379 // FIXME: Why force the use of upstream affinity here instead of VisiblePosition::inline BoxAndOffset, which will get affinity from adjacentCharacterPosition?380 auto [ box, offsetInBox] = adjacentCharacterPosition.deepEquivalent().inlineBoxAndOffset(Affinity::Upstream);381 382 if (! box)383 break; 384 if (! is<InlineTextBox>(*box)) {331 // FIXME: Why force the use of upstream affinity here instead of VisiblePosition::inlineRunAndOffset, which will get affinity from adjacentCharacterPosition? 332 auto [run, offsetInRun] = adjacentCharacterPosition.deepEquivalent().inlineRunAndOffset(Affinity::Upstream); 333 334 if (!run) 335 break; 336 if (!run->isText()) { 385 337 current = adjacentCharacterPosition; 386 338 continue; 387 339 } 388 340 389 InlineTextBox& textBox = downcast<InlineTextBox>(*box);390 int previousBoxLength = 0;391 bool previous BoxInDifferentLine = false;392 bool next BoxInDifferentLine = false;393 bool movingIntoNew Box = previouslyVisitedBox != box;394 395 if (offsetIn Box == box->caretMinOffset())396 iter = wordBreakIteratorForMinOffsetBoundary(adjacentCharacterPosition, &textBox, previousBoxLength, previousBoxInDifferentLine, string, leafBoxes);397 else if (offsetIn Box == box->caretMaxOffset())398 iter = wordBreakIteratorForMaxOffsetBoundary(adjacentCharacterPosition, &textBox, nextBoxInDifferentLine, string, leafBoxes);399 else if (movingIntoNew Box) {400 iter = wordBreakIterator( StringView(textBox.renderer().text()).substring(textBox.start(), textBox.len()));401 previouslyVisited Box = box;341 auto& textRun = downcast<LayoutIntegration::TextRunIterator>(run); 342 unsigned previousRunLength = 0; 343 bool previousRunInDifferentLine = false; 344 bool nextRunInDifferentLine = false; 345 bool movingIntoNewRun = previouslyVisitedRun != run; 346 347 if (offsetInRun == textRun->minimumCaretOffset()) 348 iter = wordBreakIteratorForMinOffsetBoundary(adjacentCharacterPosition, textRun, previousRunLength, previousRunInDifferentLine, string); 349 else if (offsetInRun == textRun->maximumCaretOffset()) 350 iter = wordBreakIteratorForMaxOffsetBoundary(adjacentCharacterPosition, textRun, nextRunInDifferentLine, string); 351 else if (movingIntoNewRun) { 352 iter = wordBreakIterator(textRun->text()); 353 previouslyVisitedRun = run; 402 354 } 403 355 … … 406 358 407 359 ubrk_first(iter); 408 int offsetInIterator = offsetIn Box - textBox.start() + previousBoxLength;360 int offsetInIterator = offsetInRun - textRun->start() + previousRunLength; 409 361 410 362 bool isWordBreak; 411 bool boxHasSameDirectionalityAsBlock = box->direction() == blockDirection;412 bool movingBackward = (direction == MoveLeft && box->direction() == TextDirection::LTR) || (direction == MoveRight && box->direction() == TextDirection::RTL);363 bool boxHasSameDirectionalityAsBlock = run->direction() == blockDirection; 364 bool movingBackward = (direction == MoveLeft && run->direction() == TextDirection::LTR) || (direction == MoveRight && run->direction() == TextDirection::RTL); 413 365 if ((skipsSpaceWhenMovingRight && boxHasSameDirectionalityAsBlock) 414 366 || (!skipsSpaceWhenMovingRight && movingBackward)) { 415 bool logicalStartInRenderer = offsetIn Box == static_cast<int>(textBox.start()) && previousBoxInDifferentLine;367 bool logicalStartInRenderer = offsetInRun == textRun->start() && previousRunInDifferentLine; 416 368 isWordBreak = isLogicalStartOfWord(iter, offsetInIterator, logicalStartInRenderer); 417 if (isWordBreak && offsetIn Box == box->caretMaxOffset() && nextBoxInDifferentLine)369 if (isWordBreak && offsetInRun == run->maximumCaretOffset() && nextRunInDifferentLine) 418 370 isWordBreak = false; 419 371 } else { 420 bool logicalEndInRenderer = offsetIn Box == static_cast<int>(textBox.start() + textBox.len()) && nextBoxInDifferentLine;372 bool logicalEndInRenderer = offsetInRun == textRun->end() && nextRunInDifferentLine; 421 373 isWordBreak = islogicalEndOfWord(iter, offsetInIterator, logicalEndInRenderer); 422 if (isWordBreak && offsetIn Box == box->caretMinOffset() && previousBoxInDifferentLine)374 if (isWordBreak && offsetInRun == run->minimumCaretOffset() && previousRunInDifferentLine) 423 375 isWordBreak = false; 424 376 } … … 1025 977 1026 978 if (!line) { 1027 Position position = previous RootInlineBoxCandidatePosition(node, visiblePosition, editableType);979 Position position = previousLineCandidatePosition(node, visiblePosition, editableType); 1028 980 if (position.isNotNull()) { 1029 981 RenderedPosition renderedPosition(position); … … 1078 1030 Node* child = node->traverseToChildAt(p.deprecatedEditingOffset()); 1079 1031 node = child ? child : node->lastDescendant(); 1080 Position position = next RootInlineBoxCandidatePosition(node, visiblePosition, editableType);1032 Position position = nextLineCandidatePosition(node, visiblePosition, editableType); 1081 1033 if (position.isNotNull()) { 1082 1034 RenderedPosition renderedPosition(position);
Note: See TracChangeset
for help on using the changeset viewer.