| 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 // -------- | 194 // -------- |
| 195 | 195 |
| 196 ImageDocument::ImageDocument(const DocumentInit& initializer) | 196 ImageDocument::ImageDocument(const DocumentInit& initializer) |
| 197 : HTMLDocument(initializer, ImageDocumentClass), | 197 : HTMLDocument(initializer, ImageDocumentClass), |
| 198 m_divElement(nullptr), | 198 m_divElement(nullptr), |
| 199 m_imageElement(nullptr), | 199 m_imageElement(nullptr), |
| 200 m_imageSizeIsKnown(false), | 200 m_imageSizeIsKnown(false), |
| 201 m_didShrinkImage(false), | 201 m_didShrinkImage(false), |
| 202 m_shouldShrinkImage(shouldShrinkToFit()), | 202 m_shouldShrinkImage(shouldShrinkToFit()), |
| 203 m_imageIsLoaded(false), | 203 m_imageIsLoaded(false), |
| 204 m_checkerSize(0), | 204 m_styleCheckerSize(0), |
| 205 m_styleMouseCursorMode(Default), |
| 205 m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport | 206 m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport |
| 206 : Desktop) { | 207 : Desktop) { |
| 207 setCompatibilityMode(QuirksMode); | 208 setCompatibilityMode(QuirksMode); |
| 208 lockCompatibilityMode(); | 209 lockCompatibilityMode(); |
| 209 UseCounter::count(*this, UseCounter::ImageDocument); | 210 UseCounter::count(*this, UseCounter::ImageDocument); |
| 210 if (!isInMainFrame()) | 211 if (!isInMainFrame()) |
| 211 UseCounter::count(*this, UseCounter::ImageDocumentInFrame); | 212 UseCounter::count(*this, UseCounter::ImageDocumentInFrame); |
| 212 } | 213 } |
| 213 | 214 |
| 214 DocumentParser* ImageDocument::createParser() { | 215 DocumentParser* ImageDocument::createParser() { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 319 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 319 if (!m_imageElement || m_imageElement->document() != this) | 320 if (!m_imageElement || m_imageElement->document() != this) |
| 320 return; | 321 return; |
| 321 | 322 |
| 322 LayoutSize imageSize = cachedImageSize(m_imageElement); | 323 LayoutSize imageSize = cachedImageSize(m_imageElement); |
| 323 | 324 |
| 324 const float scale = this->scale(); | 325 const float scale = this->scale(); |
| 325 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); | 326 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); |
| 326 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); | 327 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); |
| 327 | 328 |
| 328 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn); | 329 updateImageStyle(); |
| 329 } | 330 } |
| 330 | 331 |
| 331 void ImageDocument::imageClicked(int x, int y) { | 332 void ImageDocument::imageClicked(int x, int y) { |
| 332 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 333 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 333 | 334 |
| 334 if (!m_imageSizeIsKnown || imageFitsInWindow()) | 335 if (!m_imageSizeIsKnown || imageFitsInWindow()) |
| 335 return; | 336 return; |
| 336 | 337 |
| 337 m_shouldShrinkImage = !m_shouldShrinkImage; | 338 m_shouldShrinkImage = !m_shouldShrinkImage; |
| 338 | 339 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 imageStyle.append("-webkit-user-select: none;"); | 375 imageStyle.append("-webkit-user-select: none;"); |
| 375 | 376 |
| 376 if (shouldShrinkToFit()) { | 377 if (shouldShrinkToFit()) { |
| 377 if (m_shrinkToFitMode == Viewport) | 378 if (m_shrinkToFitMode == Viewport) |
| 378 imageStyle.append("max-width: 100%;"); | 379 imageStyle.append("max-width: 100%;"); |
| 379 | 380 |
| 380 // Once the image has fully loaded, it is displayed atop a checkerboard to | 381 // Once the image has fully loaded, it is displayed atop a checkerboard to |
| 381 // show transparency more faithfully. The pattern is generated via CSS. | 382 // show transparency more faithfully. The pattern is generated via CSS. |
| 382 if (m_imageIsLoaded) { | 383 if (m_imageIsLoaded) { |
| 383 int newCheckerSize = kBaseCheckerSize; | 384 int newCheckerSize = kBaseCheckerSize; |
| 385 MouseCursorMode newCursorMode = Default; |
| 384 | 386 |
| 385 if (m_shrinkToFitMode == Viewport) { | 387 if (m_shrinkToFitMode == Viewport) { |
| 386 double scale; | 388 double scale; |
| 387 | 389 |
| 388 if (hasFinishedParsing()) { | 390 if (hasFinishedParsing()) { |
| 389 // To ensure the checker pattern is visible for large images, the | 391 // To ensure the checker pattern is visible for large images, the |
| 390 // checker size is dynamically adjusted to account for how much the | 392 // checker size is dynamically adjusted to account for how much the |
| 391 // page is currently being scaled. | 393 // page is currently being scaled. |
| 392 scale = frame()->host()->visualViewport().scale(); | 394 scale = frame()->host()->visualViewport().scale(); |
| 393 } else { | 395 } else { |
| 394 // The checker pattern is initialized based on how large the image is | 396 // The checker pattern is initialized based on how large the image is |
| 395 // relative to the viewport. | 397 // relative to the viewport. |
| 396 int viewportWidth = frame()->host()->visualViewport().size().width(); | 398 int viewportWidth = frame()->host()->visualViewport().size().width(); |
| 397 scale = viewportWidth / static_cast<double>(calculateDivWidth()); | 399 scale = viewportWidth / static_cast<double>(calculateDivWidth()); |
| 398 } | 400 } |
| 399 | 401 |
| 400 newCheckerSize = round(std::max(1.0, newCheckerSize / scale)); | 402 newCheckerSize = round(std::max(1.0, newCheckerSize / scale)); |
| 403 } else { |
| 404 // In desktop mode, the user can click on the image to zoom in or out. |
| 405 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 406 if (imageFitsInWindow()) { |
| 407 newCursorMode = Default; |
| 408 } else { |
| 409 newCursorMode = m_shouldShrinkImage ? ZoomIn : ZoomOut; |
| 410 } |
| 401 } | 411 } |
| 402 | 412 |
| 403 // The only thing that can differ between updates is the checker size. | 413 // The only things that can differ between updates are checker size and |
| 404 if (newCheckerSize == m_checkerSize) | 414 // the type of cursor being displayed. |
| 415 if (newCheckerSize == m_styleCheckerSize && |
| 416 newCursorMode == m_styleMouseCursorMode) { |
| 405 return; | 417 return; |
| 406 m_checkerSize = newCheckerSize; | 418 } |
| 419 m_styleCheckerSize = newCheckerSize; |
| 420 m_styleMouseCursorMode = newCursorMode; |
| 407 | 421 |
| 408 imageStyle.append("background-position: 0px 0px, "); | 422 imageStyle.append("background-position: 0px 0px, "); |
| 409 imageStyle.append(AtomicString::number(m_checkerSize)); | 423 imageStyle.append(AtomicString::number(m_styleCheckerSize)); |
| 410 imageStyle.append("px "); | 424 imageStyle.append("px "); |
| 411 imageStyle.append(AtomicString::number(m_checkerSize)); | 425 imageStyle.append(AtomicString::number(m_styleCheckerSize)); |
| 412 imageStyle.append("px;"); | 426 imageStyle.append("px;"); |
| 413 | 427 |
| 414 int tileSize = m_checkerSize * 2; | 428 int tileSize = m_styleCheckerSize * 2; |
| 415 imageStyle.append("background-size: "); | 429 imageStyle.append("background-size: "); |
| 416 imageStyle.append(AtomicString::number(tileSize)); | 430 imageStyle.append(AtomicString::number(tileSize)); |
| 417 imageStyle.append("px "); | 431 imageStyle.append("px "); |
| 418 imageStyle.append(AtomicString::number(tileSize)); | 432 imageStyle.append(AtomicString::number(tileSize)); |
| 419 imageStyle.append("px;"); | 433 imageStyle.append("px;"); |
| 420 | 434 |
| 421 // Generating the checkerboard pattern this way is not exactly cheap. | 435 // Generating the checkerboard pattern this way is not exactly cheap. |
| 422 // If rasterization performance becomes an issue, we could look at using | 436 // If rasterization performance becomes an issue, we could look at using |
| 423 // a cheaper shader (e.g. pre-generate a scaled tile + base64-encode + | 437 // a cheaper shader (e.g. pre-generate a scaled tile + base64-encode + |
| 424 // inline dataURI => single bitmap shader). | 438 // inline dataURI => single bitmap shader). |
| 425 imageStyle.append( | 439 imageStyle.append( |
| 426 "background-image:" | 440 "background-image:" |
| 427 "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, " | 441 "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, " |
| 428 "#eee 75%, #eee 100%)," | 442 "#eee 75%, #eee 100%)," |
| 429 "linear-gradient(45deg, #eee 25%, white 25%, white 75%, " | 443 "linear-gradient(45deg, #eee 25%, white 25%, white 75%, " |
| 430 "#eee 75%, #eee 100%);"); | 444 "#eee 75%, #eee 100%);"); |
| 445 |
| 446 if (m_shrinkToFitMode == Desktop) { |
| 447 if (m_styleMouseCursorMode == ZoomIn) |
| 448 imageStyle.append("cursor: zoom-in;"); |
| 449 else if (m_styleMouseCursorMode == ZoomOut) |
| 450 imageStyle.append("cursor: zoom-out;"); |
| 451 } |
| 431 } | 452 } |
| 432 } | 453 } |
| 433 | 454 |
| 434 m_imageElement->setAttribute(styleAttr, imageStyle.toAtomicString()); | 455 m_imageElement->setAttribute(styleAttr, imageStyle.toAtomicString()); |
| 435 } | 456 } |
| 436 | 457 |
| 437 void ImageDocument::imageUpdated() { | 458 void ImageDocument::imageUpdated() { |
| 438 DCHECK(m_imageElement); | 459 DCHECK(m_imageElement); |
| 439 | 460 |
| 440 if (m_imageSizeIsKnown) | 461 if (m_imageSizeIsKnown) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 461 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 482 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 462 | 483 |
| 463 if (!m_imageElement || !m_imageSizeIsKnown || | 484 if (!m_imageElement || !m_imageSizeIsKnown || |
| 464 m_imageElement->document() != this) | 485 m_imageElement->document() != this) |
| 465 return; | 486 return; |
| 466 | 487 |
| 467 DCHECK(m_imageElement->cachedImage()); | 488 DCHECK(m_imageElement->cachedImage()); |
| 468 LayoutSize imageSize = cachedImageSize(m_imageElement); | 489 LayoutSize imageSize = cachedImageSize(m_imageElement); |
| 469 m_imageElement->setWidth(imageSize.width().toInt()); | 490 m_imageElement->setWidth(imageSize.width().toInt()); |
| 470 m_imageElement->setHeight(imageSize.height().toInt()); | 491 m_imageElement->setHeight(imageSize.height().toInt()); |
| 471 | 492 updateImageStyle(); |
| 472 if (imageFitsInWindow()) | |
| 473 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); | |
| 474 else | |
| 475 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut); | |
| 476 | 493 |
| 477 m_didShrinkImage = false; | 494 m_didShrinkImage = false; |
| 478 } | 495 } |
| 479 | 496 |
| 480 bool ImageDocument::imageFitsInWindow() const { | 497 bool ImageDocument::imageFitsInWindow() const { |
| 481 DCHECK_EQ(m_shrinkToFitMode, Desktop); | 498 DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| 482 return this->scale() >= 1; | 499 return this->scale() >= 1; |
| 483 } | 500 } |
| 484 | 501 |
| 485 int ImageDocument::calculateDivWidth() { | 502 int ImageDocument::calculateDivWidth() { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight, | 538 m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight, |
| 522 CSSPrimitiveValue::UnitType::Pixels); | 539 CSSPrimitiveValue::UnitType::Pixels); |
| 523 return; | 540 return; |
| 524 } | 541 } |
| 525 | 542 |
| 526 bool fitsInWindow = imageFitsInWindow(); | 543 bool fitsInWindow = imageFitsInWindow(); |
| 527 | 544 |
| 528 // If the image has been explicitly zoomed in, restore the cursor if the image | 545 // If the image has been explicitly zoomed in, restore the cursor if the image |
| 529 // fits and set it to a zoom out cursor if the image doesn't fit | 546 // fits and set it to a zoom out cursor if the image doesn't fit |
| 530 if (!m_shouldShrinkImage) { | 547 if (!m_shouldShrinkImage) { |
| 531 if (fitsInWindow) | 548 updateImageStyle(); |
| 532 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); | |
| 533 else | |
| 534 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, | |
| 535 CSSValueZoomOut); | |
| 536 return; | 549 return; |
| 537 } | 550 } |
| 538 | 551 |
| 539 if (m_didShrinkImage) { | 552 if (m_didShrinkImage) { |
| 540 // If the window has been resized so that the image fits, restore the image | 553 // If the window has been resized so that the image fits, restore the image |
| 541 // size otherwise update the restored image size. | 554 // size otherwise update the restored image size. |
| 542 if (fitsInWindow) | 555 if (fitsInWindow) |
| 543 restoreImageSize(); | 556 restoreImageSize(); |
| 544 else | 557 else |
| 545 resizeImageToFit(); | 558 resizeImageToFit(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 } | 603 } |
| 591 | 604 |
| 592 bool ImageEventListener::operator==(const EventListener& listener) const { | 605 bool ImageEventListener::operator==(const EventListener& listener) const { |
| 593 if (const ImageEventListener* imageEventListener = | 606 if (const ImageEventListener* imageEventListener = |
| 594 ImageEventListener::cast(&listener)) | 607 ImageEventListener::cast(&listener)) |
| 595 return m_doc == imageEventListener->m_doc; | 608 return m_doc == imageEventListener->m_doc; |
| 596 return false; | 609 return false; |
| 597 } | 610 } |
| 598 | 611 |
| 599 } // namespace blink | 612 } // namespace blink |
| OLD | NEW |