Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/WebKit/Source/core/html/ImageDocument.cpp

Issue 2445413003: [Blink] Display images on a dark background (Closed)
Patch Set: Rebasing Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageDocument.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include "core/layout/LayoutObject.h" 47 #include "core/layout/LayoutObject.h"
48 #include "core/loader/DocumentLoader.h" 48 #include "core/loader/DocumentLoader.h"
49 #include "core/loader/FrameLoader.h" 49 #include "core/loader/FrameLoader.h"
50 #include "core/loader/FrameLoaderClient.h" 50 #include "core/loader/FrameLoaderClient.h"
51 #include "platform/HostWindow.h" 51 #include "platform/HostWindow.h"
52 #include "wtf/text/StringBuilder.h" 52 #include "wtf/text/StringBuilder.h"
53 #include <limits> 53 #include <limits>
54 54
55 using namespace std; 55 using namespace std;
56 56
57 namespace {
58
59 // The base square size is set to 10 because it rounds nicely for both the
60 // minimum scale (0.1) and maximum scale (5.0).
61 int gBaseCheckerSize = 10;
pdr. 2016/11/02 22:54:49 Nit: since this is a constant, wdyt of: const int
gone 2016/11/03 01:28:41 Ah forgot what the proper syntax was here. Done.
62
63 } // namespace
64
57 namespace blink { 65 namespace blink {
58 66
59 using namespace HTMLNames; 67 using namespace HTMLNames;
60 68
61 class ImageEventListener : public EventListener { 69 class ImageEventListener : public EventListener {
62 public: 70 public:
63 static ImageEventListener* create(ImageDocument* document) { 71 static ImageEventListener* create(ImageDocument* document) {
64 return new ImageEventListener(document); 72 return new ImageEventListener(document);
65 } 73 }
66 static const ImageEventListener* cast(const EventListener* listener) { 74 static const ImageEventListener* cast(const EventListener* listener) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 result.append(" ("); 124 result.append(" (");
117 // FIXME: Localize numbers. Safari/OSX shows localized numbers with group 125 // FIXME: Localize numbers. Safari/OSX shows localized numbers with group
118 // separaters. For example, "1,920x1,080". 126 // separaters. For example, "1,920x1,080".
119 result.appendNumber(size.width()); 127 result.appendNumber(size.width());
120 result.append(static_cast<UChar>(0xD7)); // U+00D7 (multiplication sign) 128 result.append(static_cast<UChar>(0xD7)); // U+00D7 (multiplication sign)
121 result.appendNumber(size.height()); 129 result.appendNumber(size.height());
122 result.append(')'); 130 result.append(')');
123 return result.toString(); 131 return result.toString();
124 } 132 }
125 133
134 static LayoutSize cachedImageSize(HTMLImageElement* element) {
135 DCHECK(element->cachedImage());
136 return element->cachedImage()->imageSize(
137 LayoutObject::shouldRespectImageOrientation(element->layoutObject()),
138 1.0f);
139 }
140
126 void ImageDocumentParser::appendBytes(const char* data, size_t length) { 141 void ImageDocumentParser::appendBytes(const char* data, size_t length) {
127 if (!length) 142 if (!length)
128 return; 143 return;
129 144
130 LocalFrame* frame = document()->frame(); 145 LocalFrame* frame = document()->frame();
131 Settings* settings = frame->settings(); 146 Settings* settings = frame->settings();
132 if (!frame->loader().client()->allowImage( 147 if (!frame->loader().client()->allowImage(
133 !settings || settings->imagesEnabled(), document()->url())) 148 !settings || settings->imagesEnabled(), document()->url()))
134 return; 149 return;
135 150
(...skipping 12 matching lines...) Expand all
148 void ImageDocumentParser::finish() { 163 void ImageDocumentParser::finish() {
149 if (!isStopped() && document()->imageElement() && document()->cachedImage()) { 164 if (!isStopped() && document()->imageElement() && document()->cachedImage()) {
150 ImageResource* cachedImage = document()->cachedImage(); 165 ImageResource* cachedImage = document()->cachedImage();
151 DocumentLoader* loader = document()->loader(); 166 DocumentLoader* loader = document()->loader();
152 cachedImage->setResponse(loader->response()); 167 cachedImage->setResponse(loader->response());
153 cachedImage->finish(loader->timing().responseEnd()); 168 cachedImage->finish(loader->timing().responseEnd());
154 169
155 // Report the natural image size in the page title, regardless of zoom 170 // Report the natural image size in the page title, regardless of zoom
156 // level. At a zoom level of 1 the image is guaranteed to have an integer 171 // level. At a zoom level of 1 the image is guaranteed to have an integer
157 // size. 172 // size.
158 IntSize size = flooredIntSize( 173 IntSize size = flooredIntSize(cachedImageSize(document()->imageElement()));
159 cachedImage->imageSize(LayoutObject::shouldRespectImageOrientation(
160 document()->imageElement()->layoutObject()),
161 1.0f));
162 if (size.width()) { 174 if (size.width()) {
163 // Compute the title, we use the decoded filename of the resource, falling 175 // Compute the title, we use the decoded filename of the resource, falling
164 // back on the (decoded) hostname if there is no path. 176 // back on the (decoded) hostname if there is no path.
165 String fileName = 177 String fileName =
166 decodeURLEscapeSequences(document()->url().lastPathComponent()); 178 decodeURLEscapeSequences(document()->url().lastPathComponent());
167 if (fileName.isEmpty()) 179 if (fileName.isEmpty())
168 fileName = document()->url().host(); 180 fileName = document()->url().host();
169 document()->setTitle(imageTitle(fileName, size)); 181 document()->setTitle(imageTitle(fileName, size));
170 if (isDetached()) 182 if (isDetached())
171 return; 183 return;
172 } 184 }
173 185
174 document()->imageUpdated(); 186 document()->imageUpdated();
187 document()->imageLoaded();
175 } 188 }
176 189
177 if (!isDetached()) 190 if (!isDetached())
178 document()->finishedParsing(); 191 document()->finishedParsing();
179 } 192 }
180 193
181 // -------- 194 // --------
182 195
183 ImageDocument::ImageDocument(const DocumentInit& initializer) 196 ImageDocument::ImageDocument(const DocumentInit& initializer)
184 : HTMLDocument(initializer, ImageDocumentClass), 197 : HTMLDocument(initializer, ImageDocumentClass),
185 m_divElement(nullptr), 198 m_divElement(nullptr),
186 m_imageElement(nullptr), 199 m_imageElement(nullptr),
187 m_imageSizeIsKnown(false), 200 m_imageSizeIsKnown(false),
188 m_didShrinkImage(false), 201 m_didShrinkImage(false),
189 m_shouldShrinkImage(shouldShrinkToFit()), 202 m_shouldShrinkImage(shouldShrinkToFit()),
203 m_imageIsLoaded(false),
204 m_checkerSize(gBaseCheckerSize),
190 m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport 205 m_shrinkToFitMode(frame()->settings()->viewportEnabled() ? Viewport
191 : Desktop) { 206 : Desktop) {
192 setCompatibilityMode(QuirksMode); 207 setCompatibilityMode(QuirksMode);
193 lockCompatibilityMode(); 208 lockCompatibilityMode();
194 UseCounter::count(*this, UseCounter::ImageDocument); 209 UseCounter::count(*this, UseCounter::ImageDocument);
195 if (!isInMainFrame()) 210 if (!isInMainFrame())
196 UseCounter::count(*this, UseCounter::ImageDocumentInFrame); 211 UseCounter::count(*this, UseCounter::ImageDocumentInFrame);
197 } 212 }
198 213
199 DocumentParser* ImageDocument::createParser() { 214 DocumentParser* ImageDocument::createParser() {
(...skipping 11 matching lines...) Expand all
211 HTMLHeadElement* head = HTMLHeadElement::create(*this); 226 HTMLHeadElement* head = HTMLHeadElement::create(*this);
212 HTMLMetaElement* meta = HTMLMetaElement::create(*this); 227 HTMLMetaElement* meta = HTMLMetaElement::create(*this);
213 meta->setAttribute(nameAttr, "viewport"); 228 meta->setAttribute(nameAttr, "viewport");
214 meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1"); 229 meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1");
215 head->appendChild(meta); 230 head->appendChild(meta);
216 231
217 HTMLBodyElement* body = HTMLBodyElement::create(*this); 232 HTMLBodyElement* body = HTMLBodyElement::create(*this);
218 233
219 if (shouldShrinkToFit()) { 234 if (shouldShrinkToFit()) {
220 // Display the image prominently centered in the frame. 235 // Display the image prominently centered in the frame.
221 body->setAttribute(styleAttr, "margin: 0px;"); 236 body->setAttribute(styleAttr, "margin: 0px; background: #0e0e0e;");
222 237
223 // See w3c example on how to centering an element: 238 // See w3c example on how to center an element:
224 // https://www.w3.org/Style/Examples/007/center.en.html 239 // https://www.w3.org/Style/Examples/007/center.en.html
225 m_divElement = HTMLDivElement::create(*this); 240 m_divElement = HTMLDivElement::create(*this);
226 m_divElement->setAttribute(styleAttr, 241 m_divElement->setAttribute(styleAttr,
227 "display: flex;" 242 "display: flex;"
228 "flex-direction: column;" 243 "flex-direction: column;"
229 "justify-content: center;" 244 "justify-content: center;"
230 "align-items: center;" 245 "align-items: center;"
231 "min-height: min-content;" 246 "min-height: min-content;"
232 "min-width: min-content;" 247 "min-width: min-content;"
233 "height: 100%;" 248 "height: 100%;"
234 "width: 100%;"); 249 "width: 100%;");
235 HTMLContentElement* content = HTMLContentElement::create(*this); 250 HTMLContentElement* content = HTMLContentElement::create(*this);
236 m_divElement->appendChild(content); 251 m_divElement->appendChild(content);
237 252
238 ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot(); 253 ShadowRoot& shadowRoot = body->ensureUserAgentShadowRoot();
239 shadowRoot.appendChild(m_divElement); 254 shadowRoot.appendChild(m_divElement);
240 } else { 255 } else {
241 body->setAttribute(styleAttr, "margin: 0px;"); 256 body->setAttribute(styleAttr, "margin: 0px;");
242 } 257 }
243 258
244 willInsertBody(); 259 willInsertBody();
245 260
246 StringBuilder imageStyle;
247 imageStyle.append("-webkit-user-select: none;");
248 if (shouldShrinkToFit() && m_shrinkToFitMode == Viewport)
249 imageStyle.append("max-width: 100%");
250 m_imageElement = HTMLImageElement::create(*this); 261 m_imageElement = HTMLImageElement::create(*this);
251 m_imageElement->setAttribute(styleAttr, imageStyle.toAtomicString()); 262 updateImageStyle();
252 m_imageElement->setLoadingImageDocument(); 263 m_imageElement->setLoadingImageDocument();
253 m_imageElement->setSrc(url().getString()); 264 m_imageElement->setSrc(url().getString());
254 body->appendChild(m_imageElement.get()); 265 body->appendChild(m_imageElement.get());
255 if (loader() && m_imageElement->cachedImage()) 266 if (loader() && m_imageElement->cachedImage())
256 m_imageElement->cachedImage()->responseReceived(loader()->response(), 267 m_imageElement->cachedImage()->responseReceived(loader()->response(),
257 nullptr); 268 nullptr);
258 269
259 if (shouldShrinkToFit()) { 270 if (shouldShrinkToFit()) {
260 // Add event listeners 271 // Add event listeners
261 EventListener* listener = ImageEventListener::create(this); 272 EventListener* listener = ImageEventListener::create(this);
262 if (LocalDOMWindow* domWindow = this->domWindow()) 273 if (LocalDOMWindow* domWindow = this->domWindow())
263 domWindow->addEventListener("resize", listener, false); 274 domWindow->addEventListener(EventTypeNames::resize, listener, false);
264 if (m_shrinkToFitMode == Desktop) 275
265 m_imageElement->addEventListener("click", listener, false); 276 if (m_shrinkToFitMode == Desktop) {
277 m_imageElement->addEventListener(EventTypeNames::click, listener, false);
278 } else if (m_shrinkToFitMode == Viewport) {
279 m_imageElement->addEventListener(EventTypeNames::touchend, listener,
280 false);
281 m_imageElement->addEventListener(EventTypeNames::touchcancel, listener,
282 false);
283 }
266 } 284 }
267 285
268 rootElement->appendChild(head); 286 rootElement->appendChild(head);
269 rootElement->appendChild(body); 287 rootElement->appendChild(body);
270 } 288 }
271 289
272 float ImageDocument::scale() const { 290 float ImageDocument::scale() const {
273 DCHECK_EQ(m_shrinkToFitMode, Desktop); 291 DCHECK_EQ(m_shrinkToFitMode, Desktop);
274 if (!m_imageElement || m_imageElement->document() != this) 292 if (!m_imageElement || m_imageElement->document() != this)
275 return 1.0f; 293 return 1.0f;
(...skipping 18 matching lines...) Expand all
294 view->height() * manualZoom / imageSize.height().toFloat(); 312 view->height() * manualZoom / imageSize.height().toFloat();
295 313
296 return min(widthScale, heightScale); 314 return min(widthScale, heightScale);
297 } 315 }
298 316
299 void ImageDocument::resizeImageToFit() { 317 void ImageDocument::resizeImageToFit() {
300 DCHECK_EQ(m_shrinkToFitMode, Desktop); 318 DCHECK_EQ(m_shrinkToFitMode, Desktop);
301 if (!m_imageElement || m_imageElement->document() != this) 319 if (!m_imageElement || m_imageElement->document() != this)
302 return; 320 return;
303 321
304 DCHECK(m_imageElement->cachedImage()); 322 LayoutSize imageSize = cachedImageSize(m_imageElement);
305 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(
306 LayoutObject::shouldRespectImageOrientation(
307 m_imageElement->layoutObject()),
308 1.f);
309 323
310 const float scale = this->scale(); 324 const float scale = this->scale();
311 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); 325 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
312 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); 326 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
313 327
314 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn); 328 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
315 } 329 }
316 330
317 void ImageDocument::imageClicked(int x, int y) { 331 void ImageDocument::imageClicked(int x, int y) {
318 DCHECK_EQ(m_shrinkToFitMode, Desktop); 332 DCHECK_EQ(m_shrinkToFitMode, Desktop);
(...skipping 20 matching lines...) Expand all
339 float scrollX = 353 float scrollX =
340 imageX / scale - static_cast<float>(frame()->view()->width()) / 2; 354 imageX / scale - static_cast<float>(frame()->view()->width()) / 2;
341 float scrollY = 355 float scrollY =
342 imageY / scale - static_cast<float>(frame()->view()->height()) / 2; 356 imageY / scale - static_cast<float>(frame()->view()->height()) / 2;
343 357
344 frame()->view()->layoutViewportScrollableArea()->setScrollOffset( 358 frame()->view()->layoutViewportScrollableArea()->setScrollOffset(
345 ScrollOffset(scrollX, scrollY), ProgrammaticScroll); 359 ScrollOffset(scrollX, scrollY), ProgrammaticScroll);
346 } 360 }
347 } 361 }
348 362
363 void ImageDocument::imageLoaded() {
364 if (!shouldShrinkToFit())
365 return;
366
367 int checkerSize = gBaseCheckerSize;
368 if (m_shrinkToFitMode == Viewport) {
369 int viewportWidth = frame()->host()->visualViewport().size().width();
370 checkerSize = static_cast<int>(gBaseCheckerSize *
371 (double)calculateDivWidth() / viewportWidth);
372 }
373 m_checkerSize = checkerSize;
374
375 m_imageIsLoaded = true;
376 updateImageStyle();
377 }
378
379 void ImageDocument::updateImageStyle() {
380 StringBuilder imageStyle;
381 imageStyle.append("-webkit-user-select: none;");
382 if (shouldShrinkToFit()) {
383 if (m_shrinkToFitMode == Viewport) {
384 imageStyle.append("max-width: 100%;");
385 }
386
387 // Once the image has fully loaded, it is displayed atop a checkerboard to
388 // show transparency more faithfully. The pattern is generated via CSS.
389 if (m_imageIsLoaded) {
390 if (m_shrinkToFitMode == Viewport && hasFinishedParsing()) {
391 double newCheckerSize = gBaseCheckerSize;
pdr. 2016/11/02 22:54:49 I think your new approach here is reasonable.
392 if (m_shrinkToFitMode == Viewport) {
393 // To ensure the checker pattern is visible for large images in
394 // viewports, the checker size is dynamically adjusted to account for
395 // how much the page is currently being scaled.
396 double scale = frame()->host()->visualViewport().scale();
397 newCheckerSize = std::max(1.0, newCheckerSize / scale);
398 }
399
400 m_checkerSize = static_cast<int>(round(newCheckerSize));
pdr. 2016/11/02 22:54:49 Nit: just "m_checkerSize = round(newCheckerSize);"
gone 2016/11/03 01:28:41 Done.
401 }
402
403 imageStyle.append("background-position: 0px 0px, ");
404 imageStyle.append(AtomicString::number(m_checkerSize));
405 imageStyle.append("px ");
406 imageStyle.append(AtomicString::number(m_checkerSize));
407 imageStyle.append("px;");
408
409 int tileSize = m_checkerSize * 2;
410 imageStyle.append("background-size: ");
411 imageStyle.append(AtomicString::number(tileSize));
412 imageStyle.append("px ");
413 imageStyle.append(AtomicString::number(tileSize));
414 imageStyle.append("px;");
415
416 imageStyle.append(
417 "background-color: white;"
418 "background-image:"
419 "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, "
420 "#eee 75%, #eee 100%),"
421 "linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, "
422 "#eee 75%, #eee 100%);");
423 }
424 }
425
426 if (m_imageElement->getAttribute(styleAttr) != imageStyle.toAtomicString())
pdr. 2016/11/02 22:54:49 This large string comparison is kinda unfortunate.
gone 2016/11/03 01:28:41 After figuring out how to avoid the string compari
427 m_imageElement->setAttribute(styleAttr, imageStyle.toAtomicString());
428 }
429
349 void ImageDocument::imageUpdated() { 430 void ImageDocument::imageUpdated() {
350 DCHECK(m_imageElement); 431 DCHECK(m_imageElement);
351 432
352 if (m_imageSizeIsKnown) 433 if (m_imageSizeIsKnown)
353 return; 434 return;
354 435
355 updateStyleAndLayoutTree(); 436 updateStyleAndLayoutTree();
356 if (!m_imageElement->cachedImage() || 437 if (!m_imageElement->cachedImage() ||
357 m_imageElement->cachedImage() 438 m_imageElement->cachedImage()
358 ->imageSize(LayoutObject::shouldRespectImageOrientation( 439 ->imageSize(LayoutObject::shouldRespectImageOrientation(
(...skipping 11 matching lines...) Expand all
370 } 451 }
371 452
372 void ImageDocument::restoreImageSize() { 453 void ImageDocument::restoreImageSize() {
373 DCHECK_EQ(m_shrinkToFitMode, Desktop); 454 DCHECK_EQ(m_shrinkToFitMode, Desktop);
374 455
375 if (!m_imageElement || !m_imageSizeIsKnown || 456 if (!m_imageElement || !m_imageSizeIsKnown ||
376 m_imageElement->document() != this) 457 m_imageElement->document() != this)
377 return; 458 return;
378 459
379 DCHECK(m_imageElement->cachedImage()); 460 DCHECK(m_imageElement->cachedImage());
380 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize( 461 LayoutSize imageSize = cachedImageSize(m_imageElement);
381 LayoutObject::shouldRespectImageOrientation(
382 m_imageElement->layoutObject()),
383 1.0f);
384 m_imageElement->setWidth(imageSize.width().toInt()); 462 m_imageElement->setWidth(imageSize.width().toInt());
385 m_imageElement->setHeight(imageSize.height().toInt()); 463 m_imageElement->setHeight(imageSize.height().toInt());
386 464
387 if (imageFitsInWindow()) 465 if (imageFitsInWindow())
388 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); 466 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
389 else 467 else
390 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut); 468 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
391 469
392 m_didShrinkImage = false; 470 m_didShrinkImage = false;
393 } 471 }
394 472
395 bool ImageDocument::imageFitsInWindow() const { 473 bool ImageDocument::imageFitsInWindow() const {
396 DCHECK_EQ(m_shrinkToFitMode, Desktop); 474 DCHECK_EQ(m_shrinkToFitMode, Desktop);
397 return this->scale() >= 1; 475 return this->scale() >= 1;
398 } 476 }
399 477
478 int ImageDocument::calculateDivWidth() {
479 // Zooming in and out of an image being displayed within a viewport is done
480 // by changing the page scale factor of the page instead of changing the
481 // size of the image. The size of the image is set so that:
482 // * Images wider than the viewport take the full width of the screen.
483 // * Images taller than the viewport are initially aligned with the top of
484 // of the frame.
485 // * Images smaller in either dimension are centered along that axis.
486 LayoutSize imageSize = cachedImageSize(m_imageElement);
487 int viewportWidth = frame()->host()->visualViewport().size().width();
488
489 // For huge images, minimum-scale=0.1 is still too big on small screens.
490 // Set the <div> width so that the image will shrink to fit the width of the
491 // screen when the scale is minimum.
492 int maxWidth = std::min(imageSize.width().toInt(), viewportWidth * 10);
493 return std::max(viewportWidth, maxWidth);
494 }
495
400 void ImageDocument::windowSizeChanged() { 496 void ImageDocument::windowSizeChanged() {
401 if (!m_imageElement || !m_imageSizeIsKnown || 497 if (!m_imageElement || !m_imageSizeIsKnown ||
402 m_imageElement->document() != this) 498 m_imageElement->document() != this)
403 return; 499 return;
404 500
405 if (m_shrinkToFitMode == Viewport) { 501 if (m_shrinkToFitMode == Viewport) {
406 // Zooming in and out of an image being displayed within a viewport is done 502 LayoutSize imageSize = cachedImageSize(m_imageElement);
407 // by changing the page scale factor of the page instead of changing the 503 int divWidth = calculateDivWidth();
408 // size of the image. The size of the image is set so that:
409 // * Images wider than the viewport take the full width of the screen.
410 // * Images taller than the viewport are initially aligned with the top of
411 // of the frame.
412 // * Images smaller in either dimension are centered along that axis.
413 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(
414 LayoutObject::shouldRespectImageOrientation(
415 m_imageElement->layoutObject()),
416 1.f);
417 int viewportWidth = frame()->host()->visualViewport().size().width();
418 int viewportHeight = frame()->host()->visualViewport().size().height();
419 float viewportAspectRatio = (float)viewportWidth / viewportHeight;
420
421 // For huge images, minimum-scale=0.1 is still too big on small screens.
422 // Set the <div> width so that the image will shrink to fit the width of the
423 // screen when the scale is minimum.
424 int maxWidth = std::min(imageSize.width().toInt(), viewportWidth * 10);
425 int divWidth = std::max(viewportWidth, maxWidth);
426 m_divElement->setInlineStyleProperty(CSSPropertyWidth, divWidth, 504 m_divElement->setInlineStyleProperty(CSSPropertyWidth, divWidth,
427 CSSPrimitiveValue::UnitType::Pixels); 505 CSSPrimitiveValue::UnitType::Pixels);
428 506
429 // Explicitly set the height of the <div> containing the <img> so that it 507 // Explicitly set the height of the <div> containing the <img> so that it
430 // can display the full image without shrinking it, allowing a full-width 508 // can display the full image without shrinking it, allowing a full-width
431 // reading mode for normal-width-huge-height images. 509 // reading mode for normal-width-huge-height images.
510 int viewportWidth = frame()->host()->visualViewport().size().width();
511 int viewportHeight = frame()->host()->visualViewport().size().height();
512 float viewportAspectRatio = (float)viewportWidth / viewportHeight;
pdr. 2016/11/02 22:54:49 Super nit: float viewportAspectRatio = frame()->ho
gone 2016/11/03 01:28:41 Done.
432 int divHeight = std::max(imageSize.height().toInt(), 513 int divHeight = std::max(imageSize.height().toInt(),
433 (int)(divWidth / viewportAspectRatio)); 514 static_cast<int>(divWidth / viewportAspectRatio));
434 m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight, 515 m_divElement->setInlineStyleProperty(CSSPropertyHeight, divHeight,
435 CSSPrimitiveValue::UnitType::Pixels); 516 CSSPrimitiveValue::UnitType::Pixels);
436 return; 517 return;
437 } 518 }
438 519
439 bool fitsInWindow = imageFitsInWindow(); 520 bool fitsInWindow = imageFitsInWindow();
440 521
441 // If the image has been explicitly zoomed in, restore the cursor if the image 522 // If the image has been explicitly zoomed in, restore the cursor if the image
442 // fits and set it to a zoom out cursor if the image doesn't fit 523 // fits and set it to a zoom out cursor if the image doesn't fit
443 if (!m_shouldShrinkImage) { 524 if (!m_shouldShrinkImage) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } 569 }
489 570
490 // -------- 571 // --------
491 572
492 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) { 573 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) {
493 if (event->type() == EventTypeNames::resize) { 574 if (event->type() == EventTypeNames::resize) {
494 m_doc->windowSizeChanged(); 575 m_doc->windowSizeChanged();
495 } else if (event->type() == EventTypeNames::click && event->isMouseEvent()) { 576 } else if (event->type() == EventTypeNames::click && event->isMouseEvent()) {
496 MouseEvent* mouseEvent = toMouseEvent(event); 577 MouseEvent* mouseEvent = toMouseEvent(event);
497 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y()); 578 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
579 } else if ((event->type() == EventTypeNames::touchend ||
580 event->type() == EventTypeNames::touchcancel) &&
581 event->isTouchEvent()) {
582 m_doc->updateImageStyle();
498 } 583 }
499 } 584 }
500 585
501 bool ImageEventListener::operator==(const EventListener& listener) const { 586 bool ImageEventListener::operator==(const EventListener& listener) const {
502 if (const ImageEventListener* imageEventListener = 587 if (const ImageEventListener* imageEventListener =
503 ImageEventListener::cast(&listener)) 588 ImageEventListener::cast(&listener))
504 return m_doc == imageEventListener->m_doc; 589 return m_doc == imageEventListener->m_doc;
505 return false; 590 return false;
506 } 591 }
507 592
508 } // namespace blink 593 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageDocument.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698