OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 } | 344 } |
345 | 345 |
346 enum CursorMovementDirection { MoveLeft, MoveRight }; | 346 enum CursorMovementDirection { MoveLeft, MoveRight }; |
347 | 347 |
348 static VisiblePosition visualWordPosition(const VisiblePosition& visiblePosition
, CursorMovementDirection direction, | 348 static VisiblePosition visualWordPosition(const VisiblePosition& visiblePosition
, CursorMovementDirection direction, |
349 bool skipsSpaceWhenMovingRight) | 349 bool skipsSpaceWhenMovingRight) |
350 { | 350 { |
351 if (visiblePosition.isNull()) | 351 if (visiblePosition.isNull()) |
352 return VisiblePosition(); | 352 return VisiblePosition(); |
353 | 353 |
354 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition.dee
pEquivalent()); | 354 bool isLeftToRight = isEnclosingBoxHasLeftToRightDirection(visiblePosition.d
eepEquivalent()); |
355 InlineBox* previouslyVisitedBox = 0; | 355 InlineBox* previouslyVisitedBox = 0; |
356 VisiblePosition current = visiblePosition; | 356 VisiblePosition current = visiblePosition; |
357 TextBreakIterator* iter = 0; | 357 TextBreakIterator* iter = 0; |
358 | 358 |
359 CachedLogicallyOrderedLeafBoxes leafBoxes; | 359 CachedLogicallyOrderedLeafBoxes leafBoxes; |
360 Vector<UChar, 1024> string; | 360 Vector<UChar, 1024> string; |
361 | 361 |
362 while (1) { | 362 while (1) { |
363 VisiblePosition adjacentCharacterPosition = direction == MoveRight ? cur
rent.right(true) : current.left(true); | 363 VisiblePosition adjacentCharacterPosition = direction == MoveRight ? cur
rent.right(true) : current.left(true); |
364 if (adjacentCharacterPosition == current || adjacentCharacterPosition.is
Null()) | 364 if (adjacentCharacterPosition == current || adjacentCharacterPosition.is
Null()) |
(...skipping 25 matching lines...) Expand all Loading... |
390 previouslyVisitedBox = box; | 390 previouslyVisitedBox = box; |
391 } | 391 } |
392 | 392 |
393 if (!iter) | 393 if (!iter) |
394 break; | 394 break; |
395 | 395 |
396 iter->first(); | 396 iter->first(); |
397 int offsetInIterator = offsetInBox - textBox->start() + previousBoxLengt
h; | 397 int offsetInIterator = offsetInBox - textBox->start() + previousBoxLengt
h; |
398 | 398 |
399 bool isWordBreak; | 399 bool isWordBreak; |
400 bool boxHasSameDirectionalityAsBlock = box->direction() == blockDirectio
n; | 400 bool boxHasSameDirectionalityAsBlock = isLeftToRight ? box->direction()
== LTR : box->direction() == RTL; |
401 bool movingBackward = (direction == MoveLeft && box->direction() == LTR)
|| (direction == MoveRight && box->direction() == RTL); | 401 bool movingBackward = (direction == MoveLeft && box->direction() == LTR)
|| (direction == MoveRight && box->direction() == RTL); |
402 if ((skipsSpaceWhenMovingRight && boxHasSameDirectionalityAsBlock) | 402 if ((skipsSpaceWhenMovingRight && boxHasSameDirectionalityAsBlock) |
403 || (!skipsSpaceWhenMovingRight && movingBackward)) { | 403 || (!skipsSpaceWhenMovingRight && movingBackward)) { |
404 bool logicalStartInRenderer = offsetInBox == static_cast<int>(textBo
x->start()) && previousBoxInDifferentBlock; | 404 bool logicalStartInRenderer = offsetInBox == static_cast<int>(textBo
x->start()) && previousBoxInDifferentBlock; |
405 isWordBreak = isLogicalStartOfWord(iter, offsetInIterator, logicalSt
artInRenderer); | 405 isWordBreak = isLogicalStartOfWord(iter, offsetInIterator, logicalSt
artInRenderer); |
406 } else { | 406 } else { |
407 bool logicalEndInRenderer = offsetInBox == static_cast<int>(textBox-
>start() + textBox->len()) && nextBoxInDifferentBlock; | 407 bool logicalEndInRenderer = offsetInBox == static_cast<int>(textBox-
>start() + textBox->len()) && nextBoxInDifferentBlock; |
408 isWordBreak = islogicalEndOfWord(iter, offsetInIterator, logicalEndI
nRenderer); | 408 isWordBreak = islogicalEndOfWord(iter, offsetInIterator, logicalEndI
nRenderer); |
409 } | 409 } |
410 | 410 |
411 if (isWordBreak) | 411 if (isWordBreak) |
412 return adjacentCharacterPosition; | 412 return adjacentCharacterPosition; |
413 | 413 |
414 current = adjacentCharacterPosition; | 414 current = adjacentCharacterPosition; |
415 } | 415 } |
416 return VisiblePosition(); | 416 return VisiblePosition(); |
417 } | 417 } |
418 | 418 |
419 VisiblePosition leftWordPosition(const VisiblePosition& visiblePosition, bool sk
ipsSpaceWhenMovingRight) | 419 VisiblePosition leftWordPosition(const VisiblePosition& visiblePosition, bool sk
ipsSpaceWhenMovingRight) |
420 { | 420 { |
421 VisiblePosition leftWordBreak = visualWordPosition(visiblePosition, MoveLeft
, skipsSpaceWhenMovingRight); | 421 VisiblePosition leftWordBreak = visualWordPosition(visiblePosition, MoveLeft
, skipsSpaceWhenMovingRight); |
422 leftWordBreak = visiblePosition.honorEditingBoundaryAtOrBefore(leftWordBreak
); | 422 leftWordBreak = visiblePosition.honorEditingBoundaryAtOrBefore(leftWordBreak
); |
423 | 423 |
424 // FIXME: How should we handle a non-editable position? | 424 // FIXME: How should we handle a non-editable position? |
425 if (leftWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquival
ent())) { | 425 if (leftWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquival
ent())) |
426 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition
.deepEquivalent()); | 426 leftWordBreak = isEnclosingBoxHasLeftToRightDirection(visiblePosition.de
epEquivalent()) ? startOfEditableContent(visiblePosition) : endOfEditableContent
(visiblePosition); |
427 leftWordBreak = blockDirection == LTR ? startOfEditableContent(visiblePo
sition) : endOfEditableContent(visiblePosition); | 427 |
428 } | |
429 return leftWordBreak; | 428 return leftWordBreak; |
430 } | 429 } |
431 | 430 |
432 VisiblePosition rightWordPosition(const VisiblePosition& visiblePosition, bool s
kipsSpaceWhenMovingRight) | 431 VisiblePosition rightWordPosition(const VisiblePosition& visiblePosition, bool s
kipsSpaceWhenMovingRight) |
433 { | 432 { |
434 VisiblePosition rightWordBreak = visualWordPosition(visiblePosition, MoveRig
ht, skipsSpaceWhenMovingRight); | 433 VisiblePosition rightWordBreak = visualWordPosition(visiblePosition, MoveRig
ht, skipsSpaceWhenMovingRight); |
435 rightWordBreak = visiblePosition.honorEditingBoundaryAtOrBefore(rightWordBre
ak); | 434 rightWordBreak = visiblePosition.honorEditingBoundaryAtOrBefore(rightWordBre
ak); |
436 | 435 |
437 // FIXME: How should we handle a non-editable position? | 436 // FIXME: How should we handle a non-editable position? |
438 if (rightWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquiva
lent())) { | 437 if (rightWordBreak.isNull() && isEditablePosition(visiblePosition.deepEquiva
lent())) |
439 TextDirection blockDirection = directionOfEnclosingBlock(visiblePosition
.deepEquivalent()); | 438 rightWordBreak = isEnclosingBoxHasLeftToRightDirection(visiblePosition.d
eepEquivalent()) ? endOfEditableContent(visiblePosition) : startOfEditableConten
t(visiblePosition); |
440 rightWordBreak = blockDirection == LTR ? endOfEditableContent(visiblePos
ition) : startOfEditableContent(visiblePosition); | 439 |
441 } | |
442 return rightWordBreak; | 440 return rightWordBreak; |
443 } | 441 } |
444 | 442 |
445 | 443 |
446 enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext
}; | 444 enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext
}; |
447 | 445 |
448 typedef unsigned (*BoundarySearchFunction)(const UChar*, unsigned length, unsign
ed offset, BoundarySearchContextAvailability, bool& needMoreContext); | 446 typedef unsigned (*BoundarySearchFunction)(const UChar*, unsigned length, unsign
ed offset, BoundarySearchContextAvailability, bool& needMoreContext); |
449 | 447 |
450 static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
Function searchFunction) | 448 static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
Function searchFunction) |
451 { | 449 { |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 int caretOffset; | 1401 int caretOffset; |
1404 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); | 1402 position.position().getInlineBoxAndOffset(position.affinity(), inlineBox, ca
retOffset); |
1405 | 1403 |
1406 if (inlineBox) | 1404 if (inlineBox) |
1407 renderer = &inlineBox->renderer(); | 1405 renderer = &inlineBox->renderer(); |
1408 | 1406 |
1409 return renderer->localCaretRect(inlineBox, caretOffset); | 1407 return renderer->localCaretRect(inlineBox, caretOffset); |
1410 } | 1408 } |
1411 | 1409 |
1412 } | 1410 } |
OLD | NEW |