Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 4 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | package org.mozilla.gecko.gfx; |
michael@0 | 7 | |
michael@0 | 8 | import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; |
michael@0 | 9 | import org.mozilla.gecko.util.FloatUtils; |
michael@0 | 10 | |
michael@0 | 11 | import android.graphics.PointF; |
michael@0 | 12 | import android.graphics.RectF; |
michael@0 | 13 | import android.util.DisplayMetrics; |
michael@0 | 14 | |
michael@0 | 15 | /** |
michael@0 | 16 | * ImmutableViewportMetrics are used to store the viewport metrics |
michael@0 | 17 | * in way that we can access a version of them from multiple threads |
michael@0 | 18 | * without having to take a lock |
michael@0 | 19 | */ |
michael@0 | 20 | public class ImmutableViewportMetrics { |
michael@0 | 21 | |
michael@0 | 22 | // We need to flatten the RectF and FloatSize structures |
michael@0 | 23 | // because Java doesn't have the concept of const classes |
michael@0 | 24 | public final float pageRectLeft; |
michael@0 | 25 | public final float pageRectTop; |
michael@0 | 26 | public final float pageRectRight; |
michael@0 | 27 | public final float pageRectBottom; |
michael@0 | 28 | public final float cssPageRectLeft; |
michael@0 | 29 | public final float cssPageRectTop; |
michael@0 | 30 | public final float cssPageRectRight; |
michael@0 | 31 | public final float cssPageRectBottom; |
michael@0 | 32 | public final float viewportRectLeft; |
michael@0 | 33 | public final float viewportRectTop; |
michael@0 | 34 | public final float viewportRectRight; |
michael@0 | 35 | public final float viewportRectBottom; |
michael@0 | 36 | public final float marginLeft; |
michael@0 | 37 | public final float marginTop; |
michael@0 | 38 | public final float marginRight; |
michael@0 | 39 | public final float marginBottom; |
michael@0 | 40 | public final float zoomFactor; |
michael@0 | 41 | public final boolean isRTL; |
michael@0 | 42 | |
michael@0 | 43 | public ImmutableViewportMetrics(DisplayMetrics metrics) { |
michael@0 | 44 | viewportRectLeft = pageRectLeft = cssPageRectLeft = 0; |
michael@0 | 45 | viewportRectTop = pageRectTop = cssPageRectTop = 0; |
michael@0 | 46 | viewportRectRight = pageRectRight = cssPageRectRight = metrics.widthPixels; |
michael@0 | 47 | viewportRectBottom = pageRectBottom = cssPageRectBottom = metrics.heightPixels; |
michael@0 | 48 | marginLeft = marginTop = marginRight = marginBottom = 0; |
michael@0 | 49 | zoomFactor = 1.0f; |
michael@0 | 50 | isRTL = false; |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | /** This constructor is used by native code in AndroidJavaWrappers.cpp, be |
michael@0 | 54 | * careful when modifying the signature. |
michael@0 | 55 | */ |
michael@0 | 56 | @WrapElementForJNI(allowMultithread = true) |
michael@0 | 57 | public ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, |
michael@0 | 58 | float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft, |
michael@0 | 59 | float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom, |
michael@0 | 60 | float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight, |
michael@0 | 61 | float aViewportRectBottom, float aZoomFactor) |
michael@0 | 62 | { |
michael@0 | 63 | this(aPageRectLeft, aPageRectTop, |
michael@0 | 64 | aPageRectRight, aPageRectBottom, aCssPageRectLeft, |
michael@0 | 65 | aCssPageRectTop, aCssPageRectRight, aCssPageRectBottom, |
michael@0 | 66 | aViewportRectLeft, aViewportRectTop, aViewportRectRight, |
michael@0 | 67 | aViewportRectBottom, 0.0f, 0.0f, 0.0f, 0.0f, aZoomFactor, false); |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, |
michael@0 | 71 | float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft, |
michael@0 | 72 | float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom, |
michael@0 | 73 | float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight, |
michael@0 | 74 | float aViewportRectBottom, float aMarginLeft, |
michael@0 | 75 | float aMarginTop, float aMarginRight, |
michael@0 | 76 | float aMarginBottom, float aZoomFactor, boolean aIsRTL) |
michael@0 | 77 | { |
michael@0 | 78 | pageRectLeft = aPageRectLeft; |
michael@0 | 79 | pageRectTop = aPageRectTop; |
michael@0 | 80 | pageRectRight = aPageRectRight; |
michael@0 | 81 | pageRectBottom = aPageRectBottom; |
michael@0 | 82 | cssPageRectLeft = aCssPageRectLeft; |
michael@0 | 83 | cssPageRectTop = aCssPageRectTop; |
michael@0 | 84 | cssPageRectRight = aCssPageRectRight; |
michael@0 | 85 | cssPageRectBottom = aCssPageRectBottom; |
michael@0 | 86 | viewportRectLeft = aViewportRectLeft; |
michael@0 | 87 | viewportRectTop = aViewportRectTop; |
michael@0 | 88 | viewportRectRight = aViewportRectRight; |
michael@0 | 89 | viewportRectBottom = aViewportRectBottom; |
michael@0 | 90 | marginLeft = aMarginLeft; |
michael@0 | 91 | marginTop = aMarginTop; |
michael@0 | 92 | marginRight = aMarginRight; |
michael@0 | 93 | marginBottom = aMarginBottom; |
michael@0 | 94 | zoomFactor = aZoomFactor; |
michael@0 | 95 | isRTL = aIsRTL; |
michael@0 | 96 | } |
michael@0 | 97 | |
michael@0 | 98 | public float getWidth() { |
michael@0 | 99 | return viewportRectRight - viewportRectLeft; |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | public float getHeight() { |
michael@0 | 103 | return viewportRectBottom - viewportRectTop; |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | public float getWidthWithoutMargins() { |
michael@0 | 107 | return viewportRectRight - viewportRectLeft - marginLeft - marginRight; |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | public float getHeightWithoutMargins() { |
michael@0 | 111 | return viewportRectBottom - viewportRectTop - marginTop - marginBottom; |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | public PointF getOrigin() { |
michael@0 | 115 | return new PointF(viewportRectLeft, viewportRectTop); |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | public PointF getMarginOffset() { |
michael@0 | 119 | if (isRTL) { |
michael@0 | 120 | return new PointF(marginLeft - marginRight, marginTop); |
michael@0 | 121 | } |
michael@0 | 122 | return new PointF(marginLeft, marginTop); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | public FloatSize getSize() { |
michael@0 | 126 | return new FloatSize(viewportRectRight - viewportRectLeft, viewportRectBottom - viewportRectTop); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | public RectF getViewport() { |
michael@0 | 130 | return new RectF(viewportRectLeft, |
michael@0 | 131 | viewportRectTop, |
michael@0 | 132 | viewportRectRight, |
michael@0 | 133 | viewportRectBottom); |
michael@0 | 134 | } |
michael@0 | 135 | |
michael@0 | 136 | public RectF getCssViewport() { |
michael@0 | 137 | return RectUtils.scale(getViewport(), 1/zoomFactor); |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | public RectF getPageRect() { |
michael@0 | 141 | return new RectF(pageRectLeft, pageRectTop, pageRectRight, pageRectBottom); |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | public float getPageWidth() { |
michael@0 | 145 | return pageRectRight - pageRectLeft; |
michael@0 | 146 | } |
michael@0 | 147 | |
michael@0 | 148 | public float getPageWidthWithMargins() { |
michael@0 | 149 | return (pageRectRight - pageRectLeft) + marginLeft + marginRight; |
michael@0 | 150 | } |
michael@0 | 151 | |
michael@0 | 152 | public float getPageHeight() { |
michael@0 | 153 | return pageRectBottom - pageRectTop; |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | public float getPageHeightWithMargins() { |
michael@0 | 157 | return (pageRectBottom - pageRectTop) + marginTop + marginBottom; |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | public RectF getCssPageRect() { |
michael@0 | 161 | return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | public RectF getOverscroll() { |
michael@0 | 165 | return new RectF(Math.max(0, pageRectLeft - viewportRectLeft), |
michael@0 | 166 | Math.max(0, pageRectTop - viewportRectTop), |
michael@0 | 167 | Math.max(0, viewportRectRight - pageRectRight), |
michael@0 | 168 | Math.max(0, viewportRectBottom - pageRectBottom)); |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | /* |
michael@0 | 172 | * Returns the viewport metrics that represent a linear transition between "this" and "to" at |
michael@0 | 173 | * time "t", which is on the scale [0, 1). This function interpolates all values stored in |
michael@0 | 174 | * the viewport metrics. |
michael@0 | 175 | */ |
michael@0 | 176 | public ImmutableViewportMetrics interpolate(ImmutableViewportMetrics to, float t) { |
michael@0 | 177 | return new ImmutableViewportMetrics( |
michael@0 | 178 | FloatUtils.interpolate(pageRectLeft, to.pageRectLeft, t), |
michael@0 | 179 | FloatUtils.interpolate(pageRectTop, to.pageRectTop, t), |
michael@0 | 180 | FloatUtils.interpolate(pageRectRight, to.pageRectRight, t), |
michael@0 | 181 | FloatUtils.interpolate(pageRectBottom, to.pageRectBottom, t), |
michael@0 | 182 | FloatUtils.interpolate(cssPageRectLeft, to.cssPageRectLeft, t), |
michael@0 | 183 | FloatUtils.interpolate(cssPageRectTop, to.cssPageRectTop, t), |
michael@0 | 184 | FloatUtils.interpolate(cssPageRectRight, to.cssPageRectRight, t), |
michael@0 | 185 | FloatUtils.interpolate(cssPageRectBottom, to.cssPageRectBottom, t), |
michael@0 | 186 | FloatUtils.interpolate(viewportRectLeft, to.viewportRectLeft, t), |
michael@0 | 187 | FloatUtils.interpolate(viewportRectTop, to.viewportRectTop, t), |
michael@0 | 188 | FloatUtils.interpolate(viewportRectRight, to.viewportRectRight, t), |
michael@0 | 189 | FloatUtils.interpolate(viewportRectBottom, to.viewportRectBottom, t), |
michael@0 | 190 | FloatUtils.interpolate(marginLeft, to.marginLeft, t), |
michael@0 | 191 | FloatUtils.interpolate(marginTop, to.marginTop, t), |
michael@0 | 192 | FloatUtils.interpolate(marginRight, to.marginRight, t), |
michael@0 | 193 | FloatUtils.interpolate(marginBottom, to.marginBottom, t), |
michael@0 | 194 | FloatUtils.interpolate(zoomFactor, to.zoomFactor, t), |
michael@0 | 195 | t >= 0.5 ? to.isRTL : isRTL); |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | public ImmutableViewportMetrics setViewportSize(float width, float height) { |
michael@0 | 199 | if (FloatUtils.fuzzyEquals(width, getWidth()) && FloatUtils.fuzzyEquals(height, getHeight())) { |
michael@0 | 200 | return this; |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | return new ImmutableViewportMetrics( |
michael@0 | 204 | pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, |
michael@0 | 205 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 206 | viewportRectLeft, viewportRectTop, viewportRectLeft + width, viewportRectTop + height, |
michael@0 | 207 | marginLeft, marginTop, marginRight, marginBottom, |
michael@0 | 208 | zoomFactor, isRTL); |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | public ImmutableViewportMetrics setViewportOrigin(float newOriginX, float newOriginY) { |
michael@0 | 212 | return new ImmutableViewportMetrics( |
michael@0 | 213 | pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, |
michael@0 | 214 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 215 | newOriginX, newOriginY, newOriginX + getWidth(), newOriginY + getHeight(), |
michael@0 | 216 | marginLeft, marginTop, marginRight, marginBottom, |
michael@0 | 217 | zoomFactor, isRTL); |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | public ImmutableViewportMetrics setZoomFactor(float newZoomFactor) { |
michael@0 | 221 | return new ImmutableViewportMetrics( |
michael@0 | 222 | pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, |
michael@0 | 223 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 224 | viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, |
michael@0 | 225 | marginLeft, marginTop, marginRight, marginBottom, |
michael@0 | 226 | newZoomFactor, isRTL); |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | public ImmutableViewportMetrics offsetViewportBy(float dx, float dy) { |
michael@0 | 230 | return setViewportOrigin(viewportRectLeft + dx, viewportRectTop + dy); |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | public ImmutableViewportMetrics offsetViewportByAndClamp(float dx, float dy) { |
michael@0 | 234 | if (isRTL) { |
michael@0 | 235 | return setViewportOrigin( |
michael@0 | 236 | Math.min(pageRectRight - getWidthWithoutMargins(), Math.max(viewportRectLeft + dx, pageRectLeft)), |
michael@0 | 237 | Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins()))); |
michael@0 | 238 | } |
michael@0 | 239 | return setViewportOrigin( |
michael@0 | 240 | Math.max(pageRectLeft, Math.min(viewportRectLeft + dx, pageRectRight - getWidthWithoutMargins())), |
michael@0 | 241 | Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins()))); |
michael@0 | 242 | } |
michael@0 | 243 | |
michael@0 | 244 | public ImmutableViewportMetrics setPageRect(RectF pageRect, RectF cssPageRect) { |
michael@0 | 245 | return new ImmutableViewportMetrics( |
michael@0 | 246 | pageRect.left, pageRect.top, pageRect.right, pageRect.bottom, |
michael@0 | 247 | cssPageRect.left, cssPageRect.top, cssPageRect.right, cssPageRect.bottom, |
michael@0 | 248 | viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, |
michael@0 | 249 | marginLeft, marginTop, marginRight, marginBottom, |
michael@0 | 250 | zoomFactor, isRTL); |
michael@0 | 251 | } |
michael@0 | 252 | |
michael@0 | 253 | public ImmutableViewportMetrics setMargins(float left, float top, float right, float bottom) { |
michael@0 | 254 | if (FloatUtils.fuzzyEquals(left, marginLeft) |
michael@0 | 255 | && FloatUtils.fuzzyEquals(top, marginTop) |
michael@0 | 256 | && FloatUtils.fuzzyEquals(right, marginRight) |
michael@0 | 257 | && FloatUtils.fuzzyEquals(bottom, marginBottom)) { |
michael@0 | 258 | return this; |
michael@0 | 259 | } |
michael@0 | 260 | |
michael@0 | 261 | return new ImmutableViewportMetrics( |
michael@0 | 262 | pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, |
michael@0 | 263 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 264 | viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, |
michael@0 | 265 | left, top, right, bottom, zoomFactor, isRTL); |
michael@0 | 266 | } |
michael@0 | 267 | |
michael@0 | 268 | public ImmutableViewportMetrics setMarginsFrom(ImmutableViewportMetrics fromMetrics) { |
michael@0 | 269 | return setMargins(fromMetrics.marginLeft, |
michael@0 | 270 | fromMetrics.marginTop, |
michael@0 | 271 | fromMetrics.marginRight, |
michael@0 | 272 | fromMetrics.marginBottom); |
michael@0 | 273 | } |
michael@0 | 274 | |
michael@0 | 275 | public ImmutableViewportMetrics setIsRTL(boolean aIsRTL) { |
michael@0 | 276 | if (isRTL == aIsRTL) { |
michael@0 | 277 | return this; |
michael@0 | 278 | } |
michael@0 | 279 | |
michael@0 | 280 | return new ImmutableViewportMetrics( |
michael@0 | 281 | pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, |
michael@0 | 282 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 283 | viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, |
michael@0 | 284 | marginLeft, marginTop, marginRight, marginBottom, zoomFactor, aIsRTL); |
michael@0 | 285 | } |
michael@0 | 286 | |
michael@0 | 287 | /* This will set the zoom factor and re-scale page-size and viewport offset |
michael@0 | 288 | * accordingly. The given focus will remain at the same point on the screen |
michael@0 | 289 | * after scaling. |
michael@0 | 290 | */ |
michael@0 | 291 | public ImmutableViewportMetrics scaleTo(float newZoomFactor, PointF focus) { |
michael@0 | 292 | // cssPageRect* is invariant, since we're setting the scale factor |
michael@0 | 293 | // here. The page rect is based on the CSS page rect. |
michael@0 | 294 | float newPageRectLeft = cssPageRectLeft * newZoomFactor; |
michael@0 | 295 | float newPageRectTop = cssPageRectTop * newZoomFactor; |
michael@0 | 296 | float newPageRectRight = cssPageRectLeft + ((cssPageRectRight - cssPageRectLeft) * newZoomFactor); |
michael@0 | 297 | float newPageRectBottom = cssPageRectTop + ((cssPageRectBottom - cssPageRectTop) * newZoomFactor); |
michael@0 | 298 | |
michael@0 | 299 | PointF origin = getOrigin(); |
michael@0 | 300 | origin.offset(focus.x, focus.y); |
michael@0 | 301 | origin = PointUtils.scale(origin, newZoomFactor / zoomFactor); |
michael@0 | 302 | origin.offset(-focus.x, -focus.y); |
michael@0 | 303 | |
michael@0 | 304 | return new ImmutableViewportMetrics( |
michael@0 | 305 | newPageRectLeft, newPageRectTop, newPageRectRight, newPageRectBottom, |
michael@0 | 306 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 307 | origin.x, origin.y, origin.x + getWidth(), origin.y + getHeight(), |
michael@0 | 308 | marginLeft, marginTop, marginRight, marginBottom, |
michael@0 | 309 | newZoomFactor, isRTL); |
michael@0 | 310 | } |
michael@0 | 311 | |
michael@0 | 312 | /** Clamps the viewport to remain within the page rect. */ |
michael@0 | 313 | private ImmutableViewportMetrics clamp(float marginLeft, float marginTop, |
michael@0 | 314 | float marginRight, float marginBottom) { |
michael@0 | 315 | RectF newViewport = getViewport(); |
michael@0 | 316 | PointF offset = getMarginOffset(); |
michael@0 | 317 | |
michael@0 | 318 | // The viewport bounds ought to never exceed the page bounds. |
michael@0 | 319 | if (newViewport.right > pageRectRight + marginLeft + marginRight) |
michael@0 | 320 | newViewport.offset((pageRectRight + marginLeft + marginRight) - newViewport.right, 0); |
michael@0 | 321 | if (newViewport.left < pageRectLeft) |
michael@0 | 322 | newViewport.offset(pageRectLeft - newViewport.left, 0); |
michael@0 | 323 | |
michael@0 | 324 | if (newViewport.bottom > pageRectBottom + marginTop + marginBottom) |
michael@0 | 325 | newViewport.offset(0, (pageRectBottom + marginTop + marginBottom) - newViewport.bottom); |
michael@0 | 326 | if (newViewport.top < pageRectTop) |
michael@0 | 327 | newViewport.offset(0, pageRectTop - newViewport.top); |
michael@0 | 328 | |
michael@0 | 329 | return new ImmutableViewportMetrics( |
michael@0 | 330 | pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, |
michael@0 | 331 | cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, |
michael@0 | 332 | newViewport.left, newViewport.top, newViewport.right, newViewport.bottom, |
michael@0 | 333 | marginLeft, marginTop, marginRight, marginBottom, |
michael@0 | 334 | zoomFactor, isRTL); |
michael@0 | 335 | } |
michael@0 | 336 | |
michael@0 | 337 | public ImmutableViewportMetrics clamp() { |
michael@0 | 338 | return clamp(0, 0, 0, 0); |
michael@0 | 339 | } |
michael@0 | 340 | |
michael@0 | 341 | public ImmutableViewportMetrics clampWithMargins() { |
michael@0 | 342 | return clamp(marginLeft, marginTop, |
michael@0 | 343 | marginRight, marginBottom); |
michael@0 | 344 | } |
michael@0 | 345 | |
michael@0 | 346 | public boolean fuzzyEquals(ImmutableViewportMetrics other) { |
michael@0 | 347 | // Don't bother checking the pageRectXXX values because they are a product |
michael@0 | 348 | // of the cssPageRectXXX values and the zoomFactor, except with more rounding |
michael@0 | 349 | // error. Checking those is both inefficient and can lead to false negatives. |
michael@0 | 350 | // |
michael@0 | 351 | // This doesn't return false if the margins differ as none of the users |
michael@0 | 352 | // of this function are interested in the margins in that way. |
michael@0 | 353 | return FloatUtils.fuzzyEquals(cssPageRectLeft, other.cssPageRectLeft) |
michael@0 | 354 | && FloatUtils.fuzzyEquals(cssPageRectTop, other.cssPageRectTop) |
michael@0 | 355 | && FloatUtils.fuzzyEquals(cssPageRectRight, other.cssPageRectRight) |
michael@0 | 356 | && FloatUtils.fuzzyEquals(cssPageRectBottom, other.cssPageRectBottom) |
michael@0 | 357 | && FloatUtils.fuzzyEquals(viewportRectLeft, other.viewportRectLeft) |
michael@0 | 358 | && FloatUtils.fuzzyEquals(viewportRectTop, other.viewportRectTop) |
michael@0 | 359 | && FloatUtils.fuzzyEquals(viewportRectRight, other.viewportRectRight) |
michael@0 | 360 | && FloatUtils.fuzzyEquals(viewportRectBottom, other.viewportRectBottom) |
michael@0 | 361 | && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor); |
michael@0 | 362 | } |
michael@0 | 363 | |
michael@0 | 364 | @Override |
michael@0 | 365 | public String toString() { |
michael@0 | 366 | return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + "," |
michael@0 | 367 | + viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + "," |
michael@0 | 368 | + pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=(" |
michael@0 | 369 | + cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + "," |
michael@0 | 370 | + cssPageRectBottom + ") m=(" + marginLeft + "," |
michael@0 | 371 | + marginTop + "," + marginRight + "," |
michael@0 | 372 | + marginBottom + ") z=" + zoomFactor + ", rtl=" + isRTL; |
michael@0 | 373 | } |
michael@0 | 374 | } |