| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include "core/frame/VisualViewport.h" | 39 #include "core/frame/VisualViewport.h" |
| 40 #include "core/html/HTMLBodyElement.h" | 40 #include "core/html/HTMLBodyElement.h" |
| 41 #include "core/html/HTMLHeadElement.h" | 41 #include "core/html/HTMLHeadElement.h" |
| 42 #include "core/html/HTMLHtmlElement.h" | 42 #include "core/html/HTMLHtmlElement.h" |
| 43 #include "core/html/HTMLImageElement.h" | 43 #include "core/html/HTMLImageElement.h" |
| 44 #include "core/html/HTMLMetaElement.h" | 44 #include "core/html/HTMLMetaElement.h" |
| 45 #include "core/layout/LayoutObject.h" | 45 #include "core/layout/LayoutObject.h" |
| 46 #include "core/loader/DocumentLoader.h" | 46 #include "core/loader/DocumentLoader.h" |
| 47 #include "core/loader/FrameLoader.h" | 47 #include "core/loader/FrameLoader.h" |
| 48 #include "core/loader/FrameLoaderClient.h" | 48 #include "core/loader/FrameLoaderClient.h" |
| 49 #include "platform/HostWindow.h" |
| 49 #include "wtf/text/StringBuilder.h" | 50 #include "wtf/text/StringBuilder.h" |
| 50 #include <limits> | 51 #include <limits> |
| 51 | 52 |
| 52 using namespace std; | 53 using namespace std; |
| 53 | 54 |
| 54 namespace blink { | 55 namespace blink { |
| 55 | 56 |
| 56 using namespace HTMLNames; | 57 using namespace HTMLNames; |
| 57 | 58 |
| 58 class ImageEventListener : public EventListener { | 59 class ImageEventListener : public EventListener { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 if (m_shrinkToFitMode == Desktop) | 239 if (m_shrinkToFitMode == Desktop) |
| 239 m_imageElement->addEventListener("click", listener, false); | 240 m_imageElement->addEventListener("click", listener, false); |
| 240 } | 241 } |
| 241 | 242 |
| 242 rootElement->appendChild(head); | 243 rootElement->appendChild(head); |
| 243 rootElement->appendChild(body); | 244 rootElement->appendChild(body); |
| 244 } | 245 } |
| 245 | 246 |
| 246 float ImageDocument::scale() const | 247 float ImageDocument::scale() const |
| 247 { | 248 { |
| 249 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 248 if (!m_imageElement || m_imageElement->document() != this) | 250 if (!m_imageElement || m_imageElement->document() != this) |
| 249 return 1.0f; | 251 return 1.0f; |
| 250 | 252 |
| 251 FrameView* view = frame()->view(); | 253 FrameView* view = frame()->view(); |
| 252 if (!view) | 254 if (!view) |
| 253 return 1; | 255 return 1.0f; |
| 254 | 256 |
| 255 DCHECK(m_imageElement->cachedImage()); | 257 DCHECK(m_imageElement->cachedImage()); |
| 256 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), pageZoomFactor(
this)); | 258 const float zoom = pageZoomFactor(this); |
| 257 LayoutSize windowSize = LayoutSize(view->width(), view->height()); | 259 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), zoom); |
| 258 | 260 |
| 259 float widthScale = windowSize.width().toFloat() / imageSize.width().toFloat(
); | 261 // We want to pretend the viewport is larger when the user has zoomed the |
| 260 float heightScale = windowSize.height().toFloat() / imageSize.height().toFlo
at(); | 262 // page in (but not when the zoom is coming from device scale). |
| 263 const float manualZoom = zoom / view->getHostWindow()->windowToViewportScala
r(1.f); |
| 264 float widthScale = view->width() * manualZoom / imageSize.width().toFloat(); |
| 265 float heightScale = view->height() * manualZoom / imageSize.height().toFloat
(); |
| 261 | 266 |
| 262 return min(widthScale, heightScale); | 267 return min(widthScale, heightScale); |
| 263 } | 268 } |
| 264 | 269 |
| 265 void ImageDocument::resizeImageToFit(ScaleType type) | 270 void ImageDocument::resizeImageToFit() |
| 266 { | 271 { |
| 267 if (!m_imageElement || m_imageElement->document() != this || (pageZoomFactor
(this) > 1 && type == ScaleOnlyUnzoomedDocument)) | 272 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 273 if (!m_imageElement || m_imageElement->document() != this) |
| 268 return; | 274 return; |
| 269 | 275 |
| 270 DCHECK(m_imageElement->cachedImage()); | 276 DCHECK(m_imageElement->cachedImage()); |
| 271 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), pageZoomFactor(
this)); | 277 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), 1.f); |
| 272 | 278 |
| 273 float scale = this->scale(); | 279 const float scale = this->scale(); |
| 274 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); | 280 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); |
| 275 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); | 281 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); |
| 276 | 282 |
| 277 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn); | 283 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn); |
| 278 } | 284 } |
| 279 | 285 |
| 280 void ImageDocument::imageClicked(int x, int y) | 286 void ImageDocument::imageClicked(int x, int y) |
| 281 { | 287 { |
| 282 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 288 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 283 | 289 |
| 284 if (!m_imageSizeIsKnown || imageFitsInWindow()) | 290 if (!m_imageSizeIsKnown || imageFitsInWindow()) |
| 285 return; | 291 return; |
| 286 | 292 |
| 287 m_shouldShrinkImage = !m_shouldShrinkImage; | 293 m_shouldShrinkImage = !m_shouldShrinkImage; |
| 288 | 294 |
| 289 if (m_shouldShrinkImage) { | 295 if (m_shouldShrinkImage) { |
| 290 windowSizeChanged(ScaleZoomedDocument); | 296 windowSizeChanged(); |
| 291 } else { | 297 } else { |
| 292 restoreImageSize(ScaleZoomedDocument); | 298 restoreImageSize(); |
| 293 | 299 |
| 294 updateStyleAndLayout(); | 300 updateStyleAndLayout(); |
| 295 | 301 |
| 296 double scale = this->scale(); | 302 double scale = this->scale(); |
| 297 | 303 |
| 298 double scrollX = x / scale - static_cast<double>(frame()->view()->width(
)) / 2; | 304 double scrollX = x / scale - static_cast<double>(frame()->view()->width(
)) / 2; |
| 299 double scrollY = y / scale - static_cast<double>(frame()->view()->height
()) / 2; | 305 double scrollY = y / scale - static_cast<double>(frame()->view()->height
()) / 2; |
| 300 | 306 |
| 301 frame()->view()->setScrollPosition(DoublePoint(scrollX, scrollY), Progra
mmaticScroll); | 307 frame()->view()->setScrollPosition(DoublePoint(scrollX, scrollY), Progra
mmaticScroll); |
| 302 } | 308 } |
| 303 } | 309 } |
| 304 | 310 |
| 305 void ImageDocument::imageUpdated() | 311 void ImageDocument::imageUpdated() |
| 306 { | 312 { |
| 307 DCHECK(m_imageElement); | 313 DCHECK(m_imageElement); |
| 308 | 314 |
| 309 if (m_imageSizeIsKnown) | 315 if (m_imageSizeIsKnown) |
| 310 return; | 316 return; |
| 311 | 317 |
| 312 updateStyleAndLayoutTree(); | 318 updateStyleAndLayoutTree(); |
| 313 if (!m_imageElement->cachedImage() || m_imageElement->cachedImage()->imageSi
ze(LayoutObject::shouldRespectImageOrientation(m_imageElement->layoutObject()),
pageZoomFactor(this)).isEmpty()) | 319 if (!m_imageElement->cachedImage() || m_imageElement->cachedImage()->imageSi
ze(LayoutObject::shouldRespectImageOrientation(m_imageElement->layoutObject()),
pageZoomFactor(this)).isEmpty()) |
| 314 return; | 320 return; |
| 315 | 321 |
| 316 m_imageSizeIsKnown = true; | 322 m_imageSizeIsKnown = true; |
| 317 | 323 |
| 318 if (shouldShrinkToFit()) { | 324 if (shouldShrinkToFit()) { |
| 319 // Force resizing of the image | 325 // Force resizing of the image |
| 320 windowSizeChanged(ScaleOnlyUnzoomedDocument); | 326 windowSizeChanged(); |
| 321 } | 327 } |
| 322 } | 328 } |
| 323 | 329 |
| 324 void ImageDocument::restoreImageSize(ScaleType type) | 330 void ImageDocument::restoreImageSize() |
| 325 { | 331 { |
| 326 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 332 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 327 | 333 |
| 328 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() !=
this || (pageZoomFactor(this) < 1 && type == ScaleOnlyUnzoomedDocument)) | 334 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() !=
this) |
| 329 return; | 335 return; |
| 330 | 336 |
| 331 DCHECK(m_imageElement->cachedImage()); | 337 DCHECK(m_imageElement->cachedImage()); |
| 332 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), 1.0f); | 338 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), 1.0f); |
| 333 m_imageElement->setWidth(imageSize.width().toInt()); | 339 m_imageElement->setWidth(imageSize.width().toInt()); |
| 334 m_imageElement->setHeight(imageSize.height().toInt()); | 340 m_imageElement->setHeight(imageSize.height().toInt()); |
| 335 | 341 |
| 336 if (imageFitsInWindow()) | 342 if (imageFitsInWindow()) |
| 337 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); | 343 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); |
| 338 else | 344 else |
| 339 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOu
t); | 345 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOu
t); |
| 340 | 346 |
| 341 m_didShrinkImage = false; | 347 m_didShrinkImage = false; |
| 342 } | 348 } |
| 343 | 349 |
| 344 bool ImageDocument::imageFitsInWindow() const | 350 bool ImageDocument::imageFitsInWindow() const |
| 345 { | 351 { |
| 346 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 352 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 347 | 353 return this->scale() >= 1; |
| 348 if (!m_imageElement || m_imageElement->document() != this) | |
| 349 return true; | |
| 350 | |
| 351 FrameView* view = frame()->view(); | |
| 352 if (!view) | |
| 353 return true; | |
| 354 | |
| 355 DCHECK(m_imageElement->cachedImage()); | |
| 356 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject
::shouldRespectImageOrientation(m_imageElement->layoutObject()), pageZoomFactor(
this)); | |
| 357 LayoutSize windowSize = LayoutSize(view->width(), view->height()); | |
| 358 | |
| 359 return imageSize.width() <= windowSize.width() && imageSize.height() <= wind
owSize.height(); | |
| 360 } | 354 } |
| 361 | 355 |
| 362 void ImageDocument::windowSizeChanged(ScaleType type) | 356 void ImageDocument::windowSizeChanged() |
| 363 { | 357 { |
| 364 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() !=
this) | 358 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() !=
this) |
| 365 return; | 359 return; |
| 366 | 360 |
| 367 if (m_shrinkToFitMode == Viewport) { | 361 if (m_shrinkToFitMode == Viewport) { |
| 368 // For huge images, minimum-scale=0.1 is still too big on small screens. | 362 // For huge images, minimum-scale=0.1 is still too big on small screens. |
| 369 // Set max-width so that the image will shrink to fit the width of the s
creen when | 363 // Set max-width so that the image will shrink to fit the width of the s
creen when |
| 370 // the scale is minimum. | 364 // the scale is minimum. |
| 371 // Don't shrink height to fit because we use width=device-width in viewp
ort meta tag, | 365 // Don't shrink height to fit because we use width=device-width in viewp
ort meta tag, |
| 372 // and expect a full-width reading mode for normal-width-huge-height ima
ges. | 366 // and expect a full-width reading mode for normal-width-huge-height ima
ges. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 384 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); | 378 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); |
| 385 else | 379 else |
| 386 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZo
omOut); | 380 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZo
omOut); |
| 387 return; | 381 return; |
| 388 } | 382 } |
| 389 | 383 |
| 390 if (m_didShrinkImage) { | 384 if (m_didShrinkImage) { |
| 391 // If the window has been resized so that the image fits, restore the im
age size | 385 // If the window has been resized so that the image fits, restore the im
age size |
| 392 // otherwise update the restored image size. | 386 // otherwise update the restored image size. |
| 393 if (fitsInWindow) | 387 if (fitsInWindow) |
| 394 restoreImageSize(type); | 388 restoreImageSize(); |
| 395 else | 389 else |
| 396 resizeImageToFit(type); | 390 resizeImageToFit(); |
| 397 } else { | 391 } else { |
| 398 // If the image isn't resized but needs to be, then resize it. | 392 // If the image isn't resized but needs to be, then resize it. |
| 399 if (!fitsInWindow) { | 393 if (!fitsInWindow) { |
| 400 resizeImageToFit(type); | 394 resizeImageToFit(); |
| 401 m_didShrinkImage = true; | 395 m_didShrinkImage = true; |
| 402 } | 396 } |
| 403 } | 397 } |
| 404 } | 398 } |
| 405 | 399 |
| 406 ImageResource* ImageDocument::cachedImage() | 400 ImageResource* ImageDocument::cachedImage() |
| 407 { | 401 { |
| 408 if (!m_imageElement) { | 402 if (!m_imageElement) { |
| 409 createDocumentStructure(); | 403 createDocumentStructure(); |
| 410 if (isStopped()) { | 404 if (isStopped()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 425 { | 419 { |
| 426 visitor->trace(m_imageElement); | 420 visitor->trace(m_imageElement); |
| 427 HTMLDocument::trace(visitor); | 421 HTMLDocument::trace(visitor); |
| 428 } | 422 } |
| 429 | 423 |
| 430 // -------- | 424 // -------- |
| 431 | 425 |
| 432 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) | 426 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) |
| 433 { | 427 { |
| 434 if (event->type() == EventTypeNames::resize) { | 428 if (event->type() == EventTypeNames::resize) { |
| 435 m_doc->windowSizeChanged(ImageDocument::ScaleOnlyUnzoomedDocument); | 429 m_doc->windowSizeChanged(); |
| 436 } else if (event->type() == EventTypeNames::click && event->isMouseEvent())
{ | 430 } else if (event->type() == EventTypeNames::click && event->isMouseEvent())
{ |
| 437 MouseEvent* mouseEvent = toMouseEvent(event); | 431 MouseEvent* mouseEvent = toMouseEvent(event); |
| 438 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y()); | 432 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y()); |
| 439 } | 433 } |
| 440 } | 434 } |
| 441 | 435 |
| 442 bool ImageEventListener::operator==(const EventListener& listener) const | 436 bool ImageEventListener::operator==(const EventListener& listener) const |
| 443 { | 437 { |
| 444 if (const ImageEventListener* imageEventListener = ImageEventListener::cast(
&listener)) | 438 if (const ImageEventListener* imageEventListener = ImageEventListener::cast(
&listener)) |
| 445 return m_doc == imageEventListener->m_doc; | 439 return m_doc == imageEventListener->m_doc; |
| 446 return false; | 440 return false; |
| 447 } | 441 } |
| 448 | 442 |
| 449 } // namespace blink | 443 } // namespace blink |
| OLD | NEW |