Changeset 71465 in webkit


Ignore:
Timestamp:
Nov 5, 2010 10:49:57 PM (13 years ago)
Author:
hyatt@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=47237

Reviewed by Dan Bernstein and Simon Fraser.

Make selection work with vertical text. This patch fixes a bug in the computation of lineTop. For lines
with positive leading, lineTop was incorrectly including the top leading. Since the flipping of lines
for "lr" and "bt" writing modes involved flipping using lineTop and lineBottom, an incorrect lineTop meant
that those modes were mis-rendering. This is why the Japanese "lr" text examples have the first line smushed
too far against the border.

Fixing lineTop to no longer incorrectly include top leading has implications for editing. I ended up
rewriting positionForPoint to exactly match selection, since that seemed to be the most intuitive
behavior. I got rid of the verticalClickFudgeFactor and now just use selectionTop and selectionBottom
instead of lineTop and lineBottom. I am pretty sure the code used selectionTop in a previous incarnation
anyway and that I moved away from it when I implemented lineTop and lineBottom. The code then grew
more complicated from people trying to work with lineTop and lineBottom, but going back to selectionTop
and selectionBottom is the right behavior I think. One editing test has been updated after this change
(editing/selection/after-line-break.html), and one DOM test has been changed to not hit test past the
bottom of a line (fast/dom/Document/CaretRangeFromPoint/basic.html).

I patched selection painting of InlineTextBoxes so that the leading going up to the next line box is used
for "lr" and "bt" modes instead of the previous box. This makes sense for English text, but we may want
a different policy for Japanese text eventually (possibly just splitting the difference instead). Leaving it
this way for now, and we can collect feedback on the design.

I rewrote all of the selection gap painting code to be writing-mode aware. During the course of rewriting this
code I noticed a bug in the logicalLeftSelectionOffset and logicalRightSelectionOffset functions where there
was a coordinate space mismatch on a comparison. Fixing this improves the repaint/selection-clear.html test.

Added new tests in fast/blockflow/.

WebCore:

  • rendering/InlineFlowBox.cpp:

(WebCore::InlineFlowBox::placeBoxesInBlockDirection):

  • rendering/InlineFlowBox.h:
  • rendering/InlineTextBox.cpp:

(WebCore::InlineTextBox::selectionBottom):
(WebCore::InlineTextBox::paintSelection):
(WebCore::InlineTextBox::paintCompositionBackground):
(WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
(WebCore::InlineTextBox::paintTextMatchMarker):

  • rendering/InlineTextBox.h:
  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::selectionGapRectsForRepaint):
(WebCore::RenderBlock::paintSelection):
(WebCore::clipOutPositionedObjects):
(WebCore::blockDirectionOffset):
(WebCore::inlineDirectionOffset):
(WebCore::RenderBlock::logicalRectToPhysicalRect):
(WebCore::RenderBlock::selectionGaps):
(WebCore::RenderBlock::inlineSelectionGaps):
(WebCore::RenderBlock::blockSelectionGaps):
(WebCore::RenderBlock::blockSelectionGap):
(WebCore::RenderBlock::logicalLeftSelectionGap):
(WebCore::RenderBlock::logicalRightSelectionGap):
(WebCore::RenderBlock::logicalLeftSelectionOffset):
(WebCore::RenderBlock::logicalRightSelectionOffset):

  • rendering/RenderBlock.h:
  • rendering/RenderBox.cpp:

(WebCore::RenderBox::flipForWritingMode):

  • rendering/RenderBox.h:

(WebCore::RenderBox::logicalBottom):

  • rendering/RootInlineBox.cpp:

(WebCore::RootInlineBox::alignBoxesInBlockDirection):
(WebCore::RootInlineBox::lineSelectionGap):
(WebCore::RootInlineBox::selectionTop):
(WebCore::RootInlineBox::selectionBottom):

  • rendering/RootInlineBox.h:

LayoutTests:

  • editing/selection/after-line-break-expected.txt:
  • fast/blockflow/japanese-lr-selection.html: Added.
  • fast/blockflow/japanese-rl-selection.html: Added.
  • fast/dom/Document/CaretRangeFromPoint/basic.html:
  • platform/mac/fast/blockflow/background-horizontal-bt-expected.checksum:
  • platform/mac/fast/blockflow/background-horizontal-bt-expected.png:
  • platform/mac/fast/blockflow/background-horizontal-bt-expected.txt:
  • platform/mac/fast/blockflow/background-vertical-lr-expected.checksum:
  • platform/mac/fast/blockflow/background-vertical-lr-expected.png:
  • platform/mac/fast/blockflow/background-vertical-lr-expected.txt:
  • platform/mac/fast/blockflow/border-image-horizontal-bt-expected.checksum:
  • platform/mac/fast/blockflow/border-image-horizontal-bt-expected.png:
  • platform/mac/fast/blockflow/border-image-horizontal-bt-expected.txt:
  • platform/mac/fast/blockflow/border-image-vertical-lr-expected.checksum:
  • platform/mac/fast/blockflow/border-image-vertical-lr-expected.png:
  • platform/mac/fast/blockflow/border-image-vertical-lr-expected.txt:
  • platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.checksum:
  • platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.png:
  • platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.txt:
  • platform/mac/fast/blockflow/border-vertical-lr-expected.checksum:
  • platform/mac/fast/blockflow/border-vertical-lr-expected.png:
  • platform/mac/fast/blockflow/border-vertical-lr-expected.txt:
  • platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.checksum:
  • platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.png:
  • platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.txt:
  • platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.checksum:
  • platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.png:
  • platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.txt:
  • platform/mac/fast/blockflow/japanese-lr-selection-expected.checksum: Added.
  • platform/mac/fast/blockflow/japanese-lr-selection-expected.png: Added.
  • platform/mac/fast/blockflow/japanese-lr-selection-expected.txt: Added.
  • platform/mac/fast/blockflow/japanese-lr-text-expected.checksum:
  • platform/mac/fast/blockflow/japanese-lr-text-expected.png:
  • platform/mac/fast/blockflow/japanese-lr-text-expected.txt:
  • platform/mac/fast/blockflow/japanese-rl-selection-expected.checksum: Added.
  • platform/mac/fast/blockflow/japanese-rl-selection-expected.png: Added.
  • platform/mac/fast/blockflow/japanese-rl-selection-expected.txt: Added.
  • platform/mac/fast/repaint/selection-clear-expected.checksum:
  • platform/mac/fast/repaint/selection-clear-expected.png:
Location:
trunk
Files:
8 added
43 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r71461 r71465  
     12010-11-05  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Dan Bernstein and Simon Fraser.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=47237
     6       
     7        Make selection work with vertical text.  This patch fixes a bug in the computation of lineTop.  For lines
     8        with positive leading, lineTop was incorrectly including the top leading.  Since the flipping of lines
     9        for "lr" and "bt" writing modes involved flipping using lineTop and lineBottom, an incorrect lineTop meant
     10        that those modes were mis-rendering.  This is why the Japanese "lr" text examples have the first line smushed
     11        too far against the border.
     12       
     13        Fixing lineTop to no longer incorrectly include top leading has implications for editing.  I ended up
     14        rewriting positionForPoint to exactly match selection, since that seemed to be the most intuitive
     15        behavior.  I got rid of the verticalClickFudgeFactor and now just use selectionTop and selectionBottom
     16        instead of lineTop and lineBottom.  I am pretty sure the code used selectionTop in a previous incarnation
     17        anyway and that I moved away from it when I implemented lineTop and lineBottom.  The code then grew
     18        more complicated from people trying to work with lineTop and lineBottom, but going back to selectionTop
     19        and selectionBottom is the right behavior I think.  One editing test has been updated after this change
     20        (editing/selection/after-line-break.html), and one DOM test has been changed to not hit test past the
     21        bottom of a line (fast/dom/Document/CaretRangeFromPoint/basic.html).
     22       
     23        I patched selection painting of InlineTextBoxes so that the leading going up to the next line box is used
     24        for "lr" and "bt" modes instead of the previous box.  This makes sense for English text, but we may want
     25        a different policy for Japanese text eventually (possibly just splitting the difference instead).  Leaving it
     26        this way for now, and we can collect feedback on the design.
     27       
     28        I rewrote all of the selection gap painting code to be writing-mode aware.  During the course of rewriting this
     29        code I noticed a bug in the logicalLeftSelectionOffset and logicalRightSelectionOffset functions where there
     30        was a coordinate space mismatch on a comparison.  Fixing this improves the repaint/selection-clear.html test.
     31
     32        Added new tests in fast/blockflow/.
     33
     34        * editing/selection/after-line-break-expected.txt:
     35        * fast/blockflow/japanese-lr-selection.html: Added.
     36        * fast/blockflow/japanese-rl-selection.html: Added.
     37        * fast/dom/Document/CaretRangeFromPoint/basic.html:
     38        * platform/mac/fast/blockflow/background-horizontal-bt-expected.checksum:
     39        * platform/mac/fast/blockflow/background-horizontal-bt-expected.png:
     40        * platform/mac/fast/blockflow/background-horizontal-bt-expected.txt:
     41        * platform/mac/fast/blockflow/background-vertical-lr-expected.checksum:
     42        * platform/mac/fast/blockflow/background-vertical-lr-expected.png:
     43        * platform/mac/fast/blockflow/background-vertical-lr-expected.txt:
     44        * platform/mac/fast/blockflow/border-image-horizontal-bt-expected.checksum:
     45        * platform/mac/fast/blockflow/border-image-horizontal-bt-expected.png:
     46        * platform/mac/fast/blockflow/border-image-horizontal-bt-expected.txt:
     47        * platform/mac/fast/blockflow/border-image-vertical-lr-expected.checksum:
     48        * platform/mac/fast/blockflow/border-image-vertical-lr-expected.png:
     49        * platform/mac/fast/blockflow/border-image-vertical-lr-expected.txt:
     50        * platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.checksum:
     51        * platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.png:
     52        * platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.txt:
     53        * platform/mac/fast/blockflow/border-vertical-lr-expected.checksum:
     54        * platform/mac/fast/blockflow/border-vertical-lr-expected.png:
     55        * platform/mac/fast/blockflow/border-vertical-lr-expected.txt:
     56        * platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.checksum:
     57        * platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.png:
     58        * platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.txt:
     59        * platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.checksum:
     60        * platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.png:
     61        * platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.txt:
     62        * platform/mac/fast/blockflow/japanese-lr-selection-expected.checksum: Added.
     63        * platform/mac/fast/blockflow/japanese-lr-selection-expected.png: Added.
     64        * platform/mac/fast/blockflow/japanese-lr-selection-expected.txt: Added.
     65        * platform/mac/fast/blockflow/japanese-lr-text-expected.checksum:
     66        * platform/mac/fast/blockflow/japanese-lr-text-expected.png:
     67        * platform/mac/fast/blockflow/japanese-lr-text-expected.txt:
     68        * platform/mac/fast/blockflow/japanese-rl-selection-expected.checksum: Added.
     69        * platform/mac/fast/blockflow/japanese-rl-selection-expected.png: Added.
     70        * platform/mac/fast/blockflow/japanese-rl-selection-expected.txt: Added.
     71        * platform/mac/fast/repaint/selection-clear-expected.checksum:
     72        * platform/mac/fast/repaint/selection-clear-expected.png:
     73
    1742010-11-05  Adam Barth  <abarth@webkit.org>
    275
  • trunk/LayoutTests/editing/selection/after-line-break-expected.txt

    r34614 r71465  
    11EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 1 of DIV > BODY > HTML > #document
    22EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
    3 EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 5 of #text > DIV > BODY > HTML > #document to 5 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
     3EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    44EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    55EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
  • trunk/LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic.html

    r48188 r71465  
    7474
    7575            log("Testing lower left");
    76             test(rect.left, rect.top + rect.height, "element.firstChild", "72");
     76            test(rect.left, rect.top + rect.height - 1, "element.firstChild", "72");
    7777           
    7878            log("Testing lower right");
    79             test(rect.left + rect.width, rect.top + rect.height, "element.firstChild", "95");
     79            test(rect.left + rect.width, rect.top + rect.height - 1, "element.firstChild", "95");
    8080
    8181            log("Testing somewhere in the middle");
  • trunk/LayoutTests/platform/mac/fast/blockflow/background-horizontal-bt-expected.checksum

    r70816 r71465  
    1 39e3ac4603ba247bf6e72a72404d08f0
     11ea2c61104532aa98df08ca94928bc18
  • trunk/LayoutTests/platform/mac/fast/blockflow/background-horizontal-bt-expected.txt

    r70816 r71465  
    55    RenderBody {BODY} at (8,8) size 784x440
    66      RenderInline {SPAN} at (0,0) size 50x268
    7         RenderBlock {DIV} at (50,71) size 50x0
    8         RenderBR {BR} at (100,50) size 0x98
    9         RenderBlock {DIV} at (50,241) size 50x0
     7        RenderBlock {DIV} at (50,107) size 50x0
     8        RenderBR {BR} at (100,86) size 0x98
     9        RenderBlock {DIV} at (50,277) size 50x0
    1010      RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/background-vertical-lr-expected.checksum

    r70816 r71465  
    1 78a4f443ea4ef70d341f310787b17c3c
     11b3f13b95440c165f3238cadd0b2621b
  • trunk/LayoutTests/platform/mac/fast/blockflow/background-vertical-lr-expected.txt

    r71043 r71465  
    55    RenderBody {BODY} at (8,8) size 440x584
    66      RenderInline {SPAN} at (0,0) size 268x50
    7         RenderBlock {DIV} at (71,50) size 0x50
    8         RenderBR {BR} at (50,100) size 98x0
    9         RenderBlock {DIV} at (241,50) size 0x50
     7        RenderBlock {DIV} at (107,50) size 0x50
     8        RenderBR {BR} at (86,100) size 98x0
     9        RenderBlock {DIV} at (277,50) size 0x50
    1010      RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-image-horizontal-bt-expected.checksum

    r70813 r71465  
    1 b13ea572f0e4891b0fe4b3e77c4ad409
     111385260c56da4aa6f6b98c1c130beca
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-image-horizontal-bt-expected.txt

    r70813 r71465  
    55    RenderBody {BODY} at (8,8) size 784x444
    66      RenderInline {SPAN} at (0,0) size 80x323 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
    7         RenderBlock {DIV} at (101,102) size 25x0
    8         RenderBR {BR} at (126,80) size 0x100
    9         RenderBlock {DIV} at (50,274) size 50x0
     7        RenderBlock {DIV} at (101,117) size 25x0
     8        RenderBR {BR} at (126,95) size 0x100
     9        RenderBlock {DIV} at (50,289) size 50x0
    1010      RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-image-vertical-lr-expected.checksum

    r70813 r71465  
    1 3da47156df443000d46b5a18a91bee75
     1dad685339a6a1dd19f1e3c7c4106a7c2
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-image-vertical-lr-expected.txt

    r71043 r71465  
    55    RenderBody {BODY} at (8,8) size 444x584
    66      RenderInline {SPAN} at (0,0) size 323x80 [border: (21px none #000000) (30px none #000000) (21px none #000000)]
    7         RenderBlock {DIV} at (93,101) size 0x25
    8         RenderBR {BR} at (71,126) size 100x0
    9         RenderBlock {DIV} at (265,50) size 0x50
     7        RenderBlock {DIV} at (99,101) size 0x25
     8        RenderBR {BR} at (77,126) size 100x0
     9        RenderBlock {DIV} at (271,50) size 0x50
    1010      RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.checksum

    r70848 r71465  
    1 bb80a60d88017bd9f619869f8848ba4f
     17ce3c4e6a865a89fd9cced99be88027c
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-radius-clipping-vertical-lr-expected.txt

    r71043 r71465  
    88          RenderText {#text} at (0,0) size 0x0
    99          RenderInline {SPAN} at (0,0) size 137x613 [bgcolor=#FFFFE0] [border: (5px solid #008000)]
    10             RenderText {#text} at (5,35) size 127x613
    11               text run at (5,35) width 578: "This sentence is too long to fit"
    12               text run at (77,0) width 302: "on a single line."
     10            RenderText {#text} at (8,35) size 127x613
     11              text run at (8,35) width 578: "This sentence is too long to fit"
     12              text run at (80,0) width 302: "on a single line."
    1313        RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-vertical-lr-expected.checksum

    r71043 r71465  
    1 902397878764a7659f5b994fc8d5d02c
     13fe22708d621489faf88cf3c154a3eee
  • trunk/LayoutTests/platform/mac/fast/blockflow/border-vertical-lr-expected.txt

    r71043 r71465  
    55    RenderBody {BODY} at (8,8) size 756x584
    66      RenderInline {SPAN} at (0,0) size 218x554 [border: (2px solid #000000)]
    7         RenderText {#text} at (4,4) size 210x554
    8           text run at (4,4) width 550: "\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}"
    9           text run at (67,0) width 550: "\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B}\x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}"
    10           text run at (130,0) width 550: "\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}"
    11           text run at (193,0) width 170: "\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}"
    12       RenderText {#text} at (193,174) size 21x7
    13         text run at (193,174) width 7: " "
     7        RenderText {#text} at (21,4) size 210x554
     8          text run at (21,4) width 550: "\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}"
     9          text run at (84,0) width 550: "\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B}\x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}"
     10          text run at (147,0) width 550: "\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}"
     11          text run at (210,0) width 170: "\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}"
     12      RenderText {#text} at (210,174) size 21x7
     13        text run at (210,174) width 7: " "
    1414      RenderBR {BR} at (0,0) size 0x0
    15       RenderBR {BR} at (252,0) size 21x0
     15      RenderBR {BR} at (273,0) size 21x0
    1616      RenderInline {SPAN} at (0,0) size 413x558 [border: (5px solid #000000)]
    17         RenderText {#text} at (322,7) size 399x558
    18           text run at (322,7) width 550: "\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}"
    19           text run at (385,0) width 558: "\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B} \x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}"
    20           text run at (448,0) width 550: "\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}"
    21           text run at (511,0) width 550: "\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}"
    22           text run at (574,0) width 550: "\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}"
    23           text run at (637,0) width 558: "\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B} \x{306A}"
    24           text run at (700,0) width 381: "\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}"
     17        RenderText {#text} at (336,7) size 399x558
     18          text run at (336,7) width 550: "\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}"
     19          text run at (399,0) width 558: "\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B} \x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}"
     20          text run at (462,0) width 550: "\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}"
     21          text run at (525,0) width 550: "\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}"
     22          text run at (588,0) width 550: "\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}"
     23          text run at (651,0) width 558: "\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B} \x{306A}"
     24          text run at (714,0) width 381: "\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}"
    2525      RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.checksum

    r70843 r71465  
    1 75af7ae6474cbcd71e2abecc349489f7
     1676d6537320927d634f252c802650537
  • trunk/LayoutTests/platform/mac/fast/blockflow/box-shadow-horizontal-bt-expected.txt

    r70843 r71465  
    66      RenderBlock {DIV} at (0,0) size 600x144
    77        RenderInline {SPAN} at (0,0) size 598x137 [bgcolor=#FFFFE0] [border: (5px solid #008000)]
    8           RenderText {#text} at (21,5) size 578x127
    9             text run at (21,5) width 578: "This sentence is too long to fit"
    10             text run at (139,77) width 302: "on a single line."
     8          RenderText {#text} at (21,8) size 578x127
     9            text run at (21,8) width 578: "This sentence is too long to fit"
     10            text run at (139,80) width 302: "on a single line."
    1111        RenderText {#text} at (0,0) size 0x0
    1212      RenderBlock {DIV} at (0,194) size 600x144
    1313        RenderInline {SPAN} at (0,0) size 598x137 [bgcolor=#FFFFE0] [border: (5px solid #008000)]
    14           RenderText {#text} at (21,5) size 578x127
    15             text run at (21,5) width 578: "This sentence is too long to fit"
    16             text run at (139,77) width 302: "on a single line."
     14          RenderText {#text} at (21,8) size 578x127
     15            text run at (21,8) width 578: "This sentence is too long to fit"
     16            text run at (139,80) width 302: "on a single line."
    1717        RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.checksum

    r70848 r71465  
    1 8aa3b9d6b0c7c210b8344f9c1b2891a1
     1b054ee50905dd8bb63f6825669ddb54c
  • trunk/LayoutTests/platform/mac/fast/blockflow/box-shadow-vertical-lr-expected.txt

    r71043 r71465  
    66      RenderBlock {DIV} at (0,0) size 144x600
    77        RenderInline {SPAN} at (0,0) size 137x598 [bgcolor=#FFFFE0] [border: (5px solid #008000)]
    8           RenderText {#text} at (5,21) size 127x578
    9             text run at (5,21) width 578: "This sentence is too long to fit"
    10             text run at (77,139) width 302: "on a single line."
     8          RenderText {#text} at (8,21) size 127x578
     9            text run at (8,21) width 578: "This sentence is too long to fit"
     10            text run at (80,139) width 302: "on a single line."
    1111        RenderText {#text} at (0,0) size 0x0
    1212      RenderBlock {DIV} at (194,0) size 144x600
    1313        RenderInline {SPAN} at (0,0) size 137x598 [bgcolor=#FFFFE0] [border: (5px solid #008000)]
    14           RenderText {#text} at (5,21) size 127x578
    15             text run at (5,21) width 578: "This sentence is too long to fit"
    16             text run at (77,139) width 302: "on a single line."
     14          RenderText {#text} at (8,21) size 127x578
     15            text run at (8,21) width 578: "This sentence is too long to fit"
     16            text run at (80,139) width 302: "on a single line."
    1717        RenderText {#text} at (0,0) size 0x0
  • trunk/LayoutTests/platform/mac/fast/blockflow/japanese-lr-text-expected.checksum

    r70843 r71465  
    1 ad4edd689eb8f38dd93885d113c5b1cf
     138a1b72e930f08e66ba6db4b7acc40c4
  • trunk/LayoutTests/platform/mac/fast/blockflow/japanese-lr-text-expected.txt

    r71043 r71465  
    44  RenderBlock {HTML} at (0,0) size 398x600 [border: (10px solid #800000)]
    55    RenderBody {BODY} at (18,18) size 362x564 [border: (5px solid #000000)]
    6       RenderText {#text} at (5,5) size 341x529
    7         text run at (5,5) width 529: "\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}"
    8         text run at (37,5) width 529: "\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B}\x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}"
    9         text run at (69,5) width 529: "\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}"
    10         text run at (101,5) width 529: "\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}"
    11         text run at (133,5) width 508: "\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B}"
    12         text run at (165,5) width 508: "\x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}"
    13         text run at (197,5) width 529: "\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{8A2A}"
    14         text run at (229,5) width 529: "\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}"
    15         text run at (261,5) width 508: "\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}"
    16         text run at (293,5) width 515: "\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B} \x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}"
    17         text run at (325,5) width 297: "\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}"
     6      RenderText {#text} at (10,5) size 341x529
     7        text run at (10,5) width 529: "\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}"
     8        text run at (42,5) width 529: "\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B}\x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}"
     9        text run at (74,5) width 529: "\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}"
     10        text run at (106,5) width 529: "\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}"
     11        text run at (138,5) width 508: "\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B}"
     12        text run at (170,5) width 508: "\x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}"
     13        text run at (202,5) width 529: "\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{8A2A}"
     14        text run at (234,5) width 529: "\x{554F}\x{3057}\x{305F}\x{30A6}\x{30A7}\x{30D6}\x{30DA}\x{30FC}\x{30B8}\x{306E}\x{30B3}\x{30F3}\x{30C6}\x{30F3}\x{30C4}\x{304B}\x{3089}\x{3082}\x{691C}\x{7D22}\x{3059}\x{308B}\x{3053}\x{3068}\x{304C}"
     15        text run at (266,5) width 508: "\x{3067}\x{304D}\x{307E}\x{3059}\x{3002}\x{305B}\x{3063}\x{304B}\x{304F}\x{898B}\x{3064}\x{3051}\x{305F}\x{3059}\x{3070}\x{3089}\x{3057}\x{3044}\x{8A18}\x{4E8B}\x{304C}\x{3069}\x{3053}\x{306B}"
     16        text run at (298,5) width 515: "\x{3042}\x{3063}\x{305F}\x{304B}\x{5FD8}\x{308C}\x{3066}\x{3057}\x{307E}\x{3063}\x{305F}\x{7D4C}\x{9A13}\x{306F}\x{3042}\x{308A}\x{307E}\x{3059}\x{304B} \x{306A}\x{3089}\x{30BF}\x{30A4}\x{30C8}"
     17        text run at (330,5) width 297: "\x{30EB}\x{3068}\x{30A2}\x{30C9}\x{30EC}\x{30B9}\x{3060}\x{3051}\x{3067}\x{306A}\x{304F}\x{3001}\x{8A2A}\x{554F}"
  • trunk/LayoutTests/platform/mac/fast/repaint/selection-clear-expected.checksum

    r43400 r71465  
    1 9b4aad578aa413207070025bf8e8a1a8
     11c03f17e303470c81630cbaa31761bab
  • trunk/WebCore/ChangeLog

    r71464 r71465  
     12010-11-05  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Dan Bernstein and Simon Fraser.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=47237
     6       
     7        Make selection work with vertical text.  This patch fixes a bug in the computation of lineTop.  For lines
     8        with positive leading, lineTop was incorrectly including the top leading.  Since the flipping of lines
     9        for "lr" and "bt" writing modes involved flipping using lineTop and lineBottom, an incorrect lineTop meant
     10        that those modes were mis-rendering.  This is why the Japanese "lr" text examples have the first line smushed
     11        too far against the border.
     12       
     13        Fixing lineTop to no longer incorrectly include top leading has implications for editing.  I ended up
     14        rewriting positionForPoint to exactly match selection, since that seemed to be the most intuitive
     15        behavior.  I got rid of the verticalClickFudgeFactor and now just use selectionTop and selectionBottom
     16        instead of lineTop and lineBottom.  I am pretty sure the code used selectionTop in a previous incarnation
     17        anyway and that I moved away from it when I implemented lineTop and lineBottom.  The code then grew
     18        more complicated from people trying to work with lineTop and lineBottom, but going back to selectionTop
     19        and selectionBottom is the right behavior I think.  One editing test has been updated after this change
     20        (editing/selection/after-line-break.html), and one DOM test has been changed to not hit test past the
     21        bottom of a line (fast/dom/Document/CaretRangeFromPoint/basic.html).
     22       
     23        I patched selection painting of InlineTextBoxes so that the leading going up to the next line box is used
     24        for "lr" and "bt" modes instead of the previous box.  This makes sense for English text, but we may want
     25        a different policy for Japanese text eventually (possibly just splitting the difference instead).  Leaving it
     26        this way for now, and we can collect feedback on the design.
     27       
     28        I rewrote all of the selection gap painting code to be writing-mode aware.  During the course of rewriting this
     29        code I noticed a bug in the logicalLeftSelectionOffset and logicalRightSelectionOffset functions where there
     30        was a coordinate space mismatch on a comparison.  Fixing this improves the repaint/selection-clear.html test.
     31
     32        Added new tests in fast/blockflow/.
     33
     34        * rendering/InlineFlowBox.cpp:
     35        (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
     36        * rendering/InlineFlowBox.h:
     37        * rendering/InlineTextBox.cpp:
     38        (WebCore::InlineTextBox::selectionBottom):
     39        (WebCore::InlineTextBox::paintSelection):
     40        (WebCore::InlineTextBox::paintCompositionBackground):
     41        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
     42        (WebCore::InlineTextBox::paintTextMatchMarker):
     43        * rendering/InlineTextBox.h:
     44        * rendering/RenderBlock.cpp:
     45        (WebCore::RenderBlock::selectionGapRectsForRepaint):
     46        (WebCore::RenderBlock::paintSelection):
     47        (WebCore::clipOutPositionedObjects):
     48        (WebCore::blockDirectionOffset):
     49        (WebCore::inlineDirectionOffset):
     50        (WebCore::RenderBlock::logicalRectToPhysicalRect):
     51        (WebCore::RenderBlock::selectionGaps):
     52        (WebCore::RenderBlock::inlineSelectionGaps):
     53        (WebCore::RenderBlock::blockSelectionGaps):
     54        (WebCore::RenderBlock::blockSelectionGap):
     55        (WebCore::RenderBlock::logicalLeftSelectionGap):
     56        (WebCore::RenderBlock::logicalRightSelectionGap):
     57        (WebCore::RenderBlock::logicalLeftSelectionOffset):
     58        (WebCore::RenderBlock::logicalRightSelectionOffset):
     59        * rendering/RenderBlock.h:
     60        * rendering/RenderBox.cpp:
     61        (WebCore::RenderBox::flipForWritingMode):
     62        * rendering/RenderBox.h:
     63        (WebCore::RenderBox::logicalBottom):
     64        * rendering/RootInlineBox.cpp:
     65        (WebCore::RootInlineBox::alignBoxesInBlockDirection):
     66        (WebCore::RootInlineBox::lineSelectionGap):
     67        (WebCore::RootInlineBox::selectionTop):
     68        (WebCore::RootInlineBox::selectionBottom):
     69        * rendering/RootInlineBox.h:
     70
    1712010-11-05  Simon Fraser  <simon.fraser@apple.com>
    272
  • trunk/WebCore/rendering/InlineFlowBox.cpp

    r71177 r71465  
    481481}
    482482
    483 void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom)
     483void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop)
    484484{
    485485    if (isRootInlineBox())
     
    494494        bool isInlineFlow = curr->isInlineFlowBox();
    495495        if (isInlineFlow)
    496             static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom);
     496            static_cast<InlineFlowBox*>(curr)->placeBoxesInBlockDirection(top, maxHeight, maxAscent, strictMode, lineTop, lineBottom, setLineTop);
    497497
    498498        bool childAffectsTopBottomPos = true;
     
    526526        if (childAffectsTopBottomPos) {
    527527            int boxHeight = curr->logicalHeight();
    528             lineTop = min(lineTop, newLogicalTop);
     528            if (!setLineTop) {
     529                setLineTop = true;
     530                lineTop = newLogicalTop;
     531            } else
     532                lineTop = min(lineTop, newLogicalTop);
    529533            lineBottom = max(lineBottom, newLogicalTop + boxHeight);
    530534        }
     
    536540       
    537541        if (hasTextChildren() || strictMode) {
    538             lineTop = min(lineTop, logicalTop());
     542            if (!setLineTop) {
     543                setLineTop = true;
     544                lineTop = logicalTop();
     545            } else
     546                lineTop = min(lineTop, logicalTop());
    539547            lineBottom = max(lineBottom, logicalTop() + logicalHeight());
    540548        }
  • trunk/WebCore/rendering/InlineFlowBox.h

    r71055 r71465  
    159159    void adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
    160160                                   int maxPositionTop, int maxPositionBottom);
    161     void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom);
     161    void placeBoxesInBlockDirection(int logicalTop, int maxHeight, int maxAscent, bool strictMode, int& lineTop, int& lineBottom, bool& setLineTop);
    162162    void flipLinesInBlockDirection(int lineTop, int lineBottom);
    163163    void computeBlockDirectionOverflow(int lineTop, int lineBottom, bool strictMode, GlyphOverflowAndFallbackFontsMap&);
  • trunk/WebCore/rendering/InlineTextBox.cpp

    r71177 r71465  
    6565}
    6666
     67int InlineTextBox::selectionBottom()
     68{
     69    return root()->selectionBottom();
     70}
     71
    6772int InlineTextBox::selectionHeight()
    6873{
     
    683688    }
    684689
    685     int deltaY = logicalTop() - selectionTop();
     690    int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
    686691    int selHeight = selectionHeight();
    687692    IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
     
    708713    updateGraphicsContext(context, c, c, 0, style->colorSpace()); // Don't draw text at all!
    709714
    710     int deltaY = logicalTop() - selectionTop();
     715    int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
    711716    int selHeight = selectionHeight();
    712717    IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
     
    870875
    871876        // Calculate start & width
    872         int deltaY = logicalTop() - selectionTop();
     877        int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
    873878        int selHeight = selectionHeight();
    874879        IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
     
    912917    // Use same y positioning and height as for selection, so that when the selection and this highlight are on
    913918    // the same word there are no pieces sticking out.
    914     int deltaY = logicalTop() - selectionTop();
     919    int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
    915920    int selHeight = selectionHeight();
    916921
  • trunk/WebCore/rendering/InlineTextBox.h

    r71055 r71465  
    7575
    7676private:
    77     virtual int selectionTop();
    78     virtual int selectionHeight();
     77    int selectionTop();
     78    int selectionBottom();
     79    int selectionHeight();
    7980
    8081public:
  • trunk/WebCore/rendering/RenderBlock.cpp

    r71259 r71465  
    5656
    5757namespace WebCore {
    58 
    59 // Number of pixels to allow as a fudge factor when clicking above or below a line.
    60 // clicking up to verticalLineClickFudgeFactor pixels above a line will correspond to the closest point on the line.   
    61 static const int verticalLineClickFudgeFactor = 3;
    6258
    6359using namespace HTMLNames;
     
    25582554    int lastRight = logicalRightSelectionOffset(this, lastTop);
    25592555   
    2560     return fillSelectionGaps(this, offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), offsetFromRepaintContainer.x(), offsetFromRepaintContainer.y(), lastTop, lastLeft, lastRight);
     2556    return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
    25612557}
    25622558
     
    25682564        int lastRight = logicalRightSelectionOffset(this, lastTop);
    25692565        paintInfo.context->save();
    2570         IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
     2566        IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
    25712567        if (!gapRectsBounds.isEmpty()) {
    25722568            if (RenderLayer* layer = enclosingLayer()) {
     
    25842580}
    25852581
    2586 #ifndef BUILDING_ON_TIGER
    2587 static void clipOutPositionedObjects(const PaintInfo* paintInfo, int tx, int ty, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
     2582static void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
    25882583{
    25892584    if (!positionedObjects)
     
    25932588    for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
    25942589        RenderBox* r = *it;
    2595         paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height()));
    2596     }
    2597 }
    2598 #endif
    2599 
    2600 GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
    2601                                         int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
    2602 {
    2603 #ifndef BUILDING_ON_TIGER
     2590        paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
     2591    }
     2592}
     2593
     2594static int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
     2595{
     2596    return rootBlock->style()->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
     2597}
     2598
     2599static int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
     2600{
     2601    return rootBlock->style()->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
     2602}
     2603
     2604IntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
     2605{
     2606    IntRect result;
     2607    if (style()->isHorizontalWritingMode())
     2608        result = logicalRect;
     2609    else
     2610        result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
     2611    flipForWritingMode(result);
     2612    result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
     2613    return result;
     2614}
     2615
     2616GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     2617                                    int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
     2618{
    26042619    // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
    26052620    // Clip out floating and positioned objects when painting selection gaps.
    26062621    if (paintInfo) {
    26072622        // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
    2608         clipOutPositionedObjects(paintInfo, tx, ty, m_positionedObjects);
     2623        IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
     2624        rootBlock->flipForWritingMode(flippedBlockRect);
     2625        flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
     2626        clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects);
    26092627        if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
    26102628            for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
    2611                 clipOutPositionedObjects(paintInfo, cb->x(), cb->y(), cb->m_positionedObjects);
     2629                clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects); // FIXME: Not right for flipped writing modes.
    26122630        if (m_floatingObjects) {
    26132631            for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
    26142632                FloatingObject* r = it.current();
    2615                 paintInfo->context->clipOut(IntRect(tx + r->left() + r->m_renderer->marginLeft(),
    2616                                                     ty + r->top() + r->m_renderer->marginTop(),
    2617                                                     r->m_renderer->width(), r->m_renderer->height()));
    2618             }
    2619         }
    2620     }
    2621 #endif
     2633                IntRect floatBox = IntRect(offsetFromRootBlock.width() + r->left() + r->m_renderer->marginLeft(),
     2634                                           offsetFromRootBlock.height() + r->top() + r->m_renderer->marginTop(),
     2635                                           r->m_renderer->width(), r->m_renderer->height());
     2636                rootBlock->flipForWritingMode(floatBox);
     2637                floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
     2638                paintInfo->context->clipOut(floatBox);
     2639            }
     2640        }
     2641    }
    26222642
    26232643    // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
     
    26292649    if (hasColumns() || hasTransform() || style()->columnSpan()) {
    26302650        // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
    2631         lastTop = (ty - blockY) + height();
    2632         lastLeft = logicalLeftSelectionOffset(rootBlock, height());
    2633         lastRight = logicalRightSelectionOffset(rootBlock, height());
     2651        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
     2652        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
     2653        lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
    26342654        return result;
    26352655    }
    26362656
    26372657    if (childrenInline())
    2638         result = fillInlineSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
     2658        result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
    26392659    else
    2640         result = fillBlockSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
     2660        result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
    26412661
    26422662    // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
    26432663    if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
    2644         result.uniteCenter(fillBlockSelectionGap(lastTop, lastLeft, lastRight, ty + height(),
    2645                                                  rootBlock, blockX, blockY, paintInfo));
     2664        result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
     2665                                             logicalHeight(), paintInfo));
    26462666    return result;
    26472667}
    26482668
    2649 GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
    2650                                               int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
     2669GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     2670                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
    26512671{
    26522672    GapRects result;
     
    26562676    if (!firstLineBox()) {
    26572677        if (containsStart) {
    2658             // Go ahead and update our lastY to be the bottom of the block.  <hr>s or empty blocks with height can trip this
     2678            // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
    26592679            // case.
    2660             lastTop = (ty - blockY) + height();
    2661             lastLeft = logicalLeftSelectionOffset(rootBlock, height());
    2662             lastRight = logicalRightSelectionOffset(rootBlock, height());
     2680            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
     2681            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
     2682            lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
    26632683        }
    26642684        return result;
     
    26762696        if (!containsStart && !lastSelectedLine &&
    26772697            selectionState() != SelectionStart && selectionState() != SelectionBoth)
    2678             result.uniteCenter(fillBlockSelectionGap(lastTop, lastLeft, lastRight, ty + selTop,
    2679                                                      rootBlock, blockX, blockY, paintInfo));
    2680 
    2681         if (!paintInfo || (ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y()))
    2682             result.unite(curr->fillLineSelectionGap(selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo));
     2698            result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
     2699                                                 selTop, paintInfo));
     2700       
     2701        IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
     2702        logicalRect.move(style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
     2703        IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
     2704        if (!paintInfo || (style()->isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.bottom() && physicalRect.bottom() > paintInfo->rect.y())
     2705            || (!style()->isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.right() && physicalRect.right() > paintInfo->rect.x()))
     2706            result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
    26832707
    26842708        lastSelectedLine = curr;
     
    26912715    if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
    26922716        // Go ahead and update our lastY to be the bottom of the last selected line.
    2693         lastTop = (ty - blockY) + lastSelectedLine->selectionBottom();
    2694         lastLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
    2695         lastRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
     2717        lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
     2718        lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
     2719        lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
    26962720    }
    26972721    return result;
    26982722}
    26992723
    2700 GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
    2701                                              int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
     2724GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     2725                                         int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
    27022726{
    27032727    GapRects result;
     
    27292753            if (childState == SelectionEnd || childState == SelectionInside)
    27302754                // Fill the gap above the object.
    2731                 result.uniteCenter(fillBlockSelectionGap(lastTop, lastLeft, lastRight,
    2732                                                          ty + curr->y(), rootBlock, blockX, blockY, paintInfo));
     2755                result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
     2756                                                     curr->logicalTop(), paintInfo));
    27332757
    27342758            // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past*
     
    27422766
    27432767            if (leftGap)
    2744                 result.uniteLeft(fillLogicalLeftSelectionGap(this, curr->x(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
     2768                result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
    27452769            if (rightGap)
    2746                 result.uniteRight(fillLogicalRightSelectionGap(this, curr->x() + curr->width(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
    2747 
    2748             // Update lastTop to be just underneath the object.  lastLeft and lastRight extend as far as
     2770                result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
     2771
     2772            // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
    27492773            // they can without bumping into floating or positioned objects.  Ideally they will go right up
    27502774            // to the border of the root selection block.
    2751             lastTop = (ty - blockY) + (curr->y() + curr->height());
    2752             lastLeft = logicalLeftSelectionOffset(rootBlock, curr->y() + curr->height());
    2753             lastRight = logicalRightSelectionOffset(rootBlock, curr->y() + curr->height());
     2775            lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
     2776            lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
     2777            lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
    27542778        } else if (childState != SelectionNone)
    27552779            // We must be a block that has some selected object inside it.  Go ahead and recur.
    2756             result.unite(toRenderBlock(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(),
    2757                                                                             lastTop, lastLeft, lastRight, paintInfo));
     2780            result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
     2781                                                            lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
    27582782    }
    27592783    return result;
    27602784}
    27612785
    2762 IntRect RenderBlock::fillLineSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo* paintInfo)
    2763 {
    2764     if (width <= 0 || height <= 0)
     2786IntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     2787                                       int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
     2788{
     2789    int logicalTop = lastLogicalTop;
     2790    int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
     2791    if (logicalHeight <= 0)
    27652792        return IntRect();
    2766     IntRect gapRect(xPos, yPos, width, height);
    2767     if (paintInfo && selObj->style()->visibility() == VISIBLE)
    2768         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
    2769     return gapRect;
    2770 }
    2771 
    2772 IntRect RenderBlock::fillBlockSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
    2773                                            int blockX, int blockY, const PaintInfo* paintInfo)
    2774 {
    2775     int top = blockY + lastTop;
    2776     int height = bottomY - top;
    2777     if (height <= 0)
     2793
     2794    // Get the selection offsets for the bottom of the gap
     2795    int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
     2796    int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
     2797    int logicalWidth = logicalRight - logicalLeft;
     2798    if (logicalWidth <= 0)
    27782799        return IntRect();
    27792800
    2780     // Get the selection offsets for the bottom of the gap
    2781     int left = blockX + max(lastLeft, logicalLeftSelectionOffset(rootBlock, bottomY));
    2782     int right = blockX + min(lastRight, logicalRightSelectionOffset(rootBlock, bottomY));
    2783     int width = right - left;
    2784     if (width <= 0)
    2785         return IntRect();
    2786 
    2787     IntRect gapRect(left, top, width, height);
     2801    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
    27882802    if (paintInfo)
    27892803        paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
     
    27912805}
    27922806
    2793 IntRect RenderBlock::fillLogicalLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
    2794                                                  int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
    2795 {
    2796     int top = yPos + ty;
    2797     int left = blockX + max(logicalLeftSelectionOffset(rootBlock, yPos), logicalLeftSelectionOffset(rootBlock, yPos + height));
    2798     int right = min(xPos + tx, blockX + min(logicalRightSelectionOffset(rootBlock, yPos), logicalRightSelectionOffset(rootBlock, yPos + height)));
    2799     int width = right - left;
    2800     if (width <= 0)
     2807IntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     2808                                             RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
     2809{
     2810    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
     2811    int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
     2812    int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
     2813    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
     2814    if (rootBlockLogicalWidth <= 0)
    28012815        return IntRect();
    28022816
    2803     IntRect gapRect(left, top, width, height);
     2817    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
    28042818    if (paintInfo)
    28052819        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
     
    28072821}
    28082822
    2809 IntRect RenderBlock::fillLogicalRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
    2810                                                   int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
    2811 {
    2812     int left = max(xPos + tx, blockX + max(logicalLeftSelectionOffset(rootBlock, yPos), logicalLeftSelectionOffset(rootBlock, yPos + height)));
    2813     int top = yPos + ty;
    2814     int right = blockX + min(logicalRightSelectionOffset(rootBlock, yPos), logicalRightSelectionOffset(rootBlock, yPos + height));
    2815     int width = right - left;
    2816     if (width <= 0)
     2823IntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     2824                                              RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
     2825{
     2826    int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
     2827    int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
     2828    int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
     2829    int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
     2830    if (rootBlockLogicalWidth <= 0)
    28172831        return IntRect();
    28182832
    2819     IntRect gapRect(left, top, width, height);
     2833    IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
    28202834    if (paintInfo)
    28212835        paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
     
    28422856            return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
    28432857        return logicalLeft;
    2844     }
    2845     else {
     2858    } else {
    28462859        RenderBlock* cb = this;
    28472860        while (cb != rootBlock) {
     
    28502863        }
    28512864    }
    2852    
    28532865    return logicalLeft;
    28542866}
     
    28622874            return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
    28632875        return logicalRight;
    2864     }
    2865     else {
     2876    } else {
    28662877        RenderBlock* cb = this;
    28672878        while (cb != rootBlock) {
     
    42974308        lastRootBoxWithChildren = root;
    42984309
    4299         // set the bottom based on whether there is a next root box
    4300         // FIXME: This will consider nextRootBox even if it has no children, and maybe it shouldn't.
    4301         int bottom;
    4302         if (root->nextRootBox()) {
    4303             // FIXME: We would prefer to make the break point halfway between the bottom
    4304             // of the previous root box and the top of the next root box.
    4305             bottom = root->nextRootBox()->lineTop();
    4306         } else
    4307             bottom = root->lineBottom() + verticalLineClickFudgeFactor;
    4308 
    43094310        // check if this root line box is located at this y coordinate
    4310         if (pointInContents.y() < bottom) {
     4311        if (pointInContents.y() < root->selectionBottom()) {
    43114312            closestBox = root->closestLeafChildForXPos(pointInContents.x());
    43124313            if (closestBox)
     
    43234324
    43244325    if (closestBox) {
    4325         if (moveCaretToBoundary && pointInContents.y() < firstRootBoxWithChildren->lineTop() - verticalLineClickFudgeFactor) {
     4326        if (moveCaretToBoundary && pointInContents.y() < firstRootBoxWithChildren->selectionTop()) {
    43264327            // y coordinate is above first root line box, so return the start of the first
    43274328            return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
  • trunk/WebCore/rendering/RenderBlock.h

    r71259 r71465  
    116116
    117117    GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer);
    118     IntRect fillLogicalLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
    119                                         int blockX, int blockY, int tx, int ty, const PaintInfo*);
    120     IntRect fillLogicalRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
    121                                          int blockX, int blockY, int tx, int ty, const PaintInfo*);
    122     IntRect fillLineSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*);
    123 
     118    IntRect logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     119                                    RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo*);
     120    IntRect logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     121                                     RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo*);
    124122    void getSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap);
    125 
     123    IntRect logicalRectToPhysicalRect(const IntPoint& physicalPosition, const IntRect& logicalRect);
     124       
    126125    // Helper methods for computing line counts and heights for line counts.
    127126    RootInlineBox* lineAtIndex(int);
     
    532531    virtual bool shouldPaintSelectionGaps() const;
    533532    bool isSelectionRoot() const;
    534     GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
    535                                int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* = 0);
    536     GapRects fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
    537                                      int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*);
    538     GapRects fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
    539                                     int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*);
    540     IntRect fillBlockSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
    541                                   int blockX, int blockY, const PaintInfo*);
     533    GapRects selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     534                           int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* = 0);
     535    GapRects inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     536                           int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo*);
     537    GapRects blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     538                           int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo*);
     539    IntRect blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     540                              int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo*);
    542541    int logicalLeftSelectionOffset(RenderBlock* rootBlock, int position);
    543542    int logicalRightSelectionOffset(RenderBlock* rootBlock, int position);
    544 
     543   
    545544    virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
    546545    virtual void absoluteQuads(Vector<FloatQuad>&);
  • trunk/WebCore/rendering/RenderBox.cpp

    r71177 r71465  
    32363236    if (!style()->isFlippedBlocksWritingMode())
    32373237        return position;
    3238     return style()->isHorizontalWritingMode() ? IntPoint(position.x(), logicalHeight() - position.y()) : IntPoint(logicalHeight() - position.x(), position.y());
     3238    return style()->isHorizontalWritingMode() ? IntPoint(position.x(), height() - position.y()) : IntPoint(width() - position.x(), position.y());
     3239}
     3240
     3241IntSize RenderBox::flipForWritingMode(const IntSize& offset)
     3242{
     3243    if (!style()->isFlippedBlocksWritingMode())
     3244        return offset;
     3245    return style()->isHorizontalWritingMode() ? IntSize(offset.width(), height() - offset.height()) : IntSize(width() - offset.width(), offset.height());
    32393246}
    32403247
  • trunk/WebCore/rendering/RenderBox.h

    r71177 r71465  
    5454    int logicalRight() const { return logicalLeft() + logicalWidth(); }
    5555    int logicalTop() const { return style()->isHorizontalWritingMode() ? y() : x(); }
     56    int logicalBottom() const { return logicalTop() + logicalHeight(); }
    5657    int logicalWidth() const { return style()->isHorizontalWritingMode() ? width() : height(); }
    5758    int logicalHeight() const { return style()->isHorizontalWritingMode() ? height() : width(); }
     
    384385    int flipForWritingMode(int position);
    385386    IntPoint flipForWritingMode(const IntPoint&);
     387    IntSize flipForWritingMode(const IntSize&);
    386388    void flipForWritingMode(IntRect&);
    387389    IntSize locationOffsetIncludingFlipping();
  • trunk/WebCore/rendering/RootInlineBox.cpp

    r71246 r71465  
    239239    int lineTop = heightOfBlock;
    240240    int lineBottom = heightOfBlock;
    241     placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom);
     241    bool setLineTop = false;
     242    placeBoxesInBlockDirection(heightOfBlock, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, setLineTop);
    242243    computeBlockDirectionOverflow(lineTop, lineBottom, noQuirksMode, textBoxDataMap);
    243244    setLineTopBottomPositions(lineTop, lineBottom);
     
    250251}
    251252
    252 GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, const PaintInfo* paintInfo)
     253GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
     254                                         int selTop, int selHeight, const PaintInfo* paintInfo)
    253255{
    254256    RenderObject::SelectionState lineState = selectionState();
     
    262264    InlineBox* lastBox = lastSelectedBox();
    263265    if (leftGap)
    264         result.uniteLeft(block()->fillLogicalLeftSelectionGap(firstBox->parent()->renderer(),
    265                                                               firstBox->x(), selTop, selHeight,
    266                                                               rootBlock, blockX, blockY, tx, ty, paintInfo));
     266        result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
     267                                                          firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo));
    267268    if (rightGap)
    268         result.uniteRight(block()->fillLogicalRightSelectionGap(lastBox->parent()->renderer(),
    269                                                                 lastBox->x() + lastBox->logicalWidth(), selTop, selHeight,
    270                                                                 rootBlock, blockX, blockY, tx, ty, paintInfo));
     269        result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
     270                                                            lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo));
    271271
    272272    // When dealing with bidi text, a non-contiguous selection region is possible.
     
    279279    if (firstBox && firstBox != lastBox) {
    280280        // Now fill in any gaps on the line that occurred between two selected elements.
    281         int lastX = firstBox->x() + firstBox->logicalWidth();
     281        int lastLogicalLeft = firstBox->logicalRight();
    282282        bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject::SelectionNone;
    283283        for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) {
    284284            if (box->selectionState() != RenderObject::SelectionNone) {
    285                 if (isPreviousBoxSelected)  // VisibleSelection may be non-contiguous, see comment above.
    286                     result.uniteCenter(block()->fillLineSelectionGap(box->parent()->renderer(),
    287                                                                      lastX + tx, selTop + ty,
    288                                                                      box->x() - lastX, selHeight, paintInfo));
    289                 lastX = box->x() + box->logicalWidth();
     285                IntRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft() - lastLogicalLeft, selHeight);
     286                logicalRect.move(renderer()->style()->isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
     287                IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
     288                if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.height() > 0) {
     289                    if (paintInfo && box->parent()->renderer()->style()->visibility() == VISIBLE)
     290                        paintInfo->context->fillRect(gapRect, box->parent()->renderer()->selectionBackgroundColor(), box->parent()->renderer()->style()->colorSpace());
     291                    // VisibleSelection may be non-contiguous, see comment above.
     292                    result.uniteCenter(gapRect);
     293                }
     294                lastLogicalLeft = box->logicalRight();
    290295            }
    291296            if (box == lastBox)
     
    348353{
    349354    int selectionTop = m_lineTop;
    350     if (!prevRootBox())
     355    if (renderer()->style()->isFlippedLinesWritingMode())
    351356        return selectionTop;
    352357
    353     int prevBottom = prevRootBox()->selectionBottom();
     358    int prevBottom = prevRootBox() ? prevRootBox()->selectionBottom() : block()->borderBefore() + block()->paddingBefore();
    354359    if (prevBottom < selectionTop && block()->containsFloats()) {
    355360        // This line has actually been moved further down, probably from a large line-height, but possibly because the
    356361        // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the previous
    357         // line's bottom overflow if the offsets are greater on both sides.
    358         int prevLeft = block()->logicalLeftOffsetForLine(prevBottom, !prevRootBox());
    359         int prevRight = block()->logicalRightOffsetForLine(prevBottom, !prevRootBox());
    360         int newLeft = block()->logicalLeftOffsetForLine(selectionTop, !prevRootBox());
    361         int newRight = block()->logicalRightOffsetForLine(selectionTop, !prevRootBox());
     362        // line's bottom if the offsets are greater on both sides.
     363        int prevLeft = block()->logicalLeftOffsetForLine(prevBottom, false);
     364        int prevRight = block()->logicalRightOffsetForLine(prevBottom, false);
     365        int newLeft = block()->logicalLeftOffsetForLine(selectionTop, false);
     366        int newRight = block()->logicalRightOffsetForLine(selectionTop, false);
    362367        if (prevLeft > newLeft || prevRight < newRight)
    363368            return selectionTop;
     
    365370
    366371    return prevBottom;
     372}
     373
     374int RootInlineBox::selectionBottom() const
     375{
     376    int selectionBottom = m_lineBottom;
     377    if (!renderer()->style()->isFlippedLinesWritingMode() || !nextRootBox())
     378        return selectionBottom;
     379
     380    int nextTop = nextRootBox()->selectionTop();
     381    if (nextTop > selectionBottom && block()->containsFloats()) {
     382        // The next line has actually been moved further over, probably from a large line-height, but possibly because the
     383        // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the next
     384        // line's top if the offsets are greater on both sides.
     385        int nextLeft = block()->logicalLeftOffsetForLine(nextTop, false);
     386        int nextRight = block()->logicalRightOffsetForLine(nextTop, false);
     387        int newLeft = block()->logicalLeftOffsetForLine(selectionBottom, false);
     388        int newRight = block()->logicalRightOffsetForLine(selectionBottom, false);
     389        if (nextLeft > newLeft || nextRight < newRight)
     390            return selectionBottom;
     391    }
     392
     393    return nextTop;
    367394}
    368395
  • trunk/WebCore/rendering/RootInlineBox.h

    r71055 r71465  
    5555
    5656    int selectionTop() const;
    57     int selectionBottom() const { return lineBottom(); }
     57    int selectionBottom() const;
    5858    int selectionHeight() const { return max(0, selectionBottom() - selectionTop()); }
    5959
     
    107107    InlineBox* lastSelectedBox();
    108108
    109     GapRects fillLineSelectionGap(int selTop, int selHeight, RenderBlock* rootBlock, int blockX, int blockY,
    110                                   int tx, int ty, const PaintInfo*);
     109    GapRects lineSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock, int selTop, int selHeight, const PaintInfo*);
    111110
    112111    RenderBlock* block() const;
Note: See TracChangeset for help on using the changeset viewer.