OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
5 * | 5 * |
6 * Other contributors: | 6 * Other contributors: |
7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { ScrollAlignmentNo
Scroll, ScrollAlignmentCenter, ScrollAlignmentClosestEdge }; | 50 const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { ScrollAlignmentNo
Scroll, ScrollAlignmentCenter, ScrollAlignmentClosestEdge }; |
51 const ScrollAlignment ScrollAlignment::alignToEdgeIfNeeded = { ScrollAlignmentNo
Scroll, ScrollAlignmentClosestEdge, ScrollAlignmentClosestEdge }; | 51 const ScrollAlignment ScrollAlignment::alignToEdgeIfNeeded = { ScrollAlignmentNo
Scroll, ScrollAlignmentClosestEdge, ScrollAlignmentClosestEdge }; |
52 const ScrollAlignment ScrollAlignment::alignCenterAlways = { ScrollAlignmentCent
er, ScrollAlignmentCenter, ScrollAlignmentCenter }; | 52 const ScrollAlignment ScrollAlignment::alignCenterAlways = { ScrollAlignmentCent
er, ScrollAlignmentCenter, ScrollAlignmentCenter }; |
53 const ScrollAlignment ScrollAlignment::alignTopAlways = { ScrollAlignmentTop, Sc
rollAlignmentTop, ScrollAlignmentTop }; | 53 const ScrollAlignment ScrollAlignment::alignTopAlways = { ScrollAlignmentTop, Sc
rollAlignmentTop, ScrollAlignmentTop }; |
54 const ScrollAlignment ScrollAlignment::alignBottomAlways = { ScrollAlignmentBott
om, ScrollAlignmentBottom, ScrollAlignmentBottom }; | 54 const ScrollAlignment ScrollAlignment::alignBottomAlways = { ScrollAlignmentBott
om, ScrollAlignmentBottom, ScrollAlignmentBottom }; |
55 | 55 |
56 #define MIN_INTERSECT_FOR_REVEAL 32 | 56 #define MIN_INTERSECT_FOR_REVEAL 32 |
57 | 57 |
58 LayoutRect ScrollAlignment::getRectToExpose(const LayoutRect& visibleRect, const
LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& a
lignY) | 58 LayoutRect ScrollAlignment::getRectToExpose(const LayoutRect& visibleRect, const
LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& a
lignY) |
59 { | 59 { |
| 60 // Prevent degenerate cases by giving the visible rect a minimum non-0 size. |
| 61 LayoutRect nonZeroVisibleRect(visibleRect); |
| 62 LayoutUnit minimumLayoutUnit; |
| 63 minimumLayoutUnit.setRawValue(1); |
| 64 if (nonZeroVisibleRect.width() == LayoutUnit()) |
| 65 nonZeroVisibleRect.setWidth(minimumLayoutUnit); |
| 66 if (nonZeroVisibleRect.height() == LayoutUnit()) |
| 67 nonZeroVisibleRect.setHeight(minimumLayoutUnit); |
| 68 |
60 // Determine the appropriate X behavior. | 69 // Determine the appropriate X behavior. |
61 ScrollAlignmentBehavior scrollX; | 70 ScrollAlignmentBehavior scrollX; |
62 LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(),
visibleRect.height()); | 71 LayoutRect exposeRectX(exposeRect.x(), nonZeroVisibleRect.y(), exposeRect.wi
dth(), nonZeroVisibleRect.height()); |
63 LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width(); | 72 LayoutUnit intersectWidth = intersection(nonZeroVisibleRect, exposeRectX).wi
dth(); |
64 if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_
FOR_REVEAL) { | 73 if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_
FOR_REVEAL) { |
65 // If the rectangle is fully visible, use the specified visible behavior
. | 74 // If the rectangle is fully visible, use the specified visible behavior
. |
66 // If the rectangle is partially visible, but over a certain threshold, | 75 // If the rectangle is partially visible, but over a certain threshold, |
67 // then treat it as fully visible to avoid unnecessary horizontal scroll
ing | 76 // then treat it as fully visible to avoid unnecessary horizontal scroll
ing |
68 scrollX = getVisibleBehavior(alignX); | 77 scrollX = getVisibleBehavior(alignX); |
69 } else if (intersectWidth == visibleRect.width()) { | 78 } else if (intersectWidth == nonZeroVisibleRect.width()) { |
70 // If the rect is bigger than the visible area, don't bother trying to c
enter. Other alignments will work. | 79 // If the rect is bigger than the visible area, don't bother trying to c
enter. Other alignments will work. |
71 scrollX = getVisibleBehavior(alignX); | 80 scrollX = getVisibleBehavior(alignX); |
72 if (scrollX == ScrollAlignmentCenter) | 81 if (scrollX == ScrollAlignmentCenter) |
73 scrollX = ScrollAlignmentNoScroll; | 82 scrollX = ScrollAlignmentNoScroll; |
74 } else if (intersectWidth > 0) { | 83 } else if (intersectWidth > 0) { |
75 // If the rectangle is partially visible, but not above the minimum thre
shold, use the specified partial behavior | 84 // If the rectangle is partially visible, but not above the minimum thre
shold, use the specified partial behavior |
76 scrollX = getPartialBehavior(alignX); | 85 scrollX = getPartialBehavior(alignX); |
77 } else { | 86 } else { |
78 scrollX = getHiddenBehavior(alignX); | 87 scrollX = getHiddenBehavior(alignX); |
79 } | 88 } |
80 | 89 |
81 if (scrollX == ScrollAlignmentClosestEdge) { | 90 if (scrollX == ScrollAlignmentClosestEdge) { |
82 // Closest edge is the right in two cases: | 91 // Closest edge is the right in two cases: |
83 // (1) exposeRect to the right of and smaller than visibleRect | 92 // (1) exposeRect to the right of and smaller than nonZeroVisibleRect |
84 // (2) exposeRect to the left of and larger than visibleRect | 93 // (2) exposeRect to the left of and larger than nonZeroVisibleRect |
85 if ((exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visi
bleRect.width()) | 94 if ((exposeRect.maxX() > nonZeroVisibleRect.maxX() && exposeRect.width()
< nonZeroVisibleRect.width()) |
86 || (exposeRect.maxX() < visibleRect.maxX() && exposeRect.width() > v
isibleRect.width())) { | 95 || (exposeRect.maxX() < nonZeroVisibleRect.maxX() && exposeRect.widt
h() > nonZeroVisibleRect.width())) { |
87 scrollX = ScrollAlignmentRight; | 96 scrollX = ScrollAlignmentRight; |
88 } | 97 } |
89 } | 98 } |
90 | 99 |
91 // Given the X behavior, compute the X coordinate. | 100 // Given the X behavior, compute the X coordinate. |
92 LayoutUnit x; | 101 LayoutUnit x; |
93 if (scrollX == ScrollAlignmentNoScroll) | 102 if (scrollX == ScrollAlignmentNoScroll) |
94 x = visibleRect.x(); | 103 x = nonZeroVisibleRect.x(); |
95 else if (scrollX == ScrollAlignmentRight) | 104 else if (scrollX == ScrollAlignmentRight) |
96 x = exposeRect.maxX() - visibleRect.width(); | 105 x = exposeRect.maxX() - nonZeroVisibleRect.width(); |
97 else if (scrollX == ScrollAlignmentCenter) | 106 else if (scrollX == ScrollAlignmentCenter) |
98 x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2; | 107 x = exposeRect.x() + (exposeRect.width() - nonZeroVisibleRect.width()) /
2; |
99 else | 108 else |
100 x = exposeRect.x(); | 109 x = exposeRect.x(); |
101 | 110 |
102 // Determine the appropriate Y behavior. | 111 // Determine the appropriate Y behavior. |
103 ScrollAlignmentBehavior scrollY; | 112 ScrollAlignmentBehavior scrollY; |
104 LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(),
exposeRect.height()); | 113 LayoutRect exposeRectY(nonZeroVisibleRect.x(), exposeRect.y(), nonZeroVisibl
eRect.width(), exposeRect.height()); |
105 LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height()
; | 114 LayoutUnit intersectHeight = intersection(nonZeroVisibleRect, exposeRectY).h
eight(); |
106 if (intersectHeight == exposeRect.height()) { | 115 if (intersectHeight == exposeRect.height()) { |
107 // If the rectangle is fully visible, use the specified visible behavior
. | 116 // If the rectangle is fully visible, use the specified visible behavior
. |
108 scrollY = getVisibleBehavior(alignY); | 117 scrollY = getVisibleBehavior(alignY); |
109 } else if (intersectHeight == visibleRect.height()) { | 118 } else if (intersectHeight == nonZeroVisibleRect.height()) { |
110 // If the rect is bigger than the visible area, don't bother trying to c
enter. Other alignments will work. | 119 // If the rect is bigger than the visible area, don't bother trying to c
enter. Other alignments will work. |
111 scrollY = getVisibleBehavior(alignY); | 120 scrollY = getVisibleBehavior(alignY); |
112 if (scrollY == ScrollAlignmentCenter) | 121 if (scrollY == ScrollAlignmentCenter) |
113 scrollY = ScrollAlignmentNoScroll; | 122 scrollY = ScrollAlignmentNoScroll; |
114 } else if (intersectHeight > 0) { | 123 } else if (intersectHeight > 0) { |
115 // If the rectangle is partially visible, use the specified partial beha
vior | 124 // If the rectangle is partially visible, use the specified partial beha
vior |
116 scrollY = getPartialBehavior(alignY); | 125 scrollY = getPartialBehavior(alignY); |
117 } else { | 126 } else { |
118 scrollY = getHiddenBehavior(alignY); | 127 scrollY = getHiddenBehavior(alignY); |
119 } | 128 } |
120 | 129 |
121 if (scrollY == ScrollAlignmentClosestEdge) { | 130 if (scrollY == ScrollAlignmentClosestEdge) { |
122 // Closest edge is the bottom in two cases: | 131 // Closest edge is the bottom in two cases: |
123 // (1) exposeRect below and smaller than visibleRect | 132 // (1) exposeRect below and smaller than nonZeroVisibleRect |
124 // (2) exposeRect above and larger than visibleRect | 133 // (2) exposeRect above and larger than nonZeroVisibleRect |
125 if ((exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < vis
ibleRect.height()) | 134 if ((exposeRect.maxY() > nonZeroVisibleRect.maxY() && exposeRect.height(
) < nonZeroVisibleRect.height()) |
126 || (exposeRect.maxY() < visibleRect.maxY() && exposeRect.height() >
visibleRect.height())) { | 135 || (exposeRect.maxY() < nonZeroVisibleRect.maxY() && exposeRect.heig
ht() > nonZeroVisibleRect.height())) { |
127 scrollY = ScrollAlignmentBottom; | 136 scrollY = ScrollAlignmentBottom; |
128 } | 137 } |
129 } | 138 } |
130 | 139 |
131 // Given the Y behavior, compute the Y coordinate. | 140 // Given the Y behavior, compute the Y coordinate. |
132 LayoutUnit y; | 141 LayoutUnit y; |
133 if (scrollY == ScrollAlignmentNoScroll) | 142 if (scrollY == ScrollAlignmentNoScroll) |
134 y = visibleRect.y(); | 143 y = nonZeroVisibleRect.y(); |
135 else if (scrollY == ScrollAlignmentBottom) | 144 else if (scrollY == ScrollAlignmentBottom) |
136 y = exposeRect.maxY() - visibleRect.height(); | 145 y = exposeRect.maxY() - nonZeroVisibleRect.height(); |
137 else if (scrollY == ScrollAlignmentCenter) | 146 else if (scrollY == ScrollAlignmentCenter) |
138 y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2; | 147 y = exposeRect.y() + (exposeRect.height() - nonZeroVisibleRect.height())
/ 2; |
139 else | 148 else |
140 y = exposeRect.y(); | 149 y = exposeRect.y(); |
141 | 150 |
142 return LayoutRect(LayoutPoint(x, y), visibleRect.size()); | 151 return LayoutRect(LayoutPoint(x, y), nonZeroVisibleRect.size()); |
143 } | 152 } |
144 | 153 |
145 } // namespace blink | 154 } // namespace blink |
OLD | NEW |