| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> | 2 * Copyright (C) 2006 Eric Seidel <eric@webkit.org> |
| 3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. |
| 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 #include "third_party/skia/include/core/SkPicture.h" | 59 #include "third_party/skia/include/core/SkPicture.h" |
| 60 #include "wtf/PassRefPtr.h" | 60 #include "wtf/PassRefPtr.h" |
| 61 | 61 |
| 62 namespace blink { | 62 namespace blink { |
| 63 | 63 |
| 64 SVGImage::SVGImage(ImageObserver* observer) | 64 SVGImage::SVGImage(ImageObserver* observer) |
| 65 : Image(observer), m_hasPendingTimelineRewind(false) {} | 65 : Image(observer), m_hasPendingTimelineRewind(false) {} |
| 66 | 66 |
| 67 SVGImage::~SVGImage() { | 67 SVGImage::~SVGImage() { |
| 68 if (m_page) { | 68 if (m_page) { |
| 69 // Store m_page in a local variable, clearing m_page, so that SVGImageChrome
Client knows we're destructed. | 69 // Store m_page in a local variable, clearing m_page, so that |
| 70 // SVGImageChromeClient knows we're destructed. |
| 70 Page* currentPage = m_page.release(); | 71 Page* currentPage = m_page.release(); |
| 71 // Break both the loader and view references to the frame | 72 // Break both the loader and view references to the frame |
| 72 currentPage->willBeDestroyed(); | 73 currentPage->willBeDestroyed(); |
| 73 } | 74 } |
| 74 | 75 |
| 75 // Verify that page teardown destroyed the Chrome | 76 // Verify that page teardown destroyed the Chrome |
| 76 ASSERT(!m_chromeClient || !m_chromeClient->image()); | 77 ASSERT(!m_chromeClient || !m_chromeClient->image()); |
| 77 } | 78 } |
| 78 | 79 |
| 79 bool SVGImage::isInSVGImage(const Node* node) { | 80 bool SVGImage::isInSVGImage(const Node* node) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 LayoutReplaced::IntrinsicSizingInfo intrinsicSizingInfo; | 174 LayoutReplaced::IntrinsicSizingInfo intrinsicSizingInfo; |
| 174 layoutObject->computeIntrinsicSizingInfo(intrinsicSizingInfo); | 175 layoutObject->computeIntrinsicSizingInfo(intrinsicSizingInfo); |
| 175 | 176 |
| 176 // https://www.w3.org/TR/css3-images/#default-sizing | 177 // https://www.w3.org/TR/css3-images/#default-sizing |
| 177 | 178 |
| 178 if (intrinsicSizingInfo.hasWidth && intrinsicSizingInfo.hasHeight) | 179 if (intrinsicSizingInfo.hasWidth && intrinsicSizingInfo.hasHeight) |
| 179 return intrinsicSizingInfo.size; | 180 return intrinsicSizingInfo.size; |
| 180 | 181 |
| 181 if (svg->preserveAspectRatio()->currentValue()->align() == | 182 if (svg->preserveAspectRatio()->currentValue()->align() == |
| 182 SVGPreserveAspectRatio::kSvgPreserveaspectratioNone) { | 183 SVGPreserveAspectRatio::kSvgPreserveaspectratioNone) { |
| 183 // TODO(davve): The intrinsic aspect ratio is not used to resolve a missing
intrinsic width | 184 // TODO(davve): The intrinsic aspect ratio is not used to resolve a missing |
| 184 // or height when preserveAspectRatio is none. It's unclear whether this is
correct. See | 185 // intrinsic width or height when preserveAspectRatio is none. It's unclear |
| 185 // crbug.com/584172. | 186 // whether this is correct. See crbug.com/584172. |
| 186 return defaultObjectSize; | 187 return defaultObjectSize; |
| 187 } | 188 } |
| 188 | 189 |
| 189 if (intrinsicSizingInfo.hasWidth) { | 190 if (intrinsicSizingInfo.hasWidth) { |
| 190 if (intrinsicSizingInfo.aspectRatio.isEmpty()) | 191 if (intrinsicSizingInfo.aspectRatio.isEmpty()) |
| 191 return FloatSize(intrinsicSizingInfo.size.width(), | 192 return FloatSize(intrinsicSizingInfo.size.width(), |
| 192 defaultObjectSize.height()); | 193 defaultObjectSize.height()); |
| 193 | 194 |
| 194 return FloatSize(intrinsicSizingInfo.size.width(), | 195 return FloatSize(intrinsicSizingInfo.size.width(), |
| 195 resolveHeightForRatio(intrinsicSizingInfo.size.width(), | 196 resolveHeightForRatio(intrinsicSizingInfo.size.width(), |
| 196 intrinsicSizingInfo.aspectRatio)); | 197 intrinsicSizingInfo.aspectRatio)); |
| 197 } | 198 } |
| 198 | 199 |
| 199 if (intrinsicSizingInfo.hasHeight) { | 200 if (intrinsicSizingInfo.hasHeight) { |
| 200 if (intrinsicSizingInfo.aspectRatio.isEmpty()) | 201 if (intrinsicSizingInfo.aspectRatio.isEmpty()) |
| 201 return FloatSize(defaultObjectSize.width(), | 202 return FloatSize(defaultObjectSize.width(), |
| 202 intrinsicSizingInfo.size.height()); | 203 intrinsicSizingInfo.size.height()); |
| 203 | 204 |
| 204 return FloatSize(resolveWidthForRatio(intrinsicSizingInfo.size.height(), | 205 return FloatSize(resolveWidthForRatio(intrinsicSizingInfo.size.height(), |
| 205 intrinsicSizingInfo.aspectRatio), | 206 intrinsicSizingInfo.aspectRatio), |
| 206 intrinsicSizingInfo.size.height()); | 207 intrinsicSizingInfo.size.height()); |
| 207 } | 208 } |
| 208 | 209 |
| 209 if (!intrinsicSizingInfo.aspectRatio.isEmpty()) { | 210 if (!intrinsicSizingInfo.aspectRatio.isEmpty()) { |
| 210 // "A contain constraint is resolved by setting the concrete object size to
the largest | 211 // "A contain constraint is resolved by setting the concrete object size to |
| 211 // rectangle that has the object's intrinsic aspect ratio and additionally
has neither | 212 // the largest rectangle that has the object's intrinsic aspect ratio and |
| 212 // width nor height larger than the constraint rectangle's width and height
, respectively." | 213 // additionally has neither width nor height larger than the constraint |
| 214 // rectangle's width and height, respectively." |
| 213 float solutionWidth = resolveWidthForRatio(defaultObjectSize.height(), | 215 float solutionWidth = resolveWidthForRatio(defaultObjectSize.height(), |
| 214 intrinsicSizingInfo.aspectRatio); | 216 intrinsicSizingInfo.aspectRatio); |
| 215 if (solutionWidth <= defaultObjectSize.width()) | 217 if (solutionWidth <= defaultObjectSize.width()) |
| 216 return FloatSize(solutionWidth, defaultObjectSize.height()); | 218 return FloatSize(solutionWidth, defaultObjectSize.height()); |
| 217 | 219 |
| 218 float solutionHeight = resolveHeightForRatio( | 220 float solutionHeight = resolveHeightForRatio( |
| 219 defaultObjectSize.width(), intrinsicSizingInfo.aspectRatio); | 221 defaultObjectSize.width(), intrinsicSizingInfo.aspectRatio); |
| 220 return FloatSize(defaultObjectSize.width(), solutionHeight); | 222 return FloatSize(defaultObjectSize.width(), solutionHeight); |
| 221 } | 223 } |
| 222 | 224 |
| 223 return defaultObjectSize; | 225 return defaultObjectSize; |
| 224 } | 226 } |
| 225 | 227 |
| 226 void SVGImage::drawForContainer(SkCanvas* canvas, | 228 void SVGImage::drawForContainer(SkCanvas* canvas, |
| 227 const SkPaint& paint, | 229 const SkPaint& paint, |
| 228 const FloatSize containerSize, | 230 const FloatSize containerSize, |
| 229 float zoom, | 231 float zoom, |
| 230 const FloatRect& dstRect, | 232 const FloatRect& dstRect, |
| 231 const FloatRect& srcRect, | 233 const FloatRect& srcRect, |
| 232 const KURL& url) { | 234 const KURL& url) { |
| 233 if (!m_page) | 235 if (!m_page) |
| 234 return; | 236 return; |
| 235 | 237 |
| 236 // Temporarily disable the image observer to prevent changeInRect() calls due
re-laying out the image. | 238 // Temporarily disable the image observer to prevent changeInRect() calls due |
| 239 // re-laying out the image. |
| 237 ImageObserverDisabler imageObserverDisabler(this); | 240 ImageObserverDisabler imageObserverDisabler(this); |
| 238 | 241 |
| 239 IntSize roundedContainerSize = roundedIntSize(containerSize); | 242 IntSize roundedContainerSize = roundedIntSize(containerSize); |
| 240 | 243 |
| 241 if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { | 244 if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { |
| 242 if (LayoutSVGRoot* layoutObject = | 245 if (LayoutSVGRoot* layoutObject = |
| 243 toLayoutSVGRoot(rootElement->layoutObject())) | 246 toLayoutSVGRoot(rootElement->layoutObject())) |
| 244 layoutObject->setContainerSize(roundedContainerSize); | 247 layoutObject->setContainerSize(roundedContainerSize); |
| 245 } | 248 } |
| 246 | 249 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 277 | 280 |
| 278 // Expand the tile to account for repeat spacing. | 281 // Expand the tile to account for repeat spacing. |
| 279 FloatRect spacedTile(tile); | 282 FloatRect spacedTile(tile); |
| 280 spacedTile.expand(FloatSize(repeatSpacing)); | 283 spacedTile.expand(FloatSize(repeatSpacing)); |
| 281 | 284 |
| 282 SkPictureBuilder patternPicture(spacedTile, nullptr, &context); | 285 SkPictureBuilder patternPicture(spacedTile, nullptr, &context); |
| 283 { | 286 { |
| 284 DrawingRecorder patternPictureRecorder( | 287 DrawingRecorder patternPictureRecorder( |
| 285 patternPicture.context(), patternPicture, DisplayItem::Type::kSVGImage, | 288 patternPicture.context(), patternPicture, DisplayItem::Type::kSVGImage, |
| 286 spacedTile); | 289 spacedTile); |
| 287 // When generating an expanded tile, make sure we don't draw into the spacin
g area. | 290 // When generating an expanded tile, make sure we don't draw into the |
| 291 // spacing area. |
| 288 if (tile != spacedTile) | 292 if (tile != spacedTile) |
| 289 patternPicture.context().clip(tile); | 293 patternPicture.context().clip(tile); |
| 290 SkPaint paint; | 294 SkPaint paint; |
| 291 drawForContainer(patternPicture.context().canvas(), paint, containerSize, | 295 drawForContainer(patternPicture.context().canvas(), paint, containerSize, |
| 292 zoom, tile, srcRect, url); | 296 zoom, tile, srcRect, url); |
| 293 } | 297 } |
| 294 sk_sp<SkPicture> tilePicture = patternPicture.endRecording(); | 298 sk_sp<SkPicture> tilePicture = patternPicture.endRecording(); |
| 295 | 299 |
| 296 SkMatrix patternTransform; | 300 SkMatrix patternTransform; |
| 297 patternTransform.setTranslate(phase.x() + spacedTile.x(), | 301 patternTransform.setTranslate(phase.x() + spacedTile.x(), |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 // time=0.) The reason we do this here and not in resetAnimation() is to | 376 // time=0.) The reason we do this here and not in resetAnimation() is to |
| 373 // avoid setting timers from the latter. | 377 // avoid setting timers from the latter. |
| 374 flushPendingTimelineRewind(); | 378 flushPendingTimelineRewind(); |
| 375 | 379 |
| 376 SkPictureBuilder imagePicture(dstRect); | 380 SkPictureBuilder imagePicture(dstRect); |
| 377 { | 381 { |
| 378 ClipRecorder clipRecorder(imagePicture.context(), imagePicture, | 382 ClipRecorder clipRecorder(imagePicture.context(), imagePicture, |
| 379 DisplayItem::kClipNodeImage, | 383 DisplayItem::kClipNodeImage, |
| 380 enclosingIntRect(dstRect)); | 384 enclosingIntRect(dstRect)); |
| 381 | 385 |
| 382 // We can only draw the entire frame, clipped to the rect we want. So comput
e where the top left | 386 // We can only draw the entire frame, clipped to the rect we want. So |
| 383 // of the image would be if we were drawing without clipping, and translate
accordingly. | 387 // compute where the top left of the image would be if we were drawing |
| 388 // without clipping, and translate accordingly. |
| 384 FloatSize scale(dstRect.width() / srcRect.width(), | 389 FloatSize scale(dstRect.width() / srcRect.width(), |
| 385 dstRect.height() / srcRect.height()); | 390 dstRect.height() / srcRect.height()); |
| 386 FloatSize topLeftOffset(srcRect.location().x() * scale.width(), | 391 FloatSize topLeftOffset(srcRect.location().x() * scale.width(), |
| 387 srcRect.location().y() * scale.height()); | 392 srcRect.location().y() * scale.height()); |
| 388 FloatPoint destOffset = dstRect.location() - topLeftOffset; | 393 FloatPoint destOffset = dstRect.location() - topLeftOffset; |
| 389 AffineTransform transform = | 394 AffineTransform transform = |
| 390 AffineTransform::translation(destOffset.x(), destOffset.y()); | 395 AffineTransform::translation(destOffset.x(), destOffset.y()); |
| 391 transform.scale(scale.width(), scale.height()); | 396 transform.scale(scale.width(), scale.height()); |
| 392 TransformRecorder transformRecorder(imagePicture.context(), imagePicture, | 397 TransformRecorder transformRecorder(imagePicture.context(), imagePicture, |
| 393 transform); | 398 transform); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 frame = | 595 frame = |
| 591 LocalFrame::create(&dummyFrameLoaderClient, &page->frameHost(), 0); | 596 LocalFrame::create(&dummyFrameLoaderClient, &page->frameHost(), 0); |
| 592 frame->setView(FrameView::create(frame)); | 597 frame->setView(FrameView::create(frame)); |
| 593 frame->init(); | 598 frame->init(); |
| 594 } | 599 } |
| 595 | 600 |
| 596 FrameLoader& loader = frame->loader(); | 601 FrameLoader& loader = frame->loader(); |
| 597 loader.forceSandboxFlags(SandboxAll); | 602 loader.forceSandboxFlags(SandboxAll); |
| 598 | 603 |
| 599 frame->view()->setScrollbarsSuppressed(true); | 604 frame->view()->setScrollbarsSuppressed(true); |
| 600 frame->view()->setCanHaveScrollbars( | 605 // SVG Images will always synthesize a viewBox, if it's not available, and |
| 601 false); // SVG Images will always synthesize a
viewBox, if it's not available, and thus never see scrollbars. | 606 // thus never see scrollbars. |
| 602 frame->view()->setTransparent(true); // SVG Images are transparent. | 607 frame->view()->setCanHaveScrollbars(false); |
| 608 // SVG Images are transparent. |
| 609 frame->view()->setTransparent(true); |
| 603 | 610 |
| 604 m_page = page; | 611 m_page = page; |
| 605 | 612 |
| 606 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); | 613 TRACE_EVENT0("blink", "SVGImage::dataChanged::load"); |
| 607 loader.load(FrameLoadRequest( | 614 loader.load(FrameLoadRequest( |
| 608 0, blankURL(), | 615 0, blankURL(), |
| 609 SubstituteData(data(), AtomicString("image/svg+xml"), | 616 SubstituteData(data(), AtomicString("image/svg+xml"), |
| 610 AtomicString("UTF-8"), KURL(), ForceSynchronousLoad))); | 617 AtomicString("UTF-8"), KURL(), ForceSynchronousLoad))); |
| 611 | 618 |
| 612 // Set the concrete object size before a container size is available. | 619 // Set the concrete object size before a container size is available. |
| 613 m_intrinsicSize = roundedIntSize(concreteObjectSize(FloatSize( | 620 m_intrinsicSize = roundedIntSize(concreteObjectSize(FloatSize( |
| 614 LayoutReplaced::defaultWidth, LayoutReplaced::defaultHeight))); | 621 LayoutReplaced::defaultWidth, LayoutReplaced::defaultHeight))); |
| 615 } | 622 } |
| 616 | 623 |
| 617 return m_page ? SizeAvailable : SizeUnavailable; | 624 return m_page ? SizeAvailable : SizeUnavailable; |
| 618 } | 625 } |
| 619 | 626 |
| 620 String SVGImage::filenameExtension() const { | 627 String SVGImage::filenameExtension() const { |
| 621 return "svg"; | 628 return "svg"; |
| 622 } | 629 } |
| 623 | 630 |
| 624 } // namespace blink | 631 } // namespace blink |
| OLD | NEW |