Chromium Code Reviews| Index: third_party/WebKit/Source/core/html/ImageDocument.cpp |
| diff --git a/third_party/WebKit/Source/core/html/ImageDocument.cpp b/third_party/WebKit/Source/core/html/ImageDocument.cpp |
| index 5a716aa9331096f846fcd571083c1446490fd60f..8db35fecc367c43837c7df7c7a33a20a8ce5ff5e 100644 |
| --- a/third_party/WebKit/Source/core/html/ImageDocument.cpp |
| +++ b/third_party/WebKit/Source/core/html/ImageDocument.cpp |
| @@ -48,6 +48,7 @@ |
| #include "core/loader/FrameLoader.h" |
| #include "core/loader/FrameLoaderClient.h" |
| #include "core/loader/resource/ImageResource.h" |
| +#include "core/page/Page.h" |
| #include "platform/HostWindow.h" |
| #include "wtf/text/StringBuilder.h" |
| #include <limits> |
| @@ -235,7 +236,7 @@ void ImageDocument::createDocumentStructure() { |
| HTMLBodyElement* body = HTMLBodyElement::create(*this); |
| - if (shouldShrinkToFit()) { |
| + if (shouldCenterImage()) { |
| // Display the image prominently centered in the frame. |
| body->setAttribute(styleAttr, "margin: 0px; background: #0e0e0e;"); |
| @@ -292,6 +293,12 @@ void ImageDocument::createDocumentStructure() { |
| rootElement->appendChild(body); |
| } |
| +bool ImageDocument::shouldCenterImage() const { |
| + bool isAndroidWebView = |
| + page() ? page()->settings().getWideViewportQuirkEnabled() : false; |
| + return shouldShrinkToFit() && !isAndroidWebView; |
| +} |
| + |
| float ImageDocument::scale() const { |
| DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| if (!m_imageElement || m_imageElement->document() != this) |
| @@ -379,31 +386,36 @@ void ImageDocument::updateImageStyle() { |
| imageStyle.append("-webkit-user-select: none;"); |
| if (shouldShrinkToFit()) { |
| - if (m_shrinkToFitMode == Viewport) |
| + if (shouldCenterImage() && m_shrinkToFitMode == Viewport) { |
| + // The image occupies the full width of its parent <div>. |
| imageStyle.append("max-width: 100%;"); |
| + } |
| - // Once the image has fully loaded, it is displayed atop a checkerboard to |
| - // show transparency more faithfully. The pattern is generated via CSS. |
| if (m_imageIsLoaded) { |
| int newCheckerSize = kBaseCheckerSize; |
| MouseCursorMode newCursorMode = Default; |
| + // Images are displayed atop a checkerboard to show transparency more |
| + // faithfully. The pattern is generated via CSS. |
| if (m_shrinkToFitMode == Viewport) { |
| - double scale; |
| - |
| - if (hasFinishedParsing()) { |
| - // To ensure the checker pattern is visible for large images, the |
| - // checker size is dynamically adjusted to account for how much the |
| - // page is currently being scaled. |
| - scale = frame()->host()->visualViewport().scale(); |
| - } else { |
| - // The checker pattern is initialized based on how large the image is |
| - // relative to the viewport. |
| - int viewportWidth = frame()->host()->visualViewport().size().width(); |
| - scale = viewportWidth / static_cast<double>(calculateDivWidth()); |
| + if (shouldCenterImage()) { |
| + double scale; |
| + |
| + if (hasFinishedParsing()) { |
| + // To ensure the checker pattern is visible for large images, the |
| + // checker size is dynamically adjusted to account for how much the |
| + // page is currently being scaled. |
| + scale = frame()->host()->visualViewport().scale(); |
| + } else { |
| + // The checker pattern is initialized based on how large the image |
| + // is relative to the viewport. |
| + int viewportWidth = |
| + frame()->host()->visualViewport().size().width(); |
| + scale = viewportWidth / static_cast<double>(calculateDivWidth()); |
| + } |
| + |
| + newCheckerSize = std::round(std::max(1.0, newCheckerSize / scale)); |
| } |
| - |
| - newCheckerSize = std::round(std::max(1.0, newCheckerSize / scale)); |
| } else { |
| // In desktop mode, the user can click on the image to zoom in or out. |
| DCHECK_EQ(m_shrinkToFitMode, Desktop); |
| @@ -423,29 +435,33 @@ void ImageDocument::updateImageStyle() { |
| m_styleCheckerSize = newCheckerSize; |
| m_styleMouseCursorMode = newCursorMode; |
| - imageStyle.append("background-position: 0px 0px, "); |
| - imageStyle.append(AtomicString::number(m_styleCheckerSize)); |
| - imageStyle.append("px "); |
| - imageStyle.append(AtomicString::number(m_styleCheckerSize)); |
| - imageStyle.append("px;"); |
| - |
| - int tileSize = m_styleCheckerSize * 2; |
| - imageStyle.append("background-size: "); |
| - imageStyle.append(AtomicString::number(tileSize)); |
| - imageStyle.append("px "); |
| - imageStyle.append(AtomicString::number(tileSize)); |
| - imageStyle.append("px;"); |
| - |
| - // Generating the checkerboard pattern this way is not exactly cheap. |
| - // If rasterization performance becomes an issue, we could look at using |
| - // a cheaper shader (e.g. pre-generate a scaled tile + base64-encode + |
| - // inline dataURI => single bitmap shader). |
| - imageStyle.append( |
| - "background-image:" |
| - "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, " |
| - "#eee 75%, #eee 100%)," |
| - "linear-gradient(45deg, #eee 25%, white 25%, white 75%, " |
| - "#eee 75%, #eee 100%);"); |
| + // Generate the new image style string. |
| + if (shouldCenterImage()) { |
| + imageStyle.append("background-position: 0px 0px, "); |
| + imageStyle.append(AtomicString::number(m_styleCheckerSize)); |
| + imageStyle.append("px "); |
| + imageStyle.append(AtomicString::number(m_styleCheckerSize)); |
| + imageStyle.append("px;"); |
| + |
| + int tileSize = m_styleCheckerSize * 2; |
| + imageStyle.append("background-size: "); |
| + imageStyle.append(AtomicString::number(tileSize)); |
| + imageStyle.append("px "); |
| + imageStyle.append(AtomicString::number(tileSize)); |
| + imageStyle.append("px;"); |
| + |
| + // Generating the checkerboard pattern this way is not exactly cheap. |
| + // If rasterization performance becomes an issue, we could look at using |
| + // a cheaper shader (e.g. pre-generate a scaled tile + base64-encode + |
| + // inline dataURI => single bitmap shader). |
| + imageStyle.append( |
| + "background-image:" |
| + "linear-gradient(45deg, #eee 25%, transparent 25%, transparent " |
| + "75%, " |
| + "#eee 75%, #eee 100%)," |
| + "linear-gradient(45deg, #eee 25%, white 25%, white 75%, " |
| + "#eee 75%, #eee 100%);"); |
| + } |
| if (m_shrinkToFitMode == Desktop) { |
| if (m_styleMouseCursorMode == ZoomIn) |
| @@ -527,20 +543,32 @@ void ImageDocument::windowSizeChanged() { |
| return; |
| if (m_shrinkToFitMode == Viewport) { |
| - LayoutSize imageSize = cachedImageSize(m_imageElement); |
| - int divWidth = calculateDivWidth(); |
| - m_divElement->setInlineStyleProperty(CSSPropertyWidth, divWidth, |
| - CSSPrimitiveValue::UnitType::Pixels); |
| - |
| - // Explicitly set the height of the <div> containing the <img> so that it |
| - // can display the full image without shrinking it, allowing a full-width |
| - // reading mode for normal-width-huge-height images. |
| - float viewportAspectRatio = |
| - frame()->host()->visualViewport().size().aspectRatio(); |
| - int divHeight = std::max(imageSize.height().toInt(), |
| - static_cast<int>(divWidth / viewportAspectRatio)); |
| - m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight, |
| - CSSPrimitiveValue::UnitType::Pixels); |
| + if (shouldCenterImage()) { |
| + // Set the size of the <div> containing the <img>. The latter is set |
| + // to occupy 100% of the <div>'s width in updateImageStyle(). |
| + LayoutSize imageSize = cachedImageSize(m_imageElement); |
| + int divWidth = calculateDivWidth(); |
| + m_divElement->setInlineStyleProperty(CSSPropertyWidth, divWidth, |
| + CSSPrimitiveValue::UnitType::Pixels); |
| + |
| + // Explicitly set the height of the <div> containing the <img> so that it |
| + // can display the full image without shrinking it, allowing a full-width |
| + // reading mode for normal-width-huge-height images. |
| + float viewportAspectRatio = |
| + frame()->host()->visualViewport().size().aspectRatio(); |
| + int divHeight = |
| + std::max(imageSize.height().toInt(), |
| + static_cast<int>(divWidth / viewportAspectRatio)); |
| + m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight, |
| + CSSPrimitiveValue::UnitType::Pixels); |
| + } else { |
| + // Set the max width of the <img> to prevent it from becoming too large. |
| + // See calculateDivWidth() for details. |
| + int viewportWidth = frame()->host()->visualViewport().size().width(); |
| + m_imageElement->setInlineStyleProperty( |
|
aelias_OOO_until_Jul13
2017/01/19 00:23:49
Could you try instead returning false from ImageDo
|
| + CSSPropertyMaxWidth, viewportWidth * 10, |
| + CSSPrimitiveValue::UnitType::Pixels); |
| + } |
| return; |
| } |