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

Side by Side Diff: Source/core/rendering/RenderImage.cpp

Issue 594043005: Move paint code from RenderImage/RenderVideo into ImagePainter/VideoPainter. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Addressed comments. Created 6 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/RenderImage.h ('k') | Source/core/rendering/RenderReplaced.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org) 4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com) 5 * (C) 2006 Allan Sandfeld Jensen (kde@carewolf.com)
6 * (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 6 * (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved.
8 * Copyright (C) 2010 Google Inc. All rights reserved. 8 * Copyright (C) 2010 Google Inc. All rights reserved.
9 * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved. 9 * Copyright (C) Research In Motion Limited 2011-2012. All rights reserved.
10 * 10 *
(...skipping 20 matching lines...) Expand all
31 #include "core/HTMLNames.h" 31 #include "core/HTMLNames.h"
32 #include "core/editing/FrameSelection.h" 32 #include "core/editing/FrameSelection.h"
33 #include "core/fetch/ImageResource.h" 33 #include "core/fetch/ImageResource.h"
34 #include "core/fetch/ResourceLoadPriorityOptimizer.h" 34 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
35 #include "core/fetch/ResourceLoader.h" 35 #include "core/fetch/ResourceLoader.h"
36 #include "core/frame/LocalFrame.h" 36 #include "core/frame/LocalFrame.h"
37 #include "core/html/HTMLAreaElement.h" 37 #include "core/html/HTMLAreaElement.h"
38 #include "core/html/HTMLImageElement.h" 38 #include "core/html/HTMLImageElement.h"
39 #include "core/html/HTMLInputElement.h" 39 #include "core/html/HTMLInputElement.h"
40 #include "core/html/HTMLMapElement.h" 40 #include "core/html/HTMLMapElement.h"
41 #include "core/inspector/InspectorInstrumentation.h" 41 #include "core/paint/ImagePainter.h"
42 #include "core/paint/BoxPainter.h"
43 #include "core/rendering/HitTestResult.h" 42 #include "core/rendering/HitTestResult.h"
44 #include "core/rendering/PaintInfo.h" 43 #include "core/rendering/PaintInfo.h"
45 #include "core/rendering/RenderLayer.h" 44 #include "core/rendering/RenderLayer.h"
46 #include "core/rendering/RenderView.h" 45 #include "core/rendering/RenderView.h"
47 #include "core/rendering/TextRunConstructor.h" 46 #include "core/rendering/TextRunConstructor.h"
48 #include "core/svg/graphics/SVGImage.h" 47 #include "core/svg/graphics/SVGImage.h"
49 #include "platform/fonts/Font.h" 48 #include "platform/fonts/Font.h"
50 #include "platform/fonts/FontCache.h" 49 #include "platform/fonts/FontCache.h"
51 #include "platform/graphics/GraphicsContext.h"
52 #include "platform/graphics/GraphicsContextStateSaver.h"
53 50
54 namespace blink { 51 namespace blink {
55 52
56 float deviceScaleFactor(LocalFrame*); 53 float deviceScaleFactor(LocalFrame*);
57 54
58 using namespace HTMLNames; 55 using namespace HTMLNames;
59 56
60 RenderImage::RenderImage(Element* element) 57 RenderImage::RenderImage(Element* element)
61 : RenderReplaced(element, IntSize()) 58 : RenderReplaced(element, IntSize())
62 , m_didIncrementVisuallyNonEmptyPixelCount(false) 59 , m_didIncrementVisuallyNonEmptyPixelCount(false)
(...skipping 22 matching lines...) Expand all
85 RenderReplaced::destroy(); 82 RenderReplaced::destroy();
86 } 83 }
87 84
88 void RenderImage::setImageResource(PassOwnPtr<RenderImageResource> imageResource ) 85 void RenderImage::setImageResource(PassOwnPtr<RenderImageResource> imageResource )
89 { 86 {
90 ASSERT(!m_imageResource); 87 ASSERT(!m_imageResource);
91 m_imageResource = imageResource; 88 m_imageResource = imageResource;
92 m_imageResource->initialize(this); 89 m_imageResource->initialize(this);
93 } 90 }
94 91
95 // If we'll be displaying either alt text or an image, add some padding.
96 static const unsigned short paddingWidth = 4;
97 static const unsigned short paddingHeight = 4;
98
99 // Alt text is restricted to this maximum size, in pixels. These are 92 // Alt text is restricted to this maximum size, in pixels. These are
100 // signed integers because they are compared with other signed values. 93 // signed integers because they are compared with other signed values.
101 static const float maxAltTextWidth = 1024; 94 static const float maxAltTextWidth = 1024;
102 static const int maxAltTextHeight = 256; 95 static const int maxAltTextHeight = 256;
103 96
104 IntSize RenderImage::imageSizeForError(ImageResource* newImage) const 97 IntSize RenderImage::imageSizeForError(ImageResource* newImage) const
105 { 98 {
106 ASSERT_ARG(newImage, newImage); 99 ASSERT_ARG(newImage, newImage);
107 ASSERT_ARG(newImage, newImage->imageForRenderer(this)); 100 ASSERT_ARG(newImage, newImage->imageForRenderer(this));
108 101
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 265
273 if (newImage == m_imageResource->cachedImage()) { 266 if (newImage == m_imageResource->cachedImage()) {
274 // tell any potential compositing layers 267 // tell any potential compositing layers
275 // that the image is done and they can reference it directly. 268 // that the image is done and they can reference it directly.
276 contentChanged(ImageChanged); 269 contentChanged(ImageChanged);
277 } 270 }
278 } 271 }
279 272
280 void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf fset) 273 void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf fset)
281 { 274 {
282 LayoutUnit cWidth = contentWidth(); 275 ImagePainter(*this).paintReplaced(paintInfo, paintOffset);
283 LayoutUnit cHeight = contentHeight();
284
285 GraphicsContext* context = paintInfo.context;
286
287 if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) {
288 if (paintInfo.phase == PaintPhaseSelection)
289 return;
290
291 if (cWidth > 2 && cHeight > 2) {
292 const int borderWidth = 1;
293
294 LayoutUnit leftBorder = borderLeft();
295 LayoutUnit topBorder = borderTop();
296 LayoutUnit leftPad = paddingLeft();
297 LayoutUnit topPad = paddingTop();
298
299 // Draw an outline rect where the image should be.
300 context->setStrokeStyle(SolidStroke);
301 context->setStrokeColor(Color::lightGray);
302 context->setFillColor(Color::transparent);
303 context->drawRect(pixelSnappedIntRect(LayoutRect(paintOffset.x() + l eftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight)));
304
305 bool errorPictureDrawn = false;
306 LayoutSize imageOffset;
307 // When calculating the usable dimensions, exclude the pixels of
308 // the ouline rect so the error image/alt text doesn't draw on it.
309 LayoutUnit usableWidth = cWidth - 2 * borderWidth;
310 LayoutUnit usableHeight = cHeight - 2 * borderWidth;
311
312 RefPtr<Image> image = m_imageResource->image();
313
314 if (m_imageResource->errorOccurred() && !image->isNull() && usableWi dth >= image->width() && usableHeight >= image->height()) {
315 float deviceScaleFactor = blink::deviceScaleFactor(frame());
316 // Call brokenImage() explicitly to ensure we get the broken ima ge icon at the appropriate resolution.
317 pair<Image*, float> brokenImageAndImageScaleFactor = ImageResour ce::brokenImage(deviceScaleFactor);
318 image = brokenImageAndImageScaleFactor.first;
319 IntSize imageSize = image->size();
320 imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
321 // Center the error image, accounting for border and padding.
322 LayoutUnit centerX = (usableWidth - imageSize.width()) / 2;
323 if (centerX < 0)
324 centerX = 0;
325 LayoutUnit centerY = (usableHeight - imageSize.height()) / 2;
326 if (centerY < 0)
327 centerY = 0;
328 imageOffset = LayoutSize(leftBorder + leftPad + centerX + border Width, topBorder + topPad + centerY + borderWidth);
329 context->drawImage(image.get(), pixelSnappedIntRect(LayoutRect(p aintOffset + imageOffset, imageSize)), CompositeSourceOver, shouldRespectImageOr ientation());
330 errorPictureDrawn = true;
331 }
332
333 if (!m_altText.isEmpty()) {
334 const Font& font = style()->font();
335 const FontMetrics& fontMetrics = font.fontMetrics();
336 LayoutUnit ascent = fontMetrics.ascent();
337 LayoutPoint textRectOrigin = paintOffset;
338 textRectOrigin.move(leftBorder + leftPad + (paddingWidth / 2) - borderWidth, topBorder + topPad + (paddingHeight / 2) - borderWidth);
339 LayoutPoint textOrigin(textRectOrigin.x(), textRectOrigin.y() + ascent);
340
341 // Only draw the alt text if it'll fit within the content box,
342 // and only if it fits above the error image.
343 TextRun textRun = constructTextRun(this, font, m_altText, style( ), TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, DefaultTex tRunFlags | RespectDirection);
344 float textWidth = font.width(textRun);
345 TextRunPaintInfo textRunPaintInfo(textRun);
346 textRunPaintInfo.bounds = FloatRect(textRectOrigin, FloatSize(te xtWidth, fontMetrics.height()));
347 context->setFillColor(resolveColor(CSSPropertyColor));
348 if (textRun.direction() == RTL) {
349 int availableWidth = cWidth - static_cast<int>(paddingWidth) ;
350 textOrigin.move(availableWidth - ceilf(textWidth), 0);
351 }
352 if (errorPictureDrawn) {
353 if (usableWidth >= textWidth && fontMetrics.height() <= imag eOffset.height())
354 context->drawBidiText(font, textRunPaintInfo, textOrigin );
355 } else if (usableWidth >= textWidth && usableHeight >= fontMetri cs.height()) {
356 context->drawBidiText(font, textRunPaintInfo, textOrigin);
357 }
358 }
359 }
360 } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
361 LayoutRect contentRect = contentBoxRect();
362 contentRect.moveBy(paintOffset);
363 LayoutRect paintRect = replacedContentRect();
364 paintRect.moveBy(paintOffset);
365 bool clip = !contentRect.contains(paintRect);
366 if (clip) {
367 context->save();
368 context->clip(contentRect);
369 }
370
371 paintIntoRect(context, paintRect);
372
373 if (clip)
374 context->restore();
375 }
376 } 276 }
377 277
378 void RenderImage::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 278 void RenderImage::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
379 { 279 {
380 RenderReplaced::paint(paintInfo, paintOffset); 280 ImagePainter(*this).paint(paintInfo, paintOffset);
381
382 if (paintInfo.phase == PaintPhaseOutline)
383 paintAreaElementFocusRing(paintInfo);
384 }
385
386 void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
387 {
388 Document& document = this->document();
389
390 if (document.printing() || !document.frame()->selection().isFocusedAndActive ())
391 return;
392
393 Element* focusedElement = document.focusedElement();
394 if (!isHTMLAreaElement(focusedElement))
395 return;
396
397 HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
398 if (areaElement.imageElement() != node())
399 return;
400
401 // Even if the theme handles focus ring drawing for entire elements, it won' t do it for
402 // an area within an image, so we don't call RenderTheme::supportsFocusRing here.
403
404 Path path = areaElement.computePath(this);
405 if (path.isEmpty())
406 return;
407
408 RenderStyle* areaElementStyle = areaElement.computedStyle();
409 unsigned short outlineWidth = areaElementStyle->outlineWidth();
410 if (!outlineWidth)
411 return;
412
413 // FIXME: Clip path instead of context when Skia pathops is ready.
414 // https://crbug.com/251206
415 GraphicsContextStateSaver savedContext(*paintInfo.context);
416 paintInfo.context->clip(absoluteContentBox());
417 paintInfo.context->drawFocusRing(path, outlineWidth,
418 areaElementStyle->outlineOffset(),
419 resolveColor(areaElementStyle, CSSPropertyOutlineColor));
420 } 281 }
421 282
422 void RenderImage::areaElementFocusChanged(HTMLAreaElement* areaElement) 283 void RenderImage::areaElementFocusChanged(HTMLAreaElement* areaElement)
423 { 284 {
424 ASSERT(areaElement->imageElement() == node()); 285 ASSERT(areaElement->imageElement() == node());
425 286
426 Path path = areaElement->computePath(this); 287 Path path = areaElement->computePath(this);
427 if (path.isEmpty()) 288 if (path.isEmpty())
428 return; 289 return;
429 290
430 RenderStyle* areaElementStyle = areaElement->computedStyle(); 291 RenderStyle* areaElementStyle = areaElement->computedStyle();
431 unsigned short outlineWidth = areaElementStyle->outlineWidth(); 292 unsigned short outlineWidth = areaElementStyle->outlineWidth();
432 293
433 IntRect paintInvalidationRect = enclosingIntRect(path.boundingRect()); 294 IntRect paintInvalidationRect = enclosingIntRect(path.boundingRect());
434 paintInvalidationRect.moveBy(-absoluteContentBox().location()); 295 paintInvalidationRect.moveBy(-absoluteContentBox().location());
435 paintInvalidationRect.inflate(outlineWidth); 296 paintInvalidationRect.inflate(outlineWidth);
436 297
437 paintInvalidationOrMarkForLayout(false, &paintInvalidationRect); 298 paintInvalidationOrMarkForLayout(false, &paintInvalidationRect);
438 } 299 }
439 300
440 void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect )
441 {
442 IntRect alignedRect = pixelSnappedIntRect(rect);
443 if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() || alig nedRect.width() <= 0 || alignedRect.height() <= 0)
444 return;
445
446 RefPtr<Image> img = m_imageResource->image(alignedRect.width(), alignedRect. height());
447 if (!img || img->isNull())
448 return;
449
450 HTMLImageElement* imageElt = isHTMLImageElement(node()) ? toHTMLImageElement (node()) : 0;
451 CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator () : CompositeSourceOver;
452 Image* image = img.get();
453 InterpolationQuality interpolationQuality = BoxPainter::chooseInterpolationQ uality(*this, context, image, image, alignedRect.size());
454
455 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", " data", InspectorPaintImageEvent::data(*this));
456 // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeli ne migrates to tracing.
457 InspectorInstrumentation::willPaintImage(this);
458 InterpolationQuality previousInterpolationQuality = context->imageInterpolat ionQuality();
459 context->setImageInterpolationQuality(interpolationQuality);
460 context->drawImage(image, alignedRect, compositeOperator, shouldRespectImage Orientation());
461 context->setImageInterpolationQuality(previousInterpolationQuality);
462 InspectorInstrumentation::didPaintImage(this);
463 }
464
465 bool RenderImage::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox*) const 301 bool RenderImage::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox*) const
466 { 302 {
467 if (!RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(bleedAvoidan ce)) 303 if (!RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(bleedAvoidan ce))
468 return false; 304 return false;
469 305
470 return !const_cast<RenderImage*>(this)->boxDecorationBackgroundIsKnownToBeOb scured(); 306 return !const_cast<RenderImage*>(this)->boxDecorationBackgroundIsKnownToBeOb scured();
471 } 307 }
472 308
473 bool RenderImage::foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned) const 309 bool RenderImage::foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned) const
474 { 310 {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 return 0; 462 return 0;
627 463
628 ImageResource* cachedImage = m_imageResource->cachedImage(); 464 ImageResource* cachedImage = m_imageResource->cachedImage();
629 if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage( )) 465 if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage( ))
630 return toSVGImage(cachedImage->image())->embeddedContentBox(); 466 return toSVGImage(cachedImage->image())->embeddedContentBox();
631 467
632 return 0; 468 return 0;
633 } 469 }
634 470
635 } // namespace blink 471 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderImage.h ('k') | Source/core/rendering/RenderReplaced.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698