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 |