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

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

Issue 2358913004: Change image document zooming logic. (Closed)
Patch Set: Created 4 years, 2 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageDocument.h ('k') | third_party/WebKit/Source/core/html/ImageDocumentTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698