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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 intrinsicSize = rootElement->currentViewBoxRect().size(); | 186 intrinsicSize = rootElement->currentViewBoxRect().size(); |
187 | 187 |
188 if (!intrinsicSize.isEmpty()) | 188 if (!intrinsicSize.isEmpty()) |
189 return expandedIntSize(intrinsicSize); | 189 return expandedIntSize(intrinsicSize); |
190 | 190 |
191 // As last resort, use CSS replaced element fallback size. | 191 // As last resort, use CSS replaced element fallback size. |
192 return IntSize(300, 150); | 192 return IntSize(300, 150); |
193 } | 193 } |
194 | 194 |
195 void SVGImage::drawForContainer(SkCanvas* canvas, const SkPaint& paint, const Fl
oatSize containerSize, float zoom, const FloatRect& dstRect, | 195 void SVGImage::drawForContainer(SkCanvas* canvas, const SkPaint& paint, const Fl
oatSize containerSize, float zoom, const FloatRect& dstRect, |
196 const FloatRect& srcRect) | 196 const FloatRect& srcRect, const KURL& urlWithFragment) |
197 { | 197 { |
198 if (!m_page) | 198 if (!m_page) |
199 return; | 199 return; |
200 | 200 |
201 // Temporarily disable the image observer to prevent changeInRect() calls du
e re-laying out the image. | 201 // Temporarily disable the image observer to prevent changeInRect() calls du
e re-laying out the image. |
202 ImageObserverDisabler imageObserverDisabler(this); | 202 ImageObserverDisabler imageObserverDisabler(this); |
203 | 203 |
204 IntSize roundedContainerSize = roundedIntSize(containerSize); | 204 IntSize roundedContainerSize = roundedIntSize(containerSize); |
205 setContainerSize(roundedContainerSize); | 205 setContainerSize(roundedContainerSize); |
206 | 206 |
207 FloatRect scaledSrc = srcRect; | 207 FloatRect scaledSrc = srcRect; |
208 scaledSrc.scale(1 / zoom); | 208 scaledSrc.scale(1 / zoom); |
209 | 209 |
210 // Compensate for the container size rounding by adjusting the source rect. | 210 // Compensate for the container size rounding by adjusting the source rect. |
211 FloatSize adjustedSrcSize = scaledSrc.size(); | 211 FloatSize adjustedSrcSize = scaledSrc.size(); |
212 adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(),
roundedContainerSize.height() / containerSize.height()); | 212 adjustedSrcSize.scale(roundedContainerSize.width() / containerSize.width(),
roundedContainerSize.height() / containerSize.height()); |
213 scaledSrc.setSize(adjustedSrcSize); | 213 scaledSrc.setSize(adjustedSrcSize); |
214 | 214 |
215 draw(canvas, paint, dstRect, scaledSrc, DoNotRespectImageOrientation, ClampI
mageToSourceRect); | 215 frameView()->processUrlFragment(urlWithFragment); |
| 216 |
| 217 drawInternal(canvas, paint, dstRect, scaledSrc, DoNotRespectImageOrientation
, ClampImageToSourceRect); |
216 } | 218 } |
217 | 219 |
218 PassRefPtr<SkImage> SVGImage::imageForCurrentFrame() | 220 PassRefPtr<SkImage> SVGImage::imageForCurrentFrame() |
219 { | 221 { |
220 if (!m_page) | 222 if (!m_page) |
221 return nullptr; | 223 return nullptr; |
222 | 224 |
223 SkPictureRecorder recorder; | 225 SkPictureRecorder recorder; |
224 SkCanvas* canvas = recorder.beginRecording(width(), height()); | 226 SkCanvas* canvas = recorder.beginRecording(width(), height()); |
225 drawForContainer(canvas, SkPaint(), size(), 1, rect(), rect()); | 227 drawForContainer(canvas, SkPaint(), size(), 1, rect(), rect(), KURL()); |
226 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording()); | 228 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording()); |
227 | 229 |
228 return adoptRef( | 230 return adoptRef( |
229 SkImage::NewFromPicture(picture.get(), SkISize::Make(width(), height()),
nullptr, nullptr)); | 231 SkImage::NewFromPicture(picture.get(), SkISize::Make(width(), height()),
nullptr, nullptr)); |
230 } | 232 } |
231 | 233 |
232 void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize
containerSize, | 234 void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize
containerSize, |
233 float zoom, const FloatRect& srcRect, const FloatSize& tileScale, const Floa
tPoint& phase, | 235 float zoom, const FloatRect& srcRect, const FloatSize& tileScale, const Floa
tPoint& phase, |
234 SkXfermode::Mode compositeOp, const FloatRect& dstRect, | 236 SkXfermode::Mode compositeOp, const FloatRect& dstRect, |
235 const IntSize& repeatSpacing) | 237 const IntSize& repeatSpacing, const KURL& urlWithFragment) |
236 { | 238 { |
237 // Tile adjusted for scaling/stretch. | 239 // Tile adjusted for scaling/stretch. |
238 FloatRect tile(srcRect); | 240 FloatRect tile(srcRect); |
239 tile.scale(tileScale.width(), tileScale.height()); | 241 tile.scale(tileScale.width(), tileScale.height()); |
240 | 242 |
241 // Expand the tile to account for repeat spacing. | 243 // Expand the tile to account for repeat spacing. |
242 FloatRect spacedTile(tile); | 244 FloatRect spacedTile(tile); |
243 spacedTile.expand(repeatSpacing); | 245 spacedTile.expand(repeatSpacing); |
244 | 246 |
245 SkPictureBuilder patternPicture(spacedTile, nullptr, context); | 247 SkPictureBuilder patternPicture(spacedTile, nullptr, context); |
246 if (!DrawingRecorder::useCachedDrawingIfPossible(patternPicture.context(), *
this, DisplayItem::Type::SVGImage)) { | 248 if (!DrawingRecorder::useCachedDrawingIfPossible(patternPicture.context(), *
this, DisplayItem::Type::SVGImage)) { |
247 DrawingRecorder patternPictureRecorder(patternPicture.context(), *this,
DisplayItem::Type::SVGImage, spacedTile); | 249 DrawingRecorder patternPictureRecorder(patternPicture.context(), *this,
DisplayItem::Type::SVGImage, spacedTile); |
248 // When generating an expanded tile, make sure we don't draw into the sp
acing area. | 250 // When generating an expanded tile, make sure we don't draw into the sp
acing area. |
249 if (tile != spacedTile) | 251 if (tile != spacedTile) |
250 patternPicture.context().clip(tile); | 252 patternPicture.context().clip(tile); |
251 SkPaint paint; | 253 SkPaint paint; |
252 drawForContainer(patternPicture.context().canvas(), paint, containerSize
, zoom, tile, srcRect); | 254 drawForContainer(patternPicture.context().canvas(), paint, containerSize
, zoom, tile, srcRect, urlWithFragment); |
253 } | 255 } |
254 RefPtr<const SkPicture> tilePicture = patternPicture.endRecording(); | 256 RefPtr<const SkPicture> tilePicture = patternPicture.endRecording(); |
255 | 257 |
256 SkMatrix patternTransform; | 258 SkMatrix patternTransform; |
257 patternTransform.setTranslate(phase.x() + spacedTile.x(), phase.y() + spaced
Tile.y()); | 259 patternTransform.setTranslate(phase.x() + spacedTile.x(), phase.y() + spaced
Tile.y()); |
258 RefPtr<SkShader> patternShader = adoptRef(SkShader::CreatePictureShader( | 260 RefPtr<SkShader> patternShader = adoptRef(SkShader::CreatePictureShader( |
259 tilePicture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMod
e, | 261 tilePicture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMod
e, |
260 &patternTransform, nullptr)); | 262 &patternTransform, nullptr)); |
261 | 263 |
262 SkPaint paint; | 264 SkPaint paint; |
(...skipping 10 matching lines...) Expand all Loading... |
273 | 275 |
274 SkXfermode::Mode xfermode; | 276 SkXfermode::Mode xfermode; |
275 if (SkXfermode::AsMode(paint.getXfermode(), &xfermode)) { | 277 if (SkXfermode::AsMode(paint.getXfermode(), &xfermode)) { |
276 if (xfermode != SkXfermode::kSrcOver_Mode) | 278 if (xfermode != SkXfermode::kSrcOver_Mode) |
277 return true; | 279 return true; |
278 } | 280 } |
279 | 281 |
280 return false; | 282 return false; |
281 } | 283 } |
282 | 284 |
283 void SVGImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dst
Rect, const FloatRect& srcRect, RespectImageOrientationEnum, ImageClampingMode) | 285 void SVGImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dst
Rect, const FloatRect& srcRect, |
| 286 RespectImageOrientationEnum shouldRespectImageOrientation, ImageClampingMode
clampMode) |
284 { | 287 { |
285 if (!m_page) | 288 if (!m_page) |
286 return; | 289 return; |
287 | 290 |
| 291 // Reset any previous URL fragment identifier. |
| 292 frameView()->processUrlFragment(KURL()); |
| 293 |
| 294 drawInternal(canvas, paint, dstRect, srcRect, shouldRespectImageOrientation,
clampMode); |
| 295 } |
| 296 |
| 297 void SVGImage::drawInternal(SkCanvas* canvas, const SkPaint& paint, const FloatR
ect& dstRect, const FloatRect& srcRect, |
| 298 RespectImageOrientationEnum, ImageClampingMode) |
| 299 { |
288 FrameView* view = frameView(); | 300 FrameView* view = frameView(); |
289 view->resize(containerSize()); | 301 view->resize(containerSize()); |
290 | 302 |
291 // Always call processUrlFragment, even if the url is empty, because | |
292 // there may have been a previous url/fragment that needs to be reset. | |
293 view->processUrlFragment(m_url); | |
294 | |
295 SkPictureBuilder imagePicture(dstRect); | 303 SkPictureBuilder imagePicture(dstRect); |
296 { | 304 { |
297 ClipRecorder clipRecorder(imagePicture.context(), *this, DisplayItem::Cl
ipNodeImage, LayoutRect(enclosingIntRect(dstRect))); | 305 ClipRecorder clipRecorder(imagePicture.context(), *this, DisplayItem::Cl
ipNodeImage, LayoutRect(enclosingIntRect(dstRect))); |
298 | 306 |
299 // We can only draw the entire frame, clipped to the rect we want. So co
mpute where the top left | 307 // We can only draw the entire frame, clipped to the rect we want. So co
mpute where the top left |
300 // of the image would be if we were drawing without clipping, and transl
ate accordingly. | 308 // of the image would be if we were drawing without clipping, and transl
ate accordingly. |
301 FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / sr
cRect.height()); | 309 FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / sr
cRect.height()); |
302 FloatSize topLeftOffset(srcRect.location().x() * scale.width(), srcRect.
location().y() * scale.height()); | 310 FloatSize topLeftOffset(srcRect.location().x() * scale.width(), srcRect.
location().y() * scale.height()); |
303 FloatPoint destOffset = dstRect.location() - topLeftOffset; | 311 FloatPoint destOffset = dstRect.location() - topLeftOffset; |
304 AffineTransform transform = AffineTransform::translation(destOffset.x(),
destOffset.y()); | 312 AffineTransform transform = AffineTransform::translation(destOffset.x(),
destOffset.y()); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 | 487 |
480 return m_page; | 488 return m_page; |
481 } | 489 } |
482 | 490 |
483 String SVGImage::filenameExtension() const | 491 String SVGImage::filenameExtension() const |
484 { | 492 { |
485 return "svg"; | 493 return "svg"; |
486 } | 494 } |
487 | 495 |
488 } | 496 } |
OLD | NEW |