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

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

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