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

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

Issue 2319863006: Change image document zooming logic. (Closed)
Patch Set: add tests Created 4 years, 3 months 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
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 28 matching lines...) Expand all
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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 rootElement->appendChild(body); 246 rootElement->appendChild(body);
246 } 247 }
247 248
248 float ImageDocument::scale() const 249 float ImageDocument::scale() const
249 { 250 {
250 if (!m_imageElement || m_imageElement->document() != this) 251 if (!m_imageElement || m_imageElement->document() != this)
251 return 1.0f; 252 return 1.0f;
252 253
253 FrameView* view = frame()->view(); 254 FrameView* view = frame()->view();
254 if (!view) 255 if (!view)
255 return 1; 256 return 1;
brucedawson 2016/09/15 23:21:21 Would be nice to change this to return 1.0f, and m
Bret 2016/09/16 00:21:41 Done. Added the comment to the header file.
256 257
257 DCHECK(m_imageElement->cachedImage()); 258 DCHECK(m_imageElement->cachedImage());
258 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject ::shouldRespectImageOrientation(m_imageElement->layoutObject()), pageZoomFactor( this)); 259 const float zoom = pageZoomFactor(this);
259 LayoutSize windowSize = LayoutSize(view->width(), view->height()); 260 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject ::shouldRespectImageOrientation(m_imageElement->layoutObject()), zoom);
260 261
261 float widthScale = windowSize.width().toFloat() / imageSize.width().toFloat( ); 262 // We want to pretend the viewport is larger when the user has zoomed the
262 float heightScale = windowSize.height().toFloat() / imageSize.height().toFlo at(); 263 // page in (but not when the zoom is coming from device scale).
264 const float manualZoom = zoom / view->getHostWindow()->windowToViewportScala r(1.f);
265 float widthScale = view->width() * manualZoom / imageSize.width().toFloat();
266 float heightScale = view->height() * manualZoom / imageSize.height().toFloat ();
263 267
264 return min(widthScale, heightScale); 268 return min(widthScale, heightScale);
265 } 269 }
266 270
267 void ImageDocument::resizeImageToFit(ScaleType type) 271 void ImageDocument::resizeImageToFit()
268 { 272 {
269 if (!m_imageElement || m_imageElement->document() != this || (pageZoomFactor (this) > 1 && type == ScaleOnlyUnzoomedDocument)) 273 if (!m_imageElement || m_imageElement->document() != this)
270 return; 274 return;
271 275
272 DCHECK(m_imageElement->cachedImage()); 276 DCHECK(m_imageElement->cachedImage());
273 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);
274 278
275 float scale = this->scale(); 279 const float scale = this->scale();
276 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale)); 280 m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
277 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale)); 281 m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
278 282
279 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn); 283 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
280 } 284 }
281 285
282 void ImageDocument::imageClicked(int x, int y) 286 void ImageDocument::imageClicked(int x, int y)
283 { 287 {
284 DCHECK_EQ(m_shrinkToFitMode, Desktop); 288 DCHECK_EQ(m_shrinkToFitMode, Desktop);
285 289
286 if (!m_imageSizeIsKnown || imageFitsInWindow()) 290 if (!m_imageSizeIsKnown || imageFitsInWindow())
287 return; 291 return;
288 292
289 m_shouldShrinkImage = !m_shouldShrinkImage; 293 m_shouldShrinkImage = !m_shouldShrinkImage;
290 294
291 if (m_shouldShrinkImage) { 295 if (m_shouldShrinkImage) {
292 windowSizeChanged(ScaleZoomedDocument); 296 windowSizeChanged();
293 } else { 297 } else {
294 restoreImageSize(ScaleZoomedDocument); 298 restoreImageSize();
295 299
296 updateStyleAndLayout(); 300 updateStyleAndLayout();
297 301
298 double scale = this->scale(); 302 double scale = this->scale();
299 303
300 double scrollX = x / scale - static_cast<double>(frame()->view()->width( )) / 2; 304 double scrollX = x / scale - static_cast<double>(frame()->view()->width( )) / 2;
301 double scrollY = y / scale - static_cast<double>(frame()->view()->height ()) / 2; 305 double scrollY = y / scale - static_cast<double>(frame()->view()->height ()) / 2;
302 306
303 frame()->view()->setScrollPosition(DoublePoint(scrollX, scrollY), Progra mmaticScroll); 307 frame()->view()->setScrollPosition(DoublePoint(scrollX, scrollY), Progra mmaticScroll);
304 } 308 }
305 } 309 }
306 310
307 void ImageDocument::imageUpdated() 311 void ImageDocument::imageUpdated()
308 { 312 {
309 DCHECK(m_imageElement); 313 DCHECK(m_imageElement);
310 314
311 if (m_imageSizeIsKnown) 315 if (m_imageSizeIsKnown)
312 return; 316 return;
313 317
314 updateStyleAndLayoutTree(); 318 updateStyleAndLayoutTree();
315 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())
316 return; 320 return;
317 321
318 m_imageSizeIsKnown = true; 322 m_imageSizeIsKnown = true;
319 323
320 if (shouldShrinkToFit()) { 324 if (shouldShrinkToFit()) {
321 // Force resizing of the image 325 // Force resizing of the image
322 windowSizeChanged(ScaleOnlyUnzoomedDocument); 326 windowSizeChanged();
323 } 327 }
324 } 328 }
325 329
326 void ImageDocument::restoreImageSize(ScaleType type) 330 void ImageDocument::restoreImageSize()
327 { 331 {
328 DCHECK_EQ(m_shrinkToFitMode, Desktop); 332 DCHECK_EQ(m_shrinkToFitMode, Desktop);
329 333
330 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this || (pageZoomFactor(this) < 1 && type == ScaleOnlyUnzoomedDocument)) 334 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this)
331 return; 335 return;
332 336
333 DCHECK(m_imageElement->cachedImage()); 337 DCHECK(m_imageElement->cachedImage());
334 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);
335 m_imageElement->setWidth(imageSize.width().toInt()); 339 m_imageElement->setWidth(imageSize.width().toInt());
336 m_imageElement->setHeight(imageSize.height().toInt()); 340 m_imageElement->setHeight(imageSize.height().toInt());
337 341
338 if (imageFitsInWindow()) 342 if (imageFitsInWindow())
339 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); 343 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
340 else 344 else
341 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOu t); 345 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOu t);
342 346
343 m_didShrinkImage = false; 347 m_didShrinkImage = false;
344 } 348 }
345 349
346 bool ImageDocument::imageFitsInWindow() const 350 bool ImageDocument::imageFitsInWindow() const
347 { 351 {
348 DCHECK_EQ(m_shrinkToFitMode, Desktop); 352 DCHECK_EQ(m_shrinkToFitMode, Desktop);
349 353 return this->scale() >= 1;
350 if (!m_imageElement || m_imageElement->document() != this)
351 return true;
352
353 FrameView* view = frame()->view();
354 if (!view)
355 return true;
356
357 DCHECK(m_imageElement->cachedImage());
358 LayoutSize imageSize = m_imageElement->cachedImage()->imageSize(LayoutObject ::shouldRespectImageOrientation(m_imageElement->layoutObject()), pageZoomFactor( this));
359 LayoutSize windowSize = LayoutSize(view->width(), view->height());
360
361 return imageSize.width() <= windowSize.width() && imageSize.height() <= wind owSize.height();
362 } 354 }
363 355
364 void ImageDocument::windowSizeChanged(ScaleType type) 356 void ImageDocument::windowSizeChanged()
365 { 357 {
366 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this) 358 if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this)
367 return; 359 return;
368 360
369 if (m_shrinkToFitMode == Viewport) { 361 if (m_shrinkToFitMode == Viewport) {
370 // 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.
371 // 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
372 // the scale is minimum. 364 // the scale is minimum.
373 // 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,
374 // 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
386 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor); 378 m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
387 else 379 else
388 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZo omOut); 380 m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZo omOut);
389 return; 381 return;
390 } 382 }
391 383
392 if (m_didShrinkImage) { 384 if (m_didShrinkImage) {
393 // 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
394 // otherwise update the restored image size. 386 // otherwise update the restored image size.
395 if (fitsInWindow) 387 if (fitsInWindow)
396 restoreImageSize(type); 388 restoreImageSize();
397 else 389 else
398 resizeImageToFit(type); 390 resizeImageToFit();
399 } else { 391 } else {
400 // 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.
401 if (!fitsInWindow) { 393 if (!fitsInWindow) {
402 resizeImageToFit(type); 394 resizeImageToFit();
403 m_didShrinkImage = true; 395 m_didShrinkImage = true;
404 } 396 }
405 } 397 }
406 } 398 }
407 399
408 ImageResource* ImageDocument::cachedImage() 400 ImageResource* ImageDocument::cachedImage()
409 { 401 {
410 if (!m_imageElement) { 402 if (!m_imageElement) {
411 createDocumentStructure(); 403 createDocumentStructure();
412 if (isStopped()) { 404 if (isStopped()) {
(...skipping 14 matching lines...) Expand all
427 { 419 {
428 visitor->trace(m_imageElement); 420 visitor->trace(m_imageElement);
429 HTMLDocument::trace(visitor); 421 HTMLDocument::trace(visitor);
430 } 422 }
431 423
432 // -------- 424 // --------
433 425
434 void ImageEventListener::handleEvent(ExecutionContext*, Event* event) 426 void ImageEventListener::handleEvent(ExecutionContext*, Event* event)
435 { 427 {
436 if (event->type() == EventTypeNames::resize) { 428 if (event->type() == EventTypeNames::resize) {
437 m_doc->windowSizeChanged(ImageDocument::ScaleOnlyUnzoomedDocument); 429 m_doc->windowSizeChanged();
438 } else if (event->type() == EventTypeNames::click && event->isMouseEvent()) { 430 } else if (event->type() == EventTypeNames::click && event->isMouseEvent()) {
439 MouseEvent* mouseEvent = toMouseEvent(event); 431 MouseEvent* mouseEvent = toMouseEvent(event);
440 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y()); 432 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
441 } 433 }
442 } 434 }
443 435
444 bool ImageEventListener::operator==(const EventListener& listener) const 436 bool ImageEventListener::operator==(const EventListener& listener) const
445 { 437 {
446 if (const ImageEventListener* imageEventListener = ImageEventListener::cast( &listener)) 438 if (const ImageEventListener* imageEventListener = ImageEventListener::cast( &listener))
447 return m_doc == imageEventListener->m_doc; 439 return m_doc == imageEventListener->m_doc;
448 return false; 440 return false;
449 } 441 }
450 442
451 } // namespace blink 443 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698